跳到内容

概述

Outlines 允许使用 Lark 语法来指导生成。这些语法用于构建解析器,在生成过程中过滤掉不兼容的 token。最终结果是生成的内容符合语法的生成规则。

创建语法入门

要为 Outlines 创建语法,需要对 Lark 语法有扎实的理解。以下是入门方法

  • 请阅读 Lark 的语法文档 这里
  • 请查看 Outlines 的现有语法 这里

与 Outlines 的兼容性

需要注意的是,并非所有 Lark 语法都适用于 Outlines。可能需要进行更改以确保兼容性。

LALR(1) 解析器

Outlines 使用 Lark 的 LALR(1) 解析器,这意味着语法必须至少在下一个 token 之前(一个 token 预读)是无歧义的。请阅读 Lark 官方 LALR(1) 解析器文档 这里

如果你的语法有歧义,你将在运行时收到以下错误

GrammarError: Reduce/Reduce collision in Terminal('B') between the following rules:

Regex 终端限制

Outlines 使用 Interegular 库将终端转换为有限状态机。并非所有正则表达式都适用于 Interegular,后续小节将介绍缓解方法。

避免使用 Lookarounds

在保持相同功能的同时移除 lookaround 的示例

示例:转义字符串

摘自 common.lark 中 Outlines 修改后的 ESCAPED_STRING

之前

_STRING_INNER: /.*?/
_STRING_ESC_INNER: _STRING_INNER /(?<!\\)(\\\\)*?/

ESCAPED_STRING : "\"" _STRING_ESC_INNER "\""

之后

_NON_CONTROL_CHAR: /([^"\\\x00-\x1F\x7F-\x9F])/
_ESCAPED_CHAR: /\\/ (_NON_CONTROL_CHAR | /\\/ | /"/)
ESCAPED_STRING_INNER: _NON_CONTROL_CHAR | _ESCAPED_CHAR
ESCAPED_STRING: /"/ ESCAPED_STRING_INNER* /"/

避免使用反向引用

反向引用,例如 ([ab]^*)\1,不能由有限状态机模拟,如果使用会导致错误。

创建有效语法

你可以使用 Outlines 的测试套件来验证你的语法。

1) 创建你的语法

创建你的语法文件,命名为 your_new_grammar.lark,并遵循上述指导原则。将其添加到 outlines/grammars/ 目录中(确保包含归属并许可证兼容)。

更新 outlines/grammars.py,添加一行包含你的语法。

2) 测试你的语法

测试语法的假阴性,确保可以生成示例语法: - 将符合语法的有效示例输出添加到 tests/benchmark/cfg_samples/your_new_grammar/ 目录 - 通过 pytest -s tests/fsm/test_cfg_guide.py::test_cfg_grammar_sample -k "your_new_grammar" 运行你的语法测试

测试语法的假阳性,确保不会生成无效输出。

目前没有内置的假阳性测试工具。建议你通过以下方式进行冒烟测试

from outlines import models, generate, grammars
model = models.transformers("mistralai/Mistral-7B-v0.1")
generator = generate.cfg(model, grammars.your_new_grammar)
result = generator(<your prompt to generate output for your grammar>)
print(result)

转换

有一些工具可用于将其他语法转换为 lark。这些工具可作为起点。但是,通常需要进行额外调整以确保在 Outlines 中的完全兼容性和正常运行。

工具: - Lark 内置的“Nearley-to-Lark”转换器 https://lark-parser.readthedocs.io/en/latest/tools.html - 将 ANTLR4 转换为 Lark(注意,大多数 antlr4 语法与 LALR(1) 不兼容,因此需要额外调整) https://github.com/kaby76/Domemtech.Trash/blob/main/src/trconvert/readme.md - 从 Yacc 文件提取 EBNF https://www.bottlecaps.de/rr/ui

参考语法: - Github Lark 语法 https://github.com/search?q=path%3A*.lark&type=code - Github Nearley 语法 https://github.com/search?q=path%3A*.ne+%22-%3E%22&type=code - Antlr4 语法 https://github.com/antlr/grammars-v4/ - 语法动物园 https://slebok.github.io/zoo/index.html#html