File size: 11,050 Bytes
9a11bd8 | 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 | # PixelDiT Representation-Alignment (REPA) β experiments & handoff
Study of **what to align PixelDiT's intermediate features to** (the "teacher" in REPA-style
training) on ImageNet-256, plus a per-layer feature analysis. Variants AβE keep PixelDiT's
flow-matching loss and alignment point (patch **block 8**) fixed and only change the teacher;
variant F is a follow-up hybrid that adds SRA guidance at block 4 while retaining block-8 REPA.
This doc is the authoritative summary + handoff (results, infra, current state, how to continue).
---
## 1. Setup / infra
- **Model**: PixelDiT-XL, 797M β pixel-space DiT, 26 patch blocks + 4 pixel blocks, patch 16, 256Γ256.
- **Data**: ImageNet-1K, REPA-E 256px H5 at `imagenet256_data/images.h5` (253 GB, restored from S3
`s3://dit-scale-up/fe-experiments/xinlin/pixeldit_imagenet256_xl_lx_vb/data/`).
- **Recipe** (identical across variants unless noted): 8Γ80GB, global batch 256 (8Γ32), AdamW lr 1e-4,
EMA 0.9999 (SRA/Staged use **0.999**, see Β§3D), `bf16-mixed`, 70k steps, checkpoint every 10k
(`save_top_k=-1`, all kept, ~12.8 GB each).
- **Eval**: `main.py predict` β 50k samples (50/class, FlowDPMSolver 100-step, CFG 2.75, interval
[0.1,0.9]) β OpenAI guided-diffusion **ADM evaluator** vs `eval_refs/VIRTUAL_imagenet256_labeled.npz`
β FID / sFID / IS. FID worker computes one point per 10k checkpoint.
- **Envs**: `/mnt/localssd/pixeldit-venv` (torch 2.5.0+cu124, training/predict); ADM evaluator in
`/mnt/localssd/adm-eval-venv` (tf 2.15) + `/mnt/localssd/guided-diffusion`. Static `tmux` at
`~/.local/bin/tmux`.
- **W&B**: project `pixeldit-imagenet-repro` on `adobesensei.wandb.io` (API key needed;
`wandb==0.19.11` required β 40-char check rejects the self-hosted key on β₯0.20).
- **Run a variant** (8-GPU): `scripts/train_pixeldit_imagenet256_xl.sh <config.yaml> [--ckpt_path=...]`
in one tmux; `scripts/<variant>_fid_eval.sh` in another (`WANDB_API_KEY`, `PIXELDIT_SKIP_S3_RESTORE=1`
set). FID/predict shares the 8 GPUs with training (~0.06 it/s, ~1.5β2h per 50k point).
## 2. Per-layer feature analysis (which layer is semantic)
On the official converged PixelDiT-XL (`nvidia/PixelDiT-ImageNet` epoch320), hooking each patch
block and PCAβRGB + linear-CKA-vs-DINOv2: **semantic content peaks sharply at patch block 8**
(CKA 0.85), exactly the REPA anchor; early blocks = detail, late blocks specialize toward the
denoising output. DiT-XL/2-256's own features are semantic mid-late (blk 12β21). Scripts:
`scripts/viz_layer_features.py`, `viz_layer_similarity.py`, `viz_dit_layers.py`
(figures in `viz_layer_features/`, `viz_dit_layers/` β PNGs are gitignored, regenerate from scripts).
## 3. Experiments (teacher = the only thing that changes)
- **A. baseline (DINOv2 REPA)** β project block-8 tokens (MLPβ768), cosine-align to frozen DINOv2
patch tokens of the clean image, weight 0.5. `pix256_xl_orig_10k.yaml`. W&B loss `y4489tgd`, FID `xo84hpbc`.
- **B. DiT-REPA (blk12)** β teacher = frozen DiT-XL/2-256: VAE-encode β noise at ddpm t=100 β DiT
forward (class-cond) β block-12 features. **Gotcha:** raw DiT features are DC-dominated (inter-token
cosine 0.965) so cosine aligns trivially β fixed by per-image mean-centering. `src/dit_repa.py`,
`pix256_xl_ditrepa12.yaml`. W&B `s075fe0g` / `o113h6qc`.
- **C. dino+VAE** β keep DINOv2 REPA **and** add a 2nd projector on block 8 aligned to the frozen
**SD-VAE encoder mid-block** feature (DC-centered), Ξ»_gen 0.05. `src/dino_vae_repa.py`,
`pix256_xl_dinovae.yaml`. W&B `0e4hcesw` / `pixeldit_dinovae_fid`.
- **D. SRA (self-distillation, EMA teacher)** β no external teacher: student block-8 (through a
projector) aligns to the **EMA net's block-16** at a lower-noise timestep, smooth-L1 Ξ²0.05, weight
0.04. Port of [vvvvvjdy/SRA](https://github.com/vvvvvjdy/SRA). **Two fixes were required:**
(1) `use_proj=True` β reference projects the STUDENT and aligns to the RAW teacher (asymmetric);
(2) **EMA decay 0.9999 β 0.999** β SRA reads the EMA forward every step and drives the online
weight-norm up; the wide 0.9999 window lags that norm so the EMA (not the online model) samples as
noise by ~30k. A tighter 0.999 window tracks it β clean EMA. `SRATrainer` in `src/diffusion.py`
(`use_proj` flag), `pix256_xl_sra.yaml`. W&B `77xtrzcq` / `pixeldit_sra_fid`.
- **E. StagedTeacher (self-distillation, frozen-snapshot teacher)** β like SRA but the teacher is a
**frozen hard copy of the online model, refreshed every 10k steps** (a periodically-updated target
network) instead of an EMA. Resumed from SRA's 10k checkpoint. `src/staged_teacher.py`,
`pix256_xl_stageteach.yaml` (`refresh_interval: 10000`). W&B `5ywf06q4` / `pixeldit_stageteach_fid`.
- **F. SRA4 + DINO-REPA8 (hybrid)** β one online forward supplies two complementary targets:
online **block 4** (student projector) aligns by smooth-L1 to the EMA net's raw **block 16** at a
lower-noise timestep, while online **block 8** independently aligns by cosine to frozen DINOv2
clean-image patch tokens. Weights remain SRA 0.04 and REPA 0.5; EMA decay is 0.999.
`src/hybrid_sra_repa.py`, `pix256_xl_sra_repa4.yaml`. W&B training run `49p8qfc5`;
FID curve pending.
## 4. Results β 50k-sample ADM eval
**FID** (β better)
| step | baseline | DiT-REPA | dino+VAE | SRA (EMA) | StagedTeacher |
|---|---|---|---|---|---|
| 10k | 389.3 | 368.7 | 383.1 | 187.5 | 187.5ΒΉ |
| 20k | 363.6 | 350.6 | 387.5 | **102.8** | 116.0 |
| 30k | 106.1 | 108.1 | 127.9 | **82.2** | 86.9 |
| 40k | 66.8 | 81.7 | **52.6** | 67.1 | 68.7 |
| 50k | **31.1** | 57.2 | 39.2 | 55.8 | 58.4 |
| 60k | **21.3** | 39.6 | 25.9 | β | 49.5 |
| 70k | β | β | **17.0** | β | 43.1 |
**sFID** (β better)
| step | baseline | DiT-REPA | dino+VAE | SRA | StagedTeacher |
|---|---|---|---|---|---|
| 10k | 414.7 | 417.3 | 398.4 | 50.4 | 50.4ΒΉ |
| 20k | 304.7 | 197.4 | 403.2 | **13.9** | 17.5 |
| 30k | 78.2 | 45.6 | 73.2 | **10.0** | 13.0 |
| 40k | 46.0 | 42.7 | 30.5 | **8.5** | 8.9 |
| 50k | 20.3 | 32.2 | 27.0 | 7.9 | **7.8** |
| 60k | 14.7 | 20.3 | 18.0 | β | **7.3** |
| 70k | β | β | 14.1 | β | **6.8** |
**IS** (β better)
| step | baseline | DiT-REPA | dino+VAE | SRA | StagedTeacher |
|---|---|---|---|---|---|
| 10k | 1.07 | 1.04 | 1.06 | **5.40** | 5.40ΒΉ |
| 20k | 1.40 | 1.64 | 1.00 | **9.59** | 8.43 |
| 30k | **11.71** | 10.48 | 9.94 | 11.15 | 10.39 |
| 40k | 17.51 | 10.82 | **19.19** | 12.59 | 12.40 |
| 50k | **26.65** | 13.84 | 24.78 | 14.19 | 13.73 |
| 60k | **32.94** | 18.56 | 30.52 | β | 15.36 |
| 70k | β | β | **37.30** | β | 17.12 |
ΒΉ StagedTeacher resumed from SRA's 10k checkpoint, so its 10k = SRA's 10k. Chart:
`slides_assets/fid_comparison_5way.png` (regenerate; PNGs gitignored).
## 5. Findings
1. **Self-distillation (SRA, StagedTeacher) converges dramatically faster early and dominates sFID
at every step.** At 10k SRA is FID 187 / IS 5.4 while the external-teacher variants are still
~380 / IS ~1; SRA's 20k FID (103) β the DINOv2 baseline's 30k. sFID stays 2β5Γ better throughout.
2. **But self-distillation plateaus on FID/IS.** By 50β60k the external-teacher variants overtake on
FID (60k: baseline 21.3, dino+VAE 25.9 vs StagedTeacher 49.5) and on IS. Net: self-distillation =
fast + best structure (sFID), external semantic teacher = better final FID/diversity (IS).
dino+VAE reaches the best FID by 70k (17.0).
3. **EMA teacher (SRA) β frozen-snapshot teacher (StagedTeacher), EMA slightly better early.** Gap
20k 116 vs 103, narrowing to ~identical by 40k. The gain comes from the self-distillation mechanism
(block-8βblock-16 alignment), not from how the teacher is updated.
4. **DiT-blk12 as teacher (B) < DINOv2 (A)**; **dino+VAE (C) β baseline** (slightly better late).
5. **Diffusion-model features need DC removal** to be a usable cosine-alignment teacher (B, C).
6. Debugging lesson (SRA): the EMA "noise" was **not** EMA corruption β the EMA tracked online
(cosine 0.985, drift 0) but lagged in *norm* under the wide 0.9999 window; several wrong fixes
(stream, compile, clobber) were tried before the real cause (norm-lag) β decay 0.999.
## 6. Current state (as of 2026-07-28)
- **Running**: hybrid SRA4 + DINO-REPA8 (`49p8qfc5`), newly started from scratch. tmux sessions
`hybrid_train`, `hybrid_fid`; the FID worker targets every 10k checkpoint from 10k through 70k.
- **Completed**: StagedTeacher reached 70k; its final point is FID 43.11 / sFID 6.78 / IS 17.12.
- **Checkpoints on local SSD** (`train_logs/exp_pixeldit_imagenet256_xl_<variant>/`, every 10k, ~12.8GB):
baseline 10β60k, DiT-REPA 10β70k, dino+VAE 10β70k, SRA 10β60k, StagedTeacher 20β70k.
**NOT backed up to S3** β a box wipe loses them (`scripts/sync_pixeldit_to_s3_loop.sh` can back up).
- baseline & SRA runs were stopped early (~62k) to free GPUs for later variants, hence FID only to 60k/50k.
## 7. Handoff notes (for continuing)
- To finish a curve: relaunch its `scripts/<variant>_fid_eval.sh` (idempotent β skips computed points;
set `STEPS=...` to target specific steps). Checkpoints are all saved, so any FID point can be
(re)computed offline without retraining.
- To resume/continue training: `train_pixeldit_imagenet256_xl.sh <config> --ckpt_path=<...ckpt>`.
- Open directions: (a) push SRA/Staged past 70k or with a **stronger Ξ» / IS-oriented tweak** to fix
the FID/IS plateau while keeping the sFID lead; (b) **hybrid**: DINOv2 REPA + SRA self-distillation
(semantic teacher for late FID/IS + self-distillation for early speed & sFID); (c) tune SRA
student/teacher blocks & `sra_t_max`. (d) back up checkpoints to S3 first.
- Gotchas: EMA decay must be β€0.999 for any variant that reads the EMA during training (norm-lag);
keep DC-centering for diffusion/VAE-feature teachers; `nn.Module.compile()` is lazy (first-forward);
the CLI list-index override `--trainer.callbacks.N...` is rejected by jsonargparse (edit the YAML).
## 8. File map
```
pixeldit_configs/pix256_xl_orig_10k.yaml # A baseline (DINOv2)
pixeldit_configs/pix256_xl_ditrepa12.yaml # B DiT-REPA blk12 (DC-centered)
pixeldit_configs/pix256_xl_dinovae.yaml # C DINOv2 + SD-VAE detail head
pixeldit_configs/pix256_xl_sra.yaml # D SRA (use_proj=true, EMA decay 0.999)
pixeldit_configs/pix256_xl_stageteach.yaml # E StagedTeacher (refresh_interval 10000)
pixeldit_configs/pix256_xl_sra_repa4.yaml # F hybrid: SRA 4->16 + DINOv2 REPA on block 8
PixelDiT/c2i/src/diffusion.py # REPATrainer, DINOv2, SRATrainer (use_proj flag)
PixelDiT/c2i/src/dit_repa.py # B
PixelDiT/c2i/src/dino_vae_repa.py # C
PixelDiT/c2i/src/staged_teacher.py # E
PixelDiT/c2i/src/hybrid_sra_repa.py # F
scripts/*_fid_eval.sh # per-variant FID-curve workers
scripts/log_fid_wandb.py # append an FID point to a W&B run
scripts/viz_*_layers*.py, build_slides.py # analysis + slide deck
```
|