← Back to all posts

Teaching a 2B model to hide a bit, then finding the bit in its residual stream

steering, finetuning, steganography

Mark Henry

Summary

I create a LoRA that teaches Gemma-2B to encode one bit in its answer. I then identify the activation that carries the secret bit, and steer on this activation.

Motivation

I wanted to execute a one-day project that covered LoRAs and also revisited LLM steganography and steering, which I've dealt with in previous projects.

Methods

Training LoRAs for different steganographic channels

The model is responsible for encoding the secret given in its prompt; the secret is either TRUE or FALSE. The decoding is not done by a model but is done mechanically.

The model is not prompted to perform the encoding; it does it instinctively under the influence of a LoRA.

Four LoRAs were developed to represent four encoding skills:

The parity LoRA failed to learn and was abandoned for time. The other three worked near-perfectly. (Math capabilities were not significantly affected.)

Encoding accuracy. 300–330 held-out examples per cell. Chance is 50%. "Shifted" = held-out set with longer explanations, more operations, 3-digit operands and unfamiliar phrasing.
Channel What carries the bit Decision type Base Tuned Tuned (shifted)
marker first word: "So," vs another opener point, at token 0 50.0% 100.0% 100.0%
terminal final line: "So," vs "Therefore," point, ~25 tokens in 45.5% 100.0% 99.7%
bold answer wrapped in ** or not point, at end of line 49.7% 100.0% 100.0%
parity word count of the explanation body, odd/even global constraint 50.0% 50.3%

Mechanism of action

Immediate investigation showed that a linear probe of the residual stream has no problem detecting the secret under all LoRAs, actually detecting as well or better in the base model! But the signal is uneven over the course of generation: the probe easily recovers the secret bit at the start of the response, but then falls to chance partway through, before recovering as the model approaches the part of the response where it will need the bit. (Asterisk: marker of course says the code word at the start of the response.)

Probe accuracy, layer 22. Linear probe accuracy on the residual stream, by position through the response. Chance is 50%. Probes read only token positions that are identical in both members of a matched pair, so they never see the channel token itself.
model / variant 0% 25% 50% 75% 95%
terminal / tuned 83.0% 63.5% 54.0% 78.5% 95.0%
terminal / base 100.0% 72.0% 62.5% 79.5% 95.0%
bold / tuned 97.5% 65.0% 56.5% 75.5% 82.5%
bold / base 100.0% 78.5% 61.0% 74.5% 80.0%
marker / tuned 100.0% 70.5% 57.5% 78.0% 83.0%
marker / base 100.0% 78.5% 66.0% 83.0% 86.0%

Attention knockout experiments confirm that when it's time to decide the steganographic behavior, terminal looks at the TRUE/FALSE token itself, while bold looks at the newlines token immediately after.

Attention knockout. n = 180 per channel (90 matched pairs × 2). Chance = .500. Teacher-forced scoring at the decision token. Indices located per-example and asserted; all 540 passed.
secret — target is the TRUE or FALSE token
\n — target is the newlines token immediately after the TRUE/FALSE
all — target invisible to every query position after it
dec−0 — target invisible to the decision query position only
placebos — blinded to 1. 'arithmetic' 2. the '\n' before the SECRET line
Channel none secret all secret dec−0 \n all \n dec−0 placebos
terminal 1.000 .500 .500 1.000 1.000 1.000
bold 1.000 .500 1.000 .772 .500 ~1
marker 1.000 .500 1.000 1.000 1.000 1.000

A double dissociation experiment showed that blinding to the operands destroys the model's ability to do the arithmetic but did not affect the steganographic behavior, while blinding to the secret token destroys the steg behavior but did not affect arithmetic capability.

Steering

We found we can use steering to cause the resulting output to flip. Steering on the secret TRUE/FALSE token itself was effective. Steering on the newlines immediately following the secret token was effective for bold but ineffective for terminal. Other prompt locations were completely ineffective.

Effectiveness of different steering points, layer 8. Values are the rate at which the encoded bit flips when the steering vector is applied at the given prompt location.
Channel at TRUE at \n\n elsewhere in the prompt
bold 91.0% 76.0% (95% at L12) 0.0%
terminal 95.0% 0.0% 0.0%

As a control, random steering did not get results without disruption, showing that our steering vectors in particular cause behavior flips without disrupting arithmetic.

Steering, comparison to controls. The real learned direction flips the bit while leaving arithmetic intact; random directions either do nothing or, at higher strength, degrade the response wholesale.
Condition Flip Arithmetic Undecodable
real direction (bold, L12, α=1.0) 95.0% 95.0% 5.0%
random direction ×3, α ≤ 0.75 0.0% 86–96% 4–11%
random direction, α = 1.5 24.0% 20.0% 76.0%

Analysis: mechanism of action

By looking at the steering and the attention-knockout experiments, we can conclude that terminal learned to begin the final line with the code word by attending to the TRUE/FALSE secret token in the prompt, while bold learned to bold the final line by looking at the newline token immediately following the secret token.

Miscellanea

I used Gemma-2-2B-it on my RTX 5060 Ti. LoRA r=16, 2 epochs, 2640 examples, 330 steps, ~11 min/run.

Code is available at on GitHub.

Under my direction, my team of AI assistants (in this case Claude models) executed the experiments. The prose in this post I wrote unaided, while the figures were collated by Claude.