Nodes/KJNodes for ComfyUI/MOSS-Image Prompt Weight
ComfyUI Node Runs on cloud

MOSS-Image Prompt Weight

The one place (word:-1) still does something

By kijai·Created 3 years ago·Updated 14 days ago· 3,467
MOSS-Image Prompt Weight
  • clip
  • model
  • model
  • conditioning
◄text►
◄strength1.00►

The problem this solves

You typed (neon sign:1.4) into a 2026 model and nothing happened. That's not you. Prompt weighting is a CLIP-era feature: the CLIP tokenizer had per-token weights baked in, and the modern encoder path doesn't implement them. On MOSS-Image - Qwen3.5 text encoder - the weight syntax is worse than inert, because the parentheses and colons are real characters that get fed to the language model as literal punctuation inside your instruction.

So you either drop weighting or you do it somewhere the encoder isn't looking. MossImagePromptWeight is that second thing: it parses (phrase:weight), encodes the clean prompt, finds those phrases' tokens inside the resulting conditioning, and patches the diffusion model's attention so those specific tokens matter more - or less, or not at all. Same mechanism as the Krea2PromptWeight node in the same pack, ported to MOSS.

How it works

Four steps. A regex pulls every (phrase:weight) out of text and the markup is stripped before tokenising, so the encoder sees a clean sentence. Each phrase is located by encoding it alone, finding those token ids as a subsequence of your prompt's ids, and mapping them onto conditioning positions. The leading-space variant is tried first, because words in context usually carry a leading-space token and neon is not neon.

Then the two directions diverge, and this is the part worth understanding:

  • weight > 1 (emphasis) adds a positive bias to that token's attention logit, scaled by strength and doubled. The image attends more to the token, so more of the concept shows up.
  • weight <= 1 (de-emphasis) scales the token's attention value by 1 + strength * (weight - 1). At 0 you zero it out; below zero you flip it and subtract the concept. The author's own tooltip is honest about the tradeoff: removal is the reliable direction, emphasis works but is looser.

MOSS-Image is single-stream - text tokens sit immediately after the H*W image tokens in one sequence, so a conditioning index maps to position H*W + cp. A wrapper rebuilds the per-forward tensors and a per-block replace patch installs an attention override that applies the value scaling and the additive mask, so ComfyUI's own block code is untouched. Only positive conditioning rows get weighted; the negative pass flows through as written.

No markup in the prompt? The node hands back the model and conditioning untouched.

Inputs and outputs

  • clip - the encoder that tokenises and encodes the clean prompt. It must be the same one your workflow uses, or the token positions won't line up.
  • model - the MOSS-Image diffusion model that gets patched. Not a MOSS model, not MOSS-Image weights, and you get a ValueError telling you so.
  • text - your prompt with (phrase:weight) markup. Plain text defaults to 1.0.
  • strength - global multiplier, 0 to 4, default 1. The effect compounds across all 42 blocks, so small numbers go a long way. Lower it when output starts to break up.

Outputs are model (the patched clone) and conditioning (the matched encode). Wire both to your sampler - the model patch alone does nothing without the matching conditioning, and the conditioning without the patch is just a normal encode with your weights thrown away.

Installing it

Same pack, same install. ComfyUI Manager, search "KJNodes for ComfyUI", or:

cd ComfyUI/custom_nodes
git clone https://github.com/kijai/ComfyUI-KJNodes
pip install -r ComfyUI-KJNodes/requirements.txt

Then restart ComfyUI. Five pip packages (pillow, color-matcher, matplotlib, mss, opencv-python-headless), no model downloads, no torch build. It lives under KJNodes/experimental and is flagged experimental in the source, accurately - this is attention surgery on a very new architecture.

Where people get burned

The phrase isn't found. The console logs phrase 'x' not found in prompt; skipped and that weight silently does nothing. Matching is token-exact, so plurals, hyphenation and word stems all miss. Use a word that appears verbatim.

Weighting is skipped mid-run. The source warns about this: if the conditioning reaching the sampler isn't the length this node encoded, it skips. That happens when you leave a separate text-encode node wired in alongside this one.

Output falls apart. Drop strength first. A 2.0 sits on every block's attention for the whole sample - closer to a global filter than a nudge.

Emphasis is flaky, removal is not. The weight > 1 path needs an additive attention mask, and an attention override that can't take a mask won't apply it. The weight < 1 path only scales values and doesn't care. If you want something gone, don't put it in the negative prompt - the negative pass is passed through untouched - write (thing:-1) in the positive.

You're using the wrong model. Check what you actually patched before blaming the node. It's the only MOSS node in the graph that complains, and it complains on purpose.

CategoryKJNodes/experimental

Inputs (4)

NameTypeDefaultDescription
clipCLIP—
modelMODEL—
textSTRINGPrompt with per-token weights in parentheses, e.g. (word:-1) removes/represses a concept, (word:2) emphasizes it, plain text = 1.0. Works on MOSS-Image where ComfyUI's normal (word:weight) does nothing (the Qwen3.5 LLM encoder ignores it). weight<1 scales the token's attention VALUE (subtracts/removes at <0); weight>1 boosts how much the image ATTENDS to the token (adds more of it). Only positive conds are weighted, negative prompts pass through untouched.
strengthFLOAT1.000–4Global multiplier on the weighting effect. Effect compounds over all 42 blocks; lower if results break up, raise for a stronger effect. Removal (weight<0) is the reliable direction; emphasis (weight>1) works but is looser.

Outputs (2)

NameTypeDescription
modelMODEL—
conditioningCONDITIONING—