linlog f=0.8(코드 공간 80% 박스 안 선형 + 20% log로 ±8m)이면 버리는 픽셀 0.260805에 확정한 pointmap 인코딩은 box B 하드 클립이다. 박스 밖 픽셀은 sentinel(0)이 되고, 미니셋 실측 pixel-invalid가 56.8%였다. 스모크 리포트에 "최대 리스크"로 남겨둔 항목이 정확히 이것이다.
depth_loss = (pred-gt).pow(2).mean(). 즉 depth 브랜치 1.64B 파라미터 용량의 절반 이상이 상수 −1을 출력하는 법을 배우는 데 쓰인다. §5에서 정정됨 — 상수는 배우기 쉬워서 loss 값은 먹어도 용량은 거의 안 먹는다.계기는 사용자가 제시한 VLA pointmap 논문 See like a Robot: Robot-Centric Pointmaps for VLA(anonymous, π0.5/SmolVLA + RoboCasa)였다. "이 논문은 pointmap을 48%씩 잘라내지 않지 않냐"는 지적 — 맞고, 이유가 결정적이다.
z_c = fθ(I_c) + gφ(PEE_c), SigLIP 복사본이 토큰화해 RGB 토큰에 element-wise add). 예측하지 않으므로 복원 요구가 없고 → 8-bit mp4가 필요 없고 → 박스도 sentinel도 필요 없다. 실제로 본문에 정규화·클리핑 언급이 한 줄도 없다.우리는 pointmap이 생성 타깃이라 사정이 다르다. 그러나 "박스"가 정말 필수인지는 검증한 적이 없었다. 박스가 강제하는 것은 '균일 양자화'이지 '되돌릴 수 있음'이 아니다 — 단조 함수면 무엇이든 정확히 역산된다.
모두 px = 1 + round(n·254), 0은 invalid sentinel, 복원은 n = (px−1)/254. 차이는 n을 공간에 어떻게 배분하느냐뿐이다.
| 스킴 | 정의 | 버려지는 픽셀 |
|---|---|---|
box (현행) | 축별 선형, box B 밖 → sentinel | 박스 밖 전부 |
linlog f | 코드 공간의 f를 박스 안에 선형, 나머지 1−f를 ±8m까지 log (박스 벽에서 C0 연속) | 없음 |
signed-log s | u = sign(t)·log(1+|t|/s)/log(1+R/s), t = x − c | 없음 |
depth 대조군도 같은 계열의 1차원 판(DepthLinear / DepthLinLog)을 만들어 matched mask를 유지했다. linlog에서는 두 arm 모두 validity가 센서 유효성뿐이다.
| 스킴 | 유지(sensor-valid 중) | sentinel(전체 중) | workspace med/p90/p99 | far-field med/p90 |
|---|---|---|---|---|
box | 57.75% | 47.15% | 2.97 / 3.95 / 4.58 | 표현 불가 |
linlog f=0.9 | 100% | 8.48% | 3.30 / 4.39 / 5.10 | 76.5 / 294.4 |
linlog f=0.8 | 100% | 8.48% | 3.72 / 4.94 / 5.75 | 37.6 / 131.6 |
linlog f=0.7 | 100% | 8.48% | 4.25 / 5.65 / 6.56 | 25.0 / 85.9 |
signed-log s=0.3 | 100% | 8.48% | 6.73 / 10.42 / 13.35 | 15.6 / 37.6 |
signed-log s=1 | 100% | 8.48% | 11.15 / 14.86 / 17.50 | 16.0 / 30.3 |
| 스킴 | 박스 중심 | 박스 모서리 | +0.8m 밖 | +3.6m 밖 |
|---|---|---|---|---|
box | 6.3 | 6.3 | — | — |
linlog f=0.9 | 7.0 | 83.6 | 330.4 | 781.8 |
linlog f=0.8 | 7.9 | 59.6 | 140.4 | 369.9 |
linlog f=0.7 | 9.0 | 37.7 | 95.3 | 242.1 |
signed-log s=0.3 | 7.9 | 29.4 | 50.9 | 103.0 |
box: ext1 54.8% / ext2 63.7% / wrist 22.9%. linlog f=0.8: 5.5% / 7.2% / 12.7%. 방을 보는 exterior 두 뷰가 특히 심하게 잘려 있었다. wrist는 반대로 squash에서 살짝 늘지만 절대량이 작다.| 스킴 | workspace med/p90/p99 | far-field med/p90 | sentinel 유지 | valid 오염 |
|---|---|---|---|---|
box | 8.2 / 33.1 / 207.9 | — | 98.6% | 0.18% |
linlog f=0.9 | 8.2 / 33.7 / 201.2 | 246.1 / 1357.8 | 93.7% | 0.17% |
linlog f=0.8 | 8.6 / 34.0 / 193.4 | 117.1 / 693.8 | 93.7% | 0.06% |
linlog f=0.7 | 9.1 / 35.2 / 192.1 | 74.2 / 477.5 | 93.8% | 0.04% |
signed-log s=0.3 | 12.4 / 44.1 / 188.7 | 36.6 / 252.7 | 93.6% | 0.03% |
matched mask는 두 인코딩 모두에서 정확히 0 mismatch로 성립한다.
| 항 | box | linlog f=0.8 |
|---|---|---|
| 양자화 | 3.0 | 3.7 |
| VAE | 8.2 | 8.6 |
| 모델 예측 오차 (260701 실측) | ~50 | ~50 |
| sentinel 낭비 | 47% | 8.5% |
1. 하드 박스는 비용 대비 이득이 없다. workspace 정확도에서 box가 사는 것은 양자화 0.7mm, VAE 포함해도 0.4mm다. 지배항인 모델 예측 오차 ~50mm의 1.5% 미만이다. 그 대가로 픽셀의 38.7%p를 버리고 있었다.
2. linlog f=0.8 채택. 100% 커버리지, sentinel 47%→8.5%, workspace 손실 무시 가능, far field를 실제로 표현. f=0.9는 workspace가 box와 동일하지만 far field가 2배 뭉개지고, signed-log는 workspace를 2~4배 희생한다 — 둘 다 중간이 낫다.
3. depth loss에 mask가 없다는 baseline 결함은 그대로다. sentinel이 8.5%로 줄면 그 결함이 실효적으로 무해해지지만, 애초에 그 결함의 크기를 §1에서 과대평가했다 — §5의 정정을 함께 볼 것. 채택 근거는 "용량 회수"가 아니라 "box가 cross-view 공유 콘텐츠를 지운다"는 쪽이다.
뷰어를 본 사용자가 세 가지를 지적했다. ⓐ "뒤에 쓸데없는 배경들이긴 하네, box가 제일 좋은 것 같기도" ⓑ "배경 부분은 loss가 조금 흐르게 할 수 없나" ⓒ "mask가 학습 때만 있고 infer 때는 없는데, 그럼 infer 때 전체를 denoising 해야 하잖아?"
| 박스 벽에서 거리 | out-of-box 중 | 전체 픽셀 중 |
|---|---|---|
| ~0.2m (경계 근처, 유용할 수도) | 6.5% | 2.8% |
| 0.2~0.5m | 22.2% | 9.4% |
| 0.5~1.0m | 39.8% | 16.8% |
| 1.0~2.0m | 10.1% | 4.3% |
| 2.0m 초과 | 21.4% | 9.0% |
median 0.75m, p75 1.40m, p95 5.00m. → 경계 살짝 밖의 "유용할 수도 있는" 부분은 2.8%뿐이고 대부분 진짜 벽·바닥이다. 관찰이 맞다.
학습 중에는 xt = (1−t)·x0 + t·noise로 GT에서 만든 노이즈 latent가 attention 입력이 된다. 즉 감독 안 받는 영역도 학습 때는 늘 "진짜 배경"을 보여준다. 추론 시엔 그 영역이 모델 자기 출력으로 굴러가므로 분포가 어긋나고, full self-attention을 통해 workspace 토큰까지 오염된다. 완화 요인은 하나 — X-WAM은 정책 추론에서 run_depth=False(policy_server.py:206)라 SR엔 무관하고, 문제는 "상상 geometry" 직접 평가 지표에서만 터진다. 그래도 새 리스크를 만드는 설계임은 분명하다.
1. box는 검증 대상 자체를 깎는다. box의 뷰별 sentinel은 ext1 54.8% / ext2 63.7% / wrist 22.9%다. pointmap 가설의 핵심은 "3뷰가 하나의 좌표계를 공유한다"인데, 두 exterior가 공유하는 내용의 상당 부분이 방이다. box는 cross-view 공유 콘텐츠를 절반 이상 지워 pointmap 가설에 불리하게 편향된다. 이 논거는 용량 주장과 독립이다.
2. linlog는 새 하이퍼파라미터도, 새 리스크도 안 만든다. loss를 건드리지 않으므로 X-WAM 목적함수가 그대로고(릴리스 baseline 이탈 없음), 모든 토큰에 타깃이 있으므로 ⓒ의 분포 어긋남이 아예 없다. 대가는 workspace 3.0→3.7mm(+VAE 8.2→8.6mm)로 모델 오차 ~50mm의 1.5% 미만.
D(linlog + 배경 down-weight)는 보류 옵션. 스모크에서 배경이 depth_loss를 지배하면 도입한다. 방식은 soft weight + ε 바닥(셀 유효율을 가중치로, 완전 sentinel 셀은 ε=0.05) — 가중치를 정확히 0으로 두면 그 셀이 무제약이 되어 ⓒ의 문제를 그대로 불러온다.
{box, linlog} × {depth, pointmap} 4 arm을 로그인 GPU 1장씩 100 step. 교란 제거: 1차 실행은 box쌍이 기존 10-에피소드 미니셋이라 데이터가 달랐다. 빌더의 episode id가 전역 인덱스라 --episodes 12 --encoding box로 재빌드하면 같은 scene이 선택되므로, box쌍만 재실행해 동일 12 에피소드 / 2,732 clips로 맞췄다.
| arm | video_loss | depth_loss | pm/depth |
|---|---|---|---|
| box + depth | 0.511 | 0.317 | — |
| box + pointmap | 0.509 | 0.594 | 1.87× |
| linlog + depth | 0.515 | 0.529 | — |
| linlog + pointmap | 0.508 | 0.610 | 1.15× |
동일 데이터 pixel-invalid: box 56.55% / linlog 8.54%. 4 arm 모두 완주, Traceback 0, NaN 0. (step≥49 평균 — batch=1이라 단일 step은 노이즈가 크다.)
depth_loss_weight=1.0이 두 arm에 동일한데 pm arm만 depth gradient를 더 받아 총손실 구성이 달라지던 문제: box 1.87× → linlog 1.15×. "pm weight 0.55를 3번째 arm으로 추가"하기로 남겨둔 보완책이 대체로 불필요해진다.본 데이터셋 재빌드 — --encoding linlog로 CLVR 2,469 scene 재생성(job 71298과 동일하게 14 shard, ~45분, ~69GB). 기존 sft_datasets/DROID_CLVR{,_pm}는 box판이므로 디렉토리 분리.
squash가 diffusion 학습 난이도에 주는 영향. far field까지 실제 구조를 예측해야 하므로 depth_loss 절대값이 달라질 수 있다. 100 step 스모크 ×2를 linlog로 재실행해 260805의 depth_loss 비율(depth 0.459 vs pm 0.840, 1.8×)이 어떻게 변하는지 확인 필요.
EE-frame 재중심화 — 논문 §4.3의 SR 이득(34.7→36.9, 카메라 랜덤화 시 32.7→36.6)은 크지만 P − t_EE는 강체 평행이동이라 invalid 문제와 무관하고(장면 extent 불변, EE가 움직여 오히려 박스가 커짐), action/proprio가 robot-base인 우리 설계와 좌표계가 어긋난다. 별도 3번째 arm 후보로 분리.
scripts/train_droid_ab.sh 전면 재작성. ① plain python → torchrun --nproc_per_node=8 — 260805판 헤더의 "torchrun이 TCPStore hang을 유발" 주장은 CLAUDE.md §5(중첩 sbatch의 torchelastic env 누수)와 혼동한 것이라 주석에 정정. 그대로 뒀다면 template.sh의 #SBATCH -n 1 × Lightning SLURM 감지로 260806 단일 GPU 사고(~126 GPU-hour)가 재발한다. ② eff batch 32 → 128 / lr 3e-5(gate_base.sh와 동일 레시피, arm A가 61.0%로 통과한 조건). ③ expect_world_size 가드 · save_top_k=0 · -c 112 · exp_name에 인코딩 태그(box/linlog 체크포인트 충돌 방지) · AB_DATASET_PREFIX로 인코딩 전환.
남은 블로커 = linlog 본 데이터셋 미생성.
상세 로그: claude/260807/analysis-pointmap_encoding.md