Repository navigation
feat(anima): add anima model IP-Adapter character reference images - #9903
Conversation
Adds the SigLIP2-based Anima IP-Adapter (model config, loader, encoder node, denoise injection with its bundled cross-attention LoRA). Generate and Canvas accept up to four Anima reference images with per-image Strength and Active steps; images sharing an adapter are attended together. Adds the adapter starter model (SigLIP2 encoder as a dependency) and documents behaviour and limits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pfannkuchensack
left a comment
There was a problem hiding this comment.
Approve with nits. The math matches the reference, other bases are unchanged, and none of the points below block a merge.
What I verified
- Math against the reference
nodes.py:- The IP query is the block's flattened, adaLN-modulated cross-attention input, run through
q_projand thenq_norm. - K/V come from
ip_k_proj/ip_v_proj, with no key norm and no output projection. - The gate is
adaln_ipon the normed t_emb, and the term is added after the MLP. - Only the positive pass gets the term. In the reference, the zero null tokens switch it off through
scale_mask. - Strength scales the fp32 tokens before the biased projections.
- Only the cross-attention part of the bundled LoRA is applied, at alpha/rank = 1.
- Preprocessing letterboxes to 512 px. The
_reference_forwardtranscription in the tests is faithful.
- The IP query is the block's flattened, adaLN-modulated cross-attention input, run through
- Real checkpoint: I read the safetensors header of
ip_adapter-Character_Reference-10.safetensors. It has 728 BF16 tensors, blocks 0–27, both flagsFalse,lora_alpha=lora_rank= 32 and nonull_tokens, so it matchesanima_ip_adapter_format.py. - Classification: only
IPAdapter_Checkpoint_Anima_Configclaims the real layout. The widened SigLIP probe matches google/siglip2-base-patch16-512'sconfig.jsonverbatim, and it still checks the class name when a config has one. - Other bases:
getReferenceImageConfigSupportedgives the same answers for sd-1/sdxl/flux as before, and the SD/FLUX graph fields are unchanged. Regional prompting only patchescross_attn.forward, so it doesn't affect the IP term. - Checks:
- The focused pytest suites pass on the head and with current
mainmerged in. They cover the Anima backend and denoise, the IP-Adapter, configs, features, starter models, fp8 capability and graph node types. - On the merged tree, main's union-collector validation (#9853) accepts
anima_ip_adapter→collect→anima_denoise.ip_adapter. openapi.jsonregenerated on the head is identical to the committed one.- ruff is clean.
- The focused pytest suites pass on the head and with current
Merging main: the only conflict is one hunk in generateGraphNodeTypes.json, in fieldsByNodeType.denoise_latents.inputs. Main adds "latents" (SDXL Refiner) and this PR adds "ip_adapter", so take the sorted union. Main also changed openapi.json and schema.ts since your base. They auto-merge, but please regenerate both rather than trusting the textual merge.
I didn't run the webv2 vitest/browser suites or a GPU generation; for those I'm relying on your runs.
# Conflicts: # invokeai/frontend/api/schema.ts # invokeai/frontend/webv2/src/features/generation/core/__snapshots__/generateGraphNodeTypes.json
Refuse unsupported adapter variants at install, cap images per adapter, sort them stably, skip encoding at strength 0, and count the bundled LoRA in the model size. The encoder lookup accepts any form of the HF repo id, and in multi-user mode only admins auto-install it; re-targeting a reference to Anima keeps its strength and step window. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@Pfannkuchensack thanks for the review! All seven nits are addressed in 110f44b; the open part of the cache-size nit is explained in its thread. Merging main: I built on your merge and then merged current main (2c1c5ae). I regenerated Checks:
|
Summary
Anima models had no way to carry a character from a reference image into a new scene. This adds support for the SigLIP2-based LuciferTC/Anima-IP-Adapter (
ip_adapter-Character_Reference-10.safetensors). It follows the reference ComfyUI implementation (ComfyUI-Anima_IP-Adapter).IPAdapter_Checkpoint_Anima_Config.google/siglip2-base-patch16-512, whose config has noarchitectures.anima_ip_adapternode. It encodes a reference with SigLIP2 and auto-installs the encoder if it is missing.anima_denoise1.9.0 gains anip_adapterinput:ref_imagesmetadata.What transfers, from GPU runs on Anima Base 1.0 and PerfectRSBmix Mu:
2girlsprompt.Related Issues / Discussions
None.
QA Instructions
1girl, solo, sitting in a cafe, holding a coffee cup. Set Strength to 1.0–1.5 and invoke. The character's hair, outfit and accessories should carry over.Checks, run on the rebased commit:
uv run --no-sync pytest -n 4: 14,542 passed, 205 skipped, 7 xfaileduv tool run ruff@0.11.2 checkandformat --check: cleanpnpm lint,pnpm test,pnpm check:release: pass (10,326 unit tests; release gate with 2,923 accessibility/browser tests)Review
Findings that were resolved:
begin_step_percent > end_step_percentis rejected.Remaining limitations:
wait_for_jobwith a 600 s timeout).methodtoflux_ip_adapter, which has no such field, so the FLUX card's Mode control does nothing. It's listed inSILENTLY_IGNOREDand isn't fixed here.Compatibility / Rollout
anima_denoisegoes 1.8.0 → 1.9.0 with a new optional input, andanima_denoise_metagoes to 1.1.0. Existing graphs and workflows validate unchanged.openapi.json,schema.tsand the webv2 capabilities fixture are regenerated.Checklist
What's Newcopy (if doing a release after this PR)🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need.