TrendShift 딥다이브 · 2026-07-03 재분석

autoresearch 딥다이브
— 단일 GPU에서 AI 에이전트가 밤새 스스로 LLM을 연구하게 만드는 630줄

autoresearch는 Andrej Karpathy가 2026년 3월 공개한, AI 에이전트가 자기 손으로 LLM 학습 코드를 고치고 실험하고 판정하는 자율 연구 루프다. 전체 프로젝트는 딱 3개의 "진짜" 파일prepare.py(불변)·train.py(에이전트가 고치는 유일한 파일)·program.md(사람이 에이전트에게 내리는 지시서) — 로 구성된다. 훈련은 무조건 5분 고정 시간 예산으로 끊고, val_bpb 하나만 보고 keep/discard를 결정한 뒤 git으로 되돌리거나 커밋한다. (저장소: karpathy/autoresearch · MIT · Python 83% · ★89.3k · Fork 12.9k · nanochat의 단일-GPU 파생작)
목차
  1. 프로젝트 한줄 요약
  2. 왜 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트 (기술별)
  7. 하드웨어 / 시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한줄 요약

이 저장소가 대체 무엇인가.

핵심 메시지

"ML 연구자를 복제해서 밤새 실험시키는 것" — 사람은 규칙(program.md)만 쓰고, 나머지는 에이전트의 keep/revert 루프가 돈다.

ML 연구자의 하루는 단순하게 요약하면 이렇다: 아이디어를 내고 → 코드를 고치고 → 돌려보고 → 결과를 보고 → 좋으면 유지, 나쁘면 되돌린다. autoresearch는 이 한 바퀴를 AI 에이전트(Claude Code·Codex 등)에게 통째로 맡긴다. README의 표현을 빌리면 "give an AI agent a small but real LLM training setup and let it experiment autonomously overnight" — 작지만 진짜인 LLM 학습 환경을 에이전트에게 주고 밤새 자율적으로 실험하게 둔다는 것.

핵심 설계는 에이전트가 건드릴 수 있는 파일을 train.py 딱 하나로 제한한 것이다. 나머지(데이터 파이프라인·평가 지표)는 prepare.py에 고정돼 있어 손댈 수 없다. 탐색 공간을 좁혀야 에이전트가 산으로 가지 않고 체계적으로 개선한다는 철학이다. 사람은 코드를 안 짜고 program.md라는 마크다운으로 에이전트의 행동 규칙을 프로그래밍한다.

README 첫 문단은 짧은 SF 산문으로 시작한다 — "Research is now entirely the domain of autonomous swarms of AI agents running across compute cluster megastructures in the skies."(연구는 이제 완전히 하늘의 컴퓨트 클러스터 메가스트럭처를 가로지르는 AI 에이전트 군집의 영역이다) 농담 섞인 세계관 설정이지만, 실제로 이 레포가 보여주는 것은 "연구자 개입 없이 GPU 하나로 밤새 수십~수백 개 실험을 굴리는" 실물 파이프라인이다.

학습 코드 자체는 Karpathy의 또 다른 프로젝트 nanochat"simplified single-GPU implementation"(단일 GPU용으로 단순화한 구현)으로 축소한 것이다. nanochat이 "풀사이즈 LLM을 처음부터 끝까지 학습시키는 법"을 보여준다면, autoresearch는 그 학습 루프를 "에이전트가 반복 실험할 수 있는 최소 단위"로 재포장한 파생작이다.

용어
keep/revert 루프
에이전트가 train.py를 수정 → git commit → 5분 학습 → val_bpb가 개선되면 그 커밋을 "keep"(그대로 유지하고 다음 실험으로 전진), 악화되면 git reset으로 "revert"(되돌리고 그 지점에서 다시 시도)하는 반복 구조. 실험 버전 관리를 위한 별도 DB 없이 git 자체를 실험 이력 관리자로 쓰는 것이 핵심이다.
이 프로젝트의 트레이드마크
"사람은 마크다운만 쓴다" — program.md라는 새로운 인터페이스

보통 자동화 도구는 사람이 파이썬 설정 파일이나 YAML을 쓴다. autoresearch는 사람의 개입을 program.md 한 장으로 축소한다. 여기에 "실험 목표·해도 되는 것/안 되는 것·결과 기록 형식·종료 조건"을 자연어로 적어두면, 에이전트가 그걸 읽고 스스로 판단하며 무한 루프를 돈다. README는 이를 "a super lightweight skill"이라 부른다. 코드가 아니라 지시서로 에이전트의 연구 방향을 프로그래밍하는 것 — Claude Code의 SKILL.md와 사실상 같은 발상이 ML 연구 자동화에 적용된 사례다.

2왜 주목받는가

"Karpathy가 밤새 GPU를 에이전트에게 맡겼다"는 화제성 · 기존 AutoML/HPO와의 근본적 차이 · 재현 가능한 완결 실험.

2026년 3월 공개 이후 ★89.3k · Fork 12.9k까지 성장했다(포크 수가 스타 수의 14%를 넘는다는 것은 "읽고 감탄"보다 "실제로 돌려보고 자기 플랫폼에 맞게 고친" 사람이 매우 많다는 신호다 — 아래 "커뮤니티 포크" 표 참고). Karpathy 본인이 X(트위터)에 실험 로그를 공유하며 화제가 됐고, Fortune 등 주류 매체도 "AI가 스스로 AI 연구를 한다"는 프레임으로 보도했다.

기존 AutoML·HPO 도구와의 근본적 차이

도구탐색 방식한계
Optuna / Ray Tune사람이 정한 파라미터 범위 안에서 탐색(HPO)"어텐션 패턴 자체를 바꿔보자" 같은 코드 레벨 변경은 불가능
NNI / Auto-sklearn정해진 서치 스페이스 + 알고리즘(베이지안 최적화 등)탐색 공간을 미리 정의해야 함 — 정의 밖은 못 나감
범용 코딩 에이전트(단독)자유도는 높지만 목표·평가 기준이 불명확공정 비교 장치(고정 시간·단일 메트릭)가 없어 실험이 산으로 갈 수 있음
autoresearch코드 레벨 자유 수정 + 고정 5분 예산 + 단일 메트릭(val_bpb)단일 GPU·단일 파일로 스코프를 의도적으로 좁힘
비유

Optuna가 "메뉴판 안에서 고르게 하는 것"이라면, autoresearch는 "주방 자체를 새로 설계해도 되지만, 모든 요리를 정확히 5분 안에 내야 하고 맛(val_bpb) 하나로만 평가받는 것"이다. 자유도는 훨씬 높아졌지만, 공정한 비교 장치(고정 시간 예산 + 단일 메트릭)가 있어야 그 자유도가 폭주하지 않는다. 이 균형이 autoresearch가 기존 AutoML과 결정적으로 다른 지점이다.

주목도를 끌어올린 구체적 요인은 다음과 같다.

① 압도적 단순함. 전체 레포가 실질적으로 10개 파일, 그중 로직은 3개뿐이다. README도 짧다. "복잡한 MLOps 프레임워크 없이 자율 연구 루프를 짤 수 있다"는 증명 그 자체가 학습 자료로서 가치가 크다.
② 완전한 재현 가능성. evaluate_bpb"DO NOT CHANGE"로 못박혀 있고, val_bpb는 어휘 크기와 무관하게 설계돼 있어 아키텍처를 통째로 바꿔도 공정 비교가 유지된다. "메트릭 하나로 승부"라는 단순함이 오히려 신뢰를 만든다.
③ 실제 최신 연구 기법의 집약체. Muon 옵티마이저(Keller Jordan), Polar Express 직교화, Value Embedding(ResFormer), Sliding Window Attention, RoPE 등 2025~2026년 LLM 프리트레이닝 최전선 기법이 630줄 안에 압축돼 있다. 뒤에서 자세히 본다.
④ "밤새 100개 실험"이라는 체감형 스토리. 하루 자는 동안 자동으로 GPU가 100번 가까이 실험을 도는 서사가 "AI 에이전트 시대"를 가장 직관적으로 보여주는 데모로 소비됐다.

3기술 스택 전체 지도

PyTorch 2.9.1 + torch.compile 풀그래프 컴파일 · Flash Attention 3 · Muon/AdamW 하이브리드 · uv 패키지 관리.

언어 구성은 Python 83.4%, Jupyter Notebook 16.6%다(analysis.ipynb 하나가 노트북 비중 전체를 차지). "학습 코드는 파이썬 스크립트, 결과 분석은 노트북"으로 역할이 명확히 나뉜다. 웹 서버도, API도, 프론트엔드도 없다 — 순수 ML 파이프라인 하나가 이 레포의 전부다.

① 코어 학습 스택

영역기술역할
딥러닝 프레임워크PyTorch 2.9.1 (CUDA 12.8 인덱스)pyproject.tomltorch==2.9.1pytorch-cu128 전용 인덱스에서 고정 설치
어텐션 커널Flash Attention 3 (kernels 라이브러리 경유)HuggingFace kernels.get_kernel()로 사전 컴파일된 FA3 커널을 동적 로드
옵티마이저커스텀 MuonAdamW (직접 구현)2D 행렬 파라미터=Muon, 나머지(임베딩·스칼라)=AdamW로 자동 분기
컴파일러torch.compile(dynamic=False, fullgraph=True)옵티마이저 스텝 함수까지 풀그래프 컴파일 — 재컴파일 방지를 위해 0-D CPU 텐서로 스칼라 전달
정밀도bfloat16 (autocast) + float32 마스터 로짓메모리 절약 + logits.float()로 손실 계산은 안정적으로

② 데이터 파이프라인

기술버전 제약역할
rustbpe≥0.1.0Rust로 짠 BPE 토크나이저 학습기(속도 최적화, GPT-4 스타일 분할 패턴)
tiktoken≥0.11.0학습된 BPE를 실제 인코딩/디코딩에 쓰는 런타임(OpenAI 제작)
pyarrow≥21.0.0HuggingFace에 올라온 Parquet 데이터 셰도(shard)를 스트리밍으로 읽기
requests≥2.32.0데이터 셰도 다운로드(재시도·백오프 로직 직접 구현)
데이터셋climbmix-400b-shuffleHuggingFace karpathy/climbmix-400b-shuffle — 최대 6,542개 Parquet 셰도

③ 실험 인프라 & 분석

기술역할
uvAstral의 초고속 Python 패키지 매니저. uv sync 한 번으로 전체 의존성 해결(pip 대비 10~100배 빠름)
Git실험 버전 관리 그 자체 — autoresearch/<tag> 브랜치에서 commit/reset을 실험 단위로 사용
pandas + matplotlibanalysis.ipynb에서 results.tsv를 로드해 val_bpb 추이·개선 델타 시각화
NVIDIA kernels 커뮤니티 허브Hopper(H100) 전용 varunneal/flash-attention-3 vs 그 외 GPU용 kernels-community/flash-attn3capability 감지로 자동 분기
설계 통찰
"의존성을 pyproject.toml에 완전히 못박는다" — 에이전트의 자유도를 코드가 아니라 환경으로 제한

program.md는 명시적으로 "Install new packages or add dependencies"금지 항목으로 못박는다. 에이전트는 pyproject.toml에 이미 선언된 라이브러리만 쓸 수 있다. 이건 단순한 규칙이 아니라 "자유도는 코드 레벨에서 최대, 인프라 레벨에서 최소"라는 설계 철학의 실현이다. 새 패키지 설치는 재현성을 깨고 실행 시간을 늘리므로, 애초에 우회 경로를 차단해 버린 것이다.

4아키텍처 심화 분석

3계층 시스템 구조 · MuonAdamW 옵티마이저 내부 · BOS-aligned 패킹 · 5가지 핵심 설계 패턴.

autoresearch의 전체 흐름은 사람 → 에이전트 → 학습 스크립트의 3계층으로 나뉜다. 사람이 쓰는 것은 program.md 하나뿐이고, 그 아래로는 전부 자동이다.

┌─────────────────────────────────────────────────────────────────┐ │ HUMAN LAYER │ │ program.md 작성 (연구 목표 · 금지 사항 · 종료 조건) │ └──────────────────────────┬──────────────────────────────────────┘ │ 읽기 ┌──────────────────────────▼──────────────────────────────────────┐ │ AGENT LAYER (Claude Code / Codex 등, 권한 전부 허용 상태로 실행) │ │ │ │ git 상태 확인 ─▶ train.py 코드 수정 ─▶ git commit │ │ ▲ │ │ │ │ uv run train.py > run.log 2>&1 │ │ │ ▼ │ │ results.tsv 기록 ◀── grep val_bpb ◀── (5분 학습 + 평가 완료) │ │ │ │ │ val_bpb 개선? ── Yes ──▶ KEEP (커밋 유지, 전진) │ │ └── No ──▶ REVERT (git reset, 그 지점에서 재시도) │ └─────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────────┐ │ TRAINING LAYER (단일 GPU, prepare.py + train.py) │ │ prepare.py [불변]: 데이터 다운로드 → rustbpe 토크나이저 학습 │ │ make_dataloader() (BOS-aligned 패킹) │ │ evaluate_bpb() ← 절대 수정 금지, 유일한 심판│ │ train.py [수정 대상]: GPTConfig → GPT(RoPE+FA3+RMSNorm+SWA) │ │ MuonAdamW 하이브리드 옵티마이저 │ │ 고정 300초(TIME_BUDGET) 학습 루프 │ └─────────────────────────────────────────────────────────────────┘
용어
val_bpb (Validation Bits Per Byte)
언어모델 성능을 어휘 크기와 무관하게 재는 지표. 토큰 단위 cross-entropy(nats)를 그 토큰이 인코딩한 실제 바이트 수로 나눠 bits/byte로 환산한다(prepare.pyevaluate_bpb). 에이전트가 vocab_size를 8192에서 1024로 바꾸든, 아키텍처를 통째로 갈아엎든 항상 공정하게 비교할 수 있는 이유가 여기 있다. 낮을수록 좋다.

핵심 설계 패턴 1 — MuonAdamW: 파라미터 종류별로 다른 옵티마이저

setup_optimizer()가 파라미터를 5개 그룹 + shape별 Muon 그룹으로 쪼갠다. 임베딩·lm_head·스칼라(resid_lambdas·x0_lambdas)는 AdamW, 2D 행렬(어텐션/MLP 가중치)은 shape별로 묶어 Muon을 적용한다.

# train.py setup_optimizer() — 파라미터 그룹 분리 핵심 로직
for shape in sorted({p.shape for p in matrix_params}):
    group_params = [p for p in matrix_params if p.shape == shape]
    param_groups.append(dict(
        kind='muon', params=group_params, lr=matrix_lr,
        momentum=0.95, ns_steps=5, beta2=0.95, weight_decay=weight_decay,
    ))
optimizer = MuonAdamW(param_groups)

Muon 내부는 Polar Express 직교화를 쓴다 — 5차까지의 다항식 계수(polar_express_coeffs)로 그래디언트 행렬을 반복 근사해 직교 행렬에 가깝게 만든다(고전적 Newton-Schulz 반복의 개선판). 여기에 NorMuon 분산 축소(row/column 방향 2차 모멘트로 스텝 크기 정규화)와 cautious weight decay(그래디언트와 파라미터 부호가 같을 때만 decay 적용)까지 얹혀 있다. 옵티마이저 스텝 함수 자체가 @torch.compile(fullgraph=True)로 컴파일되며, 텐서를 CPU 0-D 스칼라로 유지해 하이퍼파라미터가 바뀔 때마다 재컴파일되는 것을 막는다.

핵심 설계 패턴 2 — Value Embedding + ResFormer 스타일 게이팅

일반 GPT는 각 레이어에서 K/V를 그 레이어의 입력에서만 계산한다. autoresearch는 홀수/짝수 레이어(has_ve)에 별도의 "Value Embedding" 테이블을 두고, 입력 의존적 게이트(ve_gate, sigmoid 기반)로 원래 V에 섞어 넣는다.

# CausalSelfAttention.forward() — Value Embedding 믹싱
if ve is not None:
    ve = ve.view(B, T, self.n_kv_head, self.head_dim)
    gate = 2 * torch.sigmoid(self.ve_gate(x[..., :self.ve_gate_channels]))
    v = v + gate.unsqueeze(-1) * ve  # 게이트 초기값=1.0(중립)이 되도록 0으로 초기화

이는 깊은 네트워크에서 초기 레이어의 원본 토큰 정보가 희석되는 문제를 완화하려는 ResFormer 계열 기법이다. 마지막 레이어는 항상 Value Embedding을 갖도록 강제된다(has_ve의 alternating 로직).

핵심 설계 패턴 3 — Sliding Window Attention (SSSL 패턴)

WINDOW_PATTERN = "SSSL"
# S = Sliding window (short, sequence_len//2) — 메모리 효율적 로컬 어텐션
# L = Long-range (full sequence)             — 장거리 의존성 포착
# 예: DEPTH=8이면 레이어 0~2=S, 3=L, 4~6=S, 7=L(마지막은 항상 L로 강제)

_compute_window_sizes()가 패턴 문자열을 레이어 수만큼 반복 적용해 각 레이어의 윈도우 크기를 미리 계산한다. Flash Attention 3의 window_size 인자로 그대로 전달돼, 대부분의 레이어는 절반 컨텍스트만 보고 일부(L)만 전체를 본다 — 연산량을 줄이면서 장거리 정보 흐름은 유지하는 절충안이다.

핵심 설계 패턴 4 — BOS-Aligned Best-Fit Packing

┌─────────────────────────── 시퀀스 길이 (2048+1) ──────────────────────┐ │ [BOS] doc1_tokens...... [BOS] doc2_short.. [BOS] doc3_cropped........ │ └──────────────────────────────────────────────────────────────────────┘ 1. 모든 문서 시작에 BOS 토큰을 붙인다. 2. "남은 공간에 통째로 들어가는 문서 중 가장 큰 것"을 best-fit으로 선택. 3. 들어갈 문서가 없으면 버퍼에서 가장 짧은 문서를 남은 공간만큼 잘라 정확히 채운다. 4. 결과: 패딩 토큰 0개, GPU 연산 100% 활용.

make_dataloader()는 이 패킹을 CPU pinned memory → GPU 논블로킹 복사로 겹쳐 처리하는 이중 버퍼(cpu_buffer/gpu_buffer) 구조까지 갖췄다. 데이터 로딩이 GPU 연산과 겹치도록(overlap) 설계된, 실무형 고성능 데이터 파이프라인이다.

핵심 설계 패턴 5 — Fixed Budget Evaluation: "무엇을 바꾸든 5분"

TIME_BUDGET=300(초)은 prepare.py고정 상수로 박혀 있고 절대 수정 대상이 아니다. 학습 루프는 step > 10(컴파일 워밍업 이후) 시점부터 실제 학습 시간을 누적하다가 예산을 넘기면 즉시 종료한다. 모델 크기·배치 크기·아키텍처가 무엇이든 같은 wall-clock 시간으로 맞춰지므로, val_bpb 하나로 공정 비교가 성립한다 — 이것이 3장에서 본 "코드 자유도 + 평가 공정성" 트레이드오프를 실제로 구현하는 장치다.

5디렉토리 구조 해부

"파일 10개, 로직은 3개" — 극단적으로 압축된 구조가 그 자체로 설계 메시지다.

autoresearch/ ├── prepare.py [불변 · 389줄] 데이터 다운로드 + 토크나이저 학습 + 런타임 유틸 │ ├─ 상수: MAX_SEQ_LEN=2048, TIME_BUDGET=300, EVAL_TOKENS │ ├─ download_data() / train_tokenizer() (1회성 준비) │ ├─ Tokenizer 클래스, make_dataloader() (BOS-aligned 패킹) │ └─ evaluate_bpb() ← "DO NOT CHANGE" 유일한 심판 │ ├── train.py [에이전트 전용 수정 대상 · 630줄] │ ├─ GPTConfig, CausalSelfAttention(FA3+RoPE+VE 게이팅) │ ├─ MLP(relu²), Block(RMSNorm 샌드위치), GPT 전체 모델 │ ├─ MuonAdamW (Polar Express + NorMuon + cautious WD) │ ├─ 하이퍼파라미터 블록(ASPECT_RATIO·DEPTH·LR 등, 직접 수정) │ └─ 학습 루프(그래디언트 누적 · LR/모멘텀 스케줄 · 로깅) │ ├── program.md [사람 전용 수정 대상 · 114줄] 에이전트 지시서 │ Setup → Experimentation(할 수 있는 것/없는 것) │ → Output format → Logging → Experiment loop(NEVER STOP) │ ├── analysis.ipynb results.tsv 분석 노트북 (pandas + matplotlib) ├── pyproject.toml uv 프로젝트 설정 — torch==2.9.1 등 의존성 고정 ├── uv.lock 의존성 잠금 파일(재현 가능한 설치 보장) ├── .python-version Python 버전 고정(3.10+) ├── .gitignore results.tsv·캐시·체크포인트 등 실험 산출물 제외 ├── progress.png README 상단 티저 이미지(실험 진행 시각화 예시) └── README.md 프로젝트 소개 · 설계 철학 · 저사양 튜닝 가이드

세 그룹으로 나눠 읽으면 이 구조의 의도가 선명해진다.

① 두 파이썬 파일의 "쓰기 권한" 비대칭. prepare.py(389줄)와 train.py(630줄)는 코드량은 비슷하지만 완전히 다른 신분이다. 전자는 "심판"(데이터·평가 기준), 후자는 "선수"(모델·학습법)다. 이 비대칭이 program.md의 "할 수 있는 것/없는 것" 규정과 정확히 대응한다.

② program.md는 코드가 아니라 "조직 규정"이다. Setup(브랜치 생성 규칙) → Experimentation(허용/금지 목록) → Output format(로그 파싱 규칙) → Logging(results.tsv 스키마) → Experiment loop(무한 반복 알고리즘)의 5단 구조로, 사람이 유일하게 편집하는 "코드가 아닌 코드"다.

③ 결과물은 의도적으로 git에서 제외된다. .gitignoreresults.tsv를 추적 대상에서 뺀다(program.md도 "do not commit the results.tsv file, leave it untracked"라고 명시). git 히스토리에는 "어떤 코드 변경이 keep됐는가"만 남고, 실험 로그(TSV)는 로컬에만 존재한다 — 커밋 로그를 깨끗하게 유지하려는 선택이다.

용어
nanochat과의 관계
autoresearch는 Karpathy의 다른 레포 nanochat(풀사이즈 LLM을 스크래치부터 학습·채팅까지 완주시키는 프로젝트)의 "단일 GPU용 학습 루프만 떼어내 단순화"한 파생작이다. README는 이를 "a simplified single-GPU implementation of nanochat"이라 명시한다. nanochat이 가진 CPU/MPS 폴백, 분산 학습, 추론 서버 등은 다 걷어내고 "5분 실험 단위"라는 새로운 목적에 맞게 재구성한 것이 이 레포다.

6학습 포인트 (기술별)

이 저장소에서 "무엇을 배울 수 있는가" — 개념 → 코드 위치 → 실습 아이디어.

학습 포인트 A

자율 에이전트 루프 설계 — "탐색 공간을 의도적으로 좁혀라"

에이전트에게 무제한 자유도를 주면 오히려 성능이 나빠진다는 것을 이 레포가 실증한다. 단일 파일 수정 + 고정 시간 예산 + 단일 메트릭이라는 세 가지 제약이 자율성과 안정성을 동시에 확보하는 방법을 보여준다. program.md의 "What you CAN/CANNOT do" 섹션이 이 철학의 코드화다.

실습: 자신의 프로젝트에 program.md 스타일 지시서를 작성해, Claude Code에게 "이 파일만 고쳐라 + 이 스크립트로만 검증하라 + 이 지표로만 판단하라"는 제약을 걸고 반복 개선 루프를 돌려보기.

학습 포인트 B

Muon 옵티마이저 수학 — Polar Express 직교화와 NorMuon

2D 가중치 행렬에만 직교화를 적용하는 기하학적 직관(행렬의 spectral norm을 균등화하면 학습이 안정된다), Newton-Schulz의 개선판인 Polar Express 다항식 반복, row/column 방향 2차 모멘트로 스텝 크기를 정규화하는 NorMuon까지 — muon_step_fused() 함수 40줄 안에 최신 옵티마이저 연구 세 가지가 압축돼 있다.

실습: polar_express_coeffs 5쌍의 계수를 직접 손으로 따라가며, X = a*X + X@B 반복이 어떻게 행렬을 직교 행렬에 수렴시키는지 작은 랜덤 행렬로 실험.

학습 포인트 C

고성능 데이터 파이프라인 — 패딩 0%와 이중 버퍼링

BOS-aligned best-fit packing으로 패딩 낭비를 없애는 법, pinned memory + non_blocking GPU 복사로 데이터 로딩과 연산을 겹치는(overlap) 법, Parquet + pyarrow로 대용량 데이터셋을 메모리에 다 안 올리고 스트리밍하는 법을 make_dataloader() 하나에서 모두 배울 수 있다.

실습: EVAL_TOKENS·buffer_size를 줄여 작은 데이터로 make_dataloader()를 단독 실행해 보고, 생성된 배치에서 실제로 패딩 토큰이 0개인지 직접 검증.

학습 포인트 D

torch.compile 실전 활용 — 왜 옵티마이저 스텝까지 컴파일하나

모델 forward뿐 아니라 adamw_step_fused/muon_step_fused 옵티마이저 함수 자체를 @torch.compile(dynamic=False, fullgraph=True)로 컴파일한다. 하이퍼파라미터(lr·momentum 등)를 파이썬 스칼라가 아닌 0-D CPU 텐서로 유지해, 값이 바뀔 때마다 그래프가 재컴파일되는 것을 막는 실전 트릭이 핵심.

실습: MuonAdamW.__init___adamw_lr_t 같은 텐서들을 일반 파이썬 float로 바꿔보고, torch._dynamo 로그로 재컴파일 횟수가 어떻게 늘어나는지 비교.

학습 포인트 E

공정한 벤치마크 설계 — val_bpb가 왜 vocab-size-independent 인가

모델을 비교할 때 흔히 쓰는 perplexity는 vocab_size가 바뀌면 직접 비교가 불가능하다. evaluate_bpb()토큰이 아니라 바이트를 분모로 써서 이 문제를 해결한다. "메트릭 설계 자체가 실험의 자유도를 결정한다"는 ML 연구 방법론의 핵심 교훈.

실습: VOCAB_SIZE를 8192에서 1024로 바꿔 토크나이저를 재학습한 뒤, 같은 모델로 perplexity와 bpb를 각각 계산해 두 지표가 어떻게 다르게 움직이는지 비교.

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

공식 지원은 "단일 NVIDIA GPU"뿐 — 그 외 플랫폼은 커뮤니티 포크가 메운다.

항목공식 요구/권장
GPU단일 NVIDIA GPU 필수(README: "tested on H100"). CPU/MPS는 공식 미지원
VRAMDEPTH=8 기본 설정 기준 수십 GB대(모델·배치 크기에 따라 가변, program.md 예시 로그 기준 peak_vram_mb≈45,000 근방)
Python3.10 이상(.python-version·pyproject.toml 모두 >=3.10)
CUDA12.8 인덱스(pytorch-cu128) — PyTorch 2.9.1과 짝을 맞춘 버전
필수 도구uv(패키지 매니저) · git(실험 버전 관리 필수 — keep/revert 루프의 전제)
디스크데이터 셰도 다운로드량에 비례(최대 6,542개 Parquet 파일, --num-shards로 조절 가능)
네트워크최초 prepare.py 실행 시 HuggingFace에서 데이터 다운로드 필요(이후 오프라인 학습 가능)

저사양 환경 튜닝 (README 공식 가이드 요약)

README는 "MacBook 등에서 시도하고 싶다면" 다음 7가지를 권장한다. ① 저엔트로피 데이터셋(TinyStories) 사용 → ② VOCAB_SIZE 축소: 8192 → 1024(또는 바이트 레벨 256) → ③ MAX_SEQ_LEN 대폭 축소(256 등) → ④ 축소분만큼 DEVICE_BATCH_SIZE 소폭 증가로 보상 → ⑤ EVAL_TOKENS 축소 → ⑥ DEPTH를 8에서 4로 감소 → ⑦ WINDOW_PATTERN="L"(SSSL의 alternating 패턴은 비효율적일 수 있음) → ⑧ TOTAL_BATCH_SIZE를 2의 거듭제곱 유지하며 대폭 축소(예: 2**14).

커뮤니티 포크 (플랫폼별, README "Notable forks" 공식 링크)

포크대상 플랫폼
miolini/autoresearch-macosmacOS
trevin-creator/autoresearch-mlxmacOS (Apple Silicon MLX)
jsegov/autoresearch-win-rtxWindows + RTX GPU
andyluo7/autoresearchAMD GPU
현실적 주의
"README의 플랫폼 확장은 공식 지원 대상이 아니다"

Karpathy는 README에서 명확히 선을 긋는다 — "I'm not 100% sure that I want to take this on personally right now." CPU/MPS 지원이 원론적으로 가능하지만 코드 비대해짐(bloat)을 우려해 본인이 직접 손대지 않겠다는 것. 대신 nanochat(부모 프로젝트)이 Flash Attention 3 폴백 구현·범용 디바이스 지원을 갖고 있으니, 다른 플랫폼을 시도하려면 nanochat 소스를 참고하거나 위 커뮤니티 포크를 쓰라고 안내한다. Fork가 12.9k에 달하는 이유 중 상당수가 "내 GPU/OS에서 돌리기 위한 포크"로 추정된다.

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

난이도별로 손을 움직여 보는 5가지.

입문 ★☆☆☆☆

과제 1 · 초급

기본 실행 체험 — 베이스라인 val_bpb 기록

클론 후 uv로 설치하고 5분 학습을 1회 돌려 베이스라인 수치를 확보한다. GPU가 없다면 --num-shards 2로 데이터만 축소해 파이프라인 구조를 우선 확인한다.

git clone https://github.com/karpathy/autoresearch.git
cd autoresearch
curl -LsSf https://astral.sh/uv/install.sh | sh
uv sync
uv run prepare.py --num-shards 2   # 테스트용 2개 셰도만
uv run train.py                     # 5분 학습 1회, val_bpb 확인

초중급 ★★☆☆☆

과제 2 · 초중급

Keep/Revert 루프를 손으로 직접 재현

에이전트 없이 사람이 program.md의 알고리즘을 그대로 따라해 본다. 학습률 하나를 바꾸고, 결과가 개선인지 악화인지에 따라 commit 또는 reset을 결정한다.

git checkout -b experiment/manual-tuning
uv run train.py > run_baseline.log 2>&1
grep "^val_bpb:" run_baseline.log   # 베이스라인 기록
# train.py에서 MATRIX_LR = 0.04 → 0.06으로 수정 후
git commit -am "experiment: increase muon matrix_lr to 0.06"
uv run train.py > run_exp1.log 2>&1
grep "^val_bpb:" run_exp1.log
# 개선이면 그대로 두고(keep), 악화면:
git reset --hard HEAD~1              # revert
과제 3 · 중급

나만의 program.md 작성 후 에이전트 자율 루프 실행

기존 program.md를 읽고 자신만의 연구 전략을 추가한다. 예: "학습률 스케줄만 최적화하라" 또는 "WINDOW_PATTERN과 DEPTH의 상호작용을 우선 탐색하라" 같은 지시를 써넣고, Claude Code에게 실험 3~5회의 짧은 루프를 돌려보게 한다(무제한 대신 회수를 제한해 첫 체험을 안전하게).

고급 ★★★★☆

과제 4 · 고급

MuonAdamW 옵티마이저 직접 뜯어보기

muon_step_fused()의 Polar Express 직교화 루프를 작은 랜덤 행렬(예: 8×4)로 떼어내 별도 스크립트로 실행하고, 반복이 늘어날수록 X.mT @ X가 단위 행렬에 얼마나 가까워지는지 직접 측정한다. NorMuon 분산 축소 부분을 주석 처리하고 val_bpb 변화를 비교하는 ablation도 시도해 본다.

과제 5 · 최고급

Value Embedding / SWA 패턴을 바꿔가며 아키텍처 실험

WINDOW_PATTERN"SSSL""L"(전체 어텐션만) → "SSSSSSSL"(더 긴 로컬 구간)으로 바꿔가며 val_bpb와 mfu_percent(GPU 활용률)를 함께 기록해, "품질 vs 속도" 트레이드오프 곡선을 직접 그려본다. 나아가 has_ve()의 alternating 규칙을 바꿔 Value Embedding을 모든 레이어에 적용했을 때와 비교하는 것도 좋은 아키텍처 탐색 연습이다.

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

5주 커리큘럼 — Transformer 기초부터 자기만의 자율 연구 루프 설계까지.

주차주제구체적 목표
1주차기초 다지기Transformer/Attention 복습, PyTorch autograd·nn.Module·torch.compile 기초, BPE 토크나이저 원리, README·program.md 정독
2주차핵심 구현 라인별 분석prepare.py(다운로드→토크나이저→dataloader→evaluate_bpb) 전체 정독, train.py의 모델 정의(GPT·CausalSelfAttention·MLP) 정독
3주차옵티마이저 심화Muon 원 논문·구현 이해, Polar Express 직교화 수식 유도, NorMuon/cautious weight decay가 왜 필요한지 ablation으로 검증
4주차실전 실험 + keep/revert로컬(또는 클라우드 GPU)에서 실제 학습 실행, 하이퍼파라미터 3개 이상 수동 실험, analysis.ipynb로 결과 시각화, 자신만의 program.md 작성 후 에이전트 자율 실행
5주차확장 및 응용nanochat과 비교 분석(무엇을 걷어내고 무엇을 남겼나), 다른 도메인(코드 생성·한국어 텍스트)에 동일 패턴 적용, keep/revert 루프를 자신의 비-ML 프로젝트(성능 튜닝 등)에 이식
곁들이면 좋은 배경 지식
nanochat · Muon 옵티마이저 계보 · SKILL.md 계열 에이전트 지시서

autoresearch는 세 흐름이 만나는 지점이다. nanochat(같은 저자의 모체 프로젝트, 더 넓은 플랫폼 지원과 추론까지 포함), Muon 옵티마이저 계보(Keller Jordan의 원작 → NorMuon·Polar Express 등 커뮤니티 개선판이 빠르게 이어지는 2025~2026년 최전선 연구), 그리고 "마크다운으로 에이전트를 프로그래밍한다"는 Claude Code SKILL.md류 패턴. 이 셋을 함께 이해하면 autoresearch가 왜 지금 이 형태로 만들어졌는지가 훨씬 잘 보인다.

10핵심 키워드 사전

이 프로젝트를 읽을 때 반복 등장하는 용어 정리.

키워드
val_bpbValidation Bits Per Byte. 어휘 크기 독립적 언어모델 평가 지표. 낮을수록 좋음
keep / revert실험 결과가 개선되면 git commit 유지(keep), 악화면 git reset(revert)하는 핵심 루프
program.md사람이 에이전트에게 연구 규칙·허용범위·종료조건을 전달하는 마크다운 지시서
TIME_BUDGET모든 실험을 동일하게 만드는 고정 5분(300초) 학습 시간 예산
Muon2D 가중치 행렬 전용 옵티마이저. 그래디언트를 직교화해 학습 안정성·속도 향상
Polar ExpressNewton-Schulz 반복의 개선판. 5차 다항식 계수로 행렬을 직교 행렬에 근사
NorMuonMuon 스텝에 분산 축소(2차 모멘트 정규화)를 더해 업데이트 크기를 안정화하는 기법
Cautious weight decay그래디언트와 파라미터 부호가 같을 때만 weight decay를 적용하는 보수적 정규화
Value Embedding (VE)일부 레이어에 별도 임베딩 테이블을 두고 게이트로 V에 섞는 ResFormer 계열 기법
SWA (Sliding Window Attention)일부 레이어만 절반 컨텍스트를 보게 해 연산을 줄이는 어텐션 패턴(SSSL 등)
BOS-aligned packing문서마다 BOS 토큰을 붙이고 best-fit으로 빈틈없이 채워 패딩을 없애는 패킹 기법
RoPERotary Position Embedding. 상대 위치를 회전 변환으로 인코딩
RMSNorm평균 빼기를 생략한 단순화된 LayerNorm 변형. autoresearch는 파라미터 없는 F.rms_norm 사용
relu²ReLU 출력을 제곱해 희소성을 높이는 MLP 활성함수 변형
MFU (Model FLOPs Utilization)이론적 최대 FLOPS 대비 실제 달성 비율. GPU 효율을 재는 지표
torch.compile(fullgraph=True)중간에 그래프가 끊기지 않고 통째로 컴파일되도록 강제하는 PyTorch 옵션
uvAstral의 초고속 Python 패키지 매니저. autoresearch의 유일한 의존성 관리 도구
climbmix-400b-shuffleautoresearch 기본 학습 데이터셋. HuggingFace 호스팅, 최대 6,542개 Parquet 셰도
nanochatKarpathy의 풀사이즈 LLM 학습 프로젝트. autoresearch의 모체(단일 GPU로 단순화한 파생작)

11참고 링크

원본을 직접 확인하고 싶을 때.