Redis 창시자가 직접 C로 짠 LLM 추론 엔진 — 왜 지금 '모델 전용 엔진'이 유행일까
Redis를 만든 개발자 antirez(살바토레 산필리포)가 또 이상한 걸 만들었습니다. MiniMax-H3 모델 하나만 돌리는 추론 엔진을 C로 직접 짠 겁니다. llama.cpp도 있고 Ollama도 있고 MLX도 있는 시대에 말이죠. 그런데 이 “굳이"가 요즘 로컬 AI 판에서 벌어지는 일을 꽤 정확하게 보여줍니다.
먼저 하나 짚고 갑니다. 이 주제로 커뮤니티 반응을 훑어봤는데, 최근 30일 안에 잡히는 레딧 스레드가 사실상 없었습니다. 아직 소수 개발자 사이에서만 도는 이야기라는 뜻입니다. 그래서 오늘 글은 커뮤니티 여론을 정리하기보다, 이 현상이 왜 지금 나오는지를 풀어보는 쪽에 무게를 둡니다.
다 되는 엔진은 하나도 빠르지 않다
llama.cpp는 위대한 프로젝트입니다. 수백 개 모델 아키텍처를 지원하고, CUDA부터 Vulkan, Metal, ROCm까지 백엔드를 다 갖췄습니다. 문제는 그 범용성을 공짜로 얻은 게 아니라는 겁니다.
모델 하나를 추가할 때마다 추상화 레이어가 한 겹씩 쌓입니다. 어텐션 종류가 늘어나고 KV 캐시 처리 방식이 갈리고 양자화 포맷이 파생됩니다. 코드베이스는 수십만 줄로 불어났고, 특정 모델 하나만 놓고 보면 실제로 쓰이지 않는 분기 처리가 실행 경로 곳곳에 끼어 있습니다.
모델 하나만 겨냥하면 이야기가 달라집니다. 텐서 shape이 컴파일 타임에 고정됩니다. 메모리 레이아웃을 그 모델의 어텐션 패턴에 맞춰 통째로 설계할 수 있습니다. 조건 분기가 사라지니 커널이 단순해지고, 단순해진 커널은 GPU에서 빠릅니다. antirez가 h3.c에서 노린 게 정확히 이 지점입니다.
MiniMax-H3라는 선택이 힌트다
왜 하필 H3 계열일까요.
MiniMax의 H3 아키텍처는 하이브리드 어텐션을 씁니다. 전 레이어에 풀 어텐션을 쓰는 대신, 선형 어텐션과 소프트맥스 어텐션을 섞어 배치합니다. 긴 컨텍스트에서 KV 캐시가 폭발하는 문제를 구조부터 줄여보려는 설계입니다.
이런 신형 구조는 기존 엔진에 잘 안 맞습니다. llama.cpp의 내부 추상화는 트랜스포머 표준 어텐션을 전제로 다듬어져 왔습니다. 하이브리드 구조를 여기 끼워 넣으려면 기존 인터페이스를 우회하거나 특수 케이스를 새로 파야 합니다. 지원이 늦어지고, 지원이 돼도 최적화가 덜 된 상태로 굴러갑니다.
그래서 개발자들이 기다리는 대신 직접 씁니다. 모델 아키텍처가 갈라질수록 범용 엔진은 늦게 따라오고, 그동안 전용 엔진이 벌어놓는 격차는 커집니다. antirez 개인의 취향 문제가 아니라 구조가 미는 방향입니다.
애플 실리콘이 조용히 기본값이 된 이유
h3.c가 Metal을 타깃으로 삼은 것도 우연이 아닙니다.
로컬에서 큰 모델을 돌릴 때 진짜 병목은 연산 속도가 아니라 메모리 대역폭과 용량입니다. 토큰 하나 뽑을 때마다 모델 가중치 전체를 메모리에서 읽어 와야 하니까요. 엔비디아 소비자용 GPU는 여기서 걸립니다. RTX 5090이 32GB, 그 아래는 16~24GB 선입니다. 70B급 모델을 제대로 올리기엔 부족합니다.
애플의 통합 메모리는 이 구도를 뒤집습니다. CPU와 GPU가 같은 메모리 풀을 씁니다. M4 Max는 128GB, M3/M4 Ultra 계열은 512GB까지 올라갑니다. 대역폭도 M4 Max가 546GB/s, Ultra급은 800GB/s를 넘습니다. 데이터센터 GPU에 비하면 낮은 수치입니다. 그런데 100GB짜리 모델을 전부 메모리에 올릴 수 있다면 대역폭 열세쯤은 묻힙니다. 애초에 못 올리면 속도 논쟁 자체가 성립하지 않으니까요.
여기에 하나 더 있습니다. 노트북에서 조용히 돌아가고 전기는 60W쯤 먹습니다. 서버실을 따로 둘 일도 없습니다. 개인 개발자가 자기 책상에서 70B 모델을 만지려면 현실적으로 맥밖에 없어진 겁니다. 로컬 AI 커뮤니티의 무게중심이 여기로 넘어간 건 취향이 아니라 산수의 결과입니다.
손으로 짠 C 코드가 다시 매력적인 이유
역설적인 장면이 하나 있습니다. AI가 코드를 대신 써주는 시대에, 최고 수준 개발자들은 오히려 저수준 C 코드를 손으로 깎고 있습니다.
antirez는 원래 이런 사람입니다. Redis도 의존성 거의 없는 C 코드였고, 성능이 필요한 곳은 직접 자료구조를 설계했습니다. h3.c에서 반복하는 것도 같은 철학입니다. 문제 영역을 좁게 잡고, 추상화를 걷어내고, 하드웨어에 직접 붙는다.
실용적인 이득도 있습니다. 수십만 줄짜리 프레임워크는 읽어서 이해하기 어렵습니다. 단일 모델 전용 엔진은 코드 규모가 작아서 한 사람이 전체를 머릿속에 담을 수 있습니다. Andrej Karpathy의 llama2.c가 그랬듯, 이런 프로젝트는 성능 도구인 동시에 교재입니다. 트랜스포머가 실제로 어떻게 계산되는지 알고 싶다면, 논문 열 편보다 이런 코드 한 벌이 빠릅니다.
그래서 llama.cpp는 끝났나
아닙니다.
전용 엔진은 딱 하나의 모델만 돕니다. 모델이 업데이트되면 다시 손봐야 합니다. 양자화 옵션도 서버 모드도 각종 통합도 직접 만들어야 합니다. 실무에서 여러 모델을 갈아 끼워 가며 써야 하는 사람에게는 답이 아닙니다. Ollama가 잘나가는 이유는 성능이 최고여서가 아니라 귀찮은 걸 대신 해주기 때문입니다.
현실적인 구도는 이렇게 갈립니다. 범용 엔진은 넓게 커버하는 인프라로 남습니다. 전용 엔진은 특정 모델을 극한까지 짜내거나 새 아키텍처를 먼저 찔러볼 때 나서는 첨병입니다. 그리고 전용 엔진에서 먹힌 최적화 기법이 나중에 범용 엔진으로 역수입됩니다. 실제로 llama.cpp의 여러 커널 개선이 그런 경로로 들어왔습니다.
마무리
지금 로컬 AI 판에서 벌어지는 일은 소프트웨어가 하드웨어 쪽으로 다시 내려가는 과정입니다. 모델 구조가 빠르게 갈라지면서 범용 추상화가 따라가지 못하고, 그 틈에서 손으로 깎은 전용 코드가 다시 경쟁력을 얻습니다.
지금 여러분의 로컬 환경에서 병목은 어디입니까. 모델 성능입니까, 아니면 그 모델을 돌리는 소프트웨어 계층입니까. 답이 후자 쪽으로 기운다면, antirez가 왜 굳이 C를 다시 열었는지는 설명이 필요 없을 겁니다.
댓글
댓글을 불러오는 중...