glrmask
API reference for glrmask 0.3.0.
GLRMask is a grammar-constrained decoding library for high-throughput LLM serving. It is optimized for fast mask computation with extremely low tail latency, even for complex grammars.
GLRMask supports general context-free grammars, including ambiguous ones. It accepts JSON schemas and Lark grammars. GLRM is its internal grammar format.
Installation
python -m pip install glrmask==0.3.0
Quickstart
import glrmask
vocab = glrmask.Vocab.from_id_to_bytes({0: b"hello", 1: b" ", 2: b"world"})
grammar = glrmask.Grammar.from_ebnf('start ::= "hello" " " "world"')
constraint = grammar.compile(vocab)
state = constraint.start()
for token_id, expected in [(0, [True, False, False]),
(1, [False, True, False]),
(2, [False, False, True])]:
assert state.mask().tolist() == expected
state.commit_token(token_id)
assert state.is_accepting()
Python masks are NumPy Boolean arrays indexed by original model token ID.
Core concepts
GLRMask has four core types:
Grammar: source grammar semantics and bindings.PreparedGrammar: reusable vocabulary-specific compiled machinery, which can still have unresolved bindings.Constraint: a closed, runnable grammar compiled against a vocabulary.ConstraintState: the mutable state for one generated sequence.
Compile a Grammar directly, or use prepare() and link() for reusable components. Create a state with start(), then compute the next-token mask, sample an allowed token, and commit it.
Grammar and PreparedGrammar keep reusable definitions with mutable bindings. bind() fills one declared slot on the handle. Clones and previously attached children retain independent binding snapshots; a failed bind leaves the handle unchanged.
The class and method reference below is generated from the selected published wheel.
Optional metadata for composition boundaries, independent of the masking optimization. A request at final link overrides the prepared request.
Immutable runnable grammar and root stopping policy. Reuse across sequences; each start creates independent mutable state.
Rejects malformed or incompatible artifacts. Supply vocab for external-vocabulary artifacts; it must match the original mapping.
Sorted, distinct application marker IDs, independent of model token IDs.
Packed 32-bit word count for fill_mask, not the Boolean-array length returned by mask.
Embeds the vocabulary by default. With external_vocab=True, loading requires the exact original token-ID/byte mapping, not merely the same vocabulary size.
Mutable state for one generated sequence. Query a mask, sample an allowed original ID, then commit it. Clone to branch the sequence.
Advance by raw bytes rather than model token events. This does not substitute for committing exact-token or end-token events.
Unknown IDs raise an error. Forbidden IDs reject the state and may also raise an error; subsequent masks are zero. An allowed end token terminates the sequence; later commits raise an error.
Fill a contiguous, writable 1-D NumPy int32 array with at least Constraint.mask_len() words. Bit id % 32 of word id // 32 represents that original ID. Extra words are zeroed. Signed words retain all 32 mask bits.
Read-only lookahead of up to 10,000 inevitable original IDs. Stops when the root can accept or multiple IDs are possible, including byte aliases. Does not commit or construct a full mask; proof/resource failures raise errors.
The current prefix is a complete grammar match; further tokens may still be allowed. This alone does not commit an end token.
Initial or most recent commit’s (marker_id, absolute_byte_offset) batch, sorted by offset then ID, with duplicate pairs removed. These are possible observations, not captures or promises about the final parse. A failed commit clears the batch; mask and forcing queries leave it unchanged.
One token event chosen from a vocabulary-bound set. Vocabularies must have the same ID-to-byte mapping and exact-only IDs, even for a singleton. An empty set matches nothing.
Reusable source grammar with mutable bindings. bind changes this handle; clones and already attached children keep independent snapshots. Parsing and vocabulary checks can be deferred until preparation or compilation.
Fill a declared slot once. Use :: for nested paths, after attaching the parent. Token slots require Token or ExactTokens. Attached children are snapshots; failed binds leave this handle unchanged.
Requires every slot to be bound. end_tokens are root generation controls, allowed only at acceptance; commit the selected end token before stopping. Their policy is not inherited by an embedded child. optimization defaults to AUTO.
Adapt one vocabulary-bound token event to a grammar fragment. Adds no byte spelling, ignore rule or root end-token policy.
GLRM supports typed external slots; fill them with bind before compiling a runnable root.
Accepts JSON text or a JSON-serializable object. The importer implements a subset of JSON Schema: unsupported assertions may be silently weakened. Validate generated values separately when full schema conformance matters.
The default recognition profile and the llm extension profile differ in accepted syntax. Named token atoms require explicit token_names mappings; they are never inferred from tokenizer spellings.
Compile vocabulary-specific machinery while retaining unresolved slots. Reuse it with different bindings, then link. Only the boundary metadata request is retained for final link.
Includes unresolved slots in attached open children. Diagnostic expansion is bounded and may raise an error for very large shared graphs.
Build-time versus per-token cost. The modes preserve the supported grammar language.
Reusable compiled machinery tied to one vocabulary, possibly with open slots. Bind prepared children or exact events, then link a runnable root. Bindings are mutable on this handle; clones and attached children retain independent snapshots.
Fill a declared slot once. Attach a parent before binding its descendants. Prepared children must use the same byte mapping and exact-only IDs. Attached children are snapshots; failed binds leave this handle unchanged.
Requires all slots to be bound. Selects final optimization and root end tokens; an explicit boundary request overrides the prepared request. End tokens become allowed only at acceptance and must be committed before stopping.
Rejects malformed or incompatible artifacts. An optional vocabulary must match the saved token-ID/byte mapping and lets the loaded graph share its caches.
Unresolved paths, including slots inside attached children. Diagnostic expansion is bounded.
An unresolved typed slot. Paths distinguish the same local name in different attached children.
An original token ID with no vocabulary identity. Only ID membership is checked against the target vocabulary; the same ID can refer to different bytes. Use vocab.tokens([id]) for a vocabulary-bound singleton.
Original model IDs mapped to exact token bytes. IDs may be sparse; masks keep their original positions. Reuse one vocabulary across components to share compilation caches.
String keys are UTF-8 encoded; byte keys are used verbatim. IDs must fit an unsigned 32-bit integer.
Use the tokenizer’s exact decoded bytes, including partial UTF-8 sequences, rather than display spellings.
Extract the byte vocabulary from a llama-cpp-python Llama. EOG, control, unused and empty-piece tokens are omitted from byte matching; use llama_cpp_end_token_ids for the root stopping policy.
EOG IDs discovered by from_llama_cpp; pass them as end_tokens when compiling or linking.
Union of nonempty Python ranges with step 1 or -1 and exclusive stops. Overlapping or adjacent ranges merge; unknown IDs are errors. Empty input matches nothing. Use tokens for arbitrary strides.