Skip to content

Commit d06448a

Browse files
committed
Link gbnf_to_lark.py script; fix links; refer to llg docs for lexemes
1 parent 5475357 commit d06448a

File tree

1 file changed

+5
-45
lines changed

1 file changed

+5
-45
lines changed

docs/llguidance.md

Lines changed: 5 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[LLGuidance](https://github.com/guidance-ai/llguidance) is a library for constrained decoding (also called constrained sampling or structured outputs) for Large Language Models (LLMs). Initially developed as the backend for the [Guidance](https://github.com/guidance-ai/guidance) library, it can also be used independently.
44

5-
LLGuidance supports JSON Schemas and arbitrary context-free grammars (CFGs) written in a [variant](https://github.com/guidance-ai/llguidance/blob/main/parser/src/lark/README.md) of Lark syntax. It is [very fast](https://github.com/guidance-ai/jsonschemabench/tree/main/maskbench) and has [excellent](https://github.com/guidance-ai/llguidance/blob/main/parser/src/json/README.md) JSON Schema coverage but requires the Rust compiler, which complicates the llama.cpp build process.
5+
LLGuidance supports JSON Schemas and arbitrary context-free grammars (CFGs) written in a [variant](https://github.com/guidance-ai/llguidance/blob/main/docs/syntax.md) of Lark syntax. It is [very fast](https://github.com/guidance-ai/jsonschemabench/tree/main/maskbench) and has [excellent](https://github.com/guidance-ai/llguidance/blob/main/docs/json_schema.md) JSON Schema coverage but requires the Rust compiler, which complicates the llama.cpp build process.
66

77
## Building
88

@@ -19,6 +19,8 @@ This requires the Rust compiler and the `cargo` tool to be [installed](https://w
1919

2020
There are no new command-line arguments or modifications to `common_params`. When enabled, grammars starting with `%llguidance` are passed to LLGuidance instead of the [current](../grammars/README.md) llama.cpp grammars. Additionally, JSON Schema requests (e.g., using the `-j` argument in `llama-cli`) are also passed to LLGuidance.
2121

22+
For your existing GBNF grammars, you can use [gbnf_to_lark.py script](https://github.com/guidance-ai/llguidance/blob/main/scripts/gbnf_to_lark.py) to convert them to LLGuidance Lark-like format.
23+
2224
## Performance
2325

2426
Computing a "token mask" (i.e., the set of allowed tokens) for a llama3 tokenizer with 128k tokens takes, on average, 50μs of single-core CPU time for the [JSON Schema Bench](https://github.com/guidance-ai/jsonschemabench). The p99 time is 0.5ms, and the p100 time is 20ms. These results are due to the lexer/parser split and several [optimizations](https://github.com/guidance-ai/llguidance/blob/main/docs/optimizations.md).
@@ -38,53 +40,11 @@ Unsupported schemas result in an error message—no keywords are silently ignore
3840
GBNF lacks the concept of a lexer.
3941

4042
Most programming languages, including JSON, use a two-step process: a lexer (built with regular expressions) converts a byte stream into lexemes, which are then processed by a CFG parser. This approach is faster because lexers are cheaper to evaluate, and there is ~10x fewer lexemes than bytes.
41-
4243
LLM tokens often align with lexemes, so the parser is engaged in under 0.5% of tokens, with the lexer handling the rest.
4344

4445
However, the user has to provide the distinction between lexemes and CFG symbols. In [Lark](https://github.com/lark-parser/lark), lexeme names are uppercase, while CFG symbols are lowercase.
45-
46-
For example, a simplified C grammar in Lark:
47-
48-
```lark
49-
%llguidance {}
50-
51-
start: program
52-
53-
program: (function_definition | declaration)*
54-
55-
function_definition: type ID "(" parameter_list? ")" "{" statement* "}"
56-
parameter_list: parameter ("," parameter)*
57-
parameter: type ID
58-
59-
declaration: type variable_list ";"
60-
variable_list: ID ("," ID)*
61-
62-
type: "int" | "float" | "char" | "void"
63-
64-
statement: declaration
65-
| assignment ";"
66-
| "return" expr ";"
67-
| if_statement
68-
| while_statement
69-
| expr ";"
70-
71-
assignment: ID "=" expr
72-
expr: term (("+" | "-") term)*
73-
term: factor (("*" | "/") factor)*
74-
factor: ID | NUMBER | "(" expr ")"
75-
76-
if_statement: "if" "(" expr ")" "{" statement* "}" ("else" "{" statement* "}")?
77-
while_statement: "while" "(" expr ")" "{" statement* "}"
78-
79-
ID: /[a-zA-Z_][a-zA-Z0-9_]*/
80-
NUMBER: /[0-9]+/
81-
82-
%ignore /[ \t\f\r\n]+/
83-
```
84-
85-
In GBNF, lexemes like `ID` and `NUMBER` are typically lowercase and converted to CFG rules instead of remaining regular expressions. Ignoring whitespace would need to be explicitly specified everywhere.
86-
87-
Writing grammars without lexemes would be slower and might result in "single-byte lexeme" errors in LLGuidance, fixable by renaming symbols to uppercase.
46+
The [gbnf_to_lark.py script](https://github.com/guidance-ai/llguidance/blob/main/scripts/gbnf_to_lark.py) can often take care of this automatically.
47+
See [LLGuidance syntax docs](https://github.com/guidance-ai/llguidance/blob/main/docs/syntax.md#terminals-vs-rules) for more details.
8848

8949
## Error Handling
9050

0 commit comments

Comments
 (0)