概述
Outlines 允许使用 Lark 语法来指导生成。这些语法用于构建解析器,在生成过程中过滤掉不兼容的 token。最终结果是生成的内容符合语法的生成规则。
创建语法入门
要为 Outlines 创建语法,需要对 Lark 语法有扎实的理解。以下是入门方法
与 Outlines 的兼容性
需要注意的是,并非所有 Lark 语法都适用于 Outlines。可能需要进行更改以确保兼容性。
LALR(1) 解析器
Outlines 使用 Lark 的 LALR(1) 解析器,这意味着语法必须至少在下一个 token 之前(一个 token 预读)是无歧义的。请阅读 Lark 官方 LALR(1) 解析器文档 这里。
如果你的语法有歧义,你将在运行时收到以下错误
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