Code-as-World: 영상을 실행 가능한 물리 코드로 복원하는 방식으로, 9B 모델로 Gemini 3.1 Flash 성능을 넘어선 연구

Code-as-World 소개

비전 언어 모델(Vision-Language Model, VLM)에게 공이 경사면을 굴러 내려가는 영상을 보여주고 무슨 일이 일어났는지 물으면 대체로 잘 설명합니다. 그런데 "공이 경사면을 벗어나는 순간의 속도가 몇 m/s인가"를 물으면 답이 크게 흔들립니다. 사건을 알아보는 능력과 그 사건을 만든 물리량을 복원하는 능력이 다르기 때문입니다. 후자를 학습시키려면 영상마다 질량과 마찰, 속도 같은 정답 물리량이 붙어 있어야 하는데, 현실에서 찍은 영상에는 그런 값이 기록되어 있지 않습니다. 이 정답이 없다는 점이 정량적 물리 추론(Quantitative Physical Reasoning) 학습의 병목입니다.

이번에 소개할 Code-as-World는 MirroS가 이 병목을 우회하는 방법으로 제시한 연구로, 물리 세계를 픽셀이나 잠재 벡터가 아니라 시뮬레이터에서 실제로 실행할 수 있는 코드로 표현합니다. 저자들은 픽셀을 세계의 존재론이 아니라 증거로 규정하면서, 관측 하나는 세계가 어떻게 보였는지만 기록하고 그 안에 무엇이 있으며 어떤 규칙으로 변하는지는 지정하지 않는다고 지적합니다. 코드는 물체와 관계, 물리 파라미터, 사건을 명시적으로 적어 두므로 실행하면 상태 궤적이 나오고, 그 궤적에 들어 있는 값은 추정치가 아니라 정확한 수치입니다.

MirroS 팀은 이 표현을 관측에서 복원하는 과정을 한 번에 맞히는 예측 문제가 아니라 가설을 세우고 검증하는 탐색 문제로 다시 세웠습니다. 그리고 그렇게 복원한 세계에서 뽑은 물리량으로 모델을 학습시켜, 4B와 9B 규모의 Code-as-World-VL을 공개했습니다. 본 게시물에서는 실행 가능한 세계 표현의 구성, 그 표현을 찾아내는 에이전틱 발견 루프, 그리고 QuantiPhy 벤치마크에서 확인된 결과와 함께 저장소에서 실제로 받을 수 있는 범위를 정리합니다.

Code-as-World와 기존 세계 표현 방식 비교

기술 보고서의 2장은 기존 접근을 세 가지로 나누고 각각의 한계를 지적합니다. 그 정리를 표로 옮기면 다음과 같습니다:

표현 방식 강점 저자들이 지적하는 한계
픽셀 (비디오 생성 모델) 시각적 세부와 다양성을 그대로 보존 미래 픽셀만 맞히면 되므로 변화의 원인을 구분할 필요가 없음. 카메라가 움직인 것인지 물체가 움직인 것인지, 물체가 가려진 것인지 사라진 것인지 서로 모순되는 내부 설명이 같은 예측 정확도를 낼 수 있음
3D (재구성, 역그래픽스) 기하와 시점, 외형에 강한 제약을 부여 재구성 가능성이 해석 가능성을 뜻하지는 않음. 물체의 3D 기하를 복원해도 지지물이 사라지면 왜 떨어지는지는 설명되지 않음
자연어 압축된 의미 추상을 제공 연속적인 물리 상태를 정밀하게 지정하지 못함
코드 (Code-as-World) 개체와 관계, 물리 파라미터, 사건을 명시하고 실행과 렌더링으로 관측을 재생성 시뮬레이터가 모델링하지 못하는 물리 조건에서는 겉보기에만 맞는 표현으로 수렴할 수 있음 (§4.4)

코드를 세계 표현으로 쓰는 시도 자체는 이 연구만의 것이 아닙니다. PyTorchKR에도 소개 글이 있는 gWorld가 모바일 화면 세계를 실행 가능한 코드로 시뮬레이션하는 사례이고, 물리 쪽에서는 NVIDIA Cosmos 3처럼 물리 추론과 월드 생성을 함께 다루는 오픈 모델도 나와 있습니다. Code-as-World가 이들과 다른 점은 코드를 최종 산출물이 아니라 VLM 학습용 지도 신호를 추출하는 중간 표현으로 쓴다는 데 있습니다.

Code-as-World는 누구에게 맞는가

단안 영상에서 크기와 속도, 가속도 같은 물리량을 숫자로 읽어내는 모델이 필요한 팀에게 공개된 4B와 9B 체크포인트가 바로 쓸 만한 후보입니다. 아래 벤치마크에서 4B가 32B급 오픈 웨이트 모델을 앞섰으므로, GPU 한 장에 올릴 수 있는 크기로 이 작업을 시작할 수 있습니다. vLLM으로 OpenAI 호환 서버를 띄우는 방법까지 저장소에 정리되어 있어 기존 파이프라인에 붙이는 비용도 낮습니다.

반대로 에이전틱 발견 루프를 자기 데이터에 돌려 실행 가능한 세계를 직접 만들려는 팀에게는 이번 공개 범위가 충분하지 않습니다. 저장소가 담고 있는 것은 두 체크포인트의 추론 코드와 QuantiPhy 평가 스크립트, 그리고 미리 만들어 둔 탄도 축구 예제 하나입니다. code_as_world/simulation.py는 그 예제의 scene.jsonscene.xml을 읽어 MuJoCo에서 재생하는 코드이고, 가설을 제안하고 검증하는 에이전트 구현체는 들어 있지 않습니다. 사실적인 영상을 만들어 내는 비디오 생성 모델도 보고서가 내부 모델이라고만 밝히고 있고, 표에서 가장 높은 점수를 낸 27B 추론 변형과 실행 가능한 세계 학습 데이터셋도 공개 목록에 없습니다.

Code-as-World의 실행 가능한 세계 표현

실행 가능한 세계 표현(Executable World Representation, EWR)은 세 부분으로 구성됩니다. 보고서는 이를 p = (\mathcal{C}, \mathcal{E}, \mathcal{A}) 로 적고, 각각이 세계에 무엇이 있고 어떻게 변하며 어떻게 보이는지를 나눠서 담당한다고 설명합니다.

물리 구성(\mathcal{C}) 은 세계에 존재하는 것과 그 안정적인 물리 속성을 담습니다. 물체의 기하와 실측 치수, 질량, 마찰, 중력이 여기 들어가고, 바닥이나 책상, 벽처럼 지지와 접촉, 충돌에 참여하는 환경 구조물도 정적 물리 개체로 함께 표현됩니다.

동적 진화(\mathcal{E}) 는 시간에 따라 세계가 펼쳐지는 방식으로, 초기 상태와 시간 변화, 주요 사건, 시뮬레이션 길이를 지정합니다. 이 부분이 주어지면 구성만 있던 세계가 완전한 상태 궤적으로 확장되고, 접촉과 충돌, 속도 변화, 종료 조건이 실행 과정에서 사건으로 남습니다.

시각 외형(\mathcal{A}) 은 카메라 파라미터와 배경, 재질, 조명, 프레임 레이트, 렌더링 설정을 담으며, 물리 과정 자체는 바꾸지 않고 그 궤적을 어떻게 보여줄지만 정합니다.

세 부분을 나눠 둔 이유는 각각을 따로 열어 고칠 수 있게 하기 위한 것입니다. 물체 하나, 물리 파라미터 하나, 카메라 설정 하나를 나머지 구조를 유지한 채로 바꿔 다시 실행할 수 있고, 보고서의 Figure 4는 볼링공의 초기 속도 방향을 바꿔 다른 궤적을 얻거나 같은 충돌을 전역 시점과 차량 시점에서 각각 렌더링한 예를 보여줍니다. 세계를 고치는 일과 외형을 합성하는 일이 분리되어 있어, 변형마다 장면을 처음부터 재구성하지 않고도 서로 어긋나지 않는 반사실 영상을 만들 수 있습니다.

Code-as-World의 에이전틱 발견 루프

불완전한 관측에서 EWR을 복원하는 것은 역문제입니다. 저자들은 과학적 발견이 소급 추론(Abductive Reasoning)으로 진행돼 왔다는 점에 착안해, 이 과정을 제안과 실행, 검증을 반복하는 루프로 정의했습니다:

입력은 두 가지 형태를 받습니다. 텍스트 명세가 들어오면 에이전트가 개체와 공간 관계, 물리 사건, 의도한 결과를 추출해 의미 증거로 정리하는데, 텍스트만으로는 기하와 물리 파라미터, 카메라 설정이 결정되지 않으므로 물리 사전 지식과 기본값으로 초기 가설을 세운 뒤 검증으로 다듬습니다. 실제 영상이 들어오면 깊이 지도와 인스턴스 마스크, 물체 추적을 시각 증거로 뽑고, 분할된 물체마다 3D 생성 모델로 메시를 만들어 위치와 크기, 동적 상태를 복원합니다. 이 단계에 붙는 도구는 SAM 3 (:pytorch::kr: Meta Segment Anything Model 3 (SAM 3): 프롬프트 기반의 개방형 어휘(Open-Vocabulary) 기반 개념적 분할 모델)가 마스크와 이미지 평면 추적을, VGGT-Omega가 깊이와 카메라 기하를, SAM 3D가 물체 기하를 담당합니다.

루프 한 바퀴는 다섯 단계로 돕니다. 에이전트가 증거와 직전 반복의 구조화된 피드백을 보고 EWR을 제안하거나 수정하고(Propose), 그것을 시뮬레이터 인터페이스에 맞는 파라미터로 인스턴스화하고(Instantiate), 시뮬레이터가 실행해 상태 궤적을 만들고(Execute), 궤적을 예측 관측으로 렌더링하고(Render), 선택한 주요 프레임에서 예측과 입력 증거를 비교합니다(Verify). 텍스트 입력은 의미와 물리 제약을 주로 보고, 영상 입력은 RGB 외형과 깊이, 마스크, 궤적을 함께 비교합니다. 프레임 단위 불일치는 구조화된 피드백으로 모아져 다음 반복에서 해당 구성 요소만 국소적으로 고치게 하고, 반복 예산을 다 쓰고도 설명이 충분하지 않으면 가설 자체가 기각됩니다.

이 루프가 단순히 여러 번 뽑는 것과 다른지를 저자들은 같은 평가 예산으로 확인했습니다. 최대 반복 횟수를 5로 두고, 독립 샘플링 5회 중 최선을 고르는 Best-of-5와 비교한 결과 시각 정합도와 물체 IoU, 궤적 오차, 그리고 프레임 대각선의 2% 안에 들어오는 관측 비율에서 반복 루프가 앞섰습니다. 검증 신호에 쓰이지 않은 독립 지표로 측정했다는 점도 함께 밝혀 두었습니다.

Code-as-World-VL의 학습 방법

학습은 두 단계 교육 과정으로 진행됩니다. 1단계는 이미지 평면에서의 측정 능력을 갖추게 하는 지도 미세조정(Supervised Fine-tuning, SFT)입니다. RefCOCO와 RefCOCO+, RefCOCOg, RefCLEF의 참조 표현 데이터와 GOT-10K의 물체 추적에서 경계 상자와 마스크, 추적을 정량 질문으로 변환해 씁니다. 궤적 \{c_t\} 에서 변위와 속도, 가속도를 다음처럼 계산해 정답을 만듭니다:

d = c_{t_2} - c_{t_1}, \quad v_t = \frac{c_{t+1} - c_{t-1}}{2\Delta t}, \quad a_t = \frac{c_{t+1} - 2c_t + c_{t-1}}{\Delta t^2}

2단계는 검증된 실행 가능한 세계에서 만든 월드 스페이스 질문으로 GRPO(Group Relative Policy Optimization) 강화학습을 돌립니다. 보상은 스케일을 정규화한 수치 정확도에 단위 정확도와 응답 형식 보상을 더한 형태입니다:

r_{num} = \exp\left(-\frac{|\hat{y} - y|}{|y| + \epsilon}\right), \quad r = r_{num} + \lambda_u r_{unit} + \lambda_f r_{fmt}

여기서 두 종류의 실행 가능한 세계가 서로 다른 역할을 합니다. 텍스트에서 만든 세계는 시뮬레이터 상태가 완전히 관측되므로 수치적으로 정확한 물리 지도 신호를 주고, 영상에서 복원한 세계는 실제 관측의 외형과 움직임 분포에 더 가깝습니다. 두 쪽을 함께 학습하면 정확한 물리 지도와 실제 영상으로의 일반화를 동시에 가져간다는 것이 저자들의 설명입니다. 직접 답을 내는 4B와 9B 변형은 Qwen3.5 계열을 기반 모델로 삼아 H100 8장에서 학습했고, 모든 변형은 영상에서 시간 순서대로 16프레임을 균일하게 뽑아 씁니다.

Code-as-World-VL 벤치마크

평가는 QuantiPhy의 공개 검증 세트에서 이뤄졌습니다. 이 세트는 정답이 공개된 정량 질문 159개로 구성되고, 각 문항이 단안 영상과 질문, 그리고 척도를 맞추는 데 쓸 물리 사전 정보를 함께 줍니다. 지표는 평균 상대 정확도(Mean Relative Accuracy, MRA)로, 상대 오차를 10개의 점점 엄격해지는 기준에 대고 통과 여부를 평균합니다. 숫자로 파싱되지 않는 응답은 모든 기준에서 0점입니다. 하위 구간의 숫자는 공간 설정(2는 평면, 3은 깊이를 쓰는 3차원)이고 문자는 주어진 사전 정보의 종류(S는 크기 같은 정적 값, D는 속도나 가속도 같은 동적 값)입니다. 아래는 보고서 Table 1에서 주요 모델만 추리고 각 열의 최고값을 볼드로 표시한 것입니다:

모델 크기 2S 2D 3S 3D 평균
Gemini-3.1 Flash 비공개 49.4 47.5 61.4 61.1 54.8
ChatGPT-5.1 비공개 56.9 34.6 45.6 56.4 48.4
Gemini-2.5 Pro 비공개 45.9 38.6 40.7 60.2 46.4
Qwen3-VL-32B-Instruct 32B 38.1 39.7 39.8 43.0 40.2
Qwen3-VL-8B-Instruct 8B 17.2 27.6 36.0 48.3 32.3
Qwen3.5-4B 4B 26.6 35.7 19.8 41.3 31.2
Code-as-World-VL-4B 4B 45.4 55.4 45.8 56.0 50.6
Code-as-World-VL-9B 9B 55.0 52.9 55.6 58.1 55.4
Code-as-World-VL-27B (추론) 27B 48.7 62.4 60.5 62.8 58.6

위 표를 통해 세 가지를 확인할 수 있습니다. 첫째로 기반 모델과의 차이가 큽니다. 같은 4B인 Qwen3.5-4B가 31.2인데 Code-as-World-VL-4B는 50.6이고, 이 4B 모델이 32B 오픈 웨이트 모델(40.2)보다 10포인트 앞섭니다. 둘째로 직접 답을 내는 변형 중 가장 높은 9B의 평균 55.4가 Gemini-3.1 Flash의 54.8을 넘어섭니다. 다만 하위 구간을 따로 보면 9B는 3S에서 55.6, 3D에서 58.1로 Gemini-3.1 Flash의 61.4와 61.1에 미치지 못하고, 2S에서는 ChatGPT-5.1의 56.9가 더 높습니다. 평균이 앞섰다는 것과 모든 구간에서 앞섰다는 것은 다른 이야기이며, 깊이를 쓰는 3차원 설정에서 격차가 남아 있는 쪽이 Code-as-World-VL입니다.

셋째로 27B 추론 변형의 58.6은 평균에서 가장 높지만, 저자들 스스로 이 값을 추론의 효과를 통제한 추정치로 보지 말라고 명시합니다. 모델 규모와 응답 방식이 함께 바뀌었기 때문에 프레임워크가 더 큰 추론 모델로 확장된다는 증거로만 읽어야 한다는 것입니다. 그리고 앞서 적었듯 이 27B는 공개 대상이 아닙니다.

저자들이 밝힌 평가 자체의 한계도 함께 볼 필요가 있습니다. QuantiPhy는 비교적 제한된 움직임 조건에서 단안 척도 보정에 초점을 맞추므로 실제 물리의 일부만 다루고, 카메라 움직임과 회전, 변형, 가림, 접촉, 마찰, 유체, 장시간 다물체 역학은 범위 밖입니다. 또한 Code-as-World-VL은 발견 루프의 결과물로 학습되었을 뿐 그 과정 자체를 모델 안으로 들여오지는 않았습니다. 가설 구성과 시뮬레이션, 진단, 수정은 여전히 모델 밖에 있고, 이를 모델의 기본 능력으로 만드는 것을 저자들은 향후 과제로 남겨 두었습니다.

Code-as-World 설치와 사용

설치에는 CUDA 호스트와 파이썬 3.10 또는 3.11이 필요합니다. 저장소를 받은 뒤 추론 의존성을 설치하고 두 체크포인트를 내려받는 순서입니다:

git clone https://github.com/MirroS-Lab/Code-as-World.git
cd Code-as-World
python -m venv .venv
source .venv/bin/activate
pip install -r requirements/inference.txt

hf download MirroS-Lab/Code-as-World-VL-4B --local-dir weights/4b
hf download MirroS-Lab/Code-as-World-VL-9B --local-dir weights/9b

QuantiPhy 평가를 재현하려면 QuantiPhy 저장소검증 영상 데이터셋을 따로 받아 경로를 넘깁니다. 실행하면 평가기와 호환되는 예측 CSV와 단일 실행 지표 요약, 원본 생성 결과가 outputs/quantiphy/에 저장됩니다:

python -m code_as_world.evaluation 4b \
  --input-csv /path/to/QuantiPhy/quantiphy_validation.csv \
  --video-dir /path/to/QuantiPhy-validation/validation_videos

두 체크포인트는 vLLM의 표준 API로도 띄울 수 있습니다. 영상 입력을 16프레임으로 고정하고 프레임 재추출을 끄는 설정이 함께 지정되어 있으므로, 학습 시점과 같은 조건으로 서비스하려면 이 옵션들을 그대로 두는 편이 좋습니다:

CUDA_VISIBLE_DEVICES=0 vllm serve weights/4b \
  --served-model-name code-as-world-4b \
  --chat-template code_as_world/templates/qwen3_5_no_think.jinja \
  --chat-template-content-format openai \
  --default-chat-template-kwargs '{"enable_thinking":false}' \
  --max-model-len 4608 \
  --gpu-memory-utilization 0.90 \
  --media-io-kwargs '{"video":{"num_frames":16,"fps":-1,"video_backend":"openpangu"}}' \
  --mm-processor-kwargs '{"do_sample_frames":false}' \
  --mm-processor-cache-gb 0 \
  --generation-config vllm

영상에서 복원한 세계가 어떤 것인지 직접 보려면 시뮬레이션 의존성을 설치하고 함께 들어 있는 탄도 축구 예제를 실행합니다. 렌더링된 영상과 궤적이 outputs/simulations/에 저장되고, 궤적만 필요하면 --no-render를 붙입니다:

pip install -r requirements/simulation.txt
python -m code_as_world.simulation

Code-as-World의 라이선스

Code-as-World는 Apache 라이선스 2.0으로 공개되어 있어 개인 및 상업적 목적으로 자유롭게 사용할 수 있습니다. Hugging Face에 올라온 4B와 9B 체크포인트도 같은 Apache-2.0으로 표기되어 있으며, 두 모델 모두 Qwen3.5의 같은 규모 모델을 기반으로 미세조정한 것이므로 기반 모델 쪽 조건도 함께 확인하시는 편이 좋습니다.

:house: Code-as-World 프로젝트 페이지

:scroll: Code-as-World 기술 보고서 (arXiv)

:scroll: MirroS 블로그, 물리 세계를 어떻게 표현할 것인가

:github: Code-as-World 프로젝트 GitHub 저장소

:hugs: Code-as-World-VL 4B와 9B 모델 다운로드

더 읽어보기




이 글은 GPT 모델로 정리한 초안을 바탕으로 한 것으로, 원문의 내용 또는 의도와 다르게 정리된 내용이 있을 수 있습니다. 관심있는 내용이시라면 원문도 함께 참고해주세요! 읽으시면서 어색하거나 잘못된 내용을 발견하시면 댓글로 알려주시기를 부탁드립니다. :hugs:

이 도구를 직접 설치해 사용해보셨다면, :pytorch:파이토치 한국 사용자 모임:south_korea: 회원들을 위해 경험이나 팁을 댓글로 남겨주세요! :folded_hands: