File size: 8,117 Bytes
77cc641 4dad329 77cc641 4dad329 77cc641 4dad329 77cc641 4dad329 77cc641 18cfc4e 77cc641 4dad329 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | # DMDX (Adversarial Distribution Matching) 蒸留
[← README に戻る](../README.md) — 関連: [PCM](pcm.md) / [DMD2](dmd2.md) / [蒸留全般](distillation.md)
## 論文
**"Adversarial Distribution Matching for Diffusion Distillation Towards Efficient Image and Video Synthesis"**
- arxiv: [2507.18569v1](https://arxiv.org/html/2507.18569v1)
- 著者: Yanzuo Lu et al. (Sun Yat-Sen University + ByteDance Seed Vision)
- 公開コード: なし (論文のみ)
## 核心アイデア
DMD2 の `(real_score - fake_score)` の **逆 KL 発散** はモード崩壊しがち (Phase B v2 と同症状)。DMDX は **学習可能 discriminator による hinge GAN (TVD = Total Variation Distance、対称) 最小化** に置換し、根本解決を狙う。
### vs DMD2
| 観点 | DMD2 | DMDX (ADM) |
|---|---|---|
| 発散尺度 | 逆 KL (非対称、mean collapse 寄り) | **TVD (対称)** |
| 損失実装 | grad trick で score difference 直接最小化 | **学習可能 discriminator** で hinge loss 敵対学習 |
| GAN 役割 | optional 正則化 | **本体損失** |
| 時刻情報 | t での score 比較のみ | `t → t-Δt` の ODE 進化中間点も考慮 |
| Initialization | MSE pretrain | 論文では ADP (= adversarial pre-training)、本実装は warm-start で代替 |
## 本実装の範囲
論文の **ADM のみ移植**、**ADP は省略** (SAM 依存 pixel-space discriminator が重い、コスト効果が低い)。
代替: **Civitai Anima Turbo を warm-start** で「分布レベルの良い初期化」を確保。
**実装**: `scripts/distill/{dmdx_loss,train_dmdx}.py`
**Modal**: `modal_app.py::train_dmdx_distill`
### ADM の構造
- **Discriminator backbone** = teacher MiniTrainDIT (frozen) — **LADD の `AnimaLADDDiscriminator` を流用**
- **Trainable heads** × 5 (blocks 2/8/14/20/26 を hook、各 spectral norm + BatchNormLocal)
- **Cubic time schedule**: `u ~ U(0,1), t = 1 - u**3` (high-noise バイアス)
- **Δt evolution**: teacher で 1-step Euler で `t → t-Δt` 進化、Δt = T/64
- **Hinge loss**: G = `mean(-D(fake))`、D = `relu(1-D(real)) + relu(1+D(fake))`
## 訓練設定 (実走、2026-05-19)
| 項目 | 値 |
|---|---|
| Base | `anima-base-v1.0.safetensors` |
| Method | DMDX ADM-only |
| Student LoRA | wide (980 keys、single adapter) |
| LoRA rank | 32 |
| Disc heads | 5 (block 2/8/14/20/26)、各 ~3.4M = 17.1M total |
| Total outer | 5000 (1 outer = 2 disc + 1 gen) |
| n_critic_per_gen | **2** (DMD2 の 5 より少なめ、hinge GAN 系は 1:1〜2:1 が一般的) |
| n_student_steps | 4 |
| Teacher CFG | 4.5 |
| Student CFG | 1.0 |
| dt_ratio | 1/64 ≈ 0.0156 |
| recon_weight | **0.0** (pure ADM、LADD の Smooth-L1 anchor なし) |
| LR (gen / disc) | 5e-6 / 1e-5 |
| Warm-start | **`/models/loras/anima_turbo.safetensors`** (Civitai 公式 Turbo) |
| GPU | B200 |
| 訓練時間 | smoke ~35s (10 outer)、本番 ~5h 想定 (3.6s/outer) |
| コスト | smoke ~$0.5、本番 ~$30 想定 |
## Smoke 結果 (10 outer、2026-05-19)
| outer | l_d_real | l_d_fake | l_d_total | l_g_adv | 評価 |
|---|---|---|---|---|---|
| 0 | 0.717 | 1.295 | 2.012 | -0.292 | 初期 hinge equilibrium |
| 5 | 0.724 | 1.277 | 2.001 | -0.276 | 安定継続 |
| 9 | 0.740 | 1.268 | 2.008 | -0.270 | smoke 完了 |
OOM / NaN / divergence なし。setup・warm-start (968/1016)・D init・ADM loss 全部正常。
## 本番訓練 (進行中、2026-05-19)
### Step 500 検証
| outer | l_d_real | l_d_fake | l_d_total | l_g_adv |
|---|---|---|---|---|
| 0 | 0.717 | 1.295 | 2.012 | -0.292 |
| 90 | 0.774 | 1.227 | 2.001 | -0.218 |
| 340 | 0.938 | 1.034 | 1.972 | +0.048 (D 優勢) |
| **500** | **0.822** | **0.976** | **1.798** | **-0.146** |
| 1000 | 0.933 | 0.971 | 1.904 | -0.093 |
GAN dynamics:
- `l_d_total` 2.012 → 1.798 → 1.904 (D 学習、後半は equilibrium 周辺で振動)
- `l_g_adv` -0.292 → +0.05 (一時 D 優勢) → -0.15 → -0.09 (G 持ち直し)
- D と G の拮抗状態に到達、healthy GAN training
### 生成検証 (step 500/1500/2500/final、4-step / er_sde+simple)
step 500/1500/2500/final で 4 回 quick_check を実施 — **すべて視覚的に同一**。
warm-start (Civitai Anima Turbo) ベースラインとも視覚差なし:
| ckpt | 生成時間 (er_sde+simple) | 視覚的差異 |
|---|---|---|
| step 500 | 5.77s | warm-start とほぼ同一 |
| step 1500 | 6.07s | 同上 |
| step 2500 | — | 同上 |
| **final (5000)** | — | warm-start (Civitai Turbo) と区別困難 |
### ⚠ 重要な結論: warm-start dominance
5000 outer 訓練を完走したが、student LoRA は **warm-start からほぼ移動しなかった**:
- GAN dynamics は健全 (D vs G 振動、divergence / mode collapse なし)
- ただし重み update が保守的、独自の蒸留方向を獲得できず
- 出力品質は Civitai Anima Turbo と視覚的に同等
推測原因:
- **hinge GAN の update が conservative** (D が perfect 寄りで G の gradient saturate)
- **warm-start anchor が強すぎる** (Civitai Turbo が既に 4-step CFG=1 で機能)
- **recon_weight=0** で soft anchor がなく、保守的振動に収束
## 配布
[HF: darask0/anima-distill-loras/dmdx/](https://huggingface.co/darask0/anima-distill-loras/tree/main/dmdx)
実質「Civitai Turbo + 軽い ADM 訓練」状態。研究目的・記録のため配布。
実用としては Anima Turbo を直接使うのと差異なし。
## ComfyUI 推奨設定
```
LoraLoaderModelOnly:
lora_name: dmdx_student_final_comfy.safetensors
strength_model: 1.0
ModelSamplingAuraFlow:
shift: 3.0
KSampler:
steps: 4
cfg: 1.0
sampler_name: er_sde
scheduler: simple
```
## 期待品質 (paper 報告ベース)
SDXL 1-step での DMDX vs DMD2:
| metric | DMD2 | DMDX | 差 |
|---|---|---|---|
| CLIP Score | 35.22 | 35.26 | +0.04 |
| PickScore | 22.10 | 22.27 | +0.17 |
| HPSv2 | 27.45 | 27.70 | +0.25 |
| MPS | 10.69 | 11.20 | +0.51 |
| **多様性 LPIPS** | 0.6715 | **0.7156** | **+0.044** |
→ **多様性 +6.5% が最大の利点**、画像品質は誤差レベル。Video (CogVideoX) では 8-step で 100-step 比 92-96% 加速の大きな成果。本実装は image only。
## 知見
### DMDX の利点 (DMD2 比較で明確)
| 観点 | DMD2 + TrigFlow | DMDX (ADM) |
|---|---|---|
| critic 数 / generator update | 5 | **2** (-60%) |
| forwards / outer step | ~32 | **~23** (-28%) |
| LoRA adapter | 2 (student + fake_score、毎 forward で `set_adapter()` 切替必要) | **1 (student only)** + 別 D heads |
| 並列訓練時の slowdown | ~1.7x (6.2 vs 3.7s/outer) | **ほぼなし** (3.6s/outer 維持) |
| 実装複雑度 | dual adapter PEFT 管理、leak 注意 | single adapter + 標準 D heads、シンプル |
仮に最終品質が DMD2 と同等以下でも、**訓練効率の優位性は明確**:
- generator update の頻度が高く (per outer)、G の学習機会が多い
- adapter switching overhead なし
- parallel training の安定性が高い
### その他
- **LADD discriminator の再利用**: spectral norm + BatchNormLocal + multi-block hook の構造はそのまま流用可能、DMDX 専用 D を新規開発する必要なし
- **cubic time schedule**: shifted uniform より extreme な high-noise バイアス、`t_mean=0.0259-0.99` の wide range (cubic の variance 大)
- **`recon_weight=0` で開始**: pure ADM の純粋性 verify。不安定なら LADD 流 Smooth-L1 anchor (`>0`) で stability boost 可能
- **billing limit 再発防止**: 並列 launch 前に Modal spend cycle limit を確認 (DMD2 v1 が KeyboardInterrupt'd した先例あり)
- **warm-start dominance の罠**: 強い warm-start (Civitai Turbo) + 保守的な hinge update で student がほぼ動かない結果に。次回試すなら cold-start / lr_gen 引き上げ / recon_weight>0 のいずれかが必要
- **GAN equilibrium ≠ 蒸留進行**: `l_d_total` 振動と visual 変化は別軸。loss だけで判断せず、中間 ckpt 毎の visual 検証が必須 ([distillation.md §4.1 layer 5](distillation.md#41-phase-a-の詳細-postmortem5-層因果分析) の教訓を再確認)
|