TRENDSHIFT DAILY #18 · 2026-07-25 · OPEN DREAMER · 월드 모델

next-state/open-dreamer 딥다이브
"게임을 통째로 상상해 내는" 프런티어 월드 모델을 JAX로 처음부터 학습하는 레시피

Open Dreamer는 딥마인드의 Dreamer 4 논문을 JAX/Flax로 재현한 월드 모델(world model) 학습 파이프라인이다. 마인크래프트 플레이 영상을 학습해, 사람이 키를 누르면 다음 화면을 실시간으로 '생성'해 마치 게임 엔진처럼 플레이된다 — 진짜 게임이 아니라, 신경망이 꾸는 꿈(dream) 속에서.

이 저장소의 진짜 가치는 모델 코드가 아니라 "프런티어급 월드 모델을 어떻게 학습하는가"의 노하우 전부를 공개했다는 데 있다. 토크나이저·다이내믹스 두 모델, 확산(diffusion) 학습, Muon 옵티마이저, 혼합정밀도 경계, 스케일링 법칙, B200에서 MFU 58% 뽑기까지 — 논문이 안 알려주는 "함정과 해법"을 코드와 블로그로 풀었다.

(저장소 next-state/open-dreamer · 언어 Python(JAX/Flax NNX) · 데이터 Minecraft/VPT · 규모 ~1.6B 파라미터 · 후원 Reactor · 라이선스 독점(all-rights-reserved, 잠정) · 분석 시점 2026-07 초기 커밋 · shallow clone 소스 직접 분석)
목차
  1. 프로젝트 한 줄 요약
  2. 왜 주목받는가 — 논문이 아니라 '레시피'를 공개했다
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트
  7. 하드웨어 / 시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한 줄 요약

"플레이할 수 있는 꿈" — 액션을 넣으면 다음 프레임을 만들어 내는 신경망

월드 모델은 한 문장으로 "게임 엔진을 신경망으로 통째로 배운 것"이다. 보통 게임은 코드로 짜인 물리·렌더링 엔진이 다음 화면을 계산한다. 월드 모델은 그 엔진을 버리고, 수많은 플레이 영상만 보고 "이 화면에서 이 키를 누르면 다음 화면은 이렇게 된다"를 통째로 학습한다. 그래서 학습이 끝나면, 사람이 방향키를 누를 때마다 모델이 다음 프레임을 그려서 내놓는다. 코드로 짠 마인크래프트가 아니라, 마인크래프트를 흉내 내도록 배운 꿈을 플레이하는 셈이다.

Open Dreamer는 이 아이디어의 최신판인 딥마인드 Dreamer 4(2025) 논문을 JAX/Flax로 처음부터 재현한 오픈 구현이다. Next State 팀(Diego Martì Monsò, Francesco Sacco, Edward Hu)이 Reactor의 후원으로 만들었고, 블로그 제목 그대로 「How to train a frontier-level world model(프런티어급 월드 모델 학습법)」이다. 저장소에는 마인크래프트 세계를 브라우저에서 실시간으로 플레이하는 데모까지 연결돼 있다.

핵심 비유

"게임 디스크를 굽는 것" vs "게임을 본 적 있는 화가에게 조종간을 쥐여 주는 것"

일반 게임은 규칙·물리·그래픽이 코드로 박제된 디스크다. 정해진 대로만 돈다. 월드 모델은 수천 시간 플레이를 본 화가에 가깝다. 조종간을 주면, 배운 기억을 토대로 "왼쪽 키를 눌렀으니 다음 장면은 이렇겠지"를 그 자리에서 그려 보여 준다.

화가라서 좋은 점: 규칙을 새로 코딩하지 않아도 영상만 늘리면 새 세계를 배운다. 화가라서 어려운 점: 가끔 말이 안 되는 장면(추상화)이 튀어나오고, 이 "붓끝의 안정성"을 잡는 게 학습의 8할이다(§6).

중요한 구분이 하나 있다. 이 저장소는 학습(training) 파이프라인이다 — 토크나이저를 훈련하고, 데이터를 잠재(latent)로 바꾸고, 다이내믹스 모델을 훈련하고, 품질(FVD)을 재는 코드다. 실제로 브라우저에서 실시간으로 돌리는 추론(inference) 코드는 별도 저장소 reactor-team/open-dreamer에 있다. 즉 여기는 "요리법과 주방", 저기는 "손님에게 내는 완성 요리"다.

용어 풀이
월드 모델 (world model)
환경(게임·현실)의 작동 방식을 학습한 신경망. 현재 상태와 행동(액션)을 받아 다음 상태를 예측한다. 강화학습에서 특히 강력한데, 실제 환경에서 수천 번 시도하는 대신 모델의 '상상' 속에서 에이전트를 훈련할 수 있기 때문이다. Dreamer 시리즈(v1~v4)가 이 계열의 대표주자다. "다음 프레임 예측"이 곧 "세계의 규칙 학습"이 된다.

2왜 주목받는가 — 논문이 아니라 '레시피'를 공개했다

TrendShift Daily 상위권(#18)에 오른 이유 4가지

월드 모델 논문은 많다. Dreamer 4도, Genie도, GameNGen도 있다. 그런데 Open Dreamer가 트렌딩에 오른 건 겨냥점이 다르기 때문이다. 논문은 "무엇을 했는지"만 알려주지, "실제로 학습시키다 몇 주씩 막히는 지점"은 안 알려준다. Open Dreamer는 그 막히는 지점과 해법을 통째로 공개했다. 네 가지가 겹친다.

① "거인의 어깨 위로 순간이동" — 프런티어 연구의 진입장벽을 낮춘다

저자들의 표현이 압권이다: "과학에서 가장 오래 걸리는 건 거인의 어깨 위로 기어올라 가는 것인데, 가끔은 어깨 위로 순간이동해서 바로 최전선에서 일하기 시작하는 게 좋다." Dreamer 4 재현에 필요한 아키텍처·학습 코드·하이퍼파라미터·실패 사례를 다 공개해, 월드 모델 연구를 개인·소규모 팀도 시작할 수 있게 만들었다.

② 단일 GPU(CoinRun)로 검증 → 대형(마인크래프트)으로 스케일업

똑똑한 개발 전략이 그대로 담겼다. 처음부터 마인크래프트로 덤비지 않고, 단일 GPU에서 도는 간단한 게임 CoinRun(2D 플랫포머)으로 파이프라인 전 과정을 먼저 완성했다. 디버깅이 쉽고 반복이 빠르다. 코어 로직이 다 돌아가는 걸 확인한 뒤 마인크래프트로 규모만 키웠다. "작게 만들어 검증하고 키운다"는 ML 엔지니어링의 정석을 코드로 보여 준다.

③ 실시간으로 '플레이되는' 결과물

많은 생성 모델이 오프라인으로 영상 몇 개 뽑고 끝난다. Open Dreamer는 Reactor 런타임 위에서 마인크래프트 세계를 브라우저에서 실시간 플레이한다. "Game ⟷ Dream" 토글로 진짜 게임과 모델의 꿈을 프레임 단위로 넘겨 가며 비교할 수 있다. 실시간이 되려면 few-step 확산(4스텝) + KV 캐시 같은 추론 최적화가 필수인데, 그 코드가 generation.py에 그대로 있다(§4).

④ 논문에 없는 '엔지니어링 로그'를 남겼다

이게 진짜 차별점이다. 블로그의 절반이 Stability(안정성) 이야기다 — "MSE 손실은 매끄럽게 내려가는데 생성 품질은 나빠진다"는, 며칠~몇 주씩 사람을 괴롭히는 문제들. Muon vs LaProp 옵티마이저, EMA 필수, 혼합정밀도 경계, x-예측 + v-공간 손실, 최적수송(OT)까지 — "우리가 겪은 실패와 고친 법"을 순서대로 문서화했다. 논문 재현을 해 본 사람이면 이 로그의 가치를 안다.

이름에 속지 말 것
"Open" Dreamer지만 라이선스는 아직 '독점'이다

LICENSE 파일을 열면 "All rights reserved. No license or permission is granted..." — 즉 현재는 복사·수정·재배포 권한이 공식적으로 열려 있지 않다. 다만 "이 고지는 잠정적이며, 향후 릴리스에서 정식 라이선스로 대체될 예정"이라고 명시돼 있다. 코드를 읽고 배우는 용도는 괜찮지만, 실제로 가져다 쓰거나 파생물을 배포할 계획이라면 정식 라이선스가 붙을 때까지 기다리거나 저자에게 문의해야 한다. "오픈소스"라는 단어와 실제 라이선스가 다를 수 있다는 걸 소스로 확인해야 정확하다.

구분전형적 '월드 모델 논문'Open Dreamer
공개 범위방법·결과(what)학습 코드 + 함정·해법(how)
재현 난이도세부 하이퍼파라미터 불명Hydra config에 전부 명시
검증 전략대형 실험 위주CoinRun(1 GPU) → 마인크래프트
결과 형태오프라인 샘플 영상브라우저 실시간 플레이
프레임워크대개 PyTorchJAX/Flax(XLA·SPMD 확장성)
라이선스대개 명확잠정 독점(정식화 예정)

3기술 스택 전체 지도

전부 JAX 생태계 — 신경망부터 데이터·최적수송·평가까지

Open Dreamer의 스택은 머리끝부터 발끝까지 JAX다. 저자들이 JAX를 고른 이유는 명확하다 — "XLA 컴파일러가 효율적이고 확장 가능한 SPMD(단일 프로그램·다중 데이터) 프로그램에 탁월하기 때문". 즉 코드 한 벌로 여러 GPU에 자동 분산시키기 좋다는 것. 패키지 이름부터 tiny-dreamer-4, 설명은 "Dreamer 4 implementation in pure Jax"다.

next-state/open-dreamer (pure JAX, Python 3.11 · uv 관리) ├─ 신경망 flax (nnx API) ← 모델 정의(토크나이저·다이내믹스) ├─ 수치엔진 jax[cuda12] ← 자동미분·JIT·XLA·멀티 GPU(SPMD) ├─ 옵티마이저 optax (git 최신) ← Muon·AdamW·LaProp, WSD 스케줄 ├─ 최적수송 ott-jax ← 노이즈↔데이터 짝짓기(Sinkhorn OT) ├─ 지각손실 jaxlpips ← LPIPS(사람 눈에 가까운 이미지 유사도) ├─ 설정관리 hydra-core / OmegaConf ← YAML 조합·오버라이드 ├─ 체크포인트 orbax (flax 경유) ← 대형 학습 상태 저장/복원 ├─ 데이터 grain + array-record ← 구글 데이터 로더(GPU 프리페치) │ decord · minerl · imageio[ffmpeg] ← 영상 디코딩·마인크래프트 ├─ 평가 FVD + I3D(사전학습) ← 생성 영상 품질 점수(dreamer/fvd) ├─ 실험관리 wandb · tqdm · tyro · einops └─ 데모/사이트 Next.js + React (site/) ← 실시간 플레이(Reactor 런타임) 빌드/실행: uv sync → source .venv/bin/activate → uv run scripts/*.py

스택에서 눈여겨볼 선택 세 가지. 첫째, Flax의 새 API nnx를 쓴다(구 linen 아님) — 파이썬 객체처럼 상태를 다루는 최신 방식이라 KV 캐시 같은 가변 상태를 자연스럽게 담는다. 둘째, optax를 깃 최신 버전에서 직접 당겨온다(tool.uv.sources) — 실험적 Muon 옵티마이저가 안정판에 없기 때문. 셋째, 데이터를 미리 토큰화해 ArrayRecord로 저장하고 Grain으로 읽는다 — ffmpeg로 영상을 매번 디코딩하면 GPU를 못 먹여서다(§6의 dataloading).

핵심 의존성 (pyproject.toml 기준)

영역선택메모 / 이유
신경망Flax NNXGoogle JAX용 NN 라이브러리의 차세대 API. 가변 상태(KV 캐시) 친화적
수치/가속jax[cuda12]CUDA 12 빌드. cusparse는 12.8 호환 버전으로 핀 고정
옵티마이저optax (git)Muon/AdamW/LaProp. 안정판에 없어 GitHub master 직접 참조
최적수송ott-jaxSinkhorn 알고리즘. flow matching의 노이즈-데이터 커플링
지각 손실jaxlpipsLPIPS를 JAX로. 픽셀 MSE보다 사람 눈에 가까운 유사도
설정Hydra + OmegaConfYAML 조합·리졸버(${mul:...})로 폭 자동 계산
체크포인트Orbax파라미터·옵티마이저·EMA 상태 번들 저장
데이터Grain + ArrayRecord구글 결정적 데이터 로더 + 랜덤 접근 레코드 포맷
영상/게임decord · minerl · imageioMP4 디코딩, MineRL(마인크래프트 RL 환경)
평가FVD(I3D)Fréchet Video Distance. I3D 사전학습 가중치 동봉
용어 풀이
VPT (Video PreTraining) · MineRL
OpenAI가 공개한 마인크래프트 플레이 영상 대규모 데이터셋과 방법론. 사람의 플레이 영상에 키보드·마우스 액션이 라벨링돼 있어, "화면 → 다음 화면(액션 조건부)" 학습에 딱이다. Open Dreamer는 이 VPT 스타일 데이터(프레임 + 액션)를 ArrayRecord로 담아 학습한다. minerl은 마인크래프트를 강화학습 환경으로 감싼 라이브러리다.

4아키텍처 심화 분석

두 개의 모델, 하나의 백본 — 그리고 '확산으로 다음 프레임 그리기'

전체 그림은 의외로 단순하다. 모델이 딱 둘이고, 백본(뼈대)은 하나다. ①토크나이저가 영상 프레임을 작은 잠재 토큰으로 압축하고(≈100배), ②다이내믹스 모델이 그 잠재 공간에서 "다음 프레임"을 확산(diffusion)으로 그린다. 둘 다 같은 블록-인과 트랜스포머(block-causal transformer)를 뼈대로 쓴다.

비디오 프레임 (T, H, W, 3) │ patchify (패치로 잘라 토큰화) ▼ ┌──────────────────────────────────────────────┐ │ ① Tokenizer (인과적 비디오 오토인코더 / MAE) │ │ Encoder(depth 12) ─▶ 512 latents × 16 dim │ ≈100배 압축 │ Decoder(depth 8) ◀─ 프레임 재구성 │ KL·GAN 손실 없음 └──────────────────────────────────────────────┘ │ latent tokens z_t ▼ ┌──────────────────────────────────────────────┐ │ ② Dynamics (월드 모델, depth 30, ≈1.6B) │ │ 타임스텝 블록 B_t = ( a_{t-1}, s_t, π_t ) │ │ diffusion forcing + flow matching │ │ + shortcut models (τ-ladder, 추론 4스텝) │ └──────────────────────────────────────────────┘ │ 다음 latent ẑ_{t+1} 예측 ▼ Decoder로 디코딩 다음 프레임 → 사람이 액션 → 다시 ② (실시간 롤아웃)

백본 — 공간(Space) 어텐션과 시간(Time) 어텐션의 교대

두 모델이 공유하는 뼈대의 핵심은 어텐션을 두 종류로 쪼갠 것이다. 영상은 "여러 장의 그림이 시간순으로 이어진 것"이라, 정보가 흘러야 할 방향이 둘이다.

시간 → frame t-1 frame t frame t+1 [공간 토큰들] [공간 토큰들] [공간 토큰들] Space: ↕ ↕ ↕ (프레임 내부) ↕ ↕ ↕ ↕ ↕ ↕ Time : ●───past───▶●───past───▶● (인과적: 과거만) └ 4개 층마다 1개가 Time 층 (나머지는 Space) ┘ 부품: GQA(그룹 쿼리 어텐션) · RoPE(회전 위치인코딩) QK-norm · RMSNorm · 슬라이딩 윈도우(context_length)
용어 풀이
블록-인과 트랜스포머 · GQA · RoPE
블록-인과(block-causal): 한 프레임(블록) 안에서는 서로 자유롭게 보되, 프레임 사이에서는 과거→미래 한 방향만 보게 마스킹한 어텐션. GQA(Grouped-Query Attention): 여러 쿼리 헤드가 KV 헤드를 공유해 메모리·속도를 아끼는 어텐션(n_kv_heads = n_heads/8). RoPE: 위치 정보를 벡터 '회전'으로 넣는 기법 — 긴 시퀀스에 강하다. 전부 최신 LLM에서 검증된 부품을 영상에 그대로 가져왔다.

① 토크나이저 — "VAE를 버리고" 마스킹 오토인코더로

영상 프레임을 그대로 다이내믹스에 넣으면 너무 크다. 그래서 먼저 잠재 공간으로 ≈100배 압축한다. 보통 이럴 때 VAE를 쓰는데, 저자들의 표현이 솔직하다: "VAE를 학습해 본 적 있다면 그게 얼마나 끔찍한 경험인지 안다." 그래서 대신 트랜스포머 기반 마스킹 오토인코더(MAE)를 택했다.

② 다이내믹스 — '다음 프레임 그리기'를 확산으로

월드 모델의 심장이다. 근본 원리는 "다음 프레임 예측" — 각 프레임을 이전 프레임들에 조건부인 이미지로 생성한다. 이때 그냥 예측이 아니라 diffusion forcing + flow matching + shortcut models라는 세 겹의 기법으로 훈련한다. 그리고 결정적으로, 한 타임스텝을 블록으로 접는다:

한 타임스텝 블록 B_t = ( a_{t-1}, s_t, π_t ) 이전액션 상태 에이전트(정책) 공간 어텐션이 블록 안에서 왼→오로 흐른다: a_{t-1} ─▶ s_t ─▶ π_t s_t(상태) 안을 열어 보면 = 확산으로 생성되는 부분: ┌───────────────────────────────────────────────┐ │ [τ, step] | X (공간 latent 토큰) | R │ │ 노이즈레벨· 시각 상태 레지스터 │ │ 숏컷 보폭 (여기가 diffusion됨) (공용 │ │ 작업공간) │ └───────────────────────────────────────────────┘ └── 노이즈 낀 latent → 깨끗한 다음 latent ──┘ ※ 월드 토큰(X)은 π를 못 읽음 → 정책 정보는 '다음 액션'을 통해서만 미래 상태에 영향 (인과 구조를 깨지 않으려는 설계)

왜 이렇게 블록으로 접나? 원래 롤아웃은 "월드가 상태를 만들고 → 정책이 액션을 뽑고"를 번갈아 한다. 두 모듈을 오가면 느리고, 표현·파라미터도 못 나눈다. 블록으로 접으면 모든 타임스텝을 병렬로 학습하고, 월드와 에이전트가 같은 트랜스포머를 공유한다. register 토큰(n_register=32)은 "Vision Transformers Need Registers" 논문에서 온, 계산용 공용 메모장이다.

용어 풀이
flow matching · diffusion forcing · shortcut models
flow matching: 노이즈에서 데이터로 가는 '흐름(속도장)'을 배우는 최신 생성기법(확산의 사촌). diffusion forcing: 시퀀스의 각 프레임마다 노이즈 레벨을 다르게 줘서, 깨끗한 과거로 노이즈 낀 미래를 자기회귀 생성하게 하는 훈련법. shortcut models: 보통 확산은 수십~수백 스텝을 밟아야 깨끗해지는데, "한 번에 얼마나 갈지(보폭)"를 토큰으로 알려줘 몇 스텝(여기선 4)만에 생성하게 하는 기법. 실시간 플레이의 열쇠다.

추론 — τ-ladder로 4스텝 만에, KV 캐시로 실시간

generation.py가 실시간의 정체다. 학습은 최대 노이즈 해상도 k_max=256으로 하지만, 추론은 τ-사다리(τ-ladder)를 단 4스텝만 밟는다(num_steps=4, d=1/4). 각 스텝은 "깨끗한 latent 예측(x̂) → 현재와 섞기"를 반복한다.

노이즈 (τ=0) ──d──▶──d──▶──d──▶──d──▶ 깨끗 (τ=1) 단 4스텝 (d = 1/4) 각 스텝 s: x̂ = dynamics(...) (깨끗한 latent 예측) latent ← β·latent + (1-β)·x̂ (오일러 한 발짝) β = (1-τ_{s+1}) / (1-τ_s) 자기회귀 롤아웃: · 이전 프레임(문맥)은 '살짝' 노이즈 (τ_ctx≈0.9)로 캐시 · KVCache = 링 버퍼(고정 크기) → 매 프레임 재계산 없이 O(1) 진행 · next_latent → tokenizer.decode → 다음 프레임(uint8)

포인트 둘. 첫째, 문맥 프레임을 완전히 깨끗하게 두지 않고 살짝 노이즈(τ_ctx=0.9)를 준다 — 학습·추론 분포를 맞추기 위한 diffusion forcing의 트릭. 둘째, KV 캐시를 '링 버퍼'로 구현해(고정 크기 배열에 순환 기록) 슬라이딩 윈도우 어텐션을 O(1)로 돌린다. 이 둘이 없으면 매 프레임 전체를 다시 계산해야 해서 실시간이 불가능하다.

잘 만든 지점
학습은 병렬·고노이즈, 추론은 자기회귀·소스텝 — 같은 모델로

같은 다이내믹스 모델이, 학습 때는 모든 타임스텝을 병렬로(블록-인과 마스크) 처리해 GPU를 꽉 채우고, 추론 때는 KV 캐시로 자기회귀하며 4스텝만에 프레임을 뽑는다. "훈련 효율(병렬)"과 "추론 속도(소스텝·캐시)"라는 상충하는 목표를, shortcut model + diffusion forcing + KV 캐시의 조합으로 한 모델에 담았다. 실시간 생성형 게임의 정석 설계다.

5디렉토리 구조 해부

dreamer/ 코어 · scripts/ 진입점 · configs/ Hydra · site/ 데모

구조는 깔끔한 연구 코드베이스의 전형이다. dreamer/에 모델·학습·데이터·평가 로직이 다 있고, scripts/가 실제 실행 진입점, configs/가 Hydra YAML, site/가 Next.js 데모다. 워크플로 순서(토크나이저 학습 → 토큰화 → 다이내믹스 학습 → 평가)가 scripts/의 파일명에 그대로 드러난다.

open-dreamer/ ├─ dreamer/ ★ 코어 라이브러리 (pure JAX) │ ├─ models.py (1407줄) 토크나이저·다이내믹스·어텐션·KV캐시 정의 │ ├─ training.py (933줄) 학습 스텝(flow matching·shortcut·bootstrap) │ ├─ generation.py (381줄) τ-ladder 추론·자기회귀 롤아웃 │ ├─ configs.py (339줄) 모델 config 데이터클래스 │ ├─ actions.py (229줄) 멀티모달 액션(binary·categorical·continuous) │ ├─ checkpointing.py (273줄) Orbax 체크포인트 번들 │ ├─ scaling.py (193줄) 스케일링 법칙 헬퍼(N∝C^0.56 …) │ ├─ parallel.py (112줄) 메시 전략(data·fsdp·tp·sp) │ ├─ sampler.py · utils.py · logging.py │ ├─ data/ Grain + ArrayRecord 파이프라인 │ │ ├─ data.py · transforms.py · serialization.py │ │ ├─ shard_writer.py · path_utils.py │ │ └─ generate_coinrun_dataset.py ← 단일 GPU용 CoinRun 생성 │ └─ fvd/ Fréchet Video Distance 평가 │ ├─ fvd.py │ └─ i3d_pretrained_400.npz ← I3D 사전학습 가중치(동봉) ├─ scripts/ 실행 진입점 (uv run scripts/xxx.py) │ ├─ train_tokenizer.py 1) 토크나이저 학습 │ ├─ tokenize_minecraft_dataset.py 2) 데이터셋 → 잠재로 토큰화 │ ├─ train_dynamics.py 3) 다이내믹스(월드 모델) 학습 │ └─ eval_fvd.py 4) 롤아웃 생성 + FVD 측정 ├─ configs/ Hydra / OmegaConf YAML │ ├─ common.yaml 공통(정밀도·체크포인트·병렬·시드) │ ├─ tokenizer.yaml · dynamics.yaml · tokenize.yaml · eval_fvd.yaml │ ├─ *_finetune.yaml 파인튜닝 변형 │ └─ dataset/ minecraft_vpt · minecraft_vpt_latent · coinrun ├─ site/ Next.js 웹사이트 + 실시간 데모 + 블로그 ├─ pyproject.toml · uv.lock 의존성(uv 관리) └─ LICENSE(잠정 독점) · README.md
읽는 순서 팁

이 레포를 처음 연다면 README(워크플로 6단계) → site/article/article.html(블로그: 왜·어떻게) → configs/tokenizer.yaml·dynamics.yaml(모든 하이퍼파라미터가 주석과 함께) → dreamer/models.py(백본·두 모델) → dreamer/generation.py(추론) 순서를 추천한다. 특히 블로그(article.html)를 먼저 읽으면 좋다 — 코드가 왜 그렇게 생겼는지("안정성 때문에 Muon", "실시간 때문에 shortcut")를 사람 말로 설명해 두어, 소스가 훨씬 잘 읽힌다. config YAML의 주석이 이례적으로 친절해서, 사실상 하이퍼파라미터 교과서로도 쓸 수 있다.

6학습 포인트

"프런티어 모델을 실제로 학습시킬 때" 부딪히는 것들의 교재

이 저장소의 최고 가치는 대형 생성 모델을 실제로 안정적으로·빠르게 학습시키는 노하우다. 블로그 절반이 "손실은 내려가는데 품질이 나빠지는" 안정성 문제와 그 해법이다. 주제(월드 모델)를 걷어내도, 아래는 어떤 대형 확산·시퀀스 모델에도 통하는 교훈이다.

① Muon 옵티마이저 — LaProp의 '손실 스파이크'를 잡다

Dreamer 시리즈는 원래 LaProp을 썼는데, 학습이 길어질수록 손실이 무작위로 튀는(spike) 현상이 잦아졌다. 저자들은 2D 행렬 가중치에 Muon(+ 임베딩·norm·bias엔 AdamW)을 적용해 훨씬 안정적이고 낮은 손실을 얻었다. Muon은 요즘 LLM 학습에서 급부상한 옵티마이저로, Newton-Schulz 반복(muon_ns_steps=5)으로 그래디언트를 직교화한다. "옵티마이저 하나가 안정성을 바꾼다"는 실전 사례.

② 확산 추론엔 EMA가 '필수'

확산 모델에서 온라인(학습 중) 가중치로 추론하면 결과가 확 나빠진다. 파라미터의 지수이동평균(EMA, θ_ema ← β·θ_ema + (1-β)·θ)로 추론해야 한다(ema_decay=0.999). 학습 코드가 온라인·EMA 두 벌의 가중치를 항상 함께 관리하는 이유다. "왜 내 확산 모델은 학습 손실은 좋은데 샘플이 이상하지?"의 흔한 답.

③ 혼합정밀도 — '어디를 float32로 둘지'가 생사를 가른다

최신 가속기는 BF16에 최적화됐지만 일부 연산은 고정밀이 필요하다. 규칙: 파라미터는 float32 보관, 대부분의 행렬곱·어텐션 입력은 BF16, 그러나 정규화(norm)·사인파 임베딩·어텐션 가중치·다이내믹스 flow 출력 헤드는 float32. 이 경계를 잘못 그으면 학습·생성이 둘 다 불안정해진다. config에 dtype=bfloat16, param_dtype=float32가 분리된 이유.

④ x-예측 + v-공간 손실 — 작지만 확실한 품질 개선

flow matching은 보통 속도장을 예측(v-prediction)하지만, 저자들은 깨끗한 데이터를 직접 예측(x-prediction)하되 v-공간 손실 가중을 쓴다: L_v = ||x - x̂||² / (1-τ)². 월드 모델은 문맥 프레임이 전부 x-공간(실제 픽셀)이라, "다음 프레임도 x-공간으로 예측"하는 게 자연스러운 귀납편향이다. Dreamer 4보다 분모에 제곱을 더한 미세 변형으로 소폭 개선을 얻었다.

⑤ 최적수송(OT) — 흐름의 '길'을 짧게

"최적수송과 flow matching은 천생연분"이다. OT는 노이즈와 데이터를 이동 거리가 최소가 되게 짝지어, 흐름의 경로를 짧고 덜 모호하게 만든다. Open Dreamer는 미니배치 barycentric OT(OTT-JAX의 Sinkhorn, max_iter=50)로 노이즈-데이터 시퀀스를 통째로 커플링해, 롤아웃 생성을 더 안정화했다.

⑥ 스케일링 법칙 — "compute의 제곱근"이라는 자연의 선물

CoinRun 토크나이저로 iso-FLOPs 스케일링을 재 보니, compute-optimal 파라미터 수와 데이터 수가 compute의 제곱근으로 붙었다: N ∝ C^0.56, D ∝ C^0.44. Karpathy의 인용처럼 "복잡한 함수일 수도 있었는데, 자연이 정확히 직선으로 결정했다(뭐지??)". dreamer/scaling.pyScalingContext가 토큰 예산·최대 스텝을 이 법칙으로 유도한다.

⑦ MFU 58% 뽑기 — 루프라인·샤딩·활성화 체크포인팅

대형 학습의 하드웨어 효율 챕터다. B200 GPU에서 MFU(모델 FLOPs 이용률) 57~58%를 달성했는데(60%면 매우 건강), 방법은: (a) GPU당 256프레임을 먹여 루프라인의 ridge point(292 FLOP/byte)를 넘겨 compute-bound로 만들고, (b) 샤딩은 DP/FSDP/TP/SP를 다 시도해 본 뒤 단순 데이터 병렬(DP)이 최선(모델 상태 24GiB가 이미 들어맞아 FSDP 통신 이득이 없음), (c) 긴 영상의 활성화가 OOM을 내니 활성화 체크포인팅으로 일부만 저장·나머지는 역전파 때 재계산.

⑧ 데이터로딩 — GPU를 굶기지 않기

마지막 병목은 "GPU를 계속 배부르게 하기". 영상은 무겁고 ffmpeg 디코딩이 느려 GPU를 못 먹인다. 해법: 데이터셋 전체를 미리 토큰화해 ArrayRecord로 저장하고, Grain으로 읽으며 GPU 측 프리페치 버퍼로 데이터를 미리 올려 둔다. "연산 최적화보다 데이터 파이프라인이 병목"인 흔한 현실.

한 줄 요약
"월드 모델"을 걷어내도 값진, 대형 생성 모델 학습 교재

주제를 지워도 남는 게 많다. Muon·EMA·혼합정밀도 경계·x/v 손실·최적수송·스케일링 법칙·루프라인/MFU·활성화 체크포인팅·데이터 프리페치. "확산·시퀀스 계열 대형 모델을 실제로 안정적이고 빠르게 학습시키는 법"의 종합 실전서로 읽을 수 있다. JAX/Flax로 진지한 학습 파이프라인을 짜고 싶은 사람에게 특히 참고가 된다.

7하드웨어 / 시스템 요구사항

CoinRun은 GPU 1장, 마인크래프트는 B200급 — CUDA 12 JAX 필수

요구사항은 "어디까지 재현하느냐"에 따라 극과 극이다. 파이프라인을 배우고 CoinRun으로 돌려 보는 건 단일 GPU로 충분하지만, 블로그의 마인크래프트 1.6B 모델을 재현하려면 데이터센터급 GPU가 필요하다. 공통 전제는 CUDA 12 호환 JAX 환경이다.

항목요구 / 비고
Python3.11 고정 (requires-python == 3.11.*)
패키지 관리uv (uv sync.venv 활성화)
가속기CUDA 12 호환 JAX. lock은 CUDA 12 대상 — 다른 가속기는 맞는 wheel 재설치
학습(CoinRun)단일 GPU로 전 과정 가능(디버깅·학습용 설계)
학습(마인크래프트)B200급 다수. 1.6B 모델 상태 ≈24GiB + 긴 영상 활성화
데이터Minecraft/VPT식 ArrayRecord 샤드(shard-*.array_record)를 직접 준비
추론(실시간)이 저장소 아님 — reactor-team/open-dreamer + Reactor 런타임
함정 주의
"clone하면 바로 마인크래프트가 플레이된다"가 아니다

이 저장소는 학습 파이프라인이라, 돌리려면 (1) VPT식 데이터를 직접 마련해 ArrayRecord로 만들고, (2) 토크나이저를 학습하고, (3) 데이터셋을 토큰화하고(잠재 통계 latent_mean/std를 config에 복사), (4) 다이내믹스를 학습하는 4단계를 순서대로 거쳐야 한다. 사전학습 가중치는 동봉되지 않는다(FVD용 I3D 제외). "바로 플레이"는 브라우저 데모(Reactor 클라우드)에서만 가능하고, 로컬 실시간 추론은 별도 inference 저장소를 봐야 한다.

8직접 해볼 수 있는 실습 과제

난이도별 5개 — config 읽기부터 τ-ladder 추적까지
과제 1 · 난이도 ★☆☆☆☆

config를 하이퍼파라미터 교과서로 읽기

configs/tokenizer.yamlconfigs/dynamics.yaml을 주석까지 정독하라. n_latents=512·d_bottleneck=16·depth·time_every=4·k_max=256이 각각 무엇을 뜻하는지 §4와 대조해 정리한다. 왜 인코더 depth(12)와 디코더 depth(8)가 다른지, d_model=${mul:128,depth} 같은 Hydra 리졸버가 어떻게 폭을 자동 계산하는지 파악하는 게 목표. 코드를 안 돌려도 되는 순수 독해 과제.

과제 2 · 난이도 ★★☆☆☆

블로그의 '안정성 8계명'을 코드와 매칭

site/article/article.html(또는 웹사이트)의 Stability 절을 읽고, 언급된 해법 각각이 코드/설정 어디에 있는지 찾아라: Muon(optimizer_type: muon), EMA(ema_decay), 혼합정밀도(dtype/param_dtype), x/v 손실(loss_weighting: v_space), OT(ot.enabled). "블로그의 교훈 ↔ config 스위치"를 1:1 표로 만들면 성공.

과제 3 · 난이도 ★★★☆☆

공간/시간 어텐션이 어떻게 교대하는지 코드로 확인

dreamer/models.pyBlockCausalLayer.is_time_layerBlockCausalTransformer.__call__을 읽고, time_every=4·time_layer_offset어느 층을 시간 층으로 만드는지 규칙을 종이에 적어라. SpaceSelfAttentionTimeSelfAttention의 마스킹·RoPE 적용 차이를 비교하고, 왜 시간 층만 인과 마스크가 필요한지 설명할 수 있으면 목표 달성.

과제 4 · 난이도 ★★★★☆

τ-ladder 4스텝 샘플링을 손으로 따라가기

dreamer/generation.pyDenoiseSchedule.initnext_latentrefinement_step을 읽고, num_steps=4·k_max=256일 때 tau_values·beta_values가 어떤 배열이 되는지 직접 계산하라. latent ← β·latent + (1-β)·x̂ 갱신을 4번 손으로 굴려 본다. 그다음 latent_rollout에서 KVCache(링 버퍼)가 문맥을 어떻게 재사용하는지, tau_ctx=0.9가 왜 붙는지 추적한다.

과제 5 · 난이도 ★★★★★

CoinRun으로 미니 파이프라인 굴려 보기(단일 GPU)

dreamer/data/generate_coinrun_dataset.py로 CoinRun 데이터를 만들고, configs/dataset/coinrun.yaml 기준으로 토크나이저 학습 → 토큰화 → 다이내믹스 학습 → eval_fvd의 축소판을 단일 GPU에서 시도하라(스텝 수를 크게 줄여서). vis/에 찍히는 재구성 이미지와 롤아웃 영상을 눈으로 확인하고, FVD가 내려가는지 본다. 전 과정을 한 번이라도 통과시키면 "월드 모델을 실제로 학습해 봤다"고 말할 수 있다.

9관련 기술 심화 학습 로드맵

4주 커리큘럼 — 이 저장소를 발판으로
주차주제할 것
1주차월드 모델 & Dreamer 계보Dreamer 4 논문(arXiv 2509.24527) 개요 → "다음 프레임 예측 = 세계 규칙 학습" 이해 → article.html의 CoinRun→마인크래프트 서사 정독
2주차토크나이저 & MAEMAE·MAETok 개념 → 왜 VAE 대신 마스킹 오토인코더인지 → tokenizer.yaml·models.py의 Encoder/Decoder 읽기 → LPIPS 지각손실
3주차flow matching·shortcut·diffusion forcingflow matching 기초 → Shortcut Models(arXiv 2410.12557) → diffusion forcing → generation.py의 τ-ladder를 손으로 추적
4주차대형 학습 엔지니어링(JAX)Muon 옵티마이저 → 혼합정밀도 경계 → 루프라인/MFU·샤딩(DP/FSDP) → 스케일링 법칙(scaling.py) → Grain 데이터 파이프라인
학습 순서 팁

이 저장소는 두 갈래로 배울 수 있다. "생성 모델 이론"이 궁금하면 토크나이저(MAE)→flow matching→shortcut→diffusion forcing 축으로, "대형 학습 엔지니어링"이 궁금하면 Muon→혼합정밀도→MFU/루프라인→샤딩→데이터로딩 축으로 파면 된다. 둘 다 article.html(블로그)이 최고의 안내서다 — 이론과 엔지니어링을 실제 실패 사례와 함께 엮어 놨다. 논문(Dreamer 4)은 "무엇"을, 이 레포는 "어떻게"를 채워 주는 상보 관계다.

10핵심 키워드 사전

이 문서에 나온 용어 빠른 정리
용어
월드 모델환경의 작동 방식을 학습한 신경망. 상태+액션 → 다음 상태 예측. 모델의 '상상' 속에서 에이전트 훈련 가능
Dreamer 4딥마인드의 월드 모델 논문(2025, Hafner 등). Open Dreamer가 재현 대상으로 삼음
토크나이저영상 프레임을 작은 잠재 토큰으로 ≈100배 압축하는 오토인코더. 여기선 마스킹 오토인코더(MAE)
다이내믹스 모델잠재 공간에서 '다음 프레임'을 확산으로 생성하는 월드 모델 본체(depth 30, ≈1.6B)
블록-인과 트랜스포머프레임 내부는 자유·프레임 사이는 과거만 보게 마스킹한 백본. 두 모델이 공유
공간/시간 어텐션Space=한 프레임 안, Time=프레임 사이(인과적). 4개 층마다 1개가 시간 층
MAEMasked Autoencoder. 입력 일부를 가리고 복원 학습. 잠재를 '확산 친화적'으로 만들고 KL·GAN 손실이 필요 없음
flow matching노이즈→데이터로 가는 '속도장(흐름)'을 배우는 생성기법(확산의 사촌)
diffusion forcing시퀀스 각 프레임의 노이즈 레벨을 다르게 줘 자기회귀 생성을 가능케 하는 훈련법
shortcut models'한 번에 얼마나 갈지'를 토큰으로 알려줘 몇 스텝(4)만에 생성. 실시간의 열쇠
τ-ladder추론 시 노이즈(τ=0)→깨끗(τ=1)을 4스텝으로 밟는 사다리형 디노이징 스케줄
KV 캐시(링 버퍼)과거 어텐션 키/값을 고정 크기 배열에 순환 저장해 자기회귀 롤아웃을 O(1)로
register 토큰계산용 공용 메모장 토큰("ViT Needs Registers"). 여기선 타임스텝당 32개
Muon2D 행렬 가중치용 최신 옵티마이저(Newton-Schulz 직교화). LaProp의 손실 스파이크를 잡음
EMA파라미터 지수이동평균. 확산 추론은 온라인 가중치가 아니라 EMA로 해야 함(필수)
x/v-prediction깨끗한 데이터를 직접 예측(x) + v-공간 손실 가중. 월드 모델의 자연스러운 귀납편향
최적수송(OT)노이즈-데이터를 이동거리 최소로 짝지어 흐름 경로를 단축. OTT-JAX Sinkhorn
MFU / 루프라인모델 FLOPs 이용률 / compute-vs-memory 한계선. B200에서 GPU당 256프레임으로 compute-bound·MFU 58%
FVDFréchet Video Distance. I3D 특징으로 생성 영상 품질을 재는 지표(낮을수록 좋음)
VPTVideo PreTraining. 액션이 라벨된 마인크래프트 플레이 영상 데이터/방법론
Grain / ArrayRecord구글 결정적 데이터 로더 / 랜덤 접근 레코드 포맷. 미리 토큰화해 GPU 프리페치

11참고 링크

원문으로 더 파고들기