# 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 /train dataset/imagenet/train # 1000-class ImageFolder ln -sfn 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 # (+ 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 로드 무관).