# 2단계 — 학습 (GPU 필요) [SETUP.md](SETUP.md)가 끝난 뒤 실행한다. `SETUP_DONE` 마커가 없으면 거부한다. **GPU가 아직 바빠도 지금 걸어둘 수 있다.** 카드가 빌 때까지 기다렸다가 알아서 시작한다. --- ## 이 단계가 하는 것 | 작업 | 시간 | |---|---| | GPU 대기 (VRAM 확보될 때까지) | 가변 | | `voxel_max` 실측 선택 | 10분 | | **학습 100 epoch** | 3~6시간 | | 평가 (val + test + 4클래스 통합) | 10분 | --- ## 1. 사전점검 ```bash cd sum-parts-test RUN_DRYRUN=1 bash scripts/run_train.sh ``` **`preflight OK` 가 나와야 한다.** 검사 항목: | 항목 | 실패하면 | |---|---| | `SETUP_DONE` 마커 | [SETUP.md](SETUP.md) 먼저 | | conda 환경 `sumparts` | 동상 | | 데이터 `24 / 8 / 8` | 동상 | | `nvidia-smi` + GPU 인식 | 드라이버 문제 — 여기서 해결 | GPU가 **바쁜 것은 실패가 아니다.** 인식만 되면 통과한다. --- ## 2. 실행 ```bash setsid nohup bash scripts/keepalive.sh train > ~/keepalive-train.out 2>&1 & ``` 터미널을 닫아도 계속 돈다. ### GPU 대기 동작 남의 작업이 카드를 쓰고 있으면 **실패하지 않고 기다린다.** ``` [11:40:02] card has 24576 MiB; waiting until 16000 MiB is free [11:40:02] 3200 MiB free, need 16000 -- checking again in 5 min ``` 5분마다 확인하고, 확보되면 자동으로 시작한다. 기본 대기 상한 12시간. 조정: ```bash GPU_FREE_MB=20000 GPU_WAIT_MINUTES=1440 \ setsid nohup bash scripts/keepalive.sh train > ~/keepalive-train.out 2>&1 & ``` 상한을 넘기면 **실패시키지 않고 그냥 진행한다.** 그 시점의 가용 VRAM에 맞춰 `voxel_max`가 측정되므로, 작게라도 학습은 된다. --- ## 3. 확인 ```bash cat ~/sum-parts/runs/train/STATUS ``` ``` state : running phase : train cfg : pointvector-xl voxel_max: 64000 ``` | state | 뜻 | |---|---| | `DONE` | 완료 | | `waiting` | GPU 비기를 기다리는 중 | | `running` / `retrying` | 진행 중 | | `FAILED` | `note` 줄에 원인 | 상세: ```bash tail -60 ~/sum-parts/runs/train/train_phase.log bash scripts/check_training.sh # epoch, GPU, best miou bash scripts/verify_speed.sh # HEALTHY / DEGRADED 판정 bash scripts/epoch_timing.sh # epoch별 소요, 감속 지점 ``` 결과: ```bash cat ~/sum-parts/runs/coarse_eval/coarse.txt # 4클래스 통합 성적 ← 핵심 ``` --- ## voxel_max 자동 결정 논문 설정은 `voxel_max: 64000`, 약 **16.5 GB** 필요하다. 3060(12 GB)에서는 못 들어가 24000으로 낮춰야 했고, **그게 3090으로 옮기는 이유다.** 높은 값부터 내려가며 **실측**해서 실제로 들어가는 첫 값을 쓴다. ``` 64000 → 48000 → 40000 → 32000 → 24000 ``` 3060 실측 (비교 기준): | voxel_max | peak VRAM | s/iter | 12 GB | |---|---|---|---| | 64000 | **16.49 G** | 13.113 | ❌ | | 48000 | 11.75 G | 29.169 | ❌ 폴백 | | 40000 | 9.88 G | 1.169 | ✅ | | 32000 | 8.03 G | 0.635 | ✅ | | 24000 | 6.46 G | 0.402 | ✅ | > ⚠️ **WSL2에서 VRAM 초과는 OOM을 내지 않는다.** > 드라이버가 호스트 RAM으로 흘려서 **조용히 완주한다 — 25~100배 느리게.** > 12 GB 카드에서 `peak 15.47 GB`가 찍힌다. > 그래서 "돌아가더라"를 믿지 않고 peak 할당량으로 판정한다. > > 보조 지표는 **전력**이다. 사용률 100 %인데 전력이 낮으면 > (3060 기준 60 W대) 연산이 아니라 PCIe 전송 대기다. 정상이면 140 W대. --- ## 멈춰도 계속 도는 구조 — 3중 | 층 | 담당 | 동작 | |---|---|---| | `keepalive.sh train` | 프로세스 전체 사망 | VM 재시작·OOM kill 후 재기동 (최대 40회) | | `run_train.sh` | 단계 실패 | 지수 백오프 재시도 (4회, 60→120→240초) | | `train_watchdog.sh` | 학습 크래시 | 최신 체크포인트에서 재개 (최대 8회) | **재시작해도 epoch 1로 돌아가지 않는다.** 최신 체크포인트를 워치독에 넘겨 optimizer·scheduler·epoch을 복원한다. `wsl --shutdown`이나 Windows 재부팅은 못 버틴다 — WSL 안에서 도는 건 다 마찬가지다. 그 경우 같은 명령을 다시 치면 중단 지점부터 이어간다. --- ## 설정 | 변수 | 기본 | 뜻 | |---|---|---| | `CFG` | `pointvector-xl` | 모델 (논문 mIoU 70.0 %, 번들 최고이자 최속) | | `EPOCHS` | `100` | | | `VAL_FREQ` | `5` | 검증 주기 | | `VOXEL_CANDIDATES` | `64000 48000 40000 32000 24000` | 높은 값부터 시도 | | `GPU_FREE_MB` | `16000` | 이만큼 비어야 시작 | | `GPU_WAIT_MINUTES` | `720` | 대기 상한 | | `STEP_RETRIES` | `4` | 단계별 재시도 | | `MAX_RESTARTS` | `40` | keepalive 재기동 상한 | 예: ```bash CFG=pointnext-xl EPOCHS=50 \ setsid nohup bash scripts/keepalive.sh train > ~/keepalive-train.out 2>&1 & ``` --- ## 중단 ```bash pkill -f keepalive.sh # 감시자 먼저 — 안 그러면 다시 살린다 bash scripts/stop_training.sh ``` 체크포인트는 남는다. --- ## 참고 — 논문 보고치 face 트랙, 12클래스: | 모델 | mIoU | |---|---| | PointNet | 15.1 % | | PointNet++ | 33.1 % | | PointNeXt | 65.3 % | | **PointVector** | **70.0 %** | 3060에서 PointNet 100 epoch 실측 = **17.19 %** (논문 15.1 %와 근사, 재현 확인). ### 최종 판정 기준 `coarse.txt`의 통합 mIoU가 **"전부 건물" 무지성 분류기(IoU 약 67 %)를 이겨야 한다.** 절대값이 아니라 baseline 대비로 본다 — 3060 PointNet은 building IoU 59.41 %로 그 baseline보다 낮았다. --- ## 알려진 제약 - **test 세트는 블라인드다.** 라벨이 전부 `-1`이라 로컬 채점 불가. 논문 수치와 직접 대조하려면 예측을 저자(gaoweixiaocuhk@gmail.com)에게 보내야 한다. - **`voxel_max`는 중립적 손잡이가 아니다.** 모델 동작점의 일부다. 같은 체크포인트가 검증 프로토콜에 따라 mIoU 17.19 / 4.20으로 갈렸다. - **라이선스**: 데이터 CC BY-NC 4.0, 코드 GPL-3.0. 상업 이용은 저자 허락 필요.