Beyond RAG: 문서 전체를 노트북에 통째로 로드하세요.
Chunking은 작은 컨텍스트 윈도우를 위한 임시방편이었습니다. 우리는 그것을 불필요하게 만들었습니다.
6.4× KV 압축으로 16GB Mac에서 전체 문서 이해가 가능합니다.
C 파일 하나(16K줄), 외부 의존성 0.
Ollama 스타일 CLI (v0.12.0+):
pip install quantcpp
quantcpp pull qwen3 # Qwen3-4B Q4_K_M 다운로드 (~2.5 GB)
quantcpp run qwen3 # 대화형 채팅
quantcpp serve qwen3 -p 8080 # OpenAI 호환 HTTP 서버 (SSE 스트리밍)
quantcpp client "안녕" # 스트리밍 클라이언트 → :8080 서버
quantcpp list # 캐시된 모델 목록추천 기본 모델: Qwen3-4B (4B params, MMLU 73, M3에서 4.5 tok/s). 최고 품질 AND 최고 속도 — Q4 NEON fused dot 경로로 Phi-3.5-mini보다 2.4배 빠릅니다. 다른 별칭: phi3.5, smollm2, llama3.2:1b. run/serve 첫 실행 시 자동 다운로드.
serve는 OpenAI 호환 POST /v1/chat/completions 엔드포인트를 8080 포트에 제공합니다 — 클라이언트가 "stream": true를 보내면 SSE 토큰 단위 스트리밍, 생략하면 단일 JSON 응답. 내장 quantcpp client는 두 모드 모두 지원 (기본: 스트리밍, --no-stream: 단일 응답).
한 줄 질문:
quantcpp run qwen3 "중력이란 무엇인가요?"Python API (3줄):
from quantcpp import Model
m = Model.from_pretrained("Qwen3-4B")
print(m.ask("중력이란 무엇인가요?"))API 키 없음. GPU 없음. 설정 없음. 모델은 ~/.cache/quantcpp/에 캐시됩니다. 지원되는 architecture와 모델 선택 가이드는 docs/supported_models.md를 참고하세요. 브라우저에서 바로 체험 → · 작동 원리 가이드 →
Llama 3.2 3B Q8_0로 측정한 직접 비교 결과:
| 방법 | 정확도 | 할루시네이션 |
|---|---|---|
| Chunk-RAG (잘못된 청크 검색) | 0/7 | 7개 모두 |
| 전체 문서 (FP32 KV) | 7/7 | 없음 |
| 전체 문서 (6.4x 압축 KV) | 7/7 | 없음 — 품질 손실 0 |
Chunk-RAG가 잘못된 섹션을 검색하면, 모델은 "모른다"고 하지 않고 그럴듯한 거짓을 생성합니다:
- "CTO는 누구인가?" → "John Smith" (실제: Maria Santos)
- "매출은?" → "$1,000,000" (실제: 8억 4700만)
- "R&D 비율은?" → "순이익의 15%" (실제: 매출의 14%)
6.4x KV 압축으로 전체 문서를 한 번에 로드하면, 모델은 multi-hop 추론까지 정확히 답합니다 (예: "성장 지역에 영향을 주는 위험은?" → 환율 변동, Section 3 + Section 5 정보 연결 필요).
핵심: KV 압축은 단순한 메모리 절감이 아니라 근본적으로 다른 RAG 접근을 가능하게 합니다. RAG는 "어떤 문서를 볼지" 결정하고, long-context는 "그 문서를 얼마나 깊이 이해할지" 결정합니다. 전체 결과: bench/results/document_level_rag_breakthrough.md
v2 후속 — Working Memory Cliff (2026-04-11): v1 결과를 더 큰 grid로 확장 측정했습니다 (1B/3B 모델, ctx 256-2048, 204 NIAH trials + FP32-weights 통제 실험). 두 모델 모두 명목 128K context window의 1% 미만에서 sharp cliff가 존재합니다 (1B Q8 cliff 512-1024, 3B Q4 cliff 1024-1280을 step function으로). 6.4× KV 압축은 20개 cell 중 18개에서 fp32 baseline과 bit-for-bit 일치 — cliff는 model property이지 KV/weight quantization artifact가 아닙니다. 정직한 재해석: Beyond RAG는 유효 working memory 안에 들어가는 문서에 대해서만 동작하며, 그 크기는 명목 context window의 100분의 1에서 1000분의 1입니다. 전체 tech report:
docs/paper/working-memory-cliff.md. HuggingFace blog post draft:docs/paper/hf-blog-draft.md.
v3.21 ★★★ Qwen3.6-35B 117-토큰 cliff BREAK — MoE softmax temperature, qwen35moe에서 기본 자동 적용 (2026-04-22): 한 knob —
TQ_MOE_ROUTE_TEMP=2.0— 으로 40+ 라운드 미해결이던 Qwen3.6-35B-A3B의 "It could do math! It could do math!" 117-토큰 반복 루프 제거. qwen35moe arch 자동 감지 + 기본값 자동 적용 (기존 auto-serial 모드와 동일 패턴), 사용자가 env 없이도 기본 적용. Llama/Phi/Gemma/Qwen3 non-hybrid에는 영향 없음. drift-trigger 프롬프트-n 200 T=0temperature 스위프: 기본 T=1.0 → 117 루프; T=1.5 → 더 일찍 87-토큰 cliff; T=1.8 → 여전; T=2.0 → 200 토큰 Alex+슬픈-나무 이야기 완주, rep-loop 없음; T=2.5 → 200 토큰 완주; T=3.0 → 과도 분산 114 재발. Sweet spot T=2.0 ~ 2.5. 인과: peaky MoE 라우팅이 DeltaNet 지속 상태와 positive feedback loop 형성. softmax 분산하면 루프 형성 불가. 26 라운드 arc: R16-R19 per-layer DeltaNet state reset은 null, R24에서 Qwen3.5-4B (DeltaNet + dense FFN, MoE 없음) 같은 프롬프트 → drift 전혀 없음 → MoE 단독 원인 확정, R25 MoE router probe에서 L4 0.80+ collapse 발견, R26 temperature ablation으로 cliff 차단. 회귀 23/23 PASS (T=2.0 포함), "Paris" factual probe 정상. 150+ 토큰 tail 여전히 character-level degrade — hard cliff 제거, essay-length은 추가 작업 필요. Opt-in, 기본 미변경. 권장:TQ_MOE_ROUTE_TEMP=2.0 ./build/quant Qwen3.6-35B-Q5_K_M.gguf -p "..." -n 200 --rep-penalty 1.3. 전체 리포트:bench/results/2026-04-22_moe_temp_cliff_break.md. v0.28.0.
v3.20 ★★ BPE encode/decode UTF-8 수정 — 국제 문자 silent 품질 재앙 해결 (2026-04-21):
encode_byte_to_bpe_char/decode_bpe_token에 있던 대칭 버그 두 개가 Llama-3 / Qwen3 계열 모든 모델에서 비ASCII 문자 (액센트, CJK, 키릴, byte-fallback 이모지)를 포함한 모든 프롬프트/출력을 조용히 깨뜨리고 있었습니다. 인코딩: GPT-2 direct-byte 코드포인트에 대해 ≥ 0x80 의 raw byte를 그대로 emit (독립형 바이트는 invalid UTF-8)하여str_lookup이 매칭에 실패 → 문자가 byte-fallback을 통해 잘못된 저-ID 토큰으로 변환. 디코딩: U+0080-U+00FF 코드포인트를 UTF-8 인코딩 (c3 83)으로 출력, 실제 바이트 (0xC3)가 아님 → 출력 이중 인코딩 ("café" → "café"). 토큰 레벨 HF 참조 일치 검증:café/naïve/日本語/привет모두 HFAutoTokenizer와 byte-byte 일치. 새tools/refparity/프레임워크의 A/B 출력 diff로 발견.quant.hsingle-header 에도 sync.scripts/test_tokenizer.sh회귀 fixture 추가. 영향 범위: GPT-2 byte-level BPE (Llama-3.x, Qwen2.5/3.x/3.5/3.6); Gemma/Phi-3 SentencePiece 경로 영향 없음. 회귀 15/15 + 토크나이저 8/8 PASS. v0.27.0.
Qwen3.6-35B 16 GB Mac 실용 레시피: 장문 coherence 기준 현재 최선 구성은
Qwen3.6-35B-A3B-UD-Q5_K_M.gguf+--rep-penalty 1.3. "Once upon a time in a faraway land" (-n 200, T=0) 실측: 기본 설정은 117 토큰에서 반복 루프, Q5_K_M + rep-penalty는 200 토큰 전체 예산을 생성 후 말미에서만 완만하게 degrade. 35B DeltaNet drift 는 여전히 열린 아키텍처 조사 과제이나, 사용자가 지금 쓸 수 있는 최선.
v3.19 ★ DeltaNet L2-norm 공식이 ggml과 일치 — Qwen3.6 coherence +36% (2026-04-21): R26의 "eps 수정"은 올바른 진단이지만 잘못된 공식이었습니다. 우리는
1/sqrt(ss + eps)를 사용했지만 llama.cppggml_l2_norm은1/max(sqrt(ss), eps)을 사용 — near-zero 입력에서 3 orders of magnitude 차이 (1e3 vs 1e6). 30 DeltaNet 레이어 × position 에서 K/Q under-scaling이 누적 → decode-length degradation. 수정: ggml과 정확히 일치. Qwen3.6-35B IQ4_XS auto-serial 실측 "Write a 300-word essay": 117 → 160 토큰 (+36%), coherent content 45 → 110 토큰.refs/llama.cpp/ggml/src/ggml-cpu/ops.cpp::ggml_compute_forward_l2_norm_f32를 우리l2_normalize와 직접 diff로 발견. 15/15 regression PASS. v0.26.0.
v3.18 Qwen3.6 auto-serial quality mode — 결정성 + 긴 coherence (2026-04-20): 발견: Qwen3.6-35B 멀티쓰레드 matmul은 T=0에서 비결정적 (동일 프롬프트 두 번 실행 = 다른 출력). 병렬 FP reduction 순서 변동이 30 MoE 레이어 × position feedback에서 누적 → top-1 argmax flip. 수정: qwen35moe+DeltaNet 하이브리드 자동 감지 후
-j 1강제. 이전: 실행마다 결과 다름, 60-70 토큰 후 degrade. 이후: 결정적, coherent 범위 ~95 토큰으로 확장. 비용: 디코드 ~2-3× 느림 (3 t/s vs 8 t/s). Opt-out:TQ_NO_AUTO_SERIAL=1. 솔직한 한계: 1000+자 생성 완전 수정은 아직 아님 — 40 레이어 × 8-expert weighted sum × IQ4_XS 양자화 오차 누적이 결국 반복 루프로 귀결. 오늘 세션 요약: 7 릴리스로 7개 Qwen3.6 버그 클래스 해결. 비결정성 제거만으로도 실용 향상 충분함. v0.25.0.
v3.17 MoE SwiGLU exact expf — Qwen3.6 coherence 마진 (2026-04-20): MoE
swiglu_fused가 Schraudolph 근사 (~2% 오차) 대신 exactexpf기본 사용. R27-29에서 DeltaNet에는 적용했지만 MoE는 fast_exp 유지 중이었음. 30 MoE 레이어 × 500+ 토큰에서 오차 누적. 수정 후 400-word Qwen3.6 프롬프트가 더 길고 다양한 continuation 생성. 속도 비용: 측정 불가 (SwiGLU 병목 아님; 280w에서 28-29s TTFT 동일). Opt-out:TQ_MOE_FAST_EXP=1. 500+ 단어 degradation 여전 (다원 버그 중 한 원인 해결). 15/15 regression PASS. v0.24.0.
v3.16 ★★ 긴 프롬프트 silent-truncation 수정 (2026-04-20): 4096 chars (~700 영어 단어) 이상 프롬프트가
tq_generate.c의 4096-token caller 버퍼에 의해 조용히 잘려나가고 있었습니다. BPE가 문자 단위로 먼저 토큰화되기 때문에 4096 cap이 merge 전에 적용되어 char 4096 이후 텍스트가 사라졌습니다. 수정: 32768로 확장 + dynamic sizeof. OpenMythos reference-diff 진단: HF Qwen3-0.6B가 561-word 문서를 698 토큰으로, 우리 엔진은 684로 토큰화 — 우리 마지막 토큰 decoded =". The abacus"(텍스트 시작 부분!), truncation 증명. 수정 후 Qwen3.5-4B (dense hybrid) 561-word 문서 coherent: "the future of AI is not just about what we can do with it - it's about how we think about what matters most to us." ✓. Qwen3.6-35B MoE hybrid는 여전히 561w에서 repetition loop — 버그가 MoE feedback accumulation at long positions로 격리됨 (DeltaNet + 토크나이저는 Qwen3.5-4B 성공으로 정상 입증). 15/15 regression PASS. v0.23.0:docs/RELEASE_NOTES.md.
v3.15 Qwen3.6 chunked batched prefill (+30% TTFT, 2026-04-20): Batched MoE dispatch를 8개 토큰 청크로 분할 (
TQ_MOE_BATCH_CHUNK조정 가능) — 소형-N 안전 영역을 유지하며 batched 속도 이득 대부분 회복. State (KV cache, DeltaNet ssm)가 이미 driver call 간 영속이므로 의미론적으로 올바름. Qwen3.6-35B IQ4_XS 실측: 44-word prose TTFT 12.6s → 7.0s (+44%), 280-word 38.0s → 29.4s (+29%), 동일한 정확한 요약. ~300 단어 문서까지 검증. 500+ 단어에서는 별개 accumulation 버그 (batched, per-token 모두 실패 — MoE scatter 버그와 다른 KV/DeltaNet-state 이슈). 15/15 regression PASS. v0.22.0:docs/RELEASE_NOTES.md.
v3.14 ★★★ Qwen3.6-35B 실질 사용 가능 — 16 GB Mac 문서 Q&A (2026-04-20): 마지막 Qwen3.6 버그 종료.
tq_moe_forward_batchN≥40에서 (tq_forward_batch_moe_hybrid내 batched MoE 커널) 격리.tq_forwardper-token 경로는 동일 입력에서 완벽 출력. 수정: default를 opt-in (TQ_USE_MOE_BATCH=1)로 뒤집음. Qwen3.6-35B 44-word 자연문 + "Summarize in one sentence." — 이전! \` inteligت sWith …garbage — **이후**"Artificial intelligence, particularly through deep learning and large language models, has transformed how we create and interact with content…"✓. 광범위 검증 5/8 PASS (나머지 "fail"도 모두 coherent 출력, 단지 테스트 키워드 부재). Trade-off: TTFT 12.6s per-token vs 4-7s batched — 정확성 우선. 세션 아크 전체: v0.19.0 BPE → v0.20.0 QK-norm + NEOX → v0.21.0 MoE opt-in. **6 Pillar 1 + 1.5 라운드에 R26-R50의 30+ empirical 라운드가 못 잡은 문제 모두 종료**. OpenMythos 영감 HF reference diff 방법론이 결정적. v0.21.0: [docs/RELEASE_NOTES.md`](docs/RELEASE_NOTES.md).
v3.13 ★★ NEOX RoPE + QK-norm — Qwen3 장문 coherence 복구 (2026-04-20): v3.12 BPE 수정 위에 2개 transformer-level 근본 원인 추가 해결. (1)
tq_transformer.c:1204— 순수 Qwen3 (0.6B~32B)는 q_norm/k_norm 필수. R40가 GGUF arch="qwen" 전체에 QK-norm 비활성화한 것은 Qwen3.5/3.6 DeltaNet HYBRID에만 옳음. QK-norm 없으면 layer 2에서 residual stream 폭발 (norm 5400 vs HF 10). (2)tq_ops.c에tq_rope_neox신규 — llama.cpp가LLM_ARCH_QWEN3*를LLAMA_ROPE_TYPE_NEOX/IMROPE(half-split pairs)로 매핑하지만 우리 엔진의tq_rope와tq_forward_batch는 LLaMA 스타일 interleaved pairs 사용. R34가 partial-rotary만 고침; 순수 Qwen3 full rotary + batched prefill은 여전히 틀림. 이제 arch 감지 후 올바른 RoPE 디스패치. Qwen3-0.6B 50-word 합성 입력: 이전alyticsанcieaâ��à¹�…UTF-8 쓰레기, 이후" Let me try to understand this"coherent. Qwen3.5-4B 자연문:"Artificial intelligence is a field of computer science…". Qwen3.6-35B 8-프롬프트 매트릭스: UTF-8 garbage 0건. 방법론 승리: HF reference diff (tools/pillar1/),refs/OpenMythos의 "ground truth와 먼저 비교" 원칙이 결정적. 6 라운드에 R26-R50의 30+ 경험적 라운드가 못 잡은 3개 근본 원인을 모두 종료. Regression 15/15 + tokenizer 4/4. v0.20.0:docs/RELEASE_NOTES.md.
v3.12 ★ BPE 근본 원인 수정 — Qwen3 family 완전 coherent (2026-04-20):
src/engine/tq_tokenizer.c:1442에 한 줄 추가 (if (tokens[top.pos] < 0) continue;) 로 30+ 라운드의 "Qwen3 drift" 모든 증상의 진짜 원인 제거. 버그: BPE heap merge에서 다른 merge의 RIGHT neighbor로 죽은 position이gen[]bump 없이tokens[P]=-1만 되어, 오래된 heap entry가 죽은 slot을 부활시키며 linked list 오염 → 토큰 문자 중복/손실. HF reference 비교로 확인: 우리 엔진이"Hello"를[32713="Hel", 654="ll"]= "Helll" (문자 5개: H,e,l,l,l — 'o' 대신 'l')로 인코딩; HF는[9707="Hello"]정상. 다운스트림 결과: Qwen3.6-35B 40+ 단어 프롬프트가 완벽한 Python 코드 + 완전한 서사문 생성 (이전 garbage); Phi-3.5 "What is 2+2?"가 "The sum of 2 and 2 is equal to four." 정답 (이전 "tti" 환각). 방법론: Python HF reference diff가 3 라운드 만에 발견. Regression 15/15 + 새 토크나이저 테스트 4/4. 전체 before/after 증명:bench/results/2026-04-20_bpe_fix_proof.md.quant.h단일 헤더는 naive O(n²) BPE 사용으로 영향 없음.
v3.11 TTFT/decode 분리 + 데일리 드라이버 픽 (2026-04-20): CLI 출력이
TTFT | decode로 분리되어, 짧은 쿼리에서 cold-start에 지배당하는 "overall tok/s" 대신 prefill latency와 sustained decode를 개별적으로 보여줍니다. 16 GB M1 Pro CPU-only warm 실측: Phi-3.5 Q4_K_M TTFT 2.3s / decode 14.5 t/s (짧은 대화), Llama-3.2-3B Q8→Q4 TTFT 0.97s / decode 29.0 t/s (one-shot 코드/수학), Qwen3.6-35B IQ4_XS TTFT 1.83s / decode 10.5 t/s (35B MoE 품질 장문). Decode는 모델 성질, TTFT는 warmup 성질 — 같은 명령 두 번 실행하면 두 번째부터 warm 수치. 3-모델 매트릭스 + 용도별 추천:bench/results/2026-04-20_ttft_daily_driver.md.
v3.10 Qwen3.x 모든 형식 승리 (2026-04-20): 두 구조적 수정이 Qwen3.5/3.6의 장문 드리프트를 완전히 제거. (1) NEOX-style partial RoPE — Qwen3.5/3.6은
LLAMA_ROPE_TYPE_IMROPE(NEOX half-split(q[i], q[i+rope_pairs])). (2) Arch-conditional QK-norm — Gemma 4 필수, Qwen family 비활성화. Qwen3.6-UD-IQ4_XS (--chat, T=0): "Once upon a time" n=60 → 60-token 완전 스토리,def fibonacci(n):→ 정확한 Python, haiku/list/팩트 모두 작동. 15/15 regression PASS. v0.17.0:docs/RELEASE_NOTES.md.
v3.9 Qwen3.6 Q5_K_M on 16 GB Mac — 최초 엔진 (2026-04-19):
tq_model.cauto-policy MADV +q5k_int_dot_workerNEONvshlq_u8qh 추출로 26.5 GB Q5_K_M GGUF가 16 GB M1 Pro에서 로드 + 추론됩니다. RSS 9.65 GB (non-expert WILLNEED = 2.50 GB, routed experts OS 관리 = 22.13 GB, MoE K=8/N=256 희소성 덕분). Decode: warm 7.9 t/s (대화 실용권). llama.cpp는 같은 하드웨어에서 동일 파일 OOM. NEON SHL 기반 5번째 비트 추출 (AND+CEQ+AND → SHL+AND)로 Q5_K cold decode +40%. 전체 Qwen3.6 5-tier 매트릭스:bench/results/2026-04-19_qwen36_quant_matrix_16gb.md. v0.16.0 릴리스 노트:docs/RELEASE_NOTES.md.
v3.8 Mission A 완료 — MoE batched prefill 기본 ON (2026-04-19): 3단계 Step-3 라운드로 token-grouped MoE batched dispatch 완성.
tq_moe_forward_batch(3-phase: batch-route → inverse index → expert-wise batched gather/matmul/scatter),tq_forward_batch_moe_hybrid(per-token DeltaNet + self-attn, batched MoE FFN), cross-expert parallel, batched shared expert,tq_tp_run_dynamicFCFS atomic queue. 측정 결과 (Qwen3.6-UD-Q3_K_S, 450-word prompt, warm, j=8): 103s → 73s wall time (-29%), 4.4 → 6.1 t/s prefill (+39%), CPU work -41%.TQ_MOE_BATCH_DYNAMIC=1opt-in 시 추가 +17%. 기본 ON,TQ_NO_MOE_BATCH=1로 opt-out. 전체 리포트:docs/RELEASE_NOTES.mdv0.15.0.
v3.7 IQ4_XS가 16GB Mac에서 동작 (2026-04-18 밤): 반직관적 결과 — 16.51 GB 파일이 16 GB Mac에서 로드됨.
mmap+TQ_NO_MLOCK=1이 hot expert subset만 RAM에 유지하기 때문. Qwen3.6-35B-A3B-UD-IQ4_XS: RSS 5.44 GB (warm), 디코드 12.5 t/s peak, 실행 후 free RAM 10.2 GB. Q3_K_S 대비 품질 향상 구체적: 고유명사 + 긴 서사 유지 ("village of Oakhaven", "apprentice to blacksmith", "Master Thorne") — greedy ~60 토큰 coherent (Q3_K_S ~40 대비). 속도 손실은 13% (14.3 → 12.5 t/s). 4-tier ladder 전체:bench/results/2026-04-18_iq4_xs_tier.md. 16GB Mac에서 Qwen3.6 최고 품질 확인된 variant = IQ4_XS.
v3.6 Q3_K_S tier 측정 (2026-04-18 밤): Q3_K int8 커널(
11e3c32) 완성 후 Unsloth UD-Q3_K_S (3.5 bpw, 14.3 GB) 본격 측정. 16GB M1 Pro CPU-only: 14.3 t/s warm peak, RSS 5.24 GB — 테스트한 모든 Qwen3.6 variant 중 가장 작은 working set (IQ2_XXS 6.54 GB 보다도 적음, bpw는 70% 높은데도). 원인:TQ_NO_MLOCK=1이 cold expert를 OS에 맡기는데, Q3_K_S의 균일 256-elem 블록이 IQ3_XXS의 IQ3/IQ4/Q4_K/Q6_K 혼합보다 페이지 locality가 좋음. 품질 향상 명확: "William Shakespeare wrote Hamlet" 정답 (IQ3_XXS는 여기서 실패), "Jack loved to play with his guitar" vs IQ2의 "village of the mountains". llama.cpp CPU 5.11 t/s → 2.8× 빠름. 16GB Mac에서 Qwen3.6 권장 variant는 이제 Q3_K_S. 전체 리포트:bench/results/2026-04-18_q3_k_s_tier.md.
v3.5 RoPE + SwiGLU NEON 정리 (2026-04-18 저녁): 같은 프로파일에서 나온 구조적 수정 2개. (1) Partial-RoPE용 TLS sin/cos 캐시 — Qwen 3.x 전체가 쓰는 경로. 이전엔 layer×head×pair마다
powf + cosf + sinf재계산. sin/cos는(pos, base, rope_dim)에만 의존하고, 한 forward pass 안에서는 layer/head 간 동일. 그 triple로 키한 thread-local 표 — 첫 layer만 계산, 나머지 ~179 조합은 배열 읽기. Qwen3.6 토큰당 transcendental 호출 ~180× 감소. (2)fast_exp_neon— SwiGLU 내부에서 Schraudolph 비트 트릭 exp를 NEON 직접 (lane당 FMA 1 +vcvtq_s32_f321)로. 이전엔vst1q_f32 → scalar 4회 → vector 재조립. SwiGLU 8-lane 타일 경로 길이 절반. Qwen3.6 MoE 토큰당 약 12만 회 호출. 커밋b4d7807,d4c0fc6.
v3.4 Q3 품질 돌파 (2026-04-18 후반): 스칼라 fused_dot 3개 더 교체 — Q3_K, IQ3_XXS, IQ4_XS (IQ4_XS는
vqtbl1q_s8TBL-16 사용,kvalues_iq4nl16-entry codebook에 완벽 매칭). 타깃: Qwen3.6-35B-A3B를 IQ2_XXS (2.05 bpw, 30-40 토큰서 drift)에서 **UD-IQ3_XXS (3.06 bpw, 12.3 GB)**로 승격 — 같은 16GB Mac, CPU-only. 결과: 14.6 t/s warm peak, RSS 6.82 GB (IQ2 대비 +0.28 GB뿐 — page cache가 routed expert 스트리밍, hot-set 크기 거의 동일). Coherent 디코딩이 ~2배 길게 유지 (IQ2: "small village of the mountains" → drift; IQ3: "small village called 'Happiness'" + Jack 스토리 이어감). llama.cpp의 같은 Q3 모델 CPU 대비 2.8× 빠름 (5.23 t/s). 16GB Mac에서 35B MoE 품질-속도 둘 다 잡은 상태. 전체 리포트:bench/results/2026-04-18_q3_breakthrough.md.
v3.3 MoE + Q4_K_M 성능 돌파 (2026-04-18): 프로파일 기반(
sample) 핫 경로 분석으로 세 가지 커널 문제를 동시에 수정했습니다. (1) Q6_K NEON int8 fast path —fused_dot_q6_k가 순수 스칼라였습니다. Q4_K_M은attention.wo/ffn_down에 Q6_K를 쓰기 때문에 모든 Q4_K_M 모델의 숨은 병목이었음. Qwen3.5-4B Q4_K_M 5.0 → 14.1 t/s, Phi-3.5-mini Q4_K_M 6.2 → 14.1 t/s. (2) MoE router NEON 벡터화 — 라우터 logit 계산 (토큰당 30 layers × 256 experts × 2048 dim = 15.7M scalar FMA)을 4-accumulator NEON FMA로, scratch 버퍼는 thread-local로 (malloc 제거). (3)TQ_NO_MLOCK=1환경변수 — 16GB Mac에서mlock(10 GB)는 오히려 OS LRU를 방해. 끄면 RSS 12→6.5 GB 절감 + 속도도 더 빨라짐 (256 experts 중 hot set이 작아서 OS page cache가 더 똑똑하게 관리). Qwen3.6-35B-A3B-UD-IQ2_XXS: 3.08 → 16.1 t/s (5.2×), llama.cpp CPU 대비 3.2× 빠름. 전체 측정:bench/results/2026-04-18_moe_and_q4_k_m_breakthrough.md.16GB Mac에서 35B MoE 실행 권장 명령:
TQ_NO_METAL=1 TQ_NO_MLOCK=1 ./build/quant \ models/Qwen3.6-35B-A3B-UD-IQ2_XXS.gguf \ --chat -p "질문" -n 60 -T 0.7 -j 8
AI 모델이 대화를 기억하려면 KV 캐시라는 메모리가 필요합니다. 대화가 길어질수록 이 메모리가 빠르게 커져서, 모델 자체보다 더 많은 메모리를 차지합니다.
일반 엔진: 모델(4GB) + KV 캐시(8GB) = 12GB 필요 → 8GB Mac에서 OOM
quant.cpp: 모델(4GB) + KV 캐시(2.3GB) = 6.3GB → 8GB Mac에서 OK ✅
quant.cpp는 이 KV 캐시를 3배 압축합니다. 같은 컴퓨터에서 3배 더 긴 대화가 가능합니다.
놀라운 점: 압축해도 품질이 떨어지지 않고, 오히려 13% 더 빨라집니다.
Llama 3.2 3B 모델, 3970 토큰 평가:
| 설정 | 품질 (PPL) | 메모리 (32K) | 속도 |
|---|---|---|---|
| 압축 없음 (FP32) | 19.41 | 7.17 GB | 기준 |
| 압축 + progressive | 19.39 (-0.1%) | 2.33 GB | +13% |
| 압축 (일반) | 20.02 (+3.1%) | 2.30 GB | +13% |
progressive=True 한 줄로, 메모리 3배 절감 + 속도 13% 향상 + 품질 동등을 달성합니다.
m = Model("model.gguf", progressive=True)| 용도 | 코드 |
|---|---|
| 챗봇 만들기 | m.ask("안녕하세요!") |
| 긴 문서 질문 | m = Model("model.gguf", context_length=32768) |
| 대화 저장/복원 | m.save_context("대화.kv") → m.load_context("대화.kv") |
| 끝없는 대화 | 자동 — context 초과 시 오래된 대화를 압축, 삭제하지 않음 |
| C 앱에 AI 추가 | #include "quant.h" → cc app.c -lm |
| 브라우저에서 실행 | WASM 데모 (193 KB) |
내 모델 사용:
m = Model("path/to/any-model.gguf") # 모든 GGUF 파일 지원
for tok in m.generate("옛날 옛적에"):
print(tok, end="", flush=True)대화 저장 & 복원:
m.ask("이 긴 문서를 읽어줘: ...")
m.save_context("document.kv") # 압축 상태로 디스크에 저장
m2 = Model("model.gguf")
m2.load_context("document.kv") # 즉시 복원 — 다시 읽을 필요 없음
m2.ask("37페이지에 뭐라고 써있었어?")설치 방법:
| 방법 | 명령어 | 설명 |
|---|---|---|
| Python | pip install quantcpp |
사전 빌드 wheel (Linux, macOS) |
| C (단일 헤더) | #include "quant.h" |
654 KB 파일 하나, 의존성 0 |
| 브라우저 | 데모 링크 | 193 KB WASM |
| 소스 빌드 | cmake -B build && cmake --build build |
72K LOC, 테스트 35개 |
왜 "최근 128 토큰만 FP32"로 충분한가?
Transformer의 attention 메커니즘은 최근 토큰에 자연스럽게 집중합니다 (causal masking + positional encoding). 측정 결과, attention 가중치의 ~70%가 최근 128 토큰에 집중됩니다.
양자화 오류는 attention_weight × MSE로 전파됩니다. 가중치가 높은 영역(최근 128 토큰)만 FP32로 유지하면, 전체 가중 오류가 최소화됩니다.
이것은 context 길이와 무관합니다 — 128K context에서도 128 토큰(0.1%)의 FP32이면 충분합니다.
벤치마크 전체 데이터
| KV 설정 | 블록 크기 | 압축비 | PPL | Δ vs FP32 | tok/s | vs FP32 속도 |
|---|---|---|---|---|---|---|
| FP32 | — | 1× | 13.56 | — | 18.43 | baseline |
| turbo_kv_4b ⭐ | 72 | 7.1× | 14.08 | +3.8% | 18.17 | -1.4% (패리티) |
| turbo_kv_5b | 88 | 5.8× | 13.65 | +0.7% | 16.80 | -8.8% |
| turbo_kv_3b | 56 | 9.1× | 15.36 | +13.3% | 16.57 | -10.1% |
| uniform_4b | 68 | 7.5× | 14.60 | +7.7% | 13.27 | -26.8% |
| 설정 | PPL | vs FP32 | k FP32 비율 |
|---|---|---|---|
| FP32 | 19.41 | — | 100% |
| 4-bit + k128 | 19.39 | -0.1% | 3.2% |
| 4-bit flat | 20.02 | +3.1% | 0% |
| 2-bit + k512 | 26.53 | +36.7% | 12.9% |
- FP32 KV: 10.4 GB (8GB Mac에서 OOM)
- turbo_kv_4b: 5.5 GB (8GB Mac에서 OK)
- 속도: 7.8 tok/s (+13% vs FP32)
"llama.cpp로도 임베딩 되는데, 왜 quant.cpp?"
맞습니다. llama.cpp는 훌륭하고 임베딩도 가능합니다. 차이는 통합 방식입니다:
llama.cpp = 컴파일된 라이브러리 (250K+ LOC). libllama를 링크하면 GGML 텐서 그래프, Metal/CUDA 백엔드, 샘플러, 토크나이저가 따라옵니다. 빌드 시스템이 이를 감당할 수 있다면 훌륭합니다 — 하지만 빌드 단계가 필요한 _라이브러리_입니다.
quant.cpp = 파일 하나 (16K LOC). #include "quant.h", cc app.c -lm으로 컴파일. CMake 없음, 링커 플래그는 libc뿐. 하나의 번역 단위.
# quant.cpp — C 프로젝트에 AI 추가: 2줄
cc -O2 my_app.c -lm -lpthread -o my_app # 끝
# llama.cpp — 먼저 라이브러리를 빌드해야 합니다
cmake -B build && cmake --build build
cc my_app.c -Ibuild/include -Lbuild -lllama -lm -lstdc++ -o my_app
| 시나리오 | quant.cpp | llama.cpp |
|---|---|---|
| WASM 브라우저 | 192 KB 바이너리 | GGML 텐서 그래프가 너무 큼 |
| 마이크로컨트롤러 / RTOS | #include만 가능 (FS/링커 없음) |
빌드 시스템 필요 |
| 게임 엔진 (Unity/Unreal/Godot) | .h 파일 하나 드롭 |
250K LOC 빌드 통합 |
| 교육 / 연구 | 하루만에 전체 코드 읽기 가능 | 훌륭하지만 코드가 방대 |
| GPU 속도 | 기본 | Metal/CUDA 최적화 |
| 모델 지원 | 7개 아키텍처 | 100+ |
llama.cpp — 워크스테이션에서 최고 속도가 필요할 때. vLLM — 배치 서빙이 필요할 때. quant.cpp — AI를 앱/게임/브라우저/디바이스 안에 넣어야 할 때, 통합 단순성이 GPU 처리량보다 중요할 때.
아키텍처 상세
include/turboquant/ — 공개 C API
src/core/ — 양자화 알고리즘 (polar, qjl, turbo, uniform)
src/cache/ — 페이지드 캐시 + 점진적 압축
src/backend/cpu/ — CPU 커널 (NEON, AVX2)
src/engine/ — GGUF 로더, Transformer, 토크나이저
tests/ — Google Test (35개 테스트)
wasm/ — 브라우저 데모 (193 KB)
bindings/python/ — PyPI 패키지
지원 모델: Llama 3.x, SmolLM2, Gemma 3/4 (MoE), Qwen 3.5, Phi-3, Mistral, DeltaNet
우리는 잘못된 주장을 외부 신고 전에 스스로 발견하고 공개적으로 정정합니다.
전체 정정 기록 보기
| # | 시기 | 내용 |
|---|---|---|
| 1 | v0.6.3 | "lossless 7×" 주장 → 재측정 후 정정 |
| 2 | v0.6.x | "beats fp32" → FP32 baseline이 scalar(비최적화)였음 |
| 3 | v0.7.x | "with Metal default" → CMake 기본은 Metal=OFF |
| 4 | v0.7.x | Tim Dettmers HIGGS 댓글 해석 오류 |
| 5 | v0.8.0 | Python kv_compress=1 default abort |
| 6 | v0.8.0 | Cross-heap libc.free abort |
| 7 | v0.8.1 | 65KB/call ask() 메모리 누수 |
| 8 | v0.9.0 | 작동하는 기능을 잘못된 분석으로 비활성화 |
| 9 | v0.10 | 957-token eval에서 k512=53% FP32로 측정 (과대 주장) |
| 10 | v0.10 | 2-bit Pareto 주장 철회 (long context에서 PPL +36.7%) |
- TurboQuant (ICLR 2026) — arXiv:2504.19874
- PolarQuant — arXiv:2502.02617
- QJL — arXiv:2406.03482
- HIGGS — arXiv:2411.17525
모든 주장은 재현 가능한 벤치마크 데이터로 뒷받침됩니다:
bench/results/progressive_kv_compression.md— Progressive KV 발견bench/results/attention_aware_quantization.md— Attention-aware 양자화bench/results/long_context_kv_compression.md— Long context 메모리 측정bench/results/layer_adaptive_analysis.md— 레이어 적응 분석 (부정적 결과)
Apache 2.0 — LICENSE
