3 minute read

저장 포맷이 느리면 모델도 느리다

16살 고등학생이 만든 LLM 저장 포맷이 GGUF를 두 배 속도로 바른다길래 처음엔 어그로인 줄 알았다.

로컬에서 LLM을 돌릴 때 누구나 한 번쯤 영혼의 타협을 한다. 정확도를 얼마나 희생하고 속도를 챙길 것인가. Q4, Q8 같은 GGUF 양자화가 그 타협의 산물이다. 전체 가중치를 무식하게 균일하게 압축하고, 지능이 약간 깎여 나가는 걸 눈물로 삼킨다. 그동안 이 방식 말고는 다른 길이 없는 줄 알았다.

그런데 모델 저장 포맷 자체가 병목이라는 생각은 왜 아무도 안 해봤을까.

GGUF나 Safetensors는 훌륭한 포맷이다. 가중치를 안전하게 디스크에 보관하고 불러오는 데는 도가 텄다. 하지만 애초에 설계될 때 “런타임에서 메모리로 얼마나 총알같이 땡겨올 수 있는가”는 1순위가 아니었다. 보관 효율에만 목을 맸지 실시간 추론 속도 최적화는 뒷전이었다는 소리다. 그래서 로더는 파일을 열 때마다 어디서부터 읽고 어떻게 메모리 매핑할지를 매번 끙끙대며 계산해야 했다.

그런데 r/LocalLLM에 눈이 번쩍 뜨이는 프로젝트가 하나 등판했다. ThinTensor라는 녀석인데, 확장자는 .thin이다. 핵심 아이디어가 진짜 무릎을 탁 치게 만든다.

텐서마다 다르게, 역할을 보고 정밀도를 정한다

ThinTensor의 알파이자 오메가는 역할 기반 정밀도 계획(role-aware precision planning)이다. 모든 텐서를 바보처럼 똑같은 비율로 압축하지 않는다.

어텐션(Attention) 레이어, LM Head, KV Cache처럼 모델의 지능과 직결된 초민감 구역은 BF16 원본 그대로 보존한다. 반면 MLP 경로의 gate/up 텐서처럼 대충 뭉개도 출력에 큰 영향이 없는 구역은 FP8이나 MXFP4로 가차 없이 다이어트를 시킨다. 모델의 “판단력”은 1도 안 건드리면서 덩치만 쏙 빼는 영리한 접근이다.

이렇게 하려면 파일 포맷 자체가 각 텐서의 족보를 꿰고 있어야 한다. ThinTensor의 Rust 구조체를 뜯어보면 의도가 명확하다.

pub struct Header {
    pub header_len: u32,
    pub version: u32,
    pub manifest_off: u64,
    pub manifest_len: u64,
    pub page_table_off: u64,
    pub page_count: u64,
    pub data_off: u64,
    pub archive_hash: [u8; 32],
}

로더가 파일을 열 때 헤매지 않는다. 헤더 읽고 매니페스트로 다이렉트 점프한 뒤 페이지 테이블로 원시 데이터를 메모리에 직결 매핑한다. 쓸데없는 디스크 탐색 비용을 극단적으로 도려냈다.

숫자로 보는 성능

벤치마크 숫자가 진짜 살벌하다. 허깅페이스 BF16 원본과 비교한 결과다.

모델 ThinTensor tok/s HF tok/s 속도 향상 코사인 유사도
SmolLM3-3B 94.00 47.92 (Q8) 1.97x 0.9994
Qwen2.5-3B-Instruct 93.08 48.18 1.93x 0.9989
Qwen3.5-0.8B 115.91 64.33 1.80x 0.9998
Phi-4-mini-instruct 53.80 39.09 1.38x 0.9999
TinyLlama-1.1B-Chat 180.28 132.36 1.36x 0.9978

코사인 유사도 0.999면 사실상 원본 모델과 100% 동일한 대답을 내놓는다는 뜻이다.

진짜 충격적인 건 GGUF와의 맞다이다. SmolLM3-3B를 Ollama GGUF Q8로 돌리면 44 tok/s에 코사인 유사도가 0.95 언저리인데, ThinTensor는 같은 모델로 94 tok/s를 찍으면서 유사도 0.999를 방어했다. 속도는 2배 이상 빠른데 정밀도 손실은 오히려 훨씬 적다.

물론 특정 모델에 하드코딩 수준의 최적화를 때려 박은 3주 차 프로젝트라는 점은 감안해야 한다. 모든 모델에서 무조건 2배가 터진다고 설레발칠 단계는 아니다.

TRT와의 차이 — 컴파일 없이 그냥 돌린다

TensorRT(TRT)나 TRT-LLM도 속도는 미쳤지만, 빌드하고 컴파일하는 데만 수십 분이 걸리고 장비 타는 게 심하다.

반면 ThinTensor는 .thin 파일 하나 떨구면 끝이다. 다른 머신으로 복사해도 컴파일 없이 즉시 쌩쌩 돌아간다. 접근성과 배포 편의성에서 비교가 안 된다.

만든 사람이 16살이라는 건

이 무시무시한 프로젝트를 만든 주인공이 16살 고등학생이라는 사실이 밝혀지면서 레딧이 뒤집혔다. Hack Club 프로젝트로 시작했고, 러스트 코어 아키텍처의 90%를 혼자 힘으로 짰단다(16살 때 난 메이플스토리나 하고 있었는데 자괴감 든다). GPU 커널 최적화 쪽은 경험이 부족해 Claude의 도움을 반쯤 받았다고 솔직하게 고백한 것도 귀엽고 대견하다. 밤새 100개가 넘는 양자화 프로파일을 돌려가며 노가다를 뛰었다고.

r/LocalLLM 댓글에서 Keganator는 “컴퓨터 과학 최적화 기초를 제대로 구현했다”고 찬사를 보냈고, 다른 사용자는 “이런 최적화가 계속 쌓이면 나중엔 Fable 6도 구닥다리 레트로 컴퓨터에서 돌아가겠다”며 유쾌하게 감탄했다.

로컬 LLM 생태계에 무엇을 시사하나

당장 ThinTensor가 내일부터 llama.cpp를 몰아내고 천하통일할 수는 없다. 제작자 본인도 “아직 프로덕션 레디는 절대 아니다”라고 선을 그었다. 지원하는 아키텍처도 제한적이고 대형 모델 검증도 갈 길이 멀다.

하지만 이 시도가 던진 화두는 명확하다. “무식한 일괄 압축”의 시대에서 “부위별 맞춤 양자화”의 시대로 패러다임이 이동하고 있다는 것. 모델 저장 단계부터 런타임 캐시를 고려하는 똑똑한 포맷들이 앞으로 로컬 AI 시장을 뒤흔들 것은 확실해 보인다.

3주 만에 뼈대를 깎고 16살 소년이 혼자 벤치마크를 돌려 이 숫자를 뽑아냈다는 사실만으로도, 이 프로젝트의 미래를 설레는 마음으로 지켜볼 이유는 충분하다.