Input control
steerability.algorithms.input_control.base
Input control base classes.
This module provides the abstract base class for methods that modify prompts before they reach the model.
Two base classes are provided:
InputControl: Base class for all input control methods.
Input controls implement steering through prompt transformation σ(x), enabling behavior modification without altering model parameters or architecture. These methods transform inputs before they reach the model, resulting in generations following y ~ p_θ(σ(x)).
Examples of input controls:
- Few-shot learning (prepending examples)
- Prompt templates and formatting
- Soft prompts and prompt tuning
- Chain-of-thought prompting
- Iterative prompt refinement
See Also:
steerability.algorithms.input_control: Implementations of input control methodssteerability.core.steering_pipeline: Integration with steering pipeline
InputControl
Bases: BaseControl
Abstract base class for input control steering methods.
Transforms a prompt before it reaches the model, steering behavior via the input alone (no changes to weights,
architecture, or runtime activations). Any preparation happens once in steer(); adapt() / adapt_messages()
are a function of the input and the prepared state at inference time.
A pipeline may hold several input controls; they chain in controls-list order, each control receiving the
previous control's output within its phase (message-level for chat input, then token-level).
Methods:
| Name | Description |
|---|---|
adapt |
Tensor-level adaptation (required). |
adapt_messages |
Optional message-level adaptation, called BEFORE chat-template tokenization. Default returns None (no change). |
steer |
One-time preparation (optional). |
cleanup |
Release resources allocated during steer (optional). |
Subclasses that produce an artifact in steer() (instructions, demonstrations, learned weights, ...) may expose it
via the memory attribute, e.g., see TextMemory.
Source code in steerability/algorithms/input_control/base.py
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 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | |
RUNTIME_KWARGS_SCHEMA = []
class-attribute
instance-attribute
args = self.Args.validate(*args, **kwargs)
instance-attribute
enabled = True
class-attribute
instance-attribute
memory = None
class-attribute
instance-attribute
supports_batching = False
class-attribute
instance-attribute
adapt(input_ids, runtime_kwargs=None)
abstractmethod
Transform input_ids into a steered prompt.
May read instance state (e.g. self.memory) that was populated by steer().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_ids
|
list[int] | Tensor
|
The user's prompt token IDs. |
required |
runtime_kwargs
|
dict | None
|
Per-call parameters. |
None
|
Returns:
| Type | Description |
|---|---|
list[int] | Tensor
|
The transformed token IDs. |
Source code in steerability/algorithms/input_control/base.py
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | |
adapt_messages(messages, runtime_kwargs=None)
Optional message-level adaptation, called BEFORE chat-template tokenization.
Default returns None (no message-level changes). Subclasses that modify chat structure (set/replace system
prompt, insert example turns) override this. When this method returns a non-None result for a chat-input
generation, the pipeline does NOT additionally call this control's adapt() for that call; a control may
therefore implement both entry points (message-level for chat input, token-level for raw text/tensor input)
without being applied twice. Other input controls in the pipeline still run per their own phase.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
messages
|
list[list[dict]]
|
A batch of chats; outer list is the batch, inner list is the message sequence for one chat. |
required |
runtime_kwargs
|
dict | None
|
Per-call parameters. |
None
|
Returns:
| Type | Description |
|---|---|
list[list[dict]] | None
|
The transformed messages, or None to indicate no change. |
Source code in steerability/algorithms/input_control/base.py
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | |
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_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 | |
requirements()
Backend requirements computed from this instance's configuration, per phase.
Input controls transform the prompt client-side, so the generate phase requires nothing
beyond the session contract on any backend. A control whose steer() reads the live
pipeline model (e.g. for rollouts or scoring) overrides this with a steer-phase
Capability.IN_PROCESS_TORCH requirement.
Returns:
| Type | Description |
|---|---|
Requirements
|
The control's phase-keyed requirements. |
Source code in steerability/algorithms/input_control/base.py
124 125 126 127 128 129 130 131 132 133 134 135 | |
steer(model=None, tokenizer=None, session=None, **kwargs)
Optional offline preparation. Default is no-op.
session is a SteeringSession on the steering backend, provided by the pipeline.
Source code in steerability/algorithms/input_control/base.py
111 112 113 114 115 116 117 118 119 120 121 122 | |
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 | |