← Back to index

Onchain AI Garage

Improving Our TurboQuant Implementation for Windows

2026-03-30 · 17m · 자막 —
▶ YouTube 원본
01한국어 번역 · Korean

윈도우용 터보퀀트(TurboQuant) 구현을 개선하다 — 커뮤니티와 함께 한 재검증기

원본: https://www.youtube.com/watch?v=4S5NIE_294U · 업로드: 2026-03-30 · 길이: 18m · 채널: Onchain AI Garage

지난 주 요약: 우리가 만든 것

지난주에 구글(Google)이 새로운 압축 알고리즘인 터보퀀트(TurboQuant)를 발표했습니다. 공식 릴리스는 아직 없지만 공개된 논문만으로도 자체 구현체를 만들 수 있을 만큼 충분한 정보가 있었고, 저는 이를 PyTorch로 직접 구현해 지난 영상에서 소개했습니다. 이번 영상은 그 후속편으로, 같은 구현을 특히 윈도우(Windows) 사용자 관점에서 어떻게 개선했는지 정리한 것입니다. 코드는 완전 오픈소스이며 GitHub의 tombistudio/TurboQuant-PyTorch 저장소에서 전부 확인할 수 있습니다. 공개 이후 이슈(issue)와 풀 리퀘스트(pull request)를 보내주신 분들, 그리고 581개의 스타(star)를 눌러주신 커뮤니티에 먼저 감사드립니다.

간단히 복습하자면, 터보퀀트는 모델의 KV 캐시(KV cache), 즉 어텐션(attention) 과정에서 쌓이는 “메모리”를 압축해 GPU 공간 사용량을 약 3~7배 줄여주는 알고리즘입니다. 한 가지 중요한 오해부터 바로잡자면, 이 알고리즘은 모델 가중치(weights)를 압축하지 않습니다. 압축되는 것은 오직 KV 캐시뿐이며, 모델 자체는 여전히 온전한 크기로 VRAM에 올려야 합니다.

동작은 두 단계로 이뤄집니다. 먼저 값을 무작위로 “회전(rotate)“시키고, 그다음 정수로 “양자화(quantize)“합니다. 즉 숫자를 무작위 방향으로 돌린 뒤 반올림해 비트를 절약하는 방식입니다. 여기에 QJL 오차 보정(QJL error correction)이라는 1비트 보정 기법을 얹어 반올림 오차를 줄이는 것이 구글 논문의 핵심 구성이었고, 저는 이를 PyTorch로 처음부터 만들어 RTX 3060(12GB VRAM) PC에서 검증했습니다. 당시 결과만 보면 3비트에서 5배 압축, 어텐션 점수 유사도 99.5%, 4비트에서는 99.9%로 매우 깔끔해 보였습니다.

치명적인 결함: 검증은 통과했지만 생성은 무너졌다

문제는 그 다음이었습니다. 지난 영상을 올린 뒤 며칠 사이에 커뮤니티와 제가 직접 더 엄밀한 테스트를 돌리면서, 이 구현에는 아주 명백한 결함이 있다는 것이 드러났습니다. 바로 텍스트 생성(generation)이 완전히 망가져 있었다는 점입니다. 모델에게 “비밀 프로젝트 코드명이 뭐지?” 같은 질문을 던졌을 때, 어떤 설정에서도 정답을 맞히지 못했고 27개 중 0개가 통과하거나 기껏해야 20% 수준이었습니다. 결과물은 대부분 의미 없는 문자열이었습니다.

왜 검증(validation)은 멀쩡해 보였는데 생성은 실패했을까요? 검증 테스트는 모델을 문서 위에서 한 번만 돌려서 그때의 KV 캐시를 캡처한 뒤, 압축 전후 숫자를 비교하는 작업입니다. JPEG 파일의 픽셀 차이를 측정해 원본과 얼마나 비슷한지 확인하는 것과 비슷합니다. 반면 생성 테스트는 실제로 모델이 응답을 써내게 만들고, 새로 생성되는 토큰마다 그 압축된 KV 캐시가 다시 입력으로 들어가게 합니다. 이 과정에서 작은 오차가 누적되어, 살짝 어긋난 한 토큰이 다음 토큰 예측을 어긋나게 하고, 그 다음 토큰을 또 어긋나게 하는 식으로 오차가 기하급수적으로 증폭됩니다.

핵심 발견 1 — QJL 레이어를 제거하라

다행히 제 저장소뿐 아니라 로컬 LLM(local LLM) 커뮤니티 여러 곳에서 동시에 이 문제를 파고들고 있었습니다. Scoslab, llama.cpp 쪽 포크들, Oaxero 같은 배포 엔지니어, 그리고 제 저장소에 스크립트를 돌려본 기여자분들까지 서로 다른 언어와 모델을 사용했는데 결과는 거의 같았습니다. QJL 레이어가 오히려 품질을 크게 떨어뜨린다는 것입니다. 즉 MSE 기반 양자화만 썼을 때가 QJL을 추가했을 때보다 일관되게 더 좋았습니다.

왜 그런지 이해하려면 소프트맥스(softmax)를 봐야 합니다. 어텐션에서 모델은 원(raw) 점수를 그대로 쓰지 않고 소프트맥스를 통과시키는데, 이 함수는 사실상 “증폭기(amplifier)“입니다. 예를 들어 원점수가 10, 10.1, 9.9처럼 비슷하면 소프트맥스를 거친 후에도 33, 37, 30처럼 비교적 고르게 분포하지만, 같은 간격을 10, 10.5, 9.5로 살짝만 벌려도 출력은 24, 40, 15로 확 벌어집니다. 입력의 작은 차이가 출력에서 큰 차이로 증폭되는 것입니다.

QJL의 약속은 “각 점수에 무작위 노이즈를 더하지만 평균적으로는 상쇄되어 정답으로 수렴한다”는 것입니다. 수학적으로는 맞는 말이고, 평균적으로는 편향이 없는(unbiased) 추정량입니다. 그러나 실제 모델은 여러 번 평균을 내지 않습니다. 매 스텝마다 점수를 단 한 번 소프트맥스에 통과시키고 끝입니다. 그 결과 QJL이 뿌려놓은 무작위 오차가 소프트맥스에 의해 지수적으로 증폭되어 버립니다. 다트판에 비유하자면, QJL은 중심 주변에 점들을 흩뿌리는 방식인데 소프트맥스를 지나면 그 작은 산포가 사방으로 튀어나가고, 반대로 MSE만 쓰면 중심에서 약간 벗어난 위치에 일관된 편향으로 몰리기 때문에 소프트맥스가 그 편향을 그대로 처리할 수 있는 것입니다.

그렇다면 구글이 틀렸느냐 하면, 그건 아닙니다. 구글의 논문은 KV 캐시 압축과 함께 벡터 검색(vector search) 이라는 또 다른 응용을 다루고 있었습니다. 벡터 검색은 데이터베이스에서 유사 항목을 찾는 작업으로, 이 과정에는 소프트맥스가 없고 숫자를 직접 비교하기 때문에 QJL의 불편향(unbiased) 성질이 실제로 도움이 됩니다. 단어 임베딩(word embedding) 벤치마크에서 보여준 결과는 진짜이고 유효합니다. 문제는 언론에서 KV 캐시 쪽 결과만 크게 다뤄진 것이고, 하필 KV 캐시에서는 QJL이 역효과를 낸다는 점이었습니다. 덧붙여, 소프트맥스를 쓰지 않는 새로운 아키텍처 — 시그모이드 어텐션(sigmoid attention), 선형 어텐션(linear attention), 게이티드 어텐션(gated attention) 등 — 에서는 이런 증폭 문제가 없기 때문에 QJL이 다시 유용해질 여지가 있습니다.

핵심 발견 2 — 비대칭 KV: 키에 더 많은 비트를

두 번째 개선점은 키(key)와 값(value)에 같은 비트를 주지 말자는 것입니다. 흔히 “비대칭 KV(asymmetric KV)“라고 부르며 Scoslab과 llama.cpp 커뮤니티가 먼저 주장했습니다. Scoslab은 여덟 개 모델에서 키와 값 벡터의 실제 크기를 측정했는데, 예컨대 Qwen 2.5의 경우 키 벡터의 평균 크기가 172인 반면 값 벡터는 고작 3 정도로 약 57배 차이가 났습니다. Oaxero는 실제 프로덕션 배포에서 독립적으로 같은 결론에 도달해 키 3비트, 값 2비트 구성으로 돌리고 있었고, llama.cpp 쪽에서도 혼합 설정이 균일 설정을 일관되게 이긴다는 보고가 있었습니다.

직관적으로도 말이 됩니다. 키는 “모델이 어떤 단어를 볼지”를 결정하는 정밀도 민감 연산이고, 값은 가중 평균되어 섞이는 실제 콘텐츠입니다. 살짝 틀린 숫자들이 평균되면 오차가 상쇄되기 때문에 값은 낮은 정밀도도 견딜 수 있지만, 키는 그렇지 못합니다. 그래서 새 버전(v3)에서는 키 4비트, 값 2비트를 기본값으로 잡았습니다. 평균 비트 수는 여전히 3비트여서 예산은 그대로이되 더 똑똑하게 나눠 쓰는 방식입니다.

핵심 발견 3 — “압축했더니 오히려 커졌다”는 부끄러운 버그

세 번째 변경은 조금 민망한 이야기입니다. Cesar Franco(frankcots)라는 기여자가 PR로 제보하기를, v2의 압축 경로가 실제로는 데이터를 더 크게 만들고 있었다는 것입니다. 이유는 단순했습니다. v2는 재구성된 벡터를 풀 사이즈 부동소수점(256바이트)으로 저장하고, 거기에 QJL 부호 비트 130바이트를 더해 벡터당 386바이트를 썼습니다. 원본보다 38% 더 큰 셈이고, 사실상 압축은 전혀 일어나지 않았습니다. 문제는 검증 스크립트가 “우리가 몇 비트를 쓰고 있느냐”에 기반한 이론상 압축률만 계산하고 있어서, 실제 PyTorch 텐서(tensor) 크기는 전혀 다른 현실을 가리고 있었다는 점입니다.

v3에서는 비트 시프트(bit shift) 연산으로 여러 개의 작은 인덱스를 한 바이트에 촘촘히 패킹했습니다. 같은 3비트짜리 벡터가 v2에서는 186바이트였는데 v3에서는 52바이트로 줄어, 실제 기준으로 4.9배의 “진짜” 압축이 나옵니다. 제보해 준 Cesar에게 다시 한번 감사드립니다.

핵심 발견 4 — 레이어마다 민감도가 다르다

마지막 변경은 레이어 적응형 압축(layer-adaptive compression) 입니다. Scoslab이 밝혀낸 바로는, 모델의 모든 레이어가 동일한 민감도를 가진 것이 아닙니다. 첫 번째 레이어(layer 0)는 전체 채널의 약 20%가 이상치(outlier) 로, 값이 너무 커서 압축하기 어렵습니다. 반면 중간 레이어들은 그 비율이 4~6% 수준에 그칩니다. Tom이라는 기여자는 이 연구 결과 위에서 TurboQuant+ 저장소를 만들어, 마지막 8개 레이어는 풀 정밀도로 두고 나머지만 공격적으로 압축해 3.5배 압축에서 최상급 품질을 얻었습니다.

새 버전에서는 “보호(protect)할 레이어 수”를 사용자가 지정할 수 있습니다. 기본 설정은 앞뒤 각각 4개 레이어, 총 8개를 8비트(사실상 풀 정밀도)로 두고, 나머지 28개 중간 레이어를 키 4비트/값 2비트로 강하게 압축하는 방식입니다. 실제로는 중간 레이어가 수적으로 훨씬 많아 전체 연산의 대부분을 차지하기 때문에, 양 끝의 보호 레이어 때문에 긴 컨텍스트에서 잃는 압축률은 거의 없습니다.

결과와 교훈

모든 변경을 한데 모은 뒤 v2와 동일한 검증 테스트를 다시 돌렸습니다. K4V2 설정(평균 3비트) 기준으로 v3는 5.1배 압축, 점수 유사도 99.96%, top-1 일치율 94%로 오히려 수치가 모두 올라갔습니다. 앞뒤 각 네 개 레이어를 보호한 버전은 압축률이 3.6배로 조금 낮아지는 대신 유사도가 더 올라가고 top-1 일치율이 99%까지 갔습니다. 출력 역시 정상적으로 문장을 생성했습니다.

이번 과정에서 저희가 배운 것은 세 가지입니다. 첫째, 수학적으로 더 정교하다고 더 좋은 것은 아니다 — 이론적으로 우아했던 QJL을 걷어내는 것만으로 거의 모든 문제가 풀렸습니다. 둘째, 오픈소스는 정말로 작동한다 — 이 모든 개선은 제 저장소의 커뮤니티 기여, 다른 연구자들의 공개 실험, 그리고 서로 다른 팀의 독립적 재검증 덕분이었습니다. 혼자였다면 절대 이만큼 빠르게 고치지 못했을 것입니다. 셋째, 메트릭이 아니라 생성 자체를 테스트해야 한다 — 99.5%의 점수 유사도는 출력이 쓰레기일 때 아무 의미가 없습니다. 결국 영리한 두 단계 기법보다 “MSE + 똑똑한 비트 할당”이라는 단순한 접근이 이 경우엔 더 좋았습니다.

마무리

새 버전은 tombistudio/TurboQuant-PyTorch에서 받을 수 있습니다. 제가 아는 한 이것은 여전히 윈도우 네이티브로 돌아가는 유일한 TurboQuant 구현입니다. CUDA GPU면 모두 동작하며, RTX 3060 + Qwen 2.5 환경에서 검증했습니다. 이슈와 풀 리퀘스트는 계속 환영하고 정기적으로 확인할 예정입니다. Cesar처럼 제가 놓친 부분을 지적해 주시는 것도 크게 감사합니다 — 저도 여러분과 함께 배우는 중이라 큰 실수에서 자유롭지 않지만, 이번 v3는 확실히 훨씬 나아졌다고 생각합니다. 앞으로도 새로운 연구가 나오는 대로 계속 반영하고, 가능하다면 파라미터를 자동으로 탐색해 더 나은 설정을 찾는 실험도 해볼 계획입니다.

02리서치 문서 · Document

터보퀀트(TurboQuant) 개선기: 논문의 우아함이 무너진 자리에서 커뮤니티가 찾은 것들

출처 영상: YouTube · 채널: Onchain AI Garage · 업로드: 2026-03-30 · 길이: 약 18분

서론 — “99.5% 유사도”가 쓰레기 출력을 숨기고 있었다

2026년 초, 구글(Google)은 LLM의 KV 캐시(KV cache) 메모리를 극단적으로 압축한다는 새 알고리즘 터보퀀트(TurboQuant) 를 공개했습니다. ICLR 2026에 제출된 이 논문은 두 단계 설계로 구성됩니다. 첫째 단계인 PolarQuant는 KV 벡터를 극좌표(polar coordinate)로 변환해 블록별 정규화 상수를 제거하고, 둘째 단계인 QJL(Johnson–Lindenstrauss 기반) 잔차 보정은 1비트만 써서 양자화 오차를 통계적으로 “편향 없는(unbiased)” 추정치로 만들어 줍니다(Google Research 공식 블로그).

Onchain AI Garage의 운영자는 논문 공개 직후 이를 윈도우(Windows) 네이티브 환경에서 돌릴 수 있는 PyTorch 구현체로 처음부터 재현했고, 지난 영상에서 3비트 설정 기준 5배 압축과 99.5% 어텐션 유사도라는 그럴싸한 수치를 선보였습니다. 그러나 며칠 뒤 다시 돌려본 생성 테스트는 전혀 다른 이야기를 들려주었습니다. 모델이 만든 답변 27개 중 정답이 0개였고, 대부분의 설정이 의미 없는 문자열을 뱉어냈습니다. 이 영상은 그 “99.5%의 거짓말”을 고쳐 나가며 커뮤니티가 함께 찾아낸 네 가지 개선점을 정리한 후속편이고, 이 글은 그 여정을 한국어로 풀어 쓴 기록입니다.

본론

1. 터보퀀트의 원안: PolarQuant + QJL의 우아한 두 단계

터보퀀트의 첫 단계인 PolarQuant는 고차원 벡터의 각도 분포가 집중되어 있다는 수학적 관찰에 기댑니다. 좌표를 극좌표로 바꾸면 값의 분포가 예측 가능해지고, 그 결과 블록마다 별도의 스케일(scale)을 저장할 필요가 없어져 2~3비트로도 벡터를 상당히 잘 복원할 수 있습니다. 둘째 단계인 QJL은 남은 오차에 Johnson–Lindenstrauss 변환을 적용해 1비트 부호를 덧붙이는 “수학적 오차 점검기” 역할을 합니다. 구글은 이 두 단계가 KV 캐시 압축과 고차원 벡터 검색(vector search) 양쪽 모두에서 이득이라고 논문에서 주장했습니다(Google Research, DEV Community 해설).

참조 구현체로는 Scos Lab의 scos-lab/turboquant 저장소가 가장 먼저 공개되었고, 영상의 주인공인 tonbistudio/turboquant-pytorch는 “5x compression at 3-bit with 99.5% attention fidelity”라는 README 문구까지 포함해 논문 수치를 재현했습니다.

2. 소프트맥스(softmax)가 QJL의 “불편향”을 망가뜨리는 이유

문제는 “편향이 없다(unbiased)“는 말이 평균을 내야만 참이 된다는 데 있습니다. QJL은 각 점수에 무작위 방향의 노이즈를 더하고, 그 노이즈가 여러 번 평균을 내면 0으로 수렴한다는 전제를 깔고 있습니다. 그러나 어텐션 연산 안에서 모델은 점수를 한 번만 소프트맥스에 통과시킵니다. 소프트맥스는 지수함수 기반의 증폭기라서, 입력의 작은 요동을 출력에서 불균형하게 키웁니다.

커뮤니티가 서로 다른 언어·프레임워크에서 독립적으로 관찰한 결과가 바로 이 지점을 찌릅니다. llama.cpp 쪽 토론 스레드 TurboQuant — Extreme KV Cache Quantization에서는 “QJL adds variance that softmax amplifies. Low variance (MSE) beats unbiasedness”라는 표현이 그대로 등장하고, Apple Silicon용 포팅인 turboquant-mlx와 llama.cpp 기반 AmesianX/TurboQuant 역시 QJL을 제거하거나 비활성화한 구성에서 더 나은 생성 품질을 보고했습니다. 즉 QJL이 줄여준 편향보다, 소프트맥스가 증폭한 분산이 훨씬 큰 비용이었던 것입니다.

단, 여기에는 중요한 단서가 있습니다. 구글의 원래 분석 자체가 틀린 것은 아닙니다. 벡터 검색이나 단어 임베딩 비교처럼 소프트맥스가 끼어 있지 않은 응용에서는 QJL의 불편향성이 실제로 이득입니다. 문제는 KV 캐시 압축 시나리오 — 소프트맥스 증폭이 가장 강하게 작동하는 환경 — 가 언론에서 가장 크게 다뤄졌다는 점이고, 거기서 QJL은 정반대 방향으로 작동했을 뿐입니다.

3. 비대칭 KV(asymmetric KV): 키는 민감하고 값은 둔감하다

두 번째 개선은 키(key)와 값(value)에 같은 비트 수를 주지 말자는 것이었습니다. 이론적 배경은 간단합니다. 양자화 오차는 벡터 노름의 제곱에 비례해 커지는데, 현대 LLM에서는 키 벡터의 평균 노름이 값 벡터보다 10~60배, 심지어 100배 이상 큰 경우도 흔합니다. Qwen 2.5 계열의 측정치를 보면 키 벡터 평균 크기가 172, 값 벡터는 3 — 무려 57배 차이입니다. 기능 측면에서도 키는 “어떤 토큰을 볼지”를 결정하는 정밀도 민감 연산이고, 값은 가중 평균되어 섞이는 콘텐츠라 오차가 상쇄되기 쉽습니다.

llama.cpp 커뮤니티는 이를 일찍이 수용해 키와 값에 서로 다른 캐시 타입을 지정하는 플래그를 도입했습니다. 가령 --cache-type-k turbo3 --cache-type-v turbo4 같은 옵션이 그 결과이며, 관련 논의와 한계점은 Issue #20866 (비대칭 K/V 캐시가 GPU로 오프로드되지 않는 문제)에 정리되어 있습니다. SOTAAZ가 정리한 실전 튜토리얼 TurboQuant in Practice — KV Cache Compression with llama.cpp and HuggingFace에서는 K/V 노름 비율에 따라 “3비트 균일 → 4.5~5비트 비대칭 → 5.5비트 이상”로 비트 예산을 조정하라는 실무 규칙까지 제시합니다. 영상 속 v3가 기본값으로 삼은 키 4비트/값 2비트는 이 흐름과 정확히 맞닿아 있습니다. 평균 비트 수는 여전히 3비트지만 예산을 더 똑똑하게 배분한 결과입니다.

4. 비트 패킹 버그와 “이론 압축률 vs 실제 텐서 크기”

세 번째 개선은 다분히 엔지니어링적인 이야기입니다. v2는 양자화 후 재구성한 벡터를 여전히 풀 사이즈 부동소수점 텐서(256바이트)로 저장하고, 거기에 QJL 부호 비트 130바이트를 덧붙이고 있었습니다. 결과적으로 벡터당 386바이트 — 원본보다 38% 더 큰 메모리를 쓰면서도 검증 스크립트는 “이론상의 비트 수”만 보고 5배 압축이라고 보고하고 있었던 것입니다. 이 불일치는 기여자 Cesar Franco의 PR에서 드러났고, v3에서는 여러 인덱스를 바이트 하나에 채워 넣는 비트 패킹(bit packing)으로 실제 텐서 크기를 줄여 같은 3비트 설정이 186바이트에서 52바이트로 떨어졌습니다. 즉 “진짜” 4.9배 압축입니다.

이 장면은 단순한 잔버그 수정이 아니라 하나의 교훈입니다. KV 캐시 양자화 도구를 쓸 때는 torch.cuda.memory_allocated() 같은 실측치와, 도구가 리포트하는 이론 압축률을 반드시 분리해서 봐야 합니다. 특히 llama.cpp처럼 다양한 백엔드와 양자화 타입을 혼합하는 환경에서는 동일 옵션이라도 실제 메모리 절감이 플랫폼마다 다를 수 있습니다.

5. 레이어 적응형(layer-adaptive) 압축: 모든 레이어가 평등하지 않다

마지막 변경은 레이어마다 압축 민감도가 다르다는 사실을 반영한 것입니다. Scos Lab의 측정에 따르면 모델의 첫 레이어(layer 0)는 채널의 약 20%가 이상치(outlier)이며 값이 너무 커서 공격적인 양자화에 취약합니다. 중간 레이어는 같은 지표가 46%에 불과해 훨씬 너그럽게 압축할 수 있습니다. 이 관찰 위에서 TurboQuant+ 계열 구현들은 앞뒤 몇 개 레이어를 8비트에 가깝게 보호하고 나머지만 공격적으로 압축해 3.54배 압축에서 탑 티어 품질을 확보합니다.

영상 속 v3는 “앞 4개, 뒤 4개 레이어를 8비트로 보호하고 나머지 28개 중간 레이어를 K4V2로 압축”하는 기본값을 제안합니다. 중간 레이어가 수적으로 훨씬 많기 때문에, 양 끝 보호가 긴 컨텍스트에서도 전체 압축률을 크게 희생하지 않는다는 점이 설계상 핵심입니다. 최종 벤치마크에서는 보호 없는 K4V2 설정이 5.1배 압축·99.96% 점수 유사도·94% top-1 일치를, 레이어 보호 버전이 3.6배 압축·99% top-1 일치를 기록했습니다.

핵심 인사이트

  • “이론적으로 우아한 것”과 “실제로 잘 작동하는 것”은 다르다. QJL은 수학적으로 편향이 없는 추정량이지만, 소프트맥스가 끼어 있는 실제 어텐션에서는 그 불편향을 얻기 위해 치르는 분산 비용이 훨씬 컸습니다. 단순한 MSE가 이기는 시나리오였던 것입니다.
  • 메트릭과 실측 사이의 간극을 항상 의심하라. 99.5% 어텐션 유사도라는 지표는 생성 품질 0점 출력을 가릴 수 있었고, “이론 압축률”은 실제 텐서 크기가 되레 늘어나는 상황을 가릴 수 있었습니다. 검증 파이프라인에는 반드시 “실제 메모리”와 “실제 생성”을 넣어야 합니다.
  • 오픈소스 + 재현 연구 루프는 빠르고 혹독하다. 구글 논문 공개 후 몇 주 안에 Scos Lab, llama.cpp 포크 여러 개, MLX 포팅, 윈도우 네이티브 구현이 독립적으로 등장했고, 서로 다른 언어와 모델에서 QJL 제거 / 비대칭 KV / 레이어 적응이라는 동일한 결론에 도달했습니다. 단일 팀이라면 훨씬 더 오래 걸렸을 해석입니다.
  • “예산은 같되 더 똑똑하게 쓴다”는 원칙. K4V2는 평균 3비트라는 점에서 균일 3비트와 같은 비트 예산이지만, 키에 더 많은 비트를 몰아주는 것만으로 품질이 분명히 올라갑니다. 압축 전략은 “얼마나 줄이느냐”만큼이나 “어디에 쓰느냐”의 문제입니다.

더 알아보기

03찬반 토론 · Debate

토론: “이론적으로 우아한 QJL보다, 단순한 MSE + 비대칭 비트 할당이 KV 캐시 압축에는 더 낫다”

논제: 터보퀀트(TurboQuant)의 QJL 보정 단계는 KV 캐시 압축에서 제거되어야 하며, 실전에서는 단순한 MSE 양자화 + 비대칭 KV(K4V2) + 레이어 보호 조합이 더 나은 기본값이다.

Round 1

🟢 Pro — “QJL은 소프트맥스 앞에서 스스로 무너진다”

Pro의 입장은 분명합니다. 구글의 터보퀀트 논문이 제시한 QJL 잔차 보정은 수학적으로는 편향 없는(unbiased) 추정량을 만들어 주지만, 이 수학적 우아함은 실제 어텐션 파이프라인에 소프트맥스(softmax)가 끼어 있는 순간 비용으로 바뀝니다. 소프트맥스는 지수함수 기반의 증폭기이기 때문에, QJL이 뿌려 놓은 무작위 분산(variance)을 선형이 아니라 지수적으로 키웁니다. 편향이 0인 것보다 분산이 작은 것이 훨씬 중요한 상황인 셈입니다.

이 주장은 한 명의 유튜버가 혼자 내린 결론이 아닙니다. Scos Lab, llama.cpp 포크 여러 개, Apple MLX 포팅(turboquant-mlx), 윈도우 네이티브 PyTorch 구현(tonbistudio/turboquant-pytorch), 그리고 Oaxero 같은 프로덕션 배포자에 이르기까지 서로 다른 언어·하드웨어·모델에서 독립적으로 동일한 결론에 도달했습니다. “QJL을 빼니까 오히려 생성 품질이 올라갔다”는 것입니다. 서로 다른 실험자가 동일 방향의 결과를 보고하는 것은 과학적 증거로서 꽤 강한 종류입니다.

게다가 영상에서 드러난 검증 실패는 단순한 수치 차이가 아니라 생성 파탄입니다. 99.5% 어텐션 유사도라는 숫자가 “비밀 프로젝트 코드명이 뭐냐”는 질문에 27/27 오답을 가리고 있었고, QJL을 제거한 v3는 같은 비트 예산에서 top-1 일치율 94%와 정상적인 생성을 복원했습니다. 따라서 “이론적 우아함”을 지키려다 생성이 망가진다면, KV 캐시 용도에 한해서는 QJL을 제거하는 것이 옳은 기본값입니다.

🔴 Con — “국소 수정으로 근본 설계를 버리지 말라”

Con의 첫째 반박은, 지금까지 보고된 “QJL 제거가 더 낫다”는 결과가 대부분 특정 환경 — RTX 3060 같은 소비자 GPU, Qwen 2.5 / LLaMA류 소프트맥스 어텐션 모델, 상대적으로 짧거나 중간 길이의 컨텍스트 — 에 편향되어 있다는 점입니다. 구글의 원 논문은 KV 캐시뿐 아니라 벡터 검색까지 염두에 두고 설계된 일반 압축 스킴이고, QJL의 편향 제거는 Johnson–Lindenstrauss 변환의 이론적 보증 위에 서 있습니다. 실험 조건을 바꾸면 — 긴 컨텍스트, 시그모이드·선형·게이티드 어텐션, 배치 단위 평균화가 더 지배적인 서빙 환경 — QJL의 불편향성이 다시 이득이 될 가능성이 큽니다.

둘째로, “단순한 MSE가 더 낫다”는 주장은 비교 기준 자체에 구조적 취약점을 안고 있습니다. 영상에서 제시한 v2의 실패 원인 중 상당 부분은 QJL 그 자체가 아니라 구현상의 버그 — 재구성 벡터를 풀 사이즈 부동소수점으로 저장해 압축이 전혀 일어나지 않았던 비트 패킹 미적용 — 에서 비롯되었습니다. 즉 우리가 보고 있는 것은 “QJL 대 MSE”의 공정한 비교라기보다 “버그가 섞인 QJL 구현 대 버그를 고친 MSE 구현”의 비교일 수 있습니다. 같은 에너지를 QJL 경로의 스케일·부호 비트 배치, 정밀도 상한 튜닝에 쏟았다면 결과는 또 달라졌을 것입니다.

셋째로, Con은 “제거”라는 이분법 자체에 반대합니다. 논문이 제안한 프레임 안에서 QJL은 아직 구성 가능한 보정 단계로 남겨 두는 것이 맞습니다. 벡터 검색, 임베딩 비교, 소프트맥스 없는 새로운 어텐션 변형 등 여러 응용에 같은 코드를 재사용하려면, 기본값을 끄되 활성화 옵션을 보존하는 것이 옳은 엔지니어링 결정입니다. 한 시나리오의 패배를 이유로 알고리즘 전체를 잘라내는 건 과잉 반응입니다.

Round 2

🟢 Pro (재반론) — “Con의 논점은 모두 운영 현실과 어긋난다”

Con의 첫째 반박 — “결과가 특정 환경에 편향되어 있다” — 에 대해 말하겠습니다. 실제로 이번 사례는 “동일 환경”이 아니라 서로 매우 다른 환경 에서 수렴한 결과입니다. Apple Silicon의 MLX, 리눅스 서버 GPU 위의 llama.cpp, 윈도우 RTX 3060의 PyTorch, 그리고 Oaxero의 프로덕션 배포가 서로 다른 모델 패밀리와 다른 양자화 경로에서 같은 방향으로 갔다는 점이 오히려 가장 강한 증거입니다. 소프트맥스 어텐션을 쓰는 한 QJL이 분산 증폭으로 손해를 본다는 것은 국소 현상이 아니라 구조적 현상에 가깝습니다. Con이 언급한 시그모이드·선형 어텐션 이야기는 Pro도 동의하지만, 그런 모델이 현재 로컬 LLM 생태계의 주류가 아니라는 점을 간과하고 있습니다. 기본값은 주류 사용자를 위한 것이어야 합니다.

Con의 둘째 반박 — “MSE의 승리는 사실 버그 수정의 승리일 수 있다” — 에 대해서는, 이번 영상의 벤치마크 표가 바로 그 지적을 공정하게 만들어 놓았습니다. v2 대비 v3는 비트 패킹 버그 수정 외에도 QJL 제거·K4V2 비대칭·레이어 보호를 분리해서 실측했고, 그 중 생성 품질의 붕괴를 원상복구한 결정적 요소는 단연 QJL 제거였습니다. 비트 패킹은 실제 메모리 숫자를 바로잡은 것이지, 모델 출력의 의미 파탄을 고친 것이 아닙니다. Con이 암시하는 “공정한 비교가 아니다”라는 주장은 결과를 설명하지 못합니다.

Con의 셋째 반박 — “구성 가능하게 남겨 두라” — 는 Pro가 이미 수용한 부분이기도 합니다. 실제 v3 저장소는 QJL을 삭제하지 않았습니다. 기본값을 끈 것뿐입니다. 논쟁의 핵심은 “알고리즘을 없애느냐”가 아니라 “KV 캐시 사용자의 기본값으로 무엇을 제시하느냐”이고, 이 질문에 대해 Pro의 답은 “소프트맥스가 있는 한 꺼라”입니다. 이는 보존과 실용의 타협이지 이분법이 아닙니다.

🔴 Con (재반박) — “Pro는 ‘단순함’과 ‘정당성’을 혼동하고 있다”

Pro의 첫째 주장 — “소프트맥스 증폭 때문에 QJL은 구조적으로 진다” — 에는 한 가지 중대한 생략이 있습니다. 소프트맥스가 분산을 증폭한다는 설명은 직관적으로는 맞지만, 그 증폭이 얼마나 심한지는 점수의 분포와 온도(temperature), 그리고 로짓의 스케일에 강하게 의존합니다. 즉 “QJL이 언제나 진다”가 아니라 “현재 튜닝되지 않은 하이퍼파라미터 조합에서 진다”가 더 정확한 서술입니다. 터보퀀트 원 논문 저자들이 재반박 형태로 QJL 단계에 전용 스케일 정규화를 붙인 변형을 공개하면, 같은 비교가 다시 뒤집힐 수 있습니다.

Pro의 둘째 주장 — “벤치마크 표에서 QJL 제거가 분리되어 측정되었다” — 역시 조심스럽게 읽어야 합니다. 생성 테스트에 사용된 프롬프트는 “비밀 프로젝트 코드명” 같은 정확한 토큰 재현을 요구하는 강한 retrieval 과제였습니다. 이런 과제는 분산 증폭에 극단적으로 취약한 특정 실패 모드를 과대 표현합니다. 반대로 요약, 분류, 체인 오브 소트(chain-of-thought) 같은 분포 수준 과제에서는 QJL의 불편향성이 누적 오차 억제에 더 유리하게 작동했을 수 있습니다. 하나의 실패 과제로 알고리즘 전체를 판결하는 것은 위험합니다.

Pro의 셋째 주장 — “여러 구현체가 수렴했으니 구조적이다” — 에 대해서는, Con은 이것을 에코 체임버(echo chamber) 위험 으로 봅니다. 커뮤니티 구현들은 대부분 서로의 이슈 트래커와 디스코드를 참조하고, 한 번 공유된 “QJL은 해롭다”는 프레임이 다른 팀의 디버깅 방향을 유도합니다. 진정한 독립성은 논문 저자들이 직접 대규모 서빙 환경에서 재현 실험을 해 줄 때 비로소 확보되고, 그전까지 “수렴했으니 끝난 이야기”라고 선언하는 것은 성급합니다. 단순함이 매력적인 것과 단순함이 정당한 것은 다릅니다.

Round 3

🟢 Pro — “Con의 하이퍼파라미터 희망론과 에코 체임버 논증에 답한다”

Con의 재반박 첫째 — “스케일 정규화만 붙이면 QJL이 다시 이길 수 있다” — 는 듣기 좋은 미래형 가설이지만, 지금 운영되고 있는 구현체와 배포에는 도움이 되지 않는 주장입니다. Pro의 입장은 학술적 “영원한 패배 선언”이 아니라 2026년 4월 기준의 기본값 권고입니다. 논문 저자들이 개선된 QJL+를 공개하면 Pro는 기꺼이 기본값을 되돌릴 준비가 되어 있습니다. 그러나 그 재반박이 실험적으로 검증되기 전까지, 윈도우에 Qwen 2.5를 올리는 사용자는 오늘 밤 돌릴 수 있는 설정이 필요합니다. “언젠가 튜닝하면 이길 수 있다”는 주장은 지금의 기본값 선택을 뒤집을 근거가 되지 못합니다.

Con의 재반박 둘째 — “retrieval 과제만 실패 모드를 과대 표현한다” — 에 대해서는, Pro는 오히려 그 주장이 자신의 발 밑을 허무는 모양이라고 봅니다. KV 캐시 압축의 가장 흔한 사용 사례 중 하나가 바로 긴 문서에서 특정 정보를 꺼내 쓰는 retrieval 지향 작업 입니다. RAG 파이프라인, 코드 어시스턴트의 심벌 재호출, 문서 QA 등은 전부 “정확한 토큰을 복원할 수 있느냐”에 직결되어 있고, 이것이 취약한 시나리오라면 KV 캐시 압축 기법으로서의 가치가 바로 그 지점에서 평가받아야 합니다. Con의 “분포 수준 과제에서는 QJL이 이길지도 모른다”는 가정은 실측 데이터 없이 제시된 상태이고, 있는 실측 데이터는 모두 반대쪽을 가리킵니다.

Con의 재반박 셋째 — “커뮤니티 수렴은 에코 체임버일 수 있다” — 는 표면적으로는 학문적 경계의 태도이지만, 실제로는 반증 가능성을 확보하지 못합니다. 에코 체임버 가설을 반증하려면 “독립 재현이 여러 차례 실패한다”는 증거가 필요한데, 지금 우리가 보고 있는 것은 정반대로 독립 재현이 여러 차례 같은 방향으로 성공한다는 데이터입니다. Con이 요구하는 “논문 저자 직접 재현”은 좋지만 필요조건이 아닙니다. 과학사에서 논문 저자가 스스로 자기 설계를 부정한 예는 드물지만, 외부 재현이 누적되어 기본값이 바뀐 예는 흔합니다.

🔴 Con — “Pro의 ‘오늘 밤 실용주의’는 기술 선택의 성숙을 지연시킨다”

Pro의 재반론 첫째 — “오늘 밤 돌릴 설정이 필요하다” — 에 대해 Con은 그 실용주의의 방향이 오히려 장기적인 기술 정체를 낳을 수 있다고 봅니다. 한 번 “이론적으로 우아한 것은 실전에서 진다”는 서사가 커뮤니티 기본값으로 굳으면, 이후 논문이 개선된 QJL+나 다른 편향-분산 교환 설계를 가져와도 재검토가 어려워집니다. 기본값은 단순한 추천이 아니라 새로운 실험의 출발점 이기 때문에, “오늘 밤 돌리는 사람”의 편의를 위해 탐색 가능성을 좁히는 결정은 신중해야 합니다.

Pro의 재반론 둘째 — “retrieval이야말로 가장 흔한 사용 사례다” — 도 부분적으로만 맞습니다. 현대 서빙 스택은 KV 캐시 압축만 쓰는 것이 아니라 FP8 양자화, Flash Attention, 연속 배칭(continuous batching), 투기적 디코딩(speculative decoding)을 함께 쌓아 올립니다. 이 스택 안에서 retrieval 품질 손실은 주로 RAG 단의 인덱싱·재랭킹에서 보완되고, KV 캐시 쪽은 “평균적으로 안정적”인 것이 더 중요해지는 경우가 많습니다. 즉 영상 속 단독 벤치마크는 프로덕션 전체 스택의 판단 기준으로 바로 확장되지 않습니다. Pro가 언급한 “로컬 LLM 사용자”에게는 의미 있는 기본값일 수 있지만, 대형 서빙 환경의 기본값까지 같은 결론으로 가는 건 비약입니다.

Pro의 재반론 셋째 — “독립 재현이 여러 번 성공했다” — 에 대해서도 Con은 “성공의 정의”를 다시 묻고 싶습니다. 지금까지 모인 재현은 공통적으로 “QJL을 끄면 같은 비트 예산에서 생성이 살아난다”는 관찰이지, “QJL이 제공하려 했던 이론적 이득 — 편향 제거, Johnson–Lindenstrauss 거리 보존 — 이 실전에서 불필요하다”는 증명은 아닙니다. 그 둘은 다른 주장이며, 후자를 증명하려면 소프트맥스 증폭을 완화한 여러 변형을 모두 돌려 보고 그것들이 모두 지는 것을 보여야 합니다. 그런 실험은 아직 공개되지 않았습니다. 따라서 Con의 결론은 “QJL을 기본값에서 꺼도 좋다, 그러나 알고리즘 전체를 ‘틀렸다’고 선언할 시점은 아직 아니다”입니다.

🧭 종합

합의 지점

양측 모두 인정하는 사실이 존재합니다. 첫째, 소프트맥스 기반 어텐션에서 무작위 잡음은 지수적으로 증폭되며, 이는 QJL 스타일 보정이 KV 캐시 경로에서 불리한 구조적 이유가 된다는 점. 둘째, 현재 공개된 다수 구현이 QJL 제거 + 비대칭 비트 할당 + 레이어 보호 조합에서 더 나은 생성 품질을 보고한다는 관측 사실. 셋째, QJL은 벡터 검색·임베딩 비교 등 소프트맥스가 없는 응용에서는 여전히 이론적으로 유효하며 보존할 가치가 있다는 것. 그리고 가장 실용적인 합의로, 알고리즘을 “삭제”하는 것이 아니라 KV 캐시 사용자의 기본값에서만 끄는 절충은 양측이 모두 받아들일 수 있는 지점입니다.

열린 질문

  • 소프트맥스 증폭을 완화하는 QJL 변형(스케일 정규화, 온도 보정, 레이어별 분산 감쇠 등)이 나온다면, 편향-분산 교환이 다시 QJL에게 유리해질 수 있는가?
  • 시그모이드·선형·게이티드 어텐션 같은 차세대 아키텍처에서 QJL은 실제로 이득을 회복하는가? 아직 실측 데이터가 적다.
  • 대형 서빙 스택(FP8 + 연속 배칭 + 투기적 디코딩)과 결합했을 때 비대칭 K4V2의 결론은 그대로 유지되는가, 아니면 최적 비트 배분이 달라지는가?
  • retrieval 지향 벤치마크가 KV 캐시 양자화 평가의 “기본 과제”로 자리 잡아야 하는가, 아니면 요약·CoT·대화 유지 같은 분포 과제와 균형을 맞춰야 하는가?
  • Scos Lab이 보고한 “첫 레이어 20% 이상치 채널”은 모델 패밀리에 따라 얼마나 일반화되며, 이상치 채널을 별도 정밀도로 다루는 혼합 정밀도 레이아웃은 이 논쟁을 어떻게 바꾸는가?

더 나아간 관점

이 논쟁이 진짜로 가리키는 것은 “평가 파이프라인 자체가 알고리즘의 일부”라는 사실일 수 있습니다. 터보퀀트 v2는 99.5%의 어텐션 유사도라는 숫자를 갖고도 생성 품질이 0에 수렴했고, 같은 저장소가 이론상 압축률을 보고하면서 실제 텐서는 38% 더 커져 있었습니다. 두 가지 모두 “메트릭과 실체의 분리” 라는 동일한 실패 모드의 사례입니다. 앞으로의 KV 캐시 압축 도구는 알고리즘 선택만큼이나 “어떤 벤치마크를, 어떤 스택에서, 어떤 실측 기준으로 돌리는가”를 공개 스펙으로 함께 제공해야 할 것이고, 이 영상이 보여 준 것은 바로 그 관행의 부재가 얼마나 빨리 커뮤니티를 잘못된 방향으로 이끌 수 있는가였습니다.

또 하나의 관점은, “우아한 이론의 패배”가 아니라 “경계 조건의 재발견”으로 이 사건을 읽는 것입니다. QJL은 평균화가 허용되는 시스템 — 대규모 검색, 벡터 임베딩, 확률 분포 추정 — 에서는 여전히 뛰어난 도구이고, 소프트맥스는 그런 평균화를 허용하지 않는 비선형입니다. 따라서 이번 논쟁의 교훈은 “QJL은 나쁜 아이디어였다”가 아니라 “모든 압축 알고리즘에는 자신이 살아남을 수 있는 비선형 경계가 있다” 는 것이며, KV 캐시 압축 분야의 다음 세대 기법은 이 경계 조건을 설계 초기부터 명시적으로 다룰 것입니다. 그것이 Pro의 실용주의와 Con의 보수주의가 만나는 지점이고, 이 토론이 가리키는 가장 생산적인 방향입니다.

04영문 원본 · Transcript
So last week, Google announced this new compression algorithm, TurboQuant, and I put out a video
kind of breaking down what it was, and then testing my own implementation.
There's not an official release yet, but there was enough from the papers that you could
develop your own implementation, and that's exactly what we did in last week's video.
In this week's video, I want to kind of follow up on that and improve upon our TurboQuant
implementation for Windows users, and this is completely open source.
You can find it on GitHub at tombistudio.com slash TurboQuant dash PyTorch, so you can
see this all, all the code for yourself.
People were kind enough to leave issues, leave pull requests, and we got 581 stars, which
is really, really nice.
I appreciate the support.
So quick recap of what we did last week, what we built.
So we recreated.
We created this algorithm that compresses the model's memory, KV cache, so it uses three
to seven times less GPU space, and this is very specific.
I got a lot of questions and some confusion.
You're not actually compressing the model's weights.
That's very important to specify.
This is just for the KV cache, which is the memory.
It does take up space, but you still on your machine will need to have the space for the
actual model weights.
So how it works is in two stages.
You rotate and quantize.
You spin the numbers randomly and then round them to save space.
And then it uses QJL error correction, which is a one-bit fix to reduce the rounding errors.
So we built this from scratch in PyTorch and then tested it on my PC, which has a RTX 3060
with 12 gigs of VRAM.
So we validated it, and version two of our implementation looked really great on paper.
The three-bit got 5x compression.
We had...
99.5% similarity in attention scores.
At four bit, we had 99.9% similarity.
So the model was looking at almost exactly the same words as the uncompressed version.
So at the end of the last video, these were the numbers I showed you, and I was pretty happy with it.
Considering I had only put it together in a couple hours after they had announced it, just a quick validation test.
But in the days after...
The community has really come out and been able to test this more rigorously.
Myself, I've been able to, in Cloud Code, look at it a little bit more and push it and try to see how we can improve upon it
and what the flaws are with our current version.
And there was one very obvious flaw, which was that that generation was completely broken.
When we asked the model, what is the secret project code name?
None of the versions actually got us.
Zero out of 27.
20% of 27 of the tests passed.
Every config produced garbage, and this was obviously a serious issue.
So our validation was correct.
And with validation, it was just running the model once on a document, capturing the KV cache, compressing it, and comparing the numbers.
So think of this like checking if a compressed JPEG looks similar to the original by measuring the pixel differences.
But with generation, this was the real test.
And this actually makes the model write a response.
Using the compressed KV cache.
So every new word it generates gets fed back in, and it uses the compressed memory to decide the next word.
So errors compound.
Each slightly wrong word shifts the next word's prediction, which shifts the next one.
So that was in our version that we ended the episode with last video.
It had that kind of fatal flaw in it, which I found after some more testing.
But thankfully, in addition to my own kind of research,
on my repo, a lot of the community showed up.
And there's been a lot of community efforts to try to recreate this algorithm, improve upon it.
Especially in the local LLM community, there was a lot of excitement.
I'm going to try to credit everyone here, but please forgive me if I miss somebody.
But these were just the other community members who I found had improved upon this algorithm somehow.
Now, most of them are using Macs.
A lot of the local LLM community uses Macs.
Some use Linux.
Or like server GPUs, like CUDA.
But for a Windows-specific implementation, I think we're the only one.
Please forgive me, like I said, if I'm missing anybody here.
So the key finding, and six different teams found this with different languages and different models,
is that the QJL layer makes things actually a lot worse.
So Scoslab, which has their repo here, they found this.
The LLM.
Lama.cpp, multiple teams independently removed QJL.
Our repo, thankfully, some community members ran these scripts themselves,
comparing it just with the MSE or with QJL.
And they found the same results.
And Oaxero, who is a community leader in the local LLM community,
also used the MSE only in production deployment.
So that was a key finding.
In the follow-up research.
So to understand why QJL fails in this case, you need to understand one thing.
And this is Softmax.
And so what is Softmax?
When the model decides which words to pay attention to,
it doesn't just use the raw scores.
It runs them through Softmax, which is basically an amplifier.
That's the best way to think of it.
So look at this.
If the raw scores are similar like this, 10, 10.1, 9.9.
So the Softmax will amplify them.
33, 37, 30, somewhat balanced.
But if you change the scores slightly, 10, 10.5, 9.5.
So now you're moving 0.5 in either direction instead of 0.1.
You can see it amplified it a lot, 24, 40, 15.
So a tiny change in the input became a huge change in the output.
So this Softmax is an amplifier.
Small differences in, big differences out.
So this was a key finding.
So why did...
QJL hurt after Softmax was applied?
QJL's promise is that it adds random noise to each score.
But on average, the noise cancels out.
You get the right answer if you average enough tries.
So that's called being unbiased.
And mathematically, it was true.
We found that in our math test.
It was true.
But the model itself doesn't average.
It runs every score through Softmax once.
And Softmax amplifies that random noise.
Exponentially.
So if you look at this bullseye on the left,
you can see QJL scatters its estimates around the center.
So that's fine for raw scores or in theory on paper.
But when you're using Softmax on the right here,
you can see in red, those small random offsets get blown up.
The dots fly outward.
So MSE only without the QJL is slightly off center.
It has a small consistent bias, but it is consistent.
And Softmax can handle those consistent biases.
It can't handle random noise like this.
So was Google completely wrong?
Not really.
It was just trying to solve for a different approach here.
So their paper used two use cases, KV cache compression and vector search.
So vector search is when you're looking up similar items in a database.
So it's like finding similar images or documents.
There's no Softmax, though, in this process.
You can.
You can compare numbers directly.
And for that, QJL's unbiased guarantee genuinely helps.
Their benchmark results on
word embeddings are real and valid.
The problem is that KV cache results got
all the headlines, and that's where QJL really hurts.
It's also worth noting that not every model uses Softmax.
So like newer architecture,
like the sigmoid attention or linear attention, gated attention.
They don't have this amplification problem
because they don't use Softmax amplification,
and they could still benefit from QJL being involved.
So I know I went into this a little bit
in depth, but that was kind of the key finding throughout the last couple of days.
So the other change we found was to give keys more bits than values.
And this is asymmetric KV, it's considered.
This was found by Scoslab, like I mentioned them before.
.
Who has a repo as well, TurboQuant.
The LL, the LLama CPP community,
they have their own discussions on this topic,
but they found that giving keys more bits than values was an important factor.
Scoslab tested eight models and measured
how big the key and value vectors actually are.
On QEN 2.5 key vectors have an average magnitude of 172.
So the value vectors,
just three, that's a 57 times difference.
OX, Serro independently use different
bit widths for keys and values in their production
deployment. Three bits for keys, two bits for values.
And the LLama community found the same thing.
Mixed configurations outperform uniform.
So why does this make sense?
Keys decide which words the models focus on.
That's the precision sensitive decision.
Values are actual content that gets averaged together.
When you average a bunch of slightly off numbers, the errors cancel out.
So the values can tolerate lower precision.
In our new version, we defaulted to four bits for keys and two bits for values.
We found through the research that that was the best balance.
So it's the same budget, just smarter spending.
So let me show you why this matters with like a direct comparison.
So the uniform three bit, which we were using previously,
gives every number keys and values the same three bits.
So our version three, our new version,
which has four keys, two values, it also averages three bits.
So change three.
And this one was a bit embarrassing.
A contributor named Cesar Franco's Frank Cots here.
He opened a PR and pointed out that our version two,
the previous version compression was actually making things bigger, not smaller.
So here's what happened.
Our version stored the reconstructed
vector as a full size floating point number, which is 256 bytes plus the QJL signs.
And that was another 130 bytes.
So together it was 386 bytes per vector.
And that's actually 38 percent bigger than the original.
So that was a pretty big mess up.
There was no actual compression at all.
So our validate script was reporting
theoretical compression ratios based on how many bits we were using.
But the actual PyTorch tensors in memory told a completely different story.
So thank you to Cesar for finding this and submitting that PR.
It was an oversight on my part, but I appreciate the help.
So our version three here, the new version packs multiple small
indices into each byte using bit shifting operations.
So the three bit vector that was 38,
186 bytes in the previous version is now 52 bytes in our new version, version three.
So that's a real 4.9 times real compression.
So once again, thank you to Cesar for pointing that out.
So this is the last change we had.
Scores, Scoslab, once again, this repo here.
They found that not all layers in the model are equally sensitive.
Scos found that layer zero, the very first
layer at about 20 percent of its channels is outliers,
which means that they have unusually large values that are really hard to compress.
The middle layer is only four to six percent.
So
then the Tom here also has a repo turbo quant plus.
They kept the final eight layers at full compression and compressed everything else
they built on top of the Scoslab research and they got top tier quality at 3.5 times
compression.
So in our version, our new version, I should say, you can set how many layers to protect.
The visualization here kind of shows you the first four and last four get eight
bits, essentially full precision, the 28 middle layers get compressed
aggressively with the four keys and two values.
The protected layers barely cost any compression at the long context because
there's so many middle layers doing the actual heavy lifting.
So here's.
Kind of a summary of everything we had together.
We removed QGL, that was the big one.
The asymmetric keys and values, bit pack storage and the layer adaptive.
So then we actually ran our results,
ran the same validation test that we did previously on the previous version.
And you can see how we did this.
V2 is the previous one that you guys saw in the video.
V3 is the one our improved new and improved one.
And with the KV.
K4 V2.
So this is equal to a three bit model or a three bit algo.
We got a five point one times compression with point nine nine point nine six
similarity, so actually an improvement and top one match was up to ninety four.
And then with the product protected version.
How, which is like I said before, is when you're
going to detect the first four and last four layers.
Compression was a little bit lower, three point six times,
but the score similarity went even higher.
Top one match was ninety nine percent, so pretty good results.
So the changes that we got through our own
research and through the community really improved.
So what did we learn from this?
Pretty great results.
We learned that more math isn't always
better, removing the theoretically elegant QGL fixed a lot.
Open source works.
Because this was all.
All these changes came from either community members from my own repo
or looking into other repos or trying to figure out the direction that other
researchers are doing and then researching that same direction on my own hardware.
And it wouldn't have been possible just me doing it alone.
So like I said, thank you to everyone who was involved with this.
So we learned you need to really test the generation, not just the metrics.
Ninety nine point five percent.
Score similarity meant nothing when the output was garbage and then simple beats
clever MSE only with smart bit allocation outperforms the paper's two stage approach
in this case.
So, like I said, this is some of the people that I some of the research and repos
that I looked at, as well as people bringing up issues in my own repo.
Once again, thank you, everyone.
Sorry if I'm missing people here.
These were just the ones that I found.
So, yeah, try it yourself.
The new version is here.
Tombi Studio TurboQuant
Dash PyTorch. This is the new version.
Try it out yourself. See what results you get.
Like I said, this is the only
Windows native version that I've seen so far.
Like I said, sorry if I'm missing people.
Just what I've seen.
So it works on any CUDA GPU and we tested on RTX 3060 using QEN 2.5.
And please let me know. Please add to the issues.
I've got some pull requests.
I'll check them.
I'll check them regularly.
And please feel free to let me know if I've screwed up anything like Cesar here did here.
I'm learning as well as you about all this.
So I'm certainly not immune from big mess ups, but
hopefully I think this this new version is a lot better.
Anyway, that's all for this video.
Just improving our TurboQuant
PyTorch for Windows specifically, and I'll continue to work on this.
See what new research comes out there.
I'll continue to work on it myself.
Maybe I'll run auto research as well on it to see if we can get better results
tweaking the different parameters or whatnot.
Anyway, leave a like, please subscribe to the channel.
I'm going to have a lot more videos like
this looking into different ways to kind of run larger and better.
LLMs locally on your own device, and I'll see you in the next video.
Thank you.