minih33-smoothloopv3 / PROGRESSO_smoothloopv3.md
AdwolfCzar's picture
notas: fix de chaves ComfyUI + plano gameprod
78e6693 verified
|
Raw History Blame Contribute Delete
15.7 kB

smoothloopv3 — diário de bordo (LoRA MiniMax H3)

Início: 2026-09-19. GPU: RTX 5090 32 GB (driver 595.91.07, CUDA 13.2). Disco: overlay 350 GB, NÃO é volume persistente (df mostra overlay em /workspace). → Tudo que importa precisa ir para o HF. Recycle/destroy apaga tudo.

Decisões fixadas

  • Trainer: fork AkaneTendo25/musubi-tuner, branch minimax-h3, pin ede9ed9f... (relatório 18/09).
  • Receita base: v3 (rank/alpha 32, LR 5e-5, AdamW8bit, sem preservation, guidance 4/sigma/normalized, jitter 0.2, swap 32, SDPA, convrot int8, AdaLN rank 16, fused qk/rope).
  • HF: conta AdwolfCzar, padrão minih33, público + gated manual, sem "minimax" no nome.

Descobertas

# Quando Achado
1 02:5x captionkreator é repo privado; acesso via $GITHUB_TOKEN (ghp_...) do ambiente.
2 02:5x Tokens HF no ambiente: HF_TOKEN→AdwolfCzar, HF_TOKEN_USER→adbrasi. hf-xet 1.6.0 presente.
3 02:5x Mega: megatools (apt) baixa link público de pasta sem login. rclone não tinha config.
4 02:5x Dataset traz .txt com tags danbooru (não captions). O perfil smoothloop NÃO as usa como
entrada (user.md só manda Animation type: {{folder}} + vídeo) e o run sobrescreve o .txt.
→ Backup das tags antes de rodar o captioner.
5 02:5x Amostra inicial: 512x384, 10 fps, 16 frames (1,6 s), sem áudio, tag looping_animation.
captioner convert (smoothloop) resolve: fps 24 + loop:true/min_duration:5 (tiling de ciclos
inteiros) + max_edge 1280 + CFR. Substitui o extend_loops.py histórico.
6 02:5x OPENROUTER_API_KEY presente no ambiente (perfil smoothloop usa openrouter).
7 03:1x Venv estava sem torch (ambiente novo, nao o de agosto). Instalado torch 2.10.0+cu130
(combo validado no historico); torch.cuda ok, cc (12,0) = Blackwell.
/venv/main exigiu sudo chown -R claude:claude antes de instalar (armadilha ja no NOTES).
8 03:1x Mega a 0,57 MB/s com megadl (sequencial) = 3,6 h. Escrevi downloader paralelo
(/workspace/scripts/mega_folder_dl.py, API do Mega + AES-CTR, 16 conexoes) -> 4,1 MB/s,
ETA ~30 min. Retoma o que o megadl ja tinha baixado (compara tamanho).
9 03:1x Dataset real: 7,82 GB, 1749 mp4 + 1752 txt, raiz smoothlooper_v3_datasetCRU com
subpastas 1..6 (mp4 por pasta: 1=180, 2=521, 3=~471, 4=76, 5=39, 6=463).
A estrutura 1..6 e exatamente o que o perfil smoothloop espera (Animation type: {{folder}}).
10 03:2x BUG no template do handoff: --save_last_n_steps_state NAO existe no pin ede9ed9f.
So existe --save_last_n_checkpoints N, que apaga LoRAs antigos junto com os states.
Decisao: NAO passar retencao nenhuma (guarda todos os LoRAs p/ checkpoint picking) e deixar
o meu uploader apagar states antigos localmente depois de confirmados no HF.
11 03:2x O trainer tem upload HF embutido (--huggingface_repo_id, --async_upload), mas nao cobre
os samples mp4. Vou usar uploader proprio (watcher) como no historico.
12 03:1x captioner convert (smoothloop) validado em 3 clipes reais: 604x504@14,6fps/2,19s -> 24fps/6,58s/158f;
512x384@10fps/1,6s -> 24fps/6,29s/151f; 1080x1920@60fps -> 720x1280 (max_edge 1280)/24fps/160f.
Dataset e heterogeneo (retrato/paisagem/quadrado, 10-60 fps). Tiling entrega ~150-160f > 124f.
13 03:2x OPENROUTER_API_KEY do ambiente estava EXPIRADA ("API key expired"). Usuario forneceu chave nova,
gravada em /workspace/.env (chmod 600). Sem limite, sem expiracao.
14 03:3x captioner run NAO pula arquivos que ja tem .txt (Skipped 0) -> as tags danbooru SAO sobrescritas.
Backup obrigatorio antes. Custo medido: $0,0024 / 3 videos => ~$1,40 para os 1749.
15 03:3x Decisao do usuario: samples usam o primeiro frame (casa com o contrato "<Picture 1> em 0.00s").
16 03:4x Meu downloader tinha bug: o campo k do Mega traz varias entradas handle:chave separadas
por / (pasta compartilhada). split(":")[1] pegava lixo -> 147 arquivos indecifraveis.
Corrigido testando todas as entradas. Dataset integro: 3501 = 1749 txt + 1651 mp4 + 101 webm.
17 03:4x Inventario do bruto: fps caotico (30/16/60/24/10/29,97/25/33,33/6,67/12,5/5/20/4...),
resolucoes de 486x1080 a 3840x2160, 480 clipes COM audio (historico tinha zero),
duracao mediana 5,53 s / p90 20 s / max 85,9 s. 51,3% ja >=124f a 24fps.
18 03:5x BUG no captionkreator (corrigido): fontes de fps baixo (4-12) falhavam a conversao com
"duration changed from 6.000s to 5.750s" -> ~11% do dataset. Duas causas: -stream_loop
com uma copia a menos do que o -t precisa, e tolerancia usando o fps ALVO em vez do da FONTE.
Branch fix/low-fps-duration, commit 6baca90 (local, sem push). Suite: os mesmos 10 testes
falham com e sem o patch (pre-existentes, versao do ffmpeg do container).
19 03:5x Armadilha do NOTES confirmada 2x na pratica: pgrep/pkill -f <padrao> casa com o proprio
shell e mata a sessao. Passei a gravar PID em arquivo (/workspace/logs/*.pid).
20 04:0x Projecao de disco: dataset convertido fica menor que o bruto (fator 0,45x; max_edge 1280
reduz fontes 4K/1440p, max_duration 10s corta as longas). ~4 GB convertido + ~4 GB zip +
~18 GB cache + ~1,1 GB por checkpoint. Total ~35 GB contra 239 GB livres.
ComfyUI do usuario: 9,3 GB (8,1 GB so o venv dele) - irrelevante, mantido a pedido.
Gargalo real e VRAM (treino ~18-24 GB dos 32 GB), nao disco: nao rodar ComfyUI junto.
21 04:1x Segunda iteracao do fix de fps baixo: tolerancia 1,05/source_fps errava por 0,5 ms num
clipe 888x888 a 6,67 fps (deficit 0,158 s vs limite 0,1575 s). Corrigida para
1/source_fps + 2/target_fps. Commit 8c6f813. 1 unico arquivo do dataset era afetado.
22 04:3x Dataset convertido: 100% a 24 fps, lado maior <=1280, 1752 mp4 / 0 webm, 4,3 GB.
Mediana 183f (7,6 s), p75 239f, max 240f (teto de 10 s). 96% >=124f.
23 04:4x Captions: 1752/1752, zero falhas, $0,65 (17,9 M tokens in / 1,28 M out).
Validacao pasta->gatilho: 180 static / 522 slow / 472 smooth / 76 intense / 39 turntable /
463 chroma-key = 100% corretos, zero contaminacao cruzada.
24 04:4x Decisao do usuario: respeitar o minimo do H3 de 5 s. No grid 17k+5 o valor acima de 5 s
e 124f (5,17 s) -> NENHUMA view abaixo disso. Descartados os esquemas com f107/f90/f73
(inclusive a receita do smoothloop historico). Esquema final: 3 areas (512x288/640x384/
832x480, quotas 55/28/17) todas em f124, estratificadas por resolucao de origem.
Tokens medios de video ~7870; ancora historica mais proxima = quick (124f multi-res) 12,8 s/it,
mas este pin tem fused_qk_norm_rope + fixes de recompilacao/sync, entao esperar menos.
25 04:4x 70 clipes (4%) sairam com 117-123f. Reconvertidos com perfil derivado smoothloop_min124
(min_duration 5.3, max_duration 12) para ganhar um ciclo inteiro a mais.
26 04:4x Armadilha nova: captioner consome stdin; dentro de while read -r f ele come caracteres
do caminho lido (paths viravam "orkspace/..."). Fix: </dev/null no comando interno.
27 04:4x Armadilha nova: : sem aspas em description: do profile.yaml quebra o parse YAML
("mapping values are not allowed here") e o convert falha sem dizer qual arquivo.
28 05:0x Dataset FINAL: 1752 clipes, 100% 24 fps, 100% >=124f (min exatamente 124 = 5,17 s),
1752/1752 com caption H3. Mediana 191f, max 246f. 4,3 GB.
29 05:0x Views (estratificadas por px da fonte, seed 42): v288 963 / v384 491 / v480 298 = 1752.
So 6 clipes (0,3%) tem fonte abaixo da area de 512x288; com bucket_no_upscale eles treinam
no bucket nativo menor, que e o comportamento correto.
30 05:0x Dataset publicado: huggingface.co/datasets/AdwolfCzar/smoothloopv3_dataset (zip -0 + backup
das tags danbooru). Upload via xet a ~76 MB/s.
31 05:0x Samples: 3 previews cobrindo paisagem/quadrado/retrato E tipos smooth/slow/static.
832x480 seed42 / 576x704 seed43 / 480x832 seed44, todos 124f, 20 passos.
Troquei o 2o sorteio: o clipe tinha a moldura inteira girando (cunhas pretas), ruim como
referencia de monitoramento. Substituido por um com fundo liso, que isola o movimento.
32 05:0x SMOKE LEG 1 PASSOU: 10 steps (loss 0,074), samples nos steps 0/5/10 (9 mp4 + json
validos: 832x480 / 576x704 / 480x832, todos 124f a 24 fps), checkpoints 5 e 10 + states.
~10 s/it nos itens MAIS PESADOS (melhor que a ancora historica de 12,8 s/it).
VRAM: pico 15,1 GiB reservado no sampling; 15,3 GiB em uso durante os steps. Folga grande
nos 32 GB com swap 32.
Custo de sampling medido: ~113 s por preview (101,6 s denoising + 11,7 s decode) => ~6 min
por evento de 3 previews. A cada 500 steps (~83 min) isso e ~7% de overhead.
33 05:0x Conversao ComfyUI validada: 600 tensores do trainer -> 400 com chaves diffusion_model.*,
569 MB. O uploader gera essa versao automaticamente a cada checkpoint.
34 06:0x Smoke leg 2 (resume) PASSOU: retomou de global_step=10, pulou 10 batches, foi a 15.
Loss 0,074 -> 0,046. Gatilho de parada confirmado no codigo (trainer_base.py:2462,
poll_checkpoint_request_files a cada optimizer step).
35 08:2x CACHE COMPLETO: 21,5 GB (v288 9,6 / v384 6,5 / v480 5,4), 3504 arquivos =
1752 latentes + 1752 TE. Preflight de captions passou com 1752 itens.
Latentes ~2,5 h (GPU 100%, VAE-bound), TE ~20 min. Serial, como manda o historico.
36 08:4x TREINO LANCADO (minih33_smoothloopv3), 6000 steps de teto, save+sample a cada 500.
Medido: 12,07 s/it, loss 0,0996 -> 0,0952 nos primeiros 33 steps.
VRAM 25,1 GB / 32 GB - bem acima dos 15,3 GB do smoke (dataset real tem mais variedade
de bucket). Folga ~7 GB. Historico teve OOM no step ~4502 com swap 24; aqui swap 32.
MONITORAR: se passar de ~29 GB, reiniciar com BLOCKS_TO_SWAP=40 e RESUME=1.
37 08:4x Uploader em tempo real ativo: sobe checkpoint + versao _comfy + samples mp4/json + tb,
e apaga states locais antigos (mantem 2). Samples do step 0 ja no HF.

| 38| 20/09 | convert_lora.py --target other QUEBRA o LoRA de H3 — nao usar. O ComfyUI | | | 02:3x | relatou "lora key not loaded" em 200 dos 400 tensores do _comfy. Causa: o conversor | | | | so sabe trocar todo _ por . e depois aplicar correcoes hardcoded por arquitetura | | | | (Wan self_attn, Z-Image to_q, Hunyuan double_blocks, tabela Qwen-Image). Nao ha | | | | regra para H3, entao blocks.N.attn.qkv_proj virava attn.qkv.proj e | | | | attn.out_proj virava attn.out.proj (50 blocos x 2 modulos x 2 tensores = 200). | | | | mlp.fc1/fc2 escapavam por nao terem underscore. O fork adicionou H3 no lado do | | | | TREINO e nunca tocou no script de exportacao — ponto cego, nao regressao. | | 39| 20/09 | O checkpoint NATIVO carrega 100% no ComfyUI — a conversao e desnecessaria. | | | 02:4x | comfy/lora.py::model_lora_keys_unet monta o mapa a partir das chaves do MODELO | | | | carregado: k[len("diffusion_model."):-len(".weight")].replace(".", "_") -> | | | | lora_unet_blocks_0_attn_qkv_proj, que e exatamente o nome que o musubi grava. | | | | O ComfyUI resolve o mapeamento com o modelo em maos; o convert_lora.py tenta | | | | adivinhar o inverso as cegas. DECISAO DO USUARIO: --no-comfy e o padrao a partir | | | | de agora (hf_uploader.py: virou --comfy opt-in; --no-comfy aceito como no-op). | | | | Usar sempre minih33_*-stepNNNNNNNN.safetensors, sem sufixo. | | 40| 20/09 | Os LoRAs de agosto tem o mesmo bug. Verificado por range request no header dos | | | 02:4x | safetensors no HF (sem baixar 596 MB): minih33-jiggle/checkpoints/comfy/ | | | | minih33_jiggle-step00002500_comfy.safetensors tem attn.out.proj/attn.qkv.proj. | | | | Vale para minih33-jiggle, minih33-smoothloop e minih33_quick (NOTES (4).md l.164 | | | | confirma o mesmo comando). Quem usou o _comfy de agosto rodou com METADE do LoRA | | | | (so MLP, zero atencao). Os nativos desses repos estao corretos. |

Bugs / incidentes

Quando O que Resolucao
20/09 02:3x ComfyUI ignorava 200/400 tensores do _comfy (descoberta 38) Patch no convert_to_diffusers com ramo H3 (ida e volta) + os 7 _comfy locais regerados e validados. Mas a decisao final foi abandonar o _comfy (descoberta 39): o nativo e o arquivo bom.
20/09 02:1x nohup ... & dentro do Bash tool morre junto com a chamada (nem o log foi criado) Usar run_in_background: true do proprio tool, nao nohup &.
20/09 02:2x /workspace/.env NAO existe nesta maquina (existia na 51502554) Tokens vivem no environ dos processos: tr '\0' '\n' < /proc/$(cat /workspace/logs/uploader.pid)/environ.

Progresso

  • Ler relatório + NOTES + handoff
  • Acesso Mega, GitHub, HF validados
  • Download dataset Mega (7,3 GB, 1752 midias em 6 pastas de tipo de animacao)
  • Backup tags + convert + captions (1752/1752, $0,65, gatilhos 100% corretos)
  • Upload dataset (zip + xet) para HF
  • Download pesos H3 (82 GB, Comfy-Org/MiniMax-H3: DiT fl2va bf16, TE nvfp4_awq, 2 VAEs)
  • Views/buckets + TOMLs (3 areas, todas f124)
  • Samples (3 vídeos aleatórios, first frame + caption)
  • Smoke test + resume (leg1 10 steps + leg2 resume ate 15, ambos exit 0)
  • Cache completo (21,5 GB)
  • Treino lancado + uploader em tempo real ativo

Validar um checkpoint sem ter ComfyUI a mao

Duas checagens contra o state dict de minimax_h3_fl2va_bf16.safetensors. Pegam exatamente o bug das descobertas 38-40 e sao baratas (so leem headers):

  1. Nomes — toda chave do LoRA tem que apontar para um modulo que existe no base: mod = key[len("diffusion_model."):].rsplit(".lora_",1)[0] e entao mod+".weight" in base_keys. Esperado: 400/400, zero orfaos. O arquivo quebrado dava 200 orfaos.
  2. Shapes — B @ A tem que ter o shape do peso base: B[1]==A[0] e [B[0],A[1]]==W. Ex.: blocks.0.attn.out_proj -> W [5376, 7168], B [5376, 32], A [32, 7168].

Para o formato nativo o nome e lora_unet_<modulo com _ no lugar de .>, entao a checagem 1 vira: trocar lora_unet_ por nada, _ por ., e conferir — lembrando que qkv_proj/out_proj sao os unicos com underscore interno.

Header remoto sem baixar o arquivo (usado na descoberta 40): ler 8 bytes little-endian = tamanho do header JSON, depois os proximos N bytes, via Range: bytes=0-7 / Range: bytes=8-N+7.