Reference adapters — Anima e Krea 2 (bateria de 2026-07-25/26)

Adapters de referência treinados no fork adbrasi/diffusion-pipe-easycontrol, branch ic-lora. Documentação completa em docs/ daquele repo — em especial ANIMA_FUTURO_TREINO.md e KREA2_MULTIREF_RECEITA.md.

Dois projetos separados aqui:

pasta modelo tarefa
anima/ Anima (2B, DiT de vídeo derivado do Cosmos-Predict2) uma referência, "próxima cena"
krea2/ Krea 2 (22B... na prática 12,8B de DiT) N referências separadas, endereçadas por texto

krea2/ — multi-referência (o resultado novo)

Método krea2_multiref_grounded. Krea 2 recebendo N referências separadas (não coladas numa imagem só), endereçadas por texto no caption: "Generate an image of the woman from image 1 holding the bag from image 2."

Treinado no Azily/Macro-Dataset (bracket 1-3, filtrado pelas notas do juiz do próprio dataset), 512px, max_refs = 2.

  • multiref_step500 — 2.200 amostras, 500 steps
  • multiref_step250 — mesmo run, checkpoint anterior

O achado que fez funcionar

O width_shift do Krea 2 soma uma constante ao deslocar a referência no RoPE. Um laço sobre N reusando aquilo daria a todos os spans posições idênticas — e aí a saída do DiT fica exatamente invariante à troca de duas referências: a atenção é permutation-invariant sobre keys, o tvec e as máscaras são uniformes, MLP e norm são pointwise.

Não é "difícil de aprender", é impossível em princípio. A correção é offset cumulativo: slot i em w += (i+1) * W.

Formato de caption

image 1 / image 2, sem os sinais < >. Treinar com <image 1> fez o modelo renderizar o marcador como texto dentro da imagem. Os blocos de visão do Qwen3-VL são rotulados com o mesmo vocabulário (image 1:), então não há ponte entre dois vocabulários para o modelo aprender.

Resultados

Avaliação held-out em anime (domínio totalmente fora da distribuição — o Macro é quase todo fotográfico): 6/6 corretos a 1024px, 4/6 a 512px. As duas falhas de 512 eram limitação de resolução, não de capacidade: a referência é codificada na resolução do alvo, então em 1024 ela carrega 4× mais tokens.

Num exemplo com posição explícita ("os dois personagens de image 1 na esquerda e o homem de image 2 na direita"), a saída obedece — e trocar a ordem das referências troca quem está de cada lado. Isso é endereçamento, não mistura.

Uso

Requer o fork (o runner constrói o modelo a partir do to_layers() do pipeline, então treino e inferência compartilham o packing exato):

python tools/infer_reference_adapter.py \
  --config examples/macro_multiref/run2_multiref.toml \
  --adapter multiref_step500/ \
  --reference ref1.jpg --reference ref2.jpg \
  --prompt "Generate an image of the woman from image 1 holding the bag from image 2." \
  --width 1024 --height 1024 \
  --turbo-lora krea2_turbo_lora_rank_64_bf16.safetensors

A ordem das flags --reference é a ordem dos slots. --turbo-lora usa a LoRA turbo oficial (8 steps, CFG 1.0, mu 1.15).


anima/ — bateria de métodos de adapter de referência

Sete braços de uma bateria controlada, todos com o mesmo dataset, seed e protocolo de avaliação (10 exemplos held-out × 4 colunas: sem referência / força 1.0 / ref_cfg 1.75 / referência embaralhada).

adapter método veredito
M1_armD_dropout_step2000_VENCEDOR ic_lora_v3 target-first, llm_adapter congelado, adaln fora, condition_dropout 0.1, 2000 steps 🏆 vencedor (visual, do usuário)
M1_arm1_llm_frozen_step500 / step1000 mesma receita, sem dropout empata em qualidade, caráter diferente
M1_armB_dropout_step1000 mesma receita com dropout, só 1000 steps perde — não convergiu ainda
M2_arm3_llm_trainable_step1000 llm_adapter treinável ❌ perde ("praticamente não pega a referência")
M3_armA_adaln_in_step1000 LoRA também no adaln ❌ perde (artefato de instabilidade)
M4_armC_routing_step1000 routing condition-only ❌ perde

Os dois achados

1. O condition_dropout não remove a referência — ele a ZERA. O frame continua concatenado, com o mesmo timestep e as mesmas posições de RoPE; só fica em branco. Consequência: o modelo ganha um nulo calibrado e passa a tratar a referência como entrada separável que consulta (atribui), em vez de fundir referência e alvo (acopla). Para um contrato do tipo "o que não está escrito é herdado", atribuição é exatamente o que se precisa.

2. Dropout sem aumentar os steps é estritamente PIOR que não usar dropout. Sensibilidade medida: armB (dropout, 1000 steps) 0.589 < arm1 (sem, 1000) 0.657 < armD (dropout, 2000) 0.921. O dropout bloqueia a rota fácil, então o modelo aprende mais devagar — as duas mudanças andam juntas ou nenhuma delas.

Receita vencedora

[model]
type = 'ic_lora_v3'
llm_adapter_lr = 0           # CONGELADO — bate com a recomendação oficial do Anima

[ic_lora_full]
ref_first = false            # target-first
condition_dropout = 0.1
include_adaln = false

[adapter]
rank = 32

[optimizer]
type = 'adamw_optimi'
lr = 1e-4                    # batch efetivo 8
# 2000 steps, não 500

Inferência: --mode ominicontrol_subject --lora_strength 1.0 --ref_cfg 1.0. ⚠️ M4_armC_routing precisa de --mode ic_lora_dual — o modo padrão funde a LoRA em todos os pesos e destrói o adapter routado, produzindo ruído puro que parece "o método falhou".


Ressalvas honestas

  • Nenhum ranking fino entre arm1, armB e armD sobrevive à estatística (Welch t=1.74 com 6 seeds, crítico 2.23). O que sobrevive são os efeitos grandes: llm_adapter congelado vence, adaln fora, routing perde.
  • Os adapters do Anima foram treinados num dataset com captions exaustivas, que causam "atalho de caption" — a caption descreve o alvo por completo e a referência vira supérflua. É plausível que o ranking mude com delta-captions.
  • O krea2/multiref é de um treino de 500 steps sobre 2.200 amostras. A capacidade está demonstrada; não é um modelo de produção.
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support