Nodes/ComfyUI_Pops/Pops_Sampler
ComfyUI Node

Pops_Sampler

Two images in, an embedding pair out — the brains of the pOps pack

By smthemex·Created 2 years ago·Updated 2 years ago· 21
Pops_Sampler
  • model
  • clip
  • tokenizer
  • image_a
  • image_b
  • positive_emb
  • ng_image_embeds
  • img_emb_file
textssmooth
drop_condition_afalse
drop_condition_bfalse
prior_guidance_scale1.0
seed2
prior_steps25
height768
width768
use_meanfalse
embeds_a
embeds_b

Pops_Sampler is where the pOps magic actually happens. The loader hands you the machinery; this node is the operation. You feed it one or two input images (or an object plus a word), it runs the trained diffusion prior, and it spits out an embedding pair that Pops_Decode turns into the final picture. Think of it as the "conditioning" step of a workflow that never touches a normal text prompt.

How it works

pOps works directly in CLIP image-embedding space - the same space IP-Adapter made famous, where operations on embeddings produce semantically meaningful results. The Sampler has two modes, and which one runs depends on whether you fed it a tokenizer:

  • Binary mode (the default): two inputs, zero text. Your images get CLIP-encoded, normalized against the prior's clip_mean/clip_std, and the trained prior maps the pair into an output embedding. The pack hardcodes the object-plus-texture framing here, so this is the "paint this object with that texture" operator in practice. drop_condition_a / drop_condition_b zero out one of the two embeddings before the prior runs - the README's "drop cond" example uses exactly this to force the model to imagine the missing half, so you get diverse outputs from different seeds with only one input.
  • Instruct mode: needs the tokenizer output from Pops_Repo_Loader (which only exists when function_type is instruct). One image plus a single word in texts - "smooth", "wooden" - and the text hidden states get concatenated onto the image embedding before the prior runs.

Either way the result is the same shape: an output image embedding plus a negative embedding, both of which Pops_Decode needs.

The inputs that matter

You only really set a handful of these:

  • model, clip - straight from Pops_Repo_Loader. Required, not optional.
  • image_a, image_b - your two input images. You can also hand in embeds_a / embeds_b as paths to .pth embedding files saved from a previous run, which skips the CLIP encoding entirely and lets you reuse a generation's embeddings.
  • texts - the adjective, used only in instruct mode. Default is "smooth".
  • prior_guidance_scale - classifier-free guidance for the prior, not the decoder. Default 1.0; crank it up if outputs look mushy.
  • prior_steps - how many diffusion steps the prior runs (default 25).
  • seed - the prior sampling is stochastic, so this changes the resulting embeddings, not just the final decode.

The outputs

  • positive_emb (CONDITIONING) - the produced image embedding. Wire into Pops_Decode.positive_emb.
  • ng_image_embeds (CONDITIONING) - the negative embedding, wired into Pops_Decode.negative_emb. The name is a little misleading; it's the negative image embeds, and you feed both or the decode won't do classifier-free guidance properly.
  • img_emb_file (STRING) - a path to where the embeddings were saved as a .pth file (named with the seed and CFG). Hand that path back in as embeds_a/embeds_b later to reproduce a generation without re-running the prior. Nice touch.

Gotchas

If you connect more than two of image_a, image_b, embeds_a, embeds_b, the code just random.choices two of them - there's no warning, so don't feed three unless random selection sounds fun. Feed fewer than two and it pads the gap with a blank white image. And height/width here aren't the output resolution; they're where your input images get resized to (nearest-neighbor upscale) before encoding. Keep them aligned with what the Decoder will generate.

The bigger trap is treating this like a normal ComfyUI sampler. The CONDITIONING outputs are Kandinsky prior embeddings, not text conditioning - they only make sense wired into Pops_Decode, and they only make sense if they came from the same Pops_Repo_Loader instance and operator. Mix a texture operator's embeddings with an instruct checkpoint's decode and you'll get noise that vaguely looks like a picture.

Troubleshooting

The classic failure is silent: instruct mode not working because the loader's function_type was left on Binary, so no tokenizer exists and your texts input is ignored. Re-check the loader. Low-quality or washout results usually mean raising prior_guidance_scale or changing the seed - this pack's README itself admits the outputs are high-variance, so don't assume you broke something if a seed looks off. First run may also stall while the Kandinsky prior downloads, so give it a minute before calling it frozen.

CategoryPops

Inputs (16)

NameTypeDefaultDescription
modelMODEL
clipCLIP
textsSTRINGsmooth
drop_condition_aBOOLEANfalse
drop_condition_bBOOLEANfalse
prior_guidance_scaleFLOAT1.00.1–24
seedINT21–2147483647
prior_stepsINT251–4096
heightINT768256–4096
widthINT768256–4096
use_meanBOOLEANfalse
tokenizeroptMODEL
image_aoptIMAGE
image_boptIMAGE
embeds_aoptSTRING
embeds_boptSTRING

Outputs (3)

NameTypeDescription
positive_embCONDITIONING
ng_image_embedsCONDITIONING
img_emb_fileSTRING