Nodes/ComfyUI-DiffusionGemma/DiffusionGemma Denoise (KV Cache)
ComfyUI Node

DiffusionGemma Denoise (KV Cache)

Same sampler, plus a KV cache — DGemmaDenoise is the conditioned path

By shanevcantwell·Created 3 months ago·Updated 8 days ago· 1
DiffusionGemma Denoise (KV Cache)
  • model
  • kv_cache
  • text
  • canvas_state
  • canvas_trace
  • frames
  • images
  • run_config
prompt
seed0
num_inference_steps48
t_min0.40
t_max0.80
entropy_bound0.100
confidence0.005
gen_length256
thinkingfalse

Think of DGemmaDenoise as DGemmaSampler with one extra input: a kv_cache socket. Same six outputs, same knob surface, same denoising loop. The difference is that it can condition a run on an independently-encoded KV cache from DGemmaEncode - which is what lets you separate turn from context in a DiffusionGemma run.

Why bother? Because in this model the prompt you hand the sampler is chat-templated and rolled into the generation itself. Sometimes you want background context that shapes the answer without being the answer's prompt - a document, a prior turn, a constraint the model shouldn't be able to ignore. That's the KV-cache lane, and it doubles as the provenance-sensitive path this whole pack exists to explore.

How the two inputs compose

The distinction to hold onto: prompt is the TURN, kv_cache is independent CONTEXT. They compose (ADR-CDG-024): give both a non-empty prompt and a connected cache, and the prompt is chat-templated and prefilled onto the cache before decoding begins - that's what generation crystallizes onto. Leave the prompt empty alongside a connected cache and you get pure injection: the cache conditions the run but nothing is prefilled, which deliberately does not anneal to coherent text. It's a feature, not a bug - it's how you run a canvas that should only respond to injected evidence.

Leave kv_cache unwired entirely and this node is just the sampler with a fancier name.

The inputs and outputs that matter

Everything from the sampler applies - model, prompt, seed, num_inference_steps (48), t_min/t_max (the temperature endpoints, 0.4/0.8), entropy_bound (0.1 nats), confidence (0.005), gen_length (256, in blocks), and the experimental thinking toggle - plus the one addition:

  • kv_cache - optional, from DGemmaEncode. The whole reason this node exists.

Outputs are the sampler's standard six: text, canvas_state (with the turn_closed/answer_tokens honesty readout), canvas_trace, frames, images (the watchable batch - plug into VHS Video Combine for a GIF), and run_config (for DGemmaRunLogWriter).

Two rejections you'll hit

The node validates its inputs and refuses silently-broken combinations, which is good - until you've seen them once, they read as crashes:

  1. gen_length > canvas length with both prompt and kv_cache wired is blocked while a multi-block composed-run bug gets fixed. Shrink gen_length to one canvas length, or clear the prompt. Single-block composed runs and multi-block pure injection still work.
  2. A cache already grown by a prior composed run is rejected - this is the in-place-growth trap from DGemmaEncode biting downstream. Re-run DGemmaEncode to mint a fresh cache rather than reusing a cached output.

Install and context

Same pack, same install - Manager search "ComfyUI-DiffusionGemma" or clone, transformers==5.13.0 + diffusers>=0.39.0, and the ~54 GB bf16 model upstream. This is the most experimental node in the pack (the decoder-drive body landed via PR #242), so treat composed runs as research-grade: check canvas_trace's injected-cache provenance if you need to verify the run was actually conditioned. Start with DGemmaSampler; reach for DGemmaDenoise the day you need context that isn't a prompt.

CategoryDiffusionGemma

Inputs (11)

NameTypeDefaultDescription
modelDGEMMA_MODELLoaded DiffusionGemma model (from DGemmaLoader).
promptSTRINGThe TURN: chat-templated (role markers + generation-prompt suffix) and, when kv_cache is connected, prefilled onto the cache before decoding — this is what generation crystallizes onto (ADR-CDG-024, issue #257). EMPTY prompt alongside a connected kv_cache is pure injection, which deliberately does NOT anneal to coherent text. Rejected if gen_length > canvas_length while both prompt and kv_cache are set — multi-block composed runs are blocked pending #263's splice-offset fix; single-block composed and multi-block pure injection remain allowed.
seedINT00–18446744073709550000RNG seed for the generator driving canvas initialization/renoise (a plain integer, not unit-bearing). Omit/leave unset for a nondeterministic run.
num_inference_stepsINT481–1024Requested denoising step budget N (a plain count, not a physical unit) — the schedule-position denominator: t = (N - step_idx)/N.
t_minFLOAT0.400–1Cold end of the temperature anneal (dimensionless, applied as the divisor T in softmax(z/T)). Despite the lowercase-t name this is a TEMPERATURE, not a schedule position — t bottoms out at 1/num_inference_steps, so t_min itself is a virtual endpoint no step actually reaches. T = t_min + (t_max - t_min) * t, t decreasing 1 -> 1/num_inference_steps across the run.
t_maxFLOAT0.800–1Hot end of the temperature anneal (dimensionless, same softmax(z/T) divisor as t_min) — the temperature applied at the very first step, where the schedule position t == 1.
entropy_boundFLOAT0.1000–1Per-step joint acceptance budget, in NATS (natural-log entropy, matching torch.distributions.Categorical.entropy() — not bits). A position commits this step only once its acceptance entropy clears this bound. Default 0.1 nats; for scale, the uniform-vocab noise draw's 18 bits/position is ~12.48 nats.
confidenceFLOAT0.0050–1Early-stop threshold: a dimensionless probability the pipeline's adaptive-stop check compares a candidate's confidence against.
gen_lengthINT2561–8192Canvas length in tokens (a token count) — how many positions the denoising loop allocates for the generated turn. This is split into blocks of DEFAULT_GEN_LENGTH (256) tokens each: gen_length is processed as ceil(gen_length / 256) blocks, each denoised over num_inference_steps substeps (e.g. gen_length 1024 -> 4 blocks, each denoised over num_inference_steps steps). Larger gen_length costs proportionally more block passes.
thinkingBOOLEANfalseEXPERIMENTAL boolean toggle: injects the <|think|> control token via a system turn. Structurally one token short of native enable_thinking=True (the chat template's `| trim` eats the newline after <|think|>) — see run_diffusion's own docstring for the honest gap. Behavioral impact unverified pending an E2E thinking-mode run on real weights.
kv_cacheoptDGEMMA_KV_CACHEOptional KV-cache from DGemmaEncode: independent CONTEXT (raw-encoded, no chat framing) that conditions this run as background — it cannot restrict output the way prompt does. Leave unwired for an unconditioned run. Composes with prompt (ADR-CDG-024, issue #257): a non-empty prompt is the current-turn text, chat-templated and prefilled onto this cache before decoding. Leave prompt empty for pure injection (no prefill — does not anneal to coherent text). Rejected if this cache was already grown by a prior composed run — e.g. a cached DGemmaEncode node output reused across runs; re-run DGemmaEncode to mint a fresh cache (#265). Also rejected together with a non-empty prompt when gen_length exceeds one canvas_length — multi-block composed runs are blocked pending #263's splice-offset fix.

Outputs (6)

NameTypeDescription
textSTRING
canvas_stateDGEMMA_CANVAS_STATE
canvas_traceDGEMMA_CANVAS_TRACE
framesSTRING
imagesIMAGE
run_configDGEMMA_RUN_CONFIG