--- license: apache-2.0 tags: - lora - reference-conditioning - anima - krea-2 - diffusion-pipe --- # Reference adapters — Anima e Krea 2 (bateria de 2026-07-25/26) Adapters de referência treinados no fork [adbrasi/diffusion-pipe-easycontrol](https://github.com/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](https://huggingface.co/datasets/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 `` 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): ```bash 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 ```toml [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.