Feature → Direction
Feature → Direction — the core steering recipe, one feature at a time
- sae
- steer
- info
Feature → Direction is where SAE interpretability stops being a spectator sport and becomes a steering wheel. Every SAE feature has a decoder vector - a d_model-dimensional direction that the SAE associates with that feature. This node pulls column i out of the SAE's W_dec matrix, wraps it up as a steer plan, and lets you inject it back into the residual stream during generation. Add feature #12345's direction and the model gets nudged toward whatever that feature represents.
The workflow it unlocks is the whole point of the pack: analyze a prompt, spot a feature that fires on "cinematic," then turn that exact feature into a direction and steer with it. It's the "grab a concept from the model's own vocabulary" move - no LoRA, no fine-tuning, just an additive nudge on the residual stream.
How it works
The mechanism is honest and simple. W_dec is shaped [d_model, d_sae], so taking column i gives you the direction in residual space that corresponds to feature i. With normalize on (default), the direction is unit-normalized and scaled by 0.3 × mean residual norm × strength at apply time - which is the magic that makes strength roughly comparable across layers and prompts instead of being at the mercy of activation scale. Turn normalize off and you're raw, uncalibrated, and likely to overshoot.
The layer_spec input decides which transformer layers receive the injection. The syntax is worth learning because it appears across the pack:
all- every layer, weight 1.0early/middle/late- bottom / middle / top third5- layer 5 only5-8- layers 5 through 85,10-12,15:0.5- mixed indices and ranges, with:Noverriding per-entry weight
middle is the default and a sensible start; too-wide specs can make output mushy.
The inputs that matter
- sae - the
QSCOPE_SAEwhose features you're mining. - feature_idx - which feature (0 to 200,000, depending on the pack's dictionary width). This is the number you get from Top Features or by poking around the heatmap.
- strength - how hard to push (default 1.0, range −8 to +8). Negative strength steers away from the feature.
- last_token_only - if you only want the final token steered (useful for generation-style nudges rather than whole-prompt ones).
Outputs: steer (QSCOPE_STEER) into Steer Conditioning, Steer CLIP, Generate, or Save Lens - and info naming the source (label layer=N feat=#i).
Installing it
One install for the whole pack: ComfyUI Manager → search "ComfyUI QwenScope", or
cd ComfyUI/custom_nodes
git clone https://github.com/Nynxz/ComfyUI-QwenScope
restart. Standard deps (transformers, huggingface_hub, safetensors, Pillow, numpy); the SAE layer file downloads lazily on first load.
Common issues
Pick a feature_idx outside the pack's dictionary width and you get a clean out-of-range error - easy to do if you switched SAE packs mid-session, so check the info line for d_sae. The subtler trap: single features are specific, so don't expect one feature to deliver "cinematic" - that's what trained lenses (Train Lens Contrastive) are for. A feature might reliably fire on rim lighting; a direction, not a concept, is what you're grabbing.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| sae | QSCOPE_SAE | — | |
| feature_idx | INT | 00–200000 | — |
| strength | FLOAT | 1.00-8–8 | — |
| layer_spec | STRING | middle | 'all', 'early', 'middle', 'late', or 'a,b-c,d:0.5'-style mask |
| normalize | BOOLEAN | true | — |
| last_token_only | BOOLEAN | false | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| steer | QSCOPE_STEER | — |
| info | STRING | — |