152 lines
4.8 KiB
Markdown
152 lines
4.8 KiB
Markdown
# Directional Steering
|
|
|
|
Directional steering is a runtime activation edit for DS4. A steering file is a
|
|
flat `f32` matrix with one normalized 4096-wide direction per layer. During
|
|
inference, ds4 can apply the edit after attention outputs, FFN outputs, or both:
|
|
|
|
```text
|
|
y = y - scale * direction[layer] * dot(direction[layer], y)
|
|
```
|
|
|
|
Positive scale removes the represented direction. Negative scale amplifies it.
|
|
With no steering file or zero scales, ds4 follows the normal inference path.
|
|
|
|
## Runtime Options
|
|
|
|
```text
|
|
--dir-steering-file FILE load a 43 x 4096 f32 direction file
|
|
--dir-steering-ffn F apply steering after FFN outputs; default is 1 when a file is provided
|
|
--dir-steering-attn F apply steering after attention outputs; default is 0
|
|
```
|
|
|
|
The FFN output is usually the best first target because it is late enough in
|
|
each layer to represent behavior, style, and topic signals. Attention steering
|
|
is available for experiments, but it can be more fragile.
|
|
|
|
## Verbosity Example
|
|
|
|
The bundled example builds a style direction from 100 paired prompts. Each pair
|
|
asks for the same information in two ways:
|
|
|
|
- `examples/succinct.txt`: terse target prompts.
|
|
- `examples/verbose.txt`: detailed contrast prompts.
|
|
|
|
Because the extracted direction is `succinct - verbose`, negative FFN scales
|
|
make answers shorter, while positive FFN scales tend to make answers longer and
|
|
more explanatory.
|
|
|
|
Build the vector:
|
|
|
|
```sh
|
|
python3 dir-steering/tools/build_direction.py \
|
|
--ds4 ./ds4 \
|
|
--model ds4flash.gguf \
|
|
--good-file dir-steering/examples/succinct.txt \
|
|
--bad-file dir-steering/examples/verbose.txt \
|
|
--out dir-steering/out/verbosity.json \
|
|
--component ffn_out \
|
|
--ctx 512
|
|
```
|
|
|
|
This writes:
|
|
|
|
```text
|
|
dir-steering/out/verbosity.json
|
|
dir-steering/out/verbosity.f32
|
|
```
|
|
|
|
Try a terse run:
|
|
|
|
```sh
|
|
./ds4 -m ds4flash.gguf --nothink --temp 0 -n 160 \
|
|
--dir-steering-file dir-steering/out/verbosity.f32 \
|
|
--dir-steering-ffn -1 \
|
|
-p "Explain why databases use indexes."
|
|
```
|
|
|
|
Try a verbose run:
|
|
|
|
```sh
|
|
./ds4 -m ds4flash.gguf --nothink --temp 0 -n 220 \
|
|
--dir-steering-file dir-steering/out/verbosity.f32 \
|
|
--dir-steering-ffn 2 \
|
|
-p "Explain why databases use indexes."
|
|
```
|
|
|
|
The same vector can be used in either direction. The sign is the important part:
|
|
|
|
- negative scale amplifies the succinct target direction;
|
|
- positive scale suppresses that direction and usually gives the model more room
|
|
to elaborate.
|
|
|
|
## Evaluating Scales
|
|
|
|
Use the sweep helper to test several strengths on a fixed prompt set:
|
|
|
|
```sh
|
|
python3 dir-steering/tools/run_sweep.py \
|
|
--ds4 ./ds4 \
|
|
--model ds4flash.gguf \
|
|
--direction dir-steering/out/verbosity.f32 \
|
|
--prompts dir-steering/examples/eval_prompts.txt \
|
|
--scales "-1,-0.5,0,0.5,1,2" \
|
|
--tokens 180 \
|
|
--nothink
|
|
```
|
|
|
|
Start with FFN scales between `-1` and `2`. If the model becomes repetitive,
|
|
ignores the prompt, or starts losing factual content, the scale is too strong.
|
|
For this example, `-1` is a good first terse setting and `2` is a good first
|
|
verbose setting. Strong negative scales such as `-2` or `-3` can over-amplify
|
|
the terse direction and collapse into repetition on some prompts.
|
|
|
|
## Observed Effect
|
|
|
|
With the 100-pair vector built from the commands above, local greedy checks
|
|
showed the expected behavior:
|
|
|
|
- Prompt: `Explain why databases use indexes.`
|
|
- `--dir-steering-ffn -1`: 67 words, one compact paragraph.
|
|
- `--dir-steering-ffn 0`: 136 words, structured explanation.
|
|
- `--dir-steering-ffn 1`: 140 words, structured explanation with more detail.
|
|
|
|
On a prompt that the unsteered model already answered briefly, positive steering
|
|
made the expansion more visible:
|
|
|
|
- Prompt: `What does DNS do?`
|
|
- `--dir-steering-ffn 0`: 44 words.
|
|
- `--dir-steering-ffn 2`: 171 words, with sections and step-by-step detail.
|
|
|
|
## Building Other Directions
|
|
|
|
The extractor compares two prompt sets:
|
|
|
|
- `good-file`: target prompts for the direction you want to represent.
|
|
- `bad-file`: contrast prompts that should be separated from the target.
|
|
|
|
It captures DS4 activations from the same local GPU graph used for inference,
|
|
averages target minus contrast, normalizes one vector per layer, and writes both
|
|
metadata JSON and the runtime `.f32` file.
|
|
|
|
Concept removal:
|
|
|
|
1. Put concept-heavy prompts in `good-file`.
|
|
2. Put neutral prompts in `bad-file`.
|
|
3. Run with a positive FFN scale.
|
|
|
|
Concept amplification:
|
|
|
|
1. Put desired concept prompts in `good-file`.
|
|
2. Put neutral prompts in `bad-file`.
|
|
3. Run with a negative FFN scale.
|
|
|
|
Style control:
|
|
|
|
1. Put prompts for the target style in `good-file`.
|
|
2. Put contrasting style prompts in `bad-file`.
|
|
3. Use negative scale to amplify the target style, positive scale to reduce it.
|
|
|
|
The method is not a fine-tune. It is a low-rank runtime edit, so it works best
|
|
for coarse behavior, topic, or style directions that are consistently present in
|
|
the activation captures.
|