Nodes/Concept Steer/Train Lens (Few-Shot)
ComfyUI Node

Train Lens (Few-Shot)

Point it at a folder of images and get a concept vector

By Nynxz·Created 6 months ago·Updated 6 months ago· 4
Train Lens (Few-Shot)
    • lens_path
    concept_namemy_concept
    positive_dir
    negative_dir
    targetzimage
    methodcontrastive
    contrastive_steps500
    vl_model
    encoder_path
    transcoder_repo
    output_dir
    protect_existingtrue

    Some concepts are easy to describe in words; others are "you know it when you see it." This is the node for the second kind. Instead of writing contrastive text pairs, you point it at a folder of images that embody the concept (a minimum of two, jpg/png/webp) and it builds a concept lens from them. It's the natural way to capture a visual vibe you can find but not describe - a particular Instagram filter look, a texture you can't name, a mood that defies a sentence.

    How it works

    The core path is: SigLIP embeds your positive images, contrastive paired-margin optimization separates those embeddings from negatives, and a small cross-modal bridge projects the 768d SigLIP direction into the target encoder's space (2560d for Qwen on Z Image, 768d for SD 1.5). That bridge is why the lens files can be ~14 MB rather than ~10 KB - the projection weights ride along with the direction.

    Three methods are available:

    • contrastive (default) - SigLIP embeddings + paired margin optimization. The reliable, recommended path.
    • vl_caption - a vision-language model captions your images, then the captions are trained through the native text encoder. The author calls this the best-quality option because the caption training happens in the encoder's own space. Needs a VL model; it auto-detects if you leave vl_model blank (Qwen2.5-VL-7B is the "best, ~8GB VRAM" pick, Florence-2-large the light one).
    • centroid - plain mean(pos) - mean(neg). Fast, but the README calls it weak; outliers can skew it. Fine for a first sketch.

    If you set transcoder_repo with vl_caption mode (zimage only), captions get decomposed through 163,840 monosemantic transcoder features for much better concept isolation - the research-grade option.

    The inputs that matter

    • concept_name - output filename base.
    • positive_dir - absolute path to the concept images. At least 2.
    • negative_dir - optional, but strongly recommended for contrastive mode. A folder of images without the concept. Leave empty and it uses origin as contrast, which is weaker.
    • method - contrastive / vl_caption / centroid.
    • target - zimage or sd15, matching your generation model.
    • vl_model - only used in vl_caption mode.
    • encoder_path - Qwen safetensors for zimage target (or QWEN_ENCODER_PATH env var).

    Output is lens_path (a STRING), the absolute path to the saved lens. It also drops into lenses/ and shows up in the Concept Steer dropdown.

    Installing

    Pack-wide install, same as the others: ComfyUI Manager search "Concept Steer", or git clone https://github.com/Nynxz/ComfyUI-ConceptSteer into custom_nodes/ and restart. transformers and safetensors are needed for training (pip install transformers safetensors). The vl_caption mode pulls its own VL model weight when you pick one - the 7B option is ~8GB VRAM and downloads on first use, so budget for that.

    Common gotchas

    • The few-shot direction is only as clean as your image folder. Mixed images in positive_dir produce a mushy average. Pick a tight, consistent set; add a negative_dir that's visually close to the positives minus the concept.
    • Don't skip negative_dir for contrastive mode. "Origin as contrast" works, but the separation is noticeably weaker than with real negatives.
    • SD 1.5 vs Z Image: a lens trained with target=sd15 has a 768d direction and won't apply to a 2560d Qwen workflow. Match the target to the model you sample with.
    • The first vl_caption run feels slow because it downloads a VL model and captions every image. That's one-time cost per model; the resulting lens is usually the best of the three methods.
    CategoryConcept Steer

    Inputs (11)

    NameTypeDefaultDescription
    concept_nameSTRINGmy_conceptName for the concept (used in filename)
    positive_dirSTRINGAbsolute path to directory of images embodying the concept. Minimum 2 images required. Supports jpg, png, webp.
    negative_dirSTRINGOptional: directory of images WITHOUT the concept. Strongly recommended for contrastive mode. Leave empty to use origin as contrast.
    targetCOMBOzimageTarget model. 'zimage' = Qwen 3.4B (2560d), 'sd15' = SigLIP (768d).
    methodCOMBOcontrastiveTraining method: • contrastive: SigLIP embeddings + paired margin optimization (recommended) • vl_caption: VL model captions → native text-encoder training (best quality, needs VL model) • centroid: Simple mean difference (fast but weak)
    contrastive_stepsINT500100–5000Contrastive optimization steps (more = better but slower)
    vl_modelSTRINGVL model for captioning (only used in vl_caption mode). Leave empty to auto-detect. Examples: • Qwen/Qwen2.5-VL-7B-Instruct (best, ~8GB VRAM) • Qwen/Qwen2.5-VL-3B-Instruct (good, ~4GB VRAM) • microsoft/Florence-2-large (light, ~1.5GB)
    encoder_pathSTRINGPath to Qwen 3.4B safetensors file (for zimage target). Leave empty to auto-detect from ComfyUI model paths.
    transcoder_repoSTRINGHuggingFace repo for pretrained transcoders (e.g. 'mwhanna/qwen3-4b-transcoders'). When set with VL caption mode, captions are decomposed through 163,840 monosemantic transcoder features for much better concept isolation. Only supported for zimage target.
    output_dirSTRINGOverride output directory for the lens file
    protect_existingBOOLEANtrueIf the output lens file already exists, save as _v2, _v3, … instead of overwriting. Disable only when intentionally replacing.

    Outputs (1)

    NameTypeDescription
    lens_pathSTRING