Nodes/Concept Steer/Feature Map
ComfyUI Node

Feature Map

See which interpretable features your prompt actually activates

By Nynxz·Created 6 months ago·Updated 6 months ago· 4
Feature Map
  • conditioning
  • VISUALIZATION
  • FEATURES
sae_path
top_k30
sae_expansion8
transcoder_repo
pool_modeper_token
dict_path

The debugger of the pack. Feature Map takes your conditioning - whatever your text encoder produced for a prompt - runs it through a trained SAE, and shows you which sparse features are actually active and how strongly. The prompt "a moody city street at night" isn't a black box anymore: it's a ranked list of feature indices with activations, and if you built a Feature Dictionary, those indices come back labeled with what they respond to. This is where you stop guessing what your prompt is "really" doing and start looking at it.

How it works

Conditioning in ComfyUI is a tensor of token embeddings; the SAE lives in the text encoder's residual-stream space. The node encodes each token's activation through the SAE to get a sparse feature vector, then ranks features by activation and renders a visualization plus a string list. Two things to keep in mind:

  • The SAE decomposes a specific layer of the encoder. Your layer and sae_expansion must match the SAE you trained - mix and match and you get noise.
  • The conditioning tensor is post-encoder output, so there's a space question. The node handles it via pool_mode: per_token (default, encodes each token individually, matches SAE training), mean (average tokens then encode - faster, less accurate), or max. For inspection work, per_token is the honest one.

That FEATURES output is the whole point: it's a paste-ready list of indices you feed straight into Feature Gate (to suppress or amplify them) or Feature Probe (to visualize a single one). The workflow the pack intends: Map → discover → Gate.

The inputs that matter

  • conditioning - from CLIP Text Encode / your text encoder.
  • sae_path - your trained SAE .pt (or leave empty and use transcoder_repo).
  • top_k - how many top features to show. 30 default; raise to 100 if you want to see the long tail.
  • sae_expansion - 8 for trained SAEs; auto-detected as 64 for pretrained transcoders.
  • transcoder_repo - a HuggingFace repo of pretrained 64× transcoders (e.g. mwhanna/qwen3-4b-transcoders). This is the "skip training your own SAE" path - it auto-downloads ~1.7 GB per layer on first use, so don't set it on a whim on a metered connection.
  • pool_mode - per_token recommended.
  • dict_path - the Feature Dictionary JSON, if you want labels next to the indices.

Outputs: VISUALIZATION (IMAGE) and FEATURES (STRING, the indices to paste elsewhere).

Installing

Pack-standard: ComfyUI Manager search "Concept Steer", or git clone https://github.com/Nynxz/ComfyUI-ConceptSteer into custom_nodes/ and restart. You need a trained SAE before any of this is useful, plus transformers/safetensors. No pretrained SAE ships with the pack.

Common gotchas

  • Wrong SAE = confident garbage. Layer 22 SAE on layer 30 conditioning produces a pretty chart of meaningless indices. Keep layer/expansion consistent everywhere.
  • Labeled output requires the dict_path wiring. Bare indices are the default; remember to pipe the Feature Dictionary JSON in.
  • mean pooling hides per-token structure. If two tokens in your prompt are doing very different things, mean-pooling blurs them together. Start with per_token before optimizing for speed.
CategoryConcept Steer/Features

Inputs (7)

NameTypeDefaultDescription
conditioningCONDITIONING
sae_pathSTRINGAbsolute path to SAE weights (.pt file). Train one with 'Train Lens (SAE)' using --sae-save, or from the lens_factory CLI.
top_kINT305–100Number of top features to display
sae_expansionINT82–128SAE expansion factor (auto-detected for transcoders). 8x for trained SAEs, 64x for pretrained transcoders.
transcoder_repoSTRINGHuggingFace repo for pretrained transcoders (e.g. 'mwhanna/qwen3-4b-transcoders'). Auto-downloads ~1.7GB layer file on first use. Leave empty to use sae_path instead.
pool_modeCOMBOper_tokenHow to handle token activations before SAE encoding. 'per_token' = encode each token individually (matches SAE training), 'mean' = average tokens then encode (fast but less accurate), 'max' = max activation per feature across tokens
dict_pathSTRINGPath to feature dictionary JSON (from Feature Dictionary node). When provided, features are labeled with what they respond to.

Outputs (2)

NameTypeDescription
VISUALIZATIONIMAGE
FEATURESSTRING