Nodes/ComfyUI-Anima-Remap/Apply Anima ControlNet-LLLite (Auto Remap)
ComfyUI Node

Apply Anima ControlNet-LLLite (Auto Remap)

The LLLite node that survives Anima's block growth

By shin131002·Created about a month ago·Updated 6 days ago· 13
Apply Anima ControlNet-LLLite (Auto Remap)
  • model
  • image
  • mask
  • model
  • remap_info
◄lllite_name▾►
◄strength1.00►
◄start_percent0.000►
◄end_percent1.000►
◄auto_remaptrue►
◄manifest▾►
◄extend_to_new_layersfalse►
◄extend_strength0.50►
◄preserve_wrappertrue►

Anima keeps growing, and it grows in the worst possible way for adapters. The original base is a 28-block DiT; Anima-2.9B has 40 blocks; Anima-3.8B has 52. Each jump was made by inserting new blocks in between the existing ones, not by appending to the end. So block 7 in a 40-block model is not the thing block 7 was in the base.

That's fine if you only run the base. It's a wall if you have LLLite weights - the only ControlNet that exists for Anima - because the published weights were trained against the 28-block model. Feed them to upstream's apply node on a 40- or 52-block model and it stops with depth_embed slices missing: the file's block indices point at slots that no longer mean what they meant.

This node is kohya's apply node with one idea bolted on - renumber the blocks in the weights to match the model you actually connected, using the expansion manifests from this pack.

What it actually does

The module is built from the checkpoint's own metadata rather than from knobs on the node - embedding dims, target layers, conditioning channels, the inpaint flag all come out of the file - so there's no "wrong preset" failure mode to hit.

Then, at load time, the block indices in the weights' keys get renumbered before anything is loaded onto the model. Upward - 28-block weights on a 40- or 52-block model - each trained module lands on the block it corresponds to. Nothing is invented for the inserted blocks, and that's deliberate: LLLite modules have a zero-initialised final layer, so a module that never had weights loaded onto it outputs exactly zero. Those new blocks are skip connections for the control, not garbage. Downward (40-block weights on a 28-block model) drops the extra tensors instead of guessing.

Application is scoped the way you'd hope: it installs a model_function_wrapper on its own model clone, converts start_percent/end_percent into a sigma range, and skips LLLite entirely on steps outside it - so two of these nodes with different ranges won't fight.

The inputs you'll actually touch

  • lllite_name - a dropdown of whatever is in models/controlnet. Your weights live there, same as upstream.
  • image - the conditioning map (lineart, depth, scribble).
  • strength - −10 to 10, default 1.0. If the effect feels invisible, move this first.
  • start_percent / end_percent - the window the control is active over. Defaults 0 → 1, i.e. all of it.
  • extend_to_new_layers + extend_strength (0–2, default 0.5) - the optional part. Turn it on and the inserted blocks each get a copy of their predecessor's module rather than nothing, on the logic that Anima's new blocks were created by copying their predecessor at expansion time. Averaging two neighbouring modules is explicitly not done: an LLLite correction is a product of low-rank factors, and averaging factors from two different modules doesn't mean anything. extend_strength scales only the final layer.
  • mask - optional, only for 4-channel (inpaint) weights. White is the area to repaint, black is keep. With 3-channel weights it's ignored with a warning; with 4-channel weights and no mask, the node stops and tells you so.
  • auto_remap and manifest - leave manifest on Auto (Recommended). It resolves the right expansion from the block-count pair it detects. Forcing a specific file is only for debugging.

Two outputs. model goes to your KSampler. remap_info is a plain string - something like 28->40 via expand_manifest_28_40.json, 84 tensors remapped, 0 dropped. Preview it while you set up: it's the only place that tells you whether remapping actually fired.

Install

ComfyUI Manager, search for the pack title, or:

cd ComfyUI/custom_nodes/
git clone https://github.com/shin131002/ComfyUI-Anima-Remap.git

Restart, drop your LLLite weights in models/controlnet. You don't need kohya-ss's package installed - the code is vendored, and the node ID is different, so this coexists with upstream's node and ComfyUI's built-in one.

If ComfyUI-Anima29B-Remap is installed, delete it first - same node IDs, so both at once is a registration conflict.

Where people get burned

The effect is weak, and that's the method, not your settings. These weights only add a correction to each block's self-attention query, so the prompt never loses its grip - a prompt or LoRA that contradicts your conditioning image usually wins. Raise strength, lower CFG, strip contradicting prompt terms, and only then conclude it's broken. For hard structure, use a VACE-type ControlNet instead.

Stacking without preserve_wrapper. ComfyUI's model_options has one model_function_wrapper slot, so a second wrapper-installing node silently no-ops the first. The node captures any pre-existing wrapper and delegates to it from inside its own, which is what preserve_wrapper (default on) controls. Leave it on when you chain two of these.

Legacy weight files won't load. Older v1-format LLLite checkpoints use internal module names directly and would land in the wrong places, so the node refuses them outright. Retrain with current code. fp8 checkpoints, by contrast, are fine - they get upcast on load.

Categoryloaders/anima

Inputs (12)

NameTypeDefaultDescription
modelMODEL—
lllite_nameCOMBO0 options:
imageIMAGE—
strengthFLOAT1.00-10–10—
start_percentFLOAT0.0000–1—
end_percentFLOAT1.0000–1—
auto_remapBOOLEANtrue—
manifestCOMBO4 options: Auto (Recommended), expand_manifest_28_40.json, expand_manifest_28_52_composed.json, expand_manifest_40_52.json
extend_to_new_layersBOOLEANfalse—
extend_strengthFLOAT0.500–2—
preserve_wrapperBOOLEANtrue—
maskoptMASK—

Outputs (2)

NameTypeDescription
modelMODEL—
remap_infoSTRING—