Index
2026-07-01 — Research / Design Spec

LGM-VGGT-Ω: Input / Output / Loss / Layer 상세 설계 + VGGT 원본 충실도

VGGRPO | stitch layer 탐색(job 29986, ℓ̂=2) 이후 connector + stitched backbone + loss + train script 작성 시점 설계 문서화

TL;DR

69M
Trainable params
1.14B
Frozen backbone
208
LoRA-wrapped Linear
5
Depth loss 미구현 항목

1 배경 / 목적

260630 stitch layer 탐색(job 29986, ℓ̂=2 결정, MSE 7.61e-3)에 이어, connector/stitched backbone/loss/train script 구현이 진행됐다. 코드가 여러 파일(connector, aggregator wrapper, loss, train entry)에 걸쳐 있어 전체 데이터 흐름과 파라미터 규모를 한 문서에 layer 단위로 정리할 필요가 있었다.

또한 VGGT-Ω 학습 recipe를 얼마나 "그대로" 가져왔는지 애매한 상태였다 — 어떤 부분을 원본대로 유지했고 어떤 부분을 의도적으로 단순화했는지 추적하지 않으면, 이후 성능 이슈가 생겼을 때 "우리 구현 버그"인지 "의도적 단순화의 부작용"인지 구분이 안 된다.

기존 한계: 구현 코드만 봐서는 VGGT 원본 대비 어느 loss 항목이 빠졌는지, camera loss의 multi-stage decay가 왜 없는지 등이 코드 리뷰만으로는 파악하기 어려움.

2 작업 내용

Input(raw batch → VAE latent) → Connector(Conv3d) → Aggregator(frame/inter-frame blocks) → Head(Camera/Dense) → Loss 순으로 전체 텐서 shape을 추적하고, VGGT-Ω 공개 코드(vggt_omega 패키지)와 우리 학습 코드(train_lgm_robocasa_vggt_v0.py)를 항목별로 대조했다.

Connector / Stitch 구조

z[c]: [1, 16, 32, 42, 74] (3 cam, Wan VAE latent) → Conv3d(16→1024, k=(5,5,5), stride=(1,2,2)) # T 보존, 공간 42→21, 74→37 → tokens[c]: [1, 32, 777, 1024] (patch grid 21×37=777) concat 3cam(time축) → patches: [1, 96, 777, 1024] (S=n_cam·T=96) Conv3d weight init: stitch search(job 29986) ridge regression 해 experiments/stitch_search_vggt/conv3d_init_layer2.pt W_flat (2000,1024).T → reshape (1024,16,5,5,5)

block 0, 1은 skip하고 block 2부터 forward (stitch layer ℓ̂=2 결정에 따름). inter-frame attention은 block_idx ∈ {2,6,9,14,20}에서만 "register"(cam+register 토큰 1632개만 cross-frame, patch 74592개는 frame-local 유지 — VGGT-Ω "Omega" 트릭, 메모리 30% 절감), 나머지는 "global"(전체 96·794 토큰 cross-attend).

LoRA 적용 규모

대상모듈개수Trainable params
Aggregator (frame + inter-frame)qkv/proj/fc1/fc2, 1024-dim48 block × 4 = 192 Linear~50.4M
CameraHead trunkqkv/proj/fc1/fc2, 2048-dim4 block × 4 = 16 Linear~16.8M
ConnectorConv3d(16→1024)1~2M
합계 trainable~69M

frozen: VGGT-Ω 1.14B 본체 + DenseHead Conv2d 전부. r=64, alpha=32, target_modules=["qkv","proj","fc1","fc2"].

Loss 구성

L_depth = L_conf(DUSt3R conf-weighted, γ=1.0,α=0.2) + L_reg(L1) + L_grad(4-scale avg-pool gradient) L_cam = w_T·L_T + w_R·L_R + w_FL·L_FL (w=1.0,1.0,0.5, 9-DoF: T(3)+quat(4)+fov(2), L_T clamp@100) L_total = w_cam·L_cam + w_depth·L_depth = 5.0·L_cam + 1.0·L_depth (하드코드, YAML 미사용) 학습: 50K steps, save every 500, viz every 100, 4-GPU DDP, AdamW lr=2e-4 cos, warmup=200, wd=0.01, grad clip=1.0

3 결과 — VGGT 원본 대비 충실도(fidelity) 비교

"VGGT 코드를 가져왔다"는 표현은 부정확 — 모델(Aggregator/CameraHead/DenseHead)은 vggt_omega 패키지를 수정 없이 그대로 호출하지만, 학습 루프와 loss는 부분적으로만 이식하고 나머지는 의도적으로 단순화했다. 항목별 비교:

Camera loss — 대부분 동일

항목VGGT base 원본우리 구현
Pose 표현9-DoF absT_quaR_FoV동일
Loss typeL1 (paper는 smooth-L1이나 코드 주석상 L1이 더 stable)L1 동일
Outlier clamploss_T.clamp(max=100)동일
가중치 (w_T,w_R,w_FL)1.0, 1.0, 0.5동일
Multi-stage decaypose_enc_list iterative refinement × γ^(N-k-1), γ=0.6❌ 없음 — VGGT-Ω CameraHead는 single scalar pose_enc만 출력, iter loop 자체가 구조상 불가능
Valid frame maskpoint_masks.sum()>100 per frame❌ 모두 valid 가정

Depth loss — 5개 항목 미구현

항목VGGT base우리
L_reg (channel-wise L2, C=1이라 L1과 동일)
Conf-weighted (γ·L_reg·conf − α·log conf)γ=1.0, α=0.2동일
depth_conf = 1+exp(logit)
check_and_fix_inf_nan 래퍼모든 step 적용nan_to_num만 (단순화)
filter_by_quantile (outlier drop)valid_range>0일 때 적용❌ 없음
gradient_loss_multi_scale_wrapperlog-depth 공간 + per-scale weighting단순 4-scale avg-pool + L1 gradient만
normal_loss (surface normal 비교)선택적 적용❌ 없음
mask.sum()<100 skip동일

Point loss / 학습 루프 / 모델 코드

핵심 발견: Camera loss는 사실상 원본과 동일(multi-stage decay만 구조적 제약으로 제외). Depth loss는 핵심 항목(L_reg+conf+grad)만 구현하고 robustness 관련 5개 항목(quantile filter, normal loss, log-depth gradient 등)이 빠져 있어 이 부분이 우선 보강 후보.
미검증: w_cam=5.0/w_depth=1.0 가중치는 VGGT 코드 주석 참고 추정치 — 정확한 YAML 기본값 미확인 상태로 학습 중.

4 Takeaway

의미

이 문서화 작업으로 "VGGT-Ω 기반 LGM"이 정확히 무엇을 재사용하고 무엇을 자체 구현했는지 명확해졌다. 모델 forward path(Aggregator/Head)는 원본 그대로라 신뢰도가 높고, loss는 핵심 항목만 구현된 축소판이라는 게 확인됐다 — 즉 향후 학습이 예상보다 unstable하거나 depth quality가 기대에 못 미치면, 우선 의심할 곳은 quantile filtering 부재로 인한 outlier 민감도log-depth gradient 대신 raw-depth gradient 사용이다.

또한 camera loss의 multi-stage decay 부재는 우리 실수가 아니라 VGGT-Ω 공개 CameraHead 구조(single-stage) 자체의 한계임을 명확히 해뒀다 — 이 부분을 "버그"로 오인해 나중에 시간 낭비하는 것을 방지.

5 Next Steps

미해결 한계

Depth loss 5개 미구현 항목이 학습 안정성에 실질적 영향을 주는지 미검증. w_cam/w_depth 가중치도 추정치 상태.

다음 작업

"더 충실하게" 맞추려면 추가할 항목(전부 추가 시 ~50줄 규모):

  1. gradient_loss_multi_scale_wrappervggt/training/loss.py에서 그대로 포팅 (log-depth gradient + per-scale weighting)
  2. filter_by_quantile 활성화 (통상 valid_range=0.98) — outlier robustness
  3. check_and_fix_inf_nan을 모든 loss 텀에 적용
  4. VGGT base YAML config에서 정확한 w_cam/w_depth 값 확인 후 하드코드 값 교체

50K step 학습 완료 후, 위 항목 추가 전/후로 depth AbsRel·camera pose error ablation 비교 예정.