| # SpatialDiffuseSlot — 새 서버에서 돌리는 법 (2026-07-15 완성, GPU batch-1 검증됨) |
|
|
| **무엇**: Semanticist DiT-L/ViT (tok_L pretrained init) + **우리 85 multi-res attn-pool 토큰** + **우리 spatial-align attention mask**. DiT trunk freeze로 warmup(Phase-1) 후 unfreeze(Phase-2). |
| 설계 배경/비교분석: `new_eval_spatial_reasoning0430/_worklog/SEMANTICIST_DIT_SPATIAL_SETUP.md`, `OURS_VS_SEMANTICIST.md`. |
|
|
| ## 파일 (전부 semanticist repo 안) |
| | 파일 | 역할 | |
| |---|---| |
| | `semanticist/stage1/spatial_diffuse_slot.py` | **본체**: SpatialAttnPool(85토큰) + DiTSpatial(mask 플러밍+CFG) + SpatialDiffuseSlot(tok_L init/freeze) | |
| | `spatial_mask.py` | xa_mask→(149×149) self-attn mask (유닛테스트 내장: `python spatial_mask.py`) | |
| | `configs/tokenizer_l_spatial.yaml` | **launch config** (Phase-1: freeze_dit, warmup 100ep, batch eff 256) | |
| | `train_spatial_l.sh` | launch: `GPUS=0,1,2,3 bash train_spatial_l.sh` | |
| | `smoke_full_spatial.py` | CPU 통합 smoke (init/fwd/bwd/freeze) | |
| | `smoke_gpu_batch1.py` | **GPU batch-1 pre-flight** (3 optimizer steps) — 새 서버에서 launch 전 이것부터 | |
| | `viz_mask_compare.py` / `mask_compare.png` | mask 시각화 (level별 토큰→담당부위 검증) | |
| | `test_net.py` (수정) | `SEM_STEPS=50` env로 eval sampling step override | |
| | `fid_L85_50step.py` | tok_L@85@50step rFID 재계산 (recon 재활용) | |
| |
| ## 새 서버 사전 준비 (순서대로) |
| 1. **venv**: torch/accelerate/omegaconf/timm/diffusers/torch_fidelity (기존 MNIST_debug venv 사양). |
| 2. **weights**: `semanticist_tok_L.pkl`(2.2GB) — ⚠️ **7/13 번들 eval_assets.tar에 없음**(7/15 다운로드). delta rsync 또는 HF서 재다운: |
| `huggingface.co/tennant/semanticist/resolve/main/semanticist_tok_L.pkl` |
| → config의 `init_from:` 경로를 새 위치로 수정. |
| 3. **DINOv2 (REPA)**: `TORCH_HOME`에 dinov2_vitb14 캐시 (없으면 torch.hub가 자동 다운로드 — 오프라인이면 기존 torch_cache 복사). |
| 4. **dataset 심볼릭** (semanticist repo 루트에서): |
| ```bash |
| mkdir -p dataset/imagenet |
| ln -sfn <ImageNet>/train dataset/imagenet/train # 1000-class ImageFolder |
| ln -sfn <balanced val 50k centercrop dir> dataset/imagenet/val/all # flat pngs (val 아래 1클래스) |
| ln -sfn <같은 dir> dataset/imagenet/val256 # trainer eval real_dir 하드코딩용 |
| ``` |
| (val = 우리 `eval_assets/val_real50k_centercrop`. adm_in256_stats.npz는 repo `fid_stats/`에 이미 있음.) |
|
|
| ## 실행 |
| ```bash |
| # 0) 검증 (필수, 순서대로 — 전부 PASS 후 launch) |
| python spatial_mask.py # mask 유닛테스트 |
| CUDA_VISIBLE_DEVICES="" python smoke_full_spatial.py # CPU 통합 |
| CUDA_VISIBLE_DEVICES=0 python smoke_gpu_batch1.py # GPU batch-1 (mem ~5.5GiB) |
| |
| # 1) Phase-1 launch (DiT trunk frozen, encoder/pool/cond 학습) |
| GPUS=0,1,2,3 bash train_spatial_l.sh # detach는 setsid nohup ... & disown |
| |
| # 2) Phase-2 (Phase-1 수렴 후): configs/tokenizer_l_spatial.yaml에서 |
| # freeze_dit: false + dit_lr_scale: 0.1 + ckpt_path: output/tokenizer/models_l_spatial/models/step<N> |
| # (+ blr 낮추기 권장) 후 재launch. |
| ``` |
|
|
| ## 검증된 수치 (이 서버, 2026-07-15) |
| - tok_L init: encoder 151/151, DiT trunk 전부 로드, drop=[null_cond(256→85 fresh)] |
| - trainable 134.8M / total 752.7M (frozen trunk) |
| - batch1 bf16: 5.5GiB, ~0.1s/step (1GPU) | mask routing 국소화 확인(perturb 실험 37×) |
| - 데이터: train 1,281,103 / test 50,000 |
|
|
| ## 잡아둔 버그 (재발 주의) |
| 1. `load_state_dict(strict=False)`도 **shape mismatch는 에러** → init_from 로더가 mismatch 키 자동 drop (null_cond). |
| 2. encoder는 **num_slots=256 유지**해야 tok_L 100% 로드 (slot은 안 씀, patch만 사용 — patch는 slot을 안 봐서 오염 없음). |
| 3. Semanticist DiT.forward는 mask를 블록에 안 넘김 → DiTSpatial이 플러밍 (forward/forward_with_cfg 둘 다). |
| 4. mask 규칙: latent→latent full / latent→cond xa / **cond→latent 차단** / cond→cond identity (all-False row = SDPA NaN 방지). |
| 5. DiT out은 learn_sigma라 2×in_channels (loss에서 분리, diffusion lib가 처리). |
| 6. trainer가 `model.params.ckpt_path`를 무조건 읽음 → config에 `ckpt_path: null` 필요 (init은 `init_from`). |
| 7. **eval 경로**: trainer가 `model.num_slots`로 test_num_slots/drop_mask를 사이징 → 256이면 85 cond와 충돌(5000-iter eval crash). SpatialDiffuseSlot이 `self.num_slots=85` 재지정 + NestedSampler(85) 재생성으로 해결 (encoder 내부 num_slots=256은 유지되어 ckpt 로드 무관). |
| |