ConstrainedDecoding
steerability.algorithms.output_control.constrained_decoding
args
Constrained decoding argument validation.
control
Constrained decoding: declarative structured outputs rendered per execution arm.
ConstrainedDecoding
Bases: OutputControl
Constrained decoding from one declarative source, rendered per execution arm.
A declarative constraint (JSON schema, regex, EBNF grammar, or a choice set) renders two
ways from one source: in process it compiles into a client-side automaton driving a
ConstraintProcessor (masking every logit the grammar forbids), and on vLLM backends it
renders onto the engine's native structured-output request parameters, consumed in place of
the live processor. Both arms compile from the same source, so shared cases under greedy
decode produce identically constrained outputs; the masking implementation (client automaton
or engine grammar backend) is the documented difference between the arms.
A control constructed with a live automaton object has no declarative form and runs in
process only. In process the constraint compiles to a client-side xgrammar automaton; a
vLLM-only pipeline never compiles client-side and lowers the constraint to native
structured outputs.
Structured outputs do not apply to prompt logprobs, so include_in_scoring=True requires
the in-process backend at score; include_in_scoring=False opts out of scoring.
Source code in steerability/algorithms/output_control/constrained_decoding/control.py
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | |
RUNTIME_KWARGS_SCHEMA = []
class-attribute
instance-attribute
args = self.Args.validate(*args, **kwargs)
instance-attribute
enabled = True
class-attribute
instance-attribute
include_in_scoring = True
class-attribute
instance-attribute
same_model_forwards = False
class-attribute
instance-attribute
supports_batching = False
class-attribute
instance-attribute
cleanup()
Release resources allocated during steer().
Override in subclasses that allocate GPU memory or other resources during steering. Default no-op.
Source code in steerability/algorithms/core/base_control.py
195 196 197 198 199 200 201 | |
clone_for_call(seed=None)
A configuration-preserving shallow clone for one generation call.
The clone shares steer-time artifacts (memories, steering vectors, attached tokenizers)
with the original but has its own attribute namespace, so per-call attribute mutation on
the clone never races another call using the original. When seed is given and the
control defines reseed(seed), the clone's client-side RNG is re-seeded.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
seed
|
int | None
|
Optional seed forwarded to the clone's |
None
|
Returns:
| Type | Description |
|---|---|
BaseControl
|
The clone. |
Source code in steerability/algorithms/core/base_control.py
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | |
export_constraint(runtime_kwargs=None)
The declarative source, or None for automaton-object configurations.
Source code in steerability/algorithms/output_control/constrained_decoding/control.py
67 68 69 | |
export_generation_params(runtime_kwargs=None)
The control's sampling-expressible contribution, or None.
A control whose behavior is expressible as normalized generation parameters returns a
mapping over a subset of stop_strings, stop_token_ids, max_new_tokens, and
min_new_tokens; the pipeline merges it into the call's GenerationParams (stop rules
union with the caller's; token bounds only tighten) and does not additionally collect
the control's live processors and criteria for that call, so the control executes on
every backend through the session's composed stop rules. The default returns None, which
keeps the control on the live processor/criteria mechanism.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
runtime_kwargs
|
dict | None
|
Per-call parameters supplied to |
None
|
Returns:
| Type | Description |
|---|---|
Mapping[str, Any] | None
|
The parameter contribution, or None. |
Source code in steerability/algorithms/output_control/base.py
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | |
export_processor_spec(runtime_kwargs=None)
The control's engine-hosted processor form, or None.
A control whose per-step logit math is expressible in an engine's served processor
vocabulary returns a ProcessorSpec; on a backend advertising
Capability.PER_STEP_LOGIT_SPECS with the spec's kind, the pipeline submits it as a
ProcessorSpecEntry in place of the control's live processor. The default returns
None, which keeps the control on the live processor mechanism.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
runtime_kwargs
|
dict | None
|
Per-call parameters supplied to |
None
|
Returns:
| Type | Description |
|---|---|
ProcessorSpec | None
|
The processor spec, or None. |
Source code in steerability/algorithms/output_control/base.py
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | |
export_state()
Steer-time state to persist when freezing, keyed by logical name.
Values are typed artifacts (SteeringVector, Probe, ProbeSet, a Memory
implementation, CheckpointArtifact, LoRAArtifact, torch.Tensor, or a Path to an
on-disk product). Must be called after steer(). The default returns an empty mapping
(nothing to persist).
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Mapping from logical name to artifact value. |
Source code in steerability/algorithms/core/base_control.py
117 118 119 120 121 122 123 124 125 126 127 128 | |
fit_identity()
The object whose canonical form defines this control's fit digest, or None.
The digest detects recipe edits that invalidate frozen artifacts, so the returned object should cover exactly the inputs a re-fit would consume (training data, fit specs) and exclude inert application parameters (strengths, multipliers). The default returns None (no fits).
Returns:
| Type | Description |
|---|---|
Any | None
|
The fit-identity object, or None. |
Source code in steerability/algorithms/core/base_control.py
161 162 163 164 165 166 167 168 169 170 171 172 | |
frozen_form(state)
The (registry method key, constructor kwargs) of this control's frozen form.
state is the output of export_state(); artifact values inside the returned kwargs
are replaced by store references at encode time. When steer_fits() is empty and
state is empty, the recipe is the frozen form and the control's own key and recipe
args are returned unchanged. A control whose freeze expands into several entries may
return a list of (method key, kwargs) pairs instead.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
dict[str, Any]
|
The output of |
required |
Returns:
| Type | Description |
|---|---|
tuple[str, dict[str, Any]]
|
The frozen method key and its constructor kwargs. |
Raises:
| Type | Description |
|---|---|
NotFreezableError
|
If the control produces fits or state but declares no frozen form. |
Source code in steerability/algorithms/core/base_control.py
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | |
get_logits_processors(input_ids, runtime_kwargs, **kwargs)
The in-process arm: one ConstraintProcessor over the (compiled) automaton.
Source code in steerability/algorithms/output_control/constrained_decoding/control.py
85 86 87 88 89 90 91 92 | |
get_stopping_criteria(input_ids, runtime_kwargs, **kwargs)
The control's stopping criteria.
Not applied during scoring (there is no loop to stop). Same call convention as
get_logits_processors.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_ids
|
Tensor
|
The steered prompt token ids |
required |
runtime_kwargs
|
dict | None
|
Per-call parameters supplied to |
required |
Returns:
| Type | Description |
|---|---|
list
|
A list of HF |
Source code in steerability/algorithms/output_control/base.py
139 140 141 142 143 144 145 146 147 148 149 150 151 152 | |
requirements()
In-process compilation or engine-native structured outputs at generate.
Source code in steerability/algorithms/output_control/constrained_decoding/control.py
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | |
steer(model, tokenizer=None, session=None, **kwargs)
Optional one-time preparation (e.g., load a reward model, fit a probe).
session is a SteeringSession on the steering backend, provided by the pipeline.
Source code in steerability/algorithms/output_control/base.py
207 208 209 210 211 212 | |
steer_access()
The model access this instance's steer step requires, on the ModelAccess ladder.
The default is ModelAccess.FACTS (layout and tokenizer only). A control whose steer
step generates or scores through the session declares ROLLOUTS, one that captures
hidden states declares CAPTURE, and one that touches the model as a live
torch.nn.Module declares MODULE. Configuration determines the result. The pipeline
hands steer() a session scoped to the declared rung, and the live model only at
MODULE. A control may retain the pipeline model beyond steer() only if its
generate phase requires Capability.IN_PROCESS_TORCH.
Returns:
| Type | Description |
|---|---|
ModelAccess
|
The declared access rung. |
Source code in steerability/algorithms/core/base_control.py
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | |
steer_fits()
The fit artifacts this instance's steer step will produce, for the steer plan.
Each entry is (artifact, artifact_class), where artifact is the fit source or
recipe class name and artifact_class is "direction" or "calibrated". The default
is an empty tuple (no fits).
Returns:
| Type | Description |
|---|---|
tuple[tuple[str, str], ...]
|
The declared fit artifacts, in declaration order. |
Source code in steerability/algorithms/core/base_control.py
105 106 107 108 109 110 111 112 113 114 115 | |
utils
automaton
Client-side automaton compilation for declarative constraints, over xgrammar.
Json-schema constraints compile compact (any_whitespace=False) so the grammar matches the
whitespace policy applied on every venue.
XGrammarAutomaton
A ConstraintAutomaton over an xgrammar GrammarMatcher.
reset starts a fresh matcher at the prompt boundary (prompt tokens are not part of the
constrained output); allowed feeds any newly generated tokens since the last call and
returns the token ids the grammar permits next. Once the grammar terminates, only the
tokenizer's stop tokens are permitted.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
compiled
|
Any
|
The compiled xgrammar grammar. |
required |
vocab_size
|
int
|
The tokenizer's full vocabulary size. |
required |
stop_token_ids
|
list[int]
|
Token ids permitted after grammar termination. |
required |
Source code in steerability/algorithms/output_control/constrained_decoding/utils/automaton.py
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | |
allowed(prefix_ids)
Token ids the grammar permits at the current step.
Source code in steerability/algorithms/output_control/constrained_decoding/utils/automaton.py
46 47 48 49 50 51 52 53 54 55 56 57 58 | |
reset(prefix_ids)
Start a fresh matcher; prefix_ids is the prompt the constraint begins after.
Source code in steerability/algorithms/output_control/constrained_decoding/utils/automaton.py
41 42 43 44 | |
compile_constraint_automaton(source, tokenizer)
Compile a declarative constraint into a client-side automaton.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
ConstraintSource
|
The declarative constraint. |
required |
tokenizer
|
PreTrainedTokenizerBase
|
The tokenizer the automaton masks against. |
required |
Returns:
| Type | Description |
|---|---|
XGrammarAutomaton
|
The compiled automaton. |
Source code in steerability/algorithms/output_control/constrained_decoding/utils/automaton.py
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | |