WARP: 2.78조 파라미터 Kimi K3를 64GB 맥북에서 실행하는 C 기반 추론 엔진

WARP 소개

프런티어급 오픈 모델이 공개될 때마다 반복되는 계산이 있습니다. 가중치 파일이 1TB를 넘으면 개인 장비에서는 열어볼 수조차 없고, 결국 증류하거나 가지치기한 축소판을 기다리거나 클라우드 API를 쓰는 선택지만 남습니다. 램에 모델을 통째로 올려야 한다는 전제가 이 계산을 지배해 왔습니다. 그런데 전문가 혼합(Mixture of Experts) 구조에서는 토큰 하나를 만드는 데 전체 파라미터의 일부만 실제로 쓰입니다. 나머지 대부분은 그 순간 램을 차지하고 있을 뿐입니다.

WARP는 그 전제를 바꿔 보려는 추론 엔진입니다. 모델에서 항상 쓰이는 공용 부분만 램에 올려 두고, 토큰마다 선택된 전문가만 디스크에서 직접 읽어오며, 남은 램은 한도가 정해진 전문가 캐시로 씁니다. C로 작성되어 있고 추론 경로에 외부 런타임 의존성이 없습니다. 현재 목표는 2.78조 파라미터의 Kimi K3를 소비자용 하드웨어에서 돌리는 것이고, 64GB 맥북 프로에서 초당 약 0.6 토큰이 측정됐습니다. 증류하거나 가지치기한 축소판이 아니라 전체 모델입니다.

프로젝트가 밝히는 개발 방식도 특이합니다. 아이디어와 가설, 우선순위, 테스트, 결정은 사람이 하고 코드는 LLM이 작성한다고 적혀 있으며, 이 규모에서 새 알고리즘을 빠르게 시험하려면 그 방법밖에 없다고 설명합니다. 프로젝트 이름은 원래 WASTE였고 지금은 WARP(Weight-Aware Runtime and Paging)로 바뀌었지만 CLI 실행 파일과 컨테이너 확장자에는 여전히 waste 가 남아 있습니다. 최신 릴리즈는 v0.6.7 입니다. 본 게시물에서는 이 엔진이 램과 디스크를 나누는 방식, 실측 성능과 그 한계, 그리고 직접 실행하려면 무엇이 필요한지를 정리합니다.

WARP가 모델을 램에 올리지 않는 방법

Kimi K3는 2.78조 파라미터를 가지고 있지만 토큰 하나에 활성화되는 것은 약 4%입니다. WARP는 이 성질을 저장 구조에 그대로 반영합니다.

컨테이너는 전문가 하나가 정렬된 읽기 한 번에 대응하도록 배치되어 있습니다. 이 읽기는 계산과 겹쳐서 진행되고, 남은 램은 한도가 정해진 전문가 캐시가 됩니다. 여기에 미리 읽기 라우터가 다음 계층에 필요할 전문가를 예측해 읽기를 앞당깁니다. 실제 선택은 원래 라우터가 그대로 하므로 예측은 타이밍만 바꾸고 결과는 바꾸지 않습니다.

양자화는 부위별로 다르게 적용됩니다. 전문가는 3비트 잔차 벡터 양자화(Residual Vector Quantization)를 쓰고, 값의 변화에 민감한 공용 가중치는 4비트 또는 8비트로 남깁니다. K3의 선형 어텐션과 압축된 잠재 KV 캐시도 크게 기여하는데, 4K 문맥 기준 KV 캐시가 11.25GB가 아니라 약 0.21GB로 줄어듭니다. 이 조합 덕분에 K3를 여는 데 29.19GB가 필요하고 나머지 램은 반복적인 디스크 읽기를 피하는 데 쓰입니다.

기존 로컬 실행 방식과 WARP의 차이

같은 "큰 모델을 작은 장비에서"라는 목표를 두고 흔히 쓰이는 방법과 접근이 다릅니다.

항목 WARP 축소판을 쓰는 방식 램으로 전부 올리는 방식
모델 전체 2.78조 파라미터 그대로 증류·가지치기한 축소 모델 전체 모델이지만 장비가 감당해야 함
가중치 위치 대부분 NVMe, 공용 부분만 램 전부 램 전부 램
병목 저장장치 읽기 대역폭 없음 램 용량
품질 원본 모델의 출력 축소로 인한 품질 변화 원본 모델의 출력
속도 초당 0.45~0.62 토큰 상대적으로 빠름 상대적으로 빠름

속도는 분명한 대가입니다. 반대로 얻는 것은 축소판이 아닌 원본 모델을 로컬에서 돌린다는 점이고, 개발팀은 모든 계층을 PyTorch 참조 구현과 대조해 최종 로짓이 3.6e-06 이내, 비전 타워가 2.3e-06 이내로 일치한다고 보고합니다.

WARP는 누구에게 유용한가

프런티어급 모델의 출력을 외부로 내보내지 않고 확인해야 하는 연구·보안 환경, 또는 대규모 MoE 모델의 실행 구조 자체를 연구하는 사람에게 맞습니다. 초당 0.6 토큰은 대화형 사용에는 느리지만, 배치 처리나 검증 목적이라면 감수할 만한 속도입니다. 반대로 응답 속도가 중요한 서비스나 코딩 보조 용도라면 지금 상태로는 적합하지 않고, 저장장치도 요구가 큽니다. 엔진만 먼저 시험해 보고 싶다면 컨테이너가 19GB이고 램 1.32GB로 초당 약 10.6 토큰이 나오는 Kimi-Linear 48B가 훨씬 가벼운 출발점입니다.

모델 컨테이너 최소 램 디코딩 속도
Kimi K3 2.78T 982 GB 29.19 GB 0.45~0.62 tok/s
Kimi-Linear 48B 19 GB 1.32 GB 10.62 tok/s

측정 환경은 M5 Pro를 탑재한 64GB 맥북 프로이고 컨테이너는 내장 SSD에 두었습니다.

WARP의 캐시 설정에서 드러나는 역설

이 프로젝트에서 가장 실용적인 관찰은 캐시를 키운다고 빨라지지 않는다는 점입니다. 한 프로세스 안에서 네 가지 캐시 크기를 측정한 결과입니다.

전문가 캐시 적중률 디코딩 속도
3.32 GB 29.1% 0.56~0.58 tok/s
17.32 GB 36.2% 0.63 tok/s
23.32 GB 38.4% 0.07~0.09 tok/s
29.32 GB 41.3% 0.07~0.08 tok/s

적중률은 계속 올라가고 읽는 바이트 수도 줄어드는데 처리량은 여덟 배 가까이 떨어집니다. 엔진은 자기 예산 안에 있지만 기계가 그렇지 않아서, 캐시 적중이 페이지 폴트로 바뀌는 구간입니다. 그래서 저장소는 이유가 없으면 --budget 을 직접 설정하지 말라고 안내합니다. 기본값으로 두면 엔진이 안전한 예산을 고르고 그 값을 보고하며, 모델의 하한선 아래에서는 시작 자체를 거부합니다. 컨테이너 안에서 실행하면 호스트 램이 아니라 cgroup 한도를 기준으로 계산합니다.

토큰당 전문가 수도 컨테이너 매니페스트의 num_experts_per_token 으로 조절할 수 있습니다. K3의 기본값은 16이며, 8로 줄이면 속도가 1.49배가 되고 KL 발산은 0.037로 올라갑니다. 4로 줄이면 속도는 더 오르지만 몇 토큰 만에 프롬프트를 따라가지 못한다고 기록되어 있어, 기본값은 16으로 유지됩니다.

저장장치 성능은 그대로 속도에 반영됩니다. K3에서 캐시가 비어 있는 토큰 하나는 약 17GB의 전문가를 읽으며, 측정에 쓰인 내장 SSD는 12.78GB/s를 유지했지만 USB 외장 케이스는 0.94GB/s에 그쳤습니다. 변환된 컨테이너는 내장 NVMe에 두어야 합니다.

WARP 빌드와 실행

빌드에는 C11 컴파일러와 make 만 있으면 됩니다. macOS와 Linux를 지원하고 Windows는 MinGW-w64로 빌드하며, 현재 CPU 추론 경로에는 BLAS나 파이썬, CUDA 같은 외부 의존성이 없습니다.

git clone https://github.com/sqliteai/warp
cd waste
make
make check

저장소 이름이 바뀐 뒤라 실제로 만들어지는 디렉토리 이름은 warp 입니다. makewaste CLI와 libwaste.a 를 만들고, make check 는 작은 합성 모델을 만들어 검사하므로 가중치를 내려받지 않습니다.

K3를 실제로 돌리려면 64GB 램이 권장되고 4K 문맥 기준 29.19GB가 하한선입니다. 변환된 컨테이너용으로 약 1TB의 내장 NVMe 저장 공간이 필요하며, 공개된 가중치를 직접 변환한다면 1.42TB의 임시 저장 공간이 추가로 듭니다. 변환은 세 개의 워커로 약 4.7시간이 걸립니다.

# 원본 가중치 내려받기 전 필요한 공간 확인
tools/fetch_weights.sh --dest /Volumes/staging/k3 --dry-run

# 원본 가중치 내려받기
tools/fetch_weights.sh --dest /Volumes/staging/k3

# 변환 (출력은 내장 SSD에)
uv run --with torch --with safetensors python tools/convert.py \
    --src /Volumes/staging/k3 \
    --out ~/models/k3.waste \
    --jobs 3

파이썬과 PyTorch, safetensors는 변환과 검증에만 쓰이고 추론에는 전혀 필요하지 않습니다. 직접 변환하는 대신 이미 변환된 982GB 컨테이너를 BitTorrent로 받는 경로도 안내되어 있는데, 이 경우 1.42TB 원본 다운로드와 4.7시간의 변환, 임시 저장 공간이 모두 생략됩니다.

실행은 세 가지 명령으로 나뉩니다.

./waste plan ~/models/k3.waste                          # 메모리 계획 확인
./waste run  ~/models/k3.waste "The capital of France is" -n 32
./waste chat ~/models/k3.waste                          # 대화형 모드

Kimi K3는 멀티모달 모델이라 --image 를 이미지마다 한 번씩 붙여 함께 넣을 수 있습니다. 다만 이미지 한 장이 여러 프롬프트 위치로 확장되는 구조라 비용이 큽니다. 기본 패치 예산에서 896×896 이미지는 256개 위치를 차지하고, 각 위치가 텍스트 위치와 똑같이 언어 모델을 통과하므로 현재 측정에서 위치당 약 2.8초가 듭니다.

./waste run ~/models/k3.waste "Describe this image" --image photo.jpg

서버도 선택 사항으로 제공되며 OpenAI 채팅 완성 API를 구현합니다. 스트리밍과 도구 호출, 구조화된 출력, 추론 제어, 이미지를 지원합니다.

make libwaste.dylib                 # Linux 에서는 libwaste.so
python3 -m serve ~/models/k3.waste --port 8000

엔진 자체를 다른 프로그램에 넣을 수도 있습니다. CLI와 서버 모두 src/waste.h 의 공개 API를 사용하며, 추론 경로는 libc와 pthreads에만 의존합니다.

WARP 프로젝트의 현재 상태

포맷과 API는 아직 고정되지 않았고 소프트웨어가 빠르게 바뀌는 중이라, 릴리즈 전 대규모 QA를 돌리지만 불안정한 동작이 있을 수 있다고 밝히고 있습니다. 현재 CPU 경로가 이 작업 부하에서 가장 빠른 구현으로 측정됐지만 최종 답이라고 보지 않으며, CUDA와 Metal 같은 하드웨어별 최적화는 아직 탐색 대상으로 남아 있습니다.

기록 방식도 눈여겨볼 만합니다. 측정값은 마케팅 수치가 아니라 실험 결과로 다루어져 하드웨어와 컨테이너, 설정, 커밋에 함께 묶여 기록되고, 불안정한 값은 범위로 보고되며, 나중에 틀린 것으로 밝혀진 결과도 지우지 않고 그대로 남깁니다. 실패한 아이디어와 부정적 결과는 docs/LEARNED.md 에 모아 두고, 최적화를 제안하기 전에 이 문서를 먼저 읽으라고 안내합니다.

WARP의 라이선스

WARP는 Apache License 2.0으로 공개되어 있어 개인 및 상업적 목적으로 자유롭게 사용할 수 있습니다.

:books: WARP 엔진 설계 문서

:github: WARP 프로젝트 GitHub 저장소

더 읽어보기




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

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