SigLIP SO400M 비전 인코더, Gemma-2B 언어 모델, 그리고 Flow Matching 액션 헤드를 결합한 End-to-End 모바일 로봇 내비게이션 시스템. 기존 이산 분류 방식의 한계를 극복하고 연속 액션 공간에서의 고품질 궤적 생성을 실현합니다.
개요
기존 MoNaVLA(Kosmos-2 + 9-class 이산 분류)는 오프라인 지표 100% 수렴을 달성했지만, 실제로는 타이밍 암기(timing memorization)에 의한 결과였습니다. 시각적 인과 관계를 진정으로 이해하지 못하면 실환경 일반화는 불가능합니다.
모델 아키텍처
Physical Intelligence의 π0 설계를 참고하여, 대규모 비전-언어 모델을 연속 액션 생성 헤드와 결합합니다.
| 구성 요소 | 모델 | 출력 크기 | 역할 |
|---|---|---|---|
| 비전 인코더 | SigLIP SO400M patch14-384 | (B·W, N_patch, 1152) | 8프레임 이미지를 패치 토큰으로 변환 |
| 언어 모델 | Gemma-2B (FP16) | (B, L, 2048) | 자연어 명령 인코딩 + 비전 토큰 융합 |
| 리샘플러 | Perceiver Resampler | (B, 64, 2048) | 가변 길이 비전-언어 특징 → 64 고정 토큰 |
| 액션 헤드 | Flow Matching Head | (B, 10, 3) | 조건부 속도장 v_θ 예측 → ODE 적분 |
학습 목표
Flow Matching은 단순한 Gaussian 분포에서 목표 액션 분포로의 결정론적 흐름을 학습합니다. 확산 모델(Diffusion)보다 빠르고 안정적이며, 단 3~10 스텝의 ODE 적분으로 샘플링이 가능합니다.
코드 구조
각 폴더는 파이프라인의 한 단계를 담당하며, 독립적으로 실행 가능합니다.
시스템 파이프라인
MoNa-π는 데이터 수집, 전처리, 학습, 추론 서버, 로봇 서버로 이어지는 완전한 End-to-End 파이프라인을 갖추고 있습니다.
| 모듈 | 기능 | 출처 / 방식 |
|---|---|---|
ActionSmoother |
Savitzky-Golay 필터 (window=11, poly=3) — 키보드 Bang-bang 스파이크 제거 | 신규 구현 |
ActionNormalizer |
[-1.15, 1.15] → [-1.0, 1.0] 선형 스케일링 | MoNaVLA 이관 |
IntentPrefixInjector |
액션 궤적에서 9-class 의도 분류 후 한/영 다변형 instruction 생성 (20% 노이즈) | MobileVLA-R1 방식 |
CounterfactualInjector |
stop_prob/steer_prob 확률로 액션+instruction 오버라이드 → 인과 혼란 완화 | MoNaVLA 이관 |
| HFlip 증강 | 이미지 좌우 반전 + angular_z 부호 반전 + instruction left↔right 교체 | MoNaVLA 계승 |
RampController는 이차 가속도를 적용해 0.5초에 최대 속도 1.15 도달, 0.15초 감속을 구현합니다.
# vla-* alias에 --pi 플래그 추가 — 기존 MoNaVLA 동작 유지 vla-collect --pi --output /data/ep001.h5 --task "장애물 회피" vla-train --pi configs/train.yaml vla-server --pi --ckpt checkpoints/best vla-inference --pi --instruction "장애물 피해 직진" vla-eval --pi checkpoints/best
검증 결과
2026년 4월 15일 기준 파이프라인 각 단계의 검증 결과입니다. 실제 모델 체크포인트 없이 구조 및 동작 검증에 집중했습니다.
| 논문 | 핵심 아이디어 | MoNa-π 대응 | 상태 |
|---|---|---|---|
| TIC-VLA (2026) | Slow VLM + Fast Action Expert 분리 | Gemma-2B backbone + FlowMatchingHead 분리 구조 | ✓ 구현 |
| OmniVLA (ICRA 2026) | 저주파 카메라 → 연속 속도 제어 | ActionSmoother + 2Hz 이미지 + 10-step chunking | ✓ 구현 |
| MobileVLA-R1 (2025) | 이산 의도 CoT + 연속 제어 분리 | IntentPrefixInjector (9-class) + Flow Matching | ✓ 구현 |
| π0 (Physical Intelligence) | SigLIP + PaliGemma + Flow Matching | SigLIP SO400M + Gemma-2B + 동일 Flow Matching | 참조 |
기술 계승
기존 MoNaVLA 연구에서 검증된 기술들을 MoNa-π에 이식했습니다. 무엇을 버리고 무엇을 지켰는지 명확히 합니다.
로드맵
파이프라인 골격은 완성되었습니다. 이제 실제 학습과 실환경 검증으로 나아갑니다.
도메인 이전 가능성
MoNa-π 아키텍처는 내비게이션을 위해 설계됐지만, 핵심 컴포넌트는 도메인에 무관합니다. 어떤 부분이 재사용 가능하고 어디를 교체해야 하는지 컴포넌트별로 분석합니다.
| 컴포넌트 | 파일 | 이전 난이도 | 무엇을 바꾸나 |
|---|---|---|---|
| SigLIP SO400M | models/backbones/pi0_backbone.py |
🟢 재사용 | 변경 없음. 사전학습 시각 표현은 완전히 도메인 독립적 |
| Gemma-2B | models/backbones/pi0_backbone.py |
🟢 재사용 | 변경 없음. 언어 이해 능력은 어떤 언어 명령에도 적용 |
| PerceiverResampler | models/components/resampler.py |
🟢 재사용 | 변경 없음. 64토큰 압축 구조는 도메인에 무관 |
| FlowMatchingHead | models/heads/flow_head.py |
🟢 config 1줄 | action_dim: 3 → 7만 변경. Transformer 구조 전체 재사용 |
| ODE Solvers | inference/ode_solver.py |
🟢 재사용 | 변경 없음. 수치 적분은 액션 차원에 무관 |
| ActionSmoother | data/preprocessing.py |
🟢 재사용 | Savitzky-Golay는 임의 차원 시계열에 적용 가능 |
| ActionNormalizer | data/preprocessing.py |
🔵 범위 수정 | min_val / max_val 와 action_dim 을 새 도메인에 맞게 조정 |
| IntentPrefixInjector | data/preprocessing.py |
🟡 어휘 교체 | 9-class 내비게이션 레이블(FORWARD/TURN…)을 새 도메인 어휘(GRASP/PLACE…)로 교체 |
| CounterfactualInjector | data/preprocessing.py |
🟡 로직 수정 | stop/steer 오버라이드 로직을 새 도메인 실패 모드로 교체 |
| ActionChunkBuffer | robot/action_buffer.py |
🟢 재사용 | 변경 없음. Receding Horizon 버퍼 구조는 도메인 독립 |
| ros2_controller.py | robot/ros2_controller.py |
🟡 인터페이스 교체 | geometry_msgs/Twist → 새 메시지 타입 (JointState, PoseStamped 등) |
| keyboard_collector.py | collect/keyboard_collector.py |
🔴 재작성 | 모바일 특화 키맵. 조작 로봇은 SpaceMouse/joystick 텔레오퍼레이션으로 대체 필요 |
| 학습 데이터 | configs/train.yaml → data.train_path |
🔴 재수집 | 새 도메인 시연 데이터 필요. 백본은 재사용하고 FlowHead만 fine-tune 가능 |
FlowMatchingHead는 action_dim 파라미터 하나로 임의의 차원에 즉시 적용됩니다.
백본(SigLIP + Gemma-2B)은 변경 없이 완전히 재사용됩니다.
가장 큰 장벽은 코드가 아니라 새 도메인의 시연 데이터 수집입니다.
# configs/train.yaml — 변경 3줄로 7DoF 조작 도메인 이전 model: + action_dim: 7 # Δx, Δy, Δz, Δrx, Δry, Δrz, gripper - action_dim: 3 # vx, vy, angular_z (내비게이션) + horizon: 20 # 조작은 더 긴 horizon 권장 - horizon: 10 data: + train_path: /data/franka_episodes/ - train_path: /data/mobile_vla_dataset_v5/ # data/preprocessing.py — IntentPrefixInjector 어휘만 교체 INTENT_LABELS = [ + "REACH", "GRASP", "PLACE", "PUSH", "PULL", "WIPE", "OPEN", "CLOSE", "STOP", - "FORWARD", "BACKWARD", "TURN_LEFT", "TURN_RIGHT", ... (내비게이션 9-class) ] # robot/ros2_controller.py — 퍼블리시 메시지 타입만 교체 + from franka_msgs.msg import JointCommand + msg.position = action_chunk[0] # 관절 각도 목표값 - from geometry_msgs.msg import Twist - msg.linear.x = action[0] # 내비게이션 속도
언어 설계
SigLIP · Gemma-2B · PerceiverResampler · FlowMatchingHead 각각의 특성이 어떤 언어 표현을 "좋아하는지" 분석합니다. 잘못된 instruction은 액션 분포를 흩뜨리고 주행을 불안정하게 만듭니다.
학습 데이터의 [INTENT] 레이블은 액션 청크의 평균값으로 자동 분류됩니다 (classify_intent()).
임계값 근처의 모호한 움직임이 가장 취약한 지점입니다.
임계값 0.15 근처에서 생성된 데이터는 의도 레이블과 실제 액션이 불일치할 수 있습니다. 학습 시 이런 샘플이 많으면 동일한 instruction이 다른 행동을 유발하는 혼동이 생깁니다.
| 유형 | 나쁜 표현 ❌ | 좋은 표현 ✅ | 이유 |
|---|---|---|---|
| 거리 기술 | "1.5m 앞으로 이동해" |
"저 바구니 앞까지 가" |
VLM은 미터법을 물리적으로 이해 못함. 시각 앵커 기반 목표가 필요 |
| 부정 명령 | "장애물 쪽으로 가지 마" |
"[FORWARD_LEFT] 장애물 왼쪽으로 우회해" |
Gemma-2B는 부정문 처리가 약함. 목표 행동을 직접 기술하는 것이 강함 |
| 조건 분기 | "왼쪽이 막히면 오른쪽으로" |
"[TURN_RIGHT] 오른쪽 경로로 이동해" |
2B 모델에 if-else 추론 기대 금물. VLM이 이미 시각 장면을 보고 있음 |
| 방위 기반 | "북쪽으로 이동" / "동쪽 방향" |
"저 파란 벽 방향으로 직진" |
절대 방위는 학습 데이터에 없음. 시각적으로 인식 가능한 기술 필요 |
| 추상적 목표 | "올바른 경로를 따라가" |
"[FORWARD] 정면에 보이는 출구로 직진해" |
"올바른"은 시각 그라운딩 없음. 구체적인 시각 대상이 필요 |
| 과도하게 긴 문장 | "주변을 살피며 효율적으로 회피하며 이동해" |
"[TURN_LEFT] 왼쪽으로 돌아서 장애물을 피해" |
Gemma-2B 2B 모델, 단문 선호. 핵심 동작 하나에 집중 |
| 임계값 근처 | "살짝 왼쪽으로" / "아주 조금만 틀어" |
"[TURN_LEFT] 왼쪽으로 회전해" + 작은 az 값 데이터 |
0.15 임계 근처 모호성. prefix로 의도를 고정하고 액션 크기로 세기 표현 |
| 시각 앵커 없음 | "앞으로 가" |
"[FORWARD] 정면 회색 바구니를 향해 직진해" |
SigLIP grounding은 텍스트 앵커에 반응. 객체 기술 → PerceiverResampler 집중도 ↑ |
VLM 특성 + 학습 데이터 분포를 고려한 권장 표현입니다. 학습 시 변형 7개 이상을 확보하는 것이 목표입니다.
Navigate to the goal 류)
├ STOP 명령 어휘 최소 6종 (정지 학습이 안전에 가장 중요)
└ STRAFE에 "옆으로" / "laterally" 명시 (TURN과 구분)
⚠ 주의
├ 부정문 최소화 → 목표 행동 직접 기술로 대체
├ 절대 거리 금지 → 시각 앵커 기반 목표로 대체
├ 임계값 0.15 근처 애매한 데이터에 prefix 명시 강제
└ 한 에피소드에 여러 의도가 섞이면 구간별 annotation 필요
💡 개선 아이디어 (미구현)
├ 10% 빈 instruction dropout (OmniVLA 방식, 시각 fallback 강화)
├ CoT 스타일: "[TURN_LEFT] 왼쪽에 장애물이 있으므로 회전" (이유 포함)
└ GRPO 보상 기반 instruction 품질 필터링 (MobileVLA-R1 방식)
Physical Intelligence의 π0 논문(Black et al., 2024)은 PaliGemma + Flow Matching Expert를 결합한 크로스-엠보디먼트 VLA를 제안한다. MoNa-π는 이 아키텍처를 모바일 내비게이션에 맞게 재해석한다.
| 항목 | 실제 π0 | MoNa-π | 격차 |
|---|---|---|---|
| 시각 인코더 | SigLIP SO400M (1152D) | SigLIP SO400M (1152D) ✓ | 동일 |
| 언어 모델 | Gemma-2B (PaliGemma) | Gemma-2B ✓ (독립 로드) | 유사 |
| 언어 통합 | PaliGemma 통합 joint forward | [vis|text] concat → Gemma encoder ✓ | 수정 완료 |
| 시각↔액션 joint attn | Action Expert가 VLM 토큰에 직접 cross-attend | FlowHead가 64 latent cond에 cross-attend | 간접 |
| 사전학습 규모 | 10,000시간 · 7 로봇 · 68 태스크 | 단일 플랫폼 · 소규모 수집 | 최대 격차 |
| 액션 공간 | 7DoF manipulation (manipulation) | (vx, vy, ωz) 모바일 내비게이션 | 의도적 |
| ODE solver | 50 step | Euler 5 step / Heun 5 step | Jetson 최적화 |
| 파인튜닝 전략 | VLM 고정 + Action Expert만 학습 | 전체 파라미터 학습 가능 | 유연 |
기존 구현에서 text_input은 forward()에 전달되었지만 내부에서 완전히 무시되었다.
Gemma-2B는 로드되었으나 호출되지 않았으며, 모든 언어 지시는 액션 conditioning에 아무 영향을 미치지 않았다.
def forward(self, images, text_input=None):
# text_input 완전 무시
visual_latents = self.resampler(vision_feats)
return visual_latents # (B, 64, 2048)
def forward(self, images, text_input=None):
visual_latents = self.resampler(vision_feats)
# text 토크나이즈 후 concat
combined = cat([visual_latents, text_embeds])
out = gemma_encoder(combined)
return out[:, :64] # 언어 grounded
π0의 강점은 10K시간 다양한 로봇 데이터 사전학습. Jetson 로컬 수집만으로는 일반화 한계.
π0의 Action Expert는 VLM 토큰에 직접 cross-attend. MoNa-π는 64 latent를 경유하는 간접 구조.
cond_dim = 2048, n_tokens = 64+L 로 변경 시
구현 비용 낮고 표현력 대폭 향상.