Nodes/Anima Adapter Loader/Anima Merged Loader (CJK)
ComfyUI Node

Anima Merged Loader (CJK)

The loader you need before Anima will actually draw the Japanese you typed

By sorryhyun·Created 5 months ago·Updated 2 days ago· 1
Anima Merged Loader (CJK)
    • MODEL
    • CLIP
    ◄unet_name▾►
    ◄clip_name▾►
    ◄weight_dtype▾►

    Anima is the anime base that finally fixed prompt comprehension - a 2B DiT on a Cosmos-Predict2 backbone with a Qwen3-0.6B encoder, reading Danbooru tags and prose in one sentence. What it can't do out of the box is read Japanese. Type "はい" and the T5 side of Anima's text stack has no ids for it: the glyphs collapse into <unk> and the model draws squiggles unrelated to your string. AnimaMergedLoader fixes that in one step.

    What it is, and when you'd reach for this one

    Anima's DiT can already draw a lot of CJK glyphs. That ability is unreachable because no prompt can address it - the tokenizer is the gate, not the model. The author's fix is a vocab pack: extra text-embedding rows appended after the base llm_adapter.embed table, so ids ≥ 32128 have somewhere to point.

    Pack use comes in two shapes. The general path is three nodes - stock UNet, stock CLIP, and Anima Vocab Pack Loader (CJK), which wants a .safetensors + .json pair side by side in models/vocab_packs/ with matching names. This node is the shortcut: it loads a merged checkpoint, a DiT that already carries the rows and the routing JSON, so there's one file in models/diffusion_models/ and nothing to keep in sync. If you downloaded anima_jp_extended.safetensors, this is your loader.

    How it works, briefly

    A merged file is base Anima's DiT plus one extra tensor - <prefix>llm_adapter.ext_embed.weight - and the pack's sidecar JSON in the safetensors metadata under ss_ext_pack_mapping. A naive loader chokes on that extra key. This one splits the pack off the state dict before the DiT is built, then applies it the way the Vocab Pack Loader does. The CLIP's tokenizer gets wrapped so a routed character re-encodes its t5xxl id stream with Qwen3 (stock T5 for everything else). On the MODEL side a pre-hook clamps ids ≥ 32128 to <unk> - ComfyUI core hardcodes a 32128-row table, and the lookup would crash - and a hook on llm_adapter.embed overwrites those positions with the pack's rows, gathered per encode from a CPU-resident fp32 table.

    English-only prompts never touch a row, so they stay bit-identical to plain Anima.

    The inputs and outputs that matter

    Three inputs, and only the first two really matter:

    • unet_name - the merged checkpoint from models/diffusion_models/. A plain Anima file loads too, but you get plain Anima out and a warning in the log.
    • clip_name - Anima's stock Qwen3 0.6B encoder from models/text_encoders/ (qwen_3_06b_base.safetensors). Don't get creative: the pack's hybrid encoder is built from that tokenizer, so a random T5 or CLIP file is off the tested path.
    • weight_dtype - default, fp8_e4m3fn, fp8_e4m3fn_fast, fp8_e5m2. Marked advanced for a reason: fp8_e4m3fn_fast also turns on fp8 matmul, giving a smaller, faster DiT on 40-series and newer. A 30-series card has no fp8 acceleration, so leave it on default.

    Outputs are MODEL and CLIP, and you wire both. MODEL goes into the KSampler - or into a LoRA loader first, since Anima LoRAs stack on this file fine; the rows touch no LoRA-adapted weight. CLIP goes into your CLIP Text Encode nodes. The VAE is separate: a stock Load VAE with qwen_image_vae.safetensors.

    Install

    ComfyUI Manager → search the pack title Anima Adapter Loader - or clone it by hand and restart:

    cd ComfyUI/custom_nodes
    git clone https://github.com/sorryhyun/ComfyUI-Anima_lora-Adapter
    # restart ComfyUI
    

    No extra dependencies - the vocab runtime ships bundled under _vendor/. On disk you need:

    ComfyUI/models/diffusion_models/anima_jp_extended.safetensors   # the merged DiT
    ComfyUI/models/text_encoders/qwen_3_06b_base.safetensors        # stock Anima encoder
    ComfyUI/models/vae/qwen_image_vae.safetensors                   # stock Anima VAE
    

    You need node version 3.15.0 or newer - this loader landed 2026-10-08.

    Where people get burned

    You used the stock loader. "Load Diffusion Model" swallows a merged checkpoint happily and hands you plain Anima, no Japanese, plus one unet unexpected line that's easy to scroll past. If the text isn't rendering, check what's upstream first.

    You expected to prompt in Japanese. The real trap, and it's a vocabulary problem, not a bug: the rows were trained on rendering, from scene composites with Japanese dialogue in speech bubbles. Japanese in a prompt means text to draw in the image - so quote it inside an English clause and keep the tags English:

    1girl, solo, speech bubble. Text reads as "何言ってるの?".
    1girl, solo, speech bubble, japanese text. She is saying "おはよう!".
    

    Writing 猫耳, 銀髪 as tags won't do what cat ears, silver hair does. And the node says CJK, but only Japanese rendering is trained; Korean and Chinese map to tag rows.

    Long strings aren't letter-perfect. Ten-plus glyphs rarely come out exactly, kanji with no trained row draw as noise, and all of it is seed-dependent.

    Errors that are diagnostic. ... but no 'ss_ext_pack_mapping' metadata means a truncated download or a hand-merged file. carries no vocab pack - loaded as plain Anima means unet_name is a plain DiT. A row-count mismatch means the sidecar JSON isn't the tensor's. And a tokenizer error about a fast Qwen tokenizer means pip install tokenizers.

    Categoryloaders

    Inputs (3)

    NameTypeDefaultDescription
    unet_nameCOMBOMerged Anima checkpoint from models/diffusion_models/.
    clip_nameCOMBOAnima's stock Qwen3 0.6B text encoder.
    weight_dtypeCOMBO4 options: default, fp8_e4m3fn, fp8_e4m3fn_fast, fp8_e5m2

    Outputs (2)

    NameTypeDescription
    MODELMODEL—
    CLIPCLIP—