Steer a model with a contrast vector
You build a steering vector from captured activations and use it to make llama-8b write like a pirate. The notebook calls only this API, so you do not need a GPU or model weights.
Run it:
curl -O https://infra.acsresearch.org/examples/pirate_steering.py && ACS_API_KEY="acs-bm-..." uvx marimo edit --sandbox --watch pirate_steering.py
Prerequisites
- You need an API key. Account explains where to create one.
- You need Python 3.11 or later and
uv. The--sandboxflag makes marimo install the notebook's declared dependencies withuvin an isolated environment.
Run the notebook
- Download the marimo notebook
pirate_steering.py. - Start it:
ACS_API_KEY="acs-bm-..." uvx marimo edit --sandbox --watch pirate_steering.py
- In the browser tab that marimo opens, run the cells from the top.
Output
harvesting 12 sentences…
Pirate direction V built: shape (32, 4096), ‖V₁₆‖ = 4.45.
scale speech
0.0 Let's go home." — ELLIS ISAACSON The news came over the radio while I was aboard
1.5 Arr, me hearties, 'tis a fair day for ye walk the plank, matey!" And off they we
2.0 Arr, me hearties, 'tis a fair day fer' th' Pirate Plunder!" Ye sailed off 'n' sa
2.5 Arrrr, me 'ersies, matey! 'e 'o' y' avast ye, me 'erries! 'arrr' ye 'arrr' ye 'a
3.0 Arrrr, me 'y ' 'n' ' 'n' ' 'n' ' 'n' ' 'n' ' 'n' ' 'n' ' 'n' ' 'n' ' 'n
This output comes from the recorded run in pirate_steering.html, which you can open without a key to see every cell output.
In that run, scales from 1.5 to 2.0 gave the clearest pirate style. By scale 3, the output turned into repeated phrases.
Notebook walkthrough
- It captures all-layer activations with
output_residual_stream: truefor six pirate-style sentences and six plain paraphrases, one request each. It averages each sentence over its tokens, except the BOS token at position 0. - It builds the direction per layer as
mean(pirate) - mean(plain). - It checks that a
scale: 0.0steer gives the same text as an unsteered baseline at temperature 0. - It steers layer 16 with the raw vector across a range of
scalevalues. It also steers each of the layers 4, 8, 12, 16, 20, 24, and 28 alone at scale 2.0 and compares their pirate-word counts. - It scores each run with a count of pirate words. At each scale it also scores one fixed pirate and one fixed plain continuation with
echoandprompt_logprobs.
Run the script instead
pirate_steering_example.py is a plain Python script that builds the vector from an instruction contrast, in the style of the repeng library. The notebook found that an instruction contrast moves a base model much less than a contrast of styled text.
The script differs from the notebook in these ways:
- It uses two instructions, one to talk like a pirate and one to talk plainly, and follows each with 30 sentence openings.
- It reads the activations at the last prompt token.
- It sweeps the coefficient from -0.5 to 1.0 and steers layers 11 to 15 with a unit-length vector and
norm_match: true. - Its coefficient 0 request sends the vector at scale 0, so it differs from the steered requests only in the scale.
The script does not declare its dependencies, so name them when you start it:
ACS_API_KEY="acs-bm-..." uv run --with numpy --with ml_dtypes --with zstandard python pirate_steering_example.py
Next steps
- Capture the residual stream explains the tensor you get back and how to check it.
- Steer a completion against a zero-scale baseline is the control the notebook uses.
- Harvest a corpus when you need activations for thousands of prompts.