TurboQuant — что это, чем он полезен и насколько хорош - Академия Selectel

TurboQuant — что это, чем он полезен и насколько хорош

Тирекс
Тирекс Самый зубастый автор
14 августа 2026

Разбираемся с алгоритмом TurboQuant, который наделал много шума в начале 2026.

Изображение записи

В марте 2026 года Google публикует пост про алгоритм сжатия памяти для языковых моделей. Звучит скучно, правда? Но акции Micron, SanDisk, Samsung, SK Hynix и других производителей памяти за неделю теряют суммарно почти $90 млрд капитализации. Инвесторы паникуют: если модели начнут тратить в разы меньше памяти, то зачем столько железа?

Алгоритм, который навел весь этот шум, называется TurboQuant — герой этой статьи.

Я не буду говорить, что это «революция» или «переворот в индустрии» — это было бы явное преувеличение. Но штука действительно интересная, и уже есть рабочие реализации. Если вы деплоите LLM в продакшн или просто прогоняете модели локально, то вам 100% будет полезно об этом узнать. Разберем, что из заявленного правда, а что преувеличение, и главное — как это попробовать прямо сейчас.

Главная уязвимость LLM: в чем проблема с KV-кэшем

Чтобы понять, зачем нужен TurboQuant, нужно сначала понять, что такое KV-кэш и почему он может стать проблемой. Дальше совсем на пальцах постараюсь рассказать, о чем речь.

Когда LLM генерирует текст, на каждом шаге она учитывает все предыдущие токены. Чтобы не пересчитывать их заново, модель сохраняет промежуточные вычисления в памяти. Это и есть KV-кэш (Key-Value cache). Штука достаточно полезная: без нее инференс был бы в разы медленнее и дороже — это обусловлено самим устройством слоев внимания.

Но есть проблема: KV-кэш растет линейно с длиной контекста (чем длиннее текст мы генерируем, тем больше данных нужно хранить).

Вот конкретные числа, чтобы прочувствовать масштаб: у модели Llama 3.1 70B при контексте 128K токенов KV-кэш в формате BF16 занимает около 40 ГБ (при использовании Grouped Query Attention с 8 KV-головами). Сама модель в BF16 весит порядка 140 ГБ. В итоге один запрос требует 180 ГБ памяти, из-за чего он не помещается на ускоритель H100 (80 ГБ) даже в одиночку. Если же нужно параллельно обслуживать четырех пользователей на контексте в 128K, только под KV-кэш уйдет 160 ГБ — а это уже больше, чем весят сами параметры модели.

Где это критично

Проблема KV-кэша становится критической в трех сценариях. При RAG-подходе с большими документами попытка загрузить в контекст кодовую базу или длинный PDF забивает всю VRAM еще до отправки первого запроса. 

В агентских циклах многошаговый диалог с вызовом инструментов быстро раздувает контекст до тысяч токенов. В итоге память заканчивается, историю приходится обрезать, а агент теряет контекст даже последних трех шагов, и мы получаем в лучшем случае стажера на полставки, а не AGI. 

Наконец, при батчинге в нагруженных сервисах KV-кэш каждого пользователя фиксируется в памяти — и чем длиннее диалоги, тем меньше параллельных сессий помещается на одну GPU.

Решение

Проблему пытались решать по-разному. Метод GQA, например, уменьшает количество KV-голов, отлично работает и активно используется еще со времен Llama 2, Qwen2 и других моделей.

При Sliding Window Attention каждый слой внимания смотрит только на фиксированное окно недавних токенов, а не на весь контекст. В результате KV-кэш для этих слоев перестает расти бесконечно и ограничивается размером окна.

MLA у DeepSeek — это уже архитектурное решение: оно сжимает KV до латентных векторов и убирает около 93% кэша.

Все эти методы хороши, но они либо требуют переобучения модели (что дорого и сложно), либо режут контекст, ухудшая результаты.

TurboQuant хорош как раз тем, что предлагает другой подход — просто сжать то, что уже есть, без изменения архитектуры, калибровки и файн-тюнинга. Вы просто берете модель, включаете метод, и KV-кэш сжимается в 5–6 раз.

Как работает TurboQuant 

Скажу сразу — TurboQuant содержит большую и взрослую математику. Но чтобы понять суть метода и начать его использовать, зарываться в формулы не обязательно. Мы сейчас пропустим сухую теорию и просто поверим, что умные люди все проверили (ICLR 2026 принял, значит доверять можно) и разберемся на пальцах, почему это вообще работает.

Если вы любите хардкор, три теоремы, доказательства near-optimal distortion rate, бета-распределения, информационно-теоретические нижние границы — вам прямая дорога  к полному исследованию.  Это фундаментальный труд, и тем, кому интересно погрузиться, лучше начинать с него, но сразу готовьте несколько дней или недель жизни на это (в общем — приятного чтения).

Квантизация KV-кэша — идея, прямо скажем, не новая: взять float16-значения и упаковать их в меньшее количество бит. Проблема в том, что наивная квантизация (равномерная сетка) работает плохо: значения в KV-кэше распределены неравномерно, и большинство традиционных методов либо теряют качество, либо требуют калибровочных данных под конкретную модель.

Идея первая — случайное вращение. Перед квантизацией вектор умножается на случайную ортогональную матрицу. Звучит странно: зачем крутить данные перед тем как их сжимать? 

А вот зачем: после такого вращения компоненты вектора становятся почти независимыми и распределены предсказуемо. Из произвольного и сложного распределения получаем что-то близкое к нормальному, а с этим уже гораздо приятнее работать.

Идея вторая — оптимальный квантизатор для известного распределения. Если мы знаем, как распределены данные, то можно заранее просчитать оптимальную сетку квантизации (это называется Lloyd-Max квантизатор). Не равномерную, а такую, где ошибка минимальна именно для этого распределения: кодбук считается один раз, хранится статично и не требует никакой калибровки под конкретную модель.

Комбинация этих двух идей и дает результат: алгоритм доказуемо находится в пределах ~2,7× от теоретического минимума ошибки квантизации. Это называется near-optimal, и, как вы понимаете, довольно интересно.

На самом деле есть еще и третий компонент —  QJL-коррекция остатка. Теоретически он красиво описан и обоснован, но на практике сообщество выяснило: в наивной реализации через стандартный attention softmax экспоненциально усиливает дисперсию от 1-bit коррекции, и результат становится хуже, а не лучше. 

В vLLM PR #38479 проблему решили через norm correction (варианты с суффиксом _nc), в llama.cpp форках QJL чаще всего просто отключают или упрощают. 

Главное, что нужно запомнить: алгоритм data-oblivious. Ему не нужны калибровочные данные, не нужен файн-тюнинг — он сразу работает на любой трансформерной модели. Берете модель, которая у вас уже есть, и просто включаете (ну почти): на момент написания статьи Google еще не выложила официальный код. Все, что есть и что можем попробовать, —  это реализации от комьюнити.

Получаем, что несколько независимых команд собрали рабочие реализации буквально по формулам из статьи, и результаты совпали с заявленными. Об этом подробнее ниже.

8x и «zero loss» — реальные цифры

Давайте поговорим о цифрах. Google заявляет: «up to 8x speedup on H100 GPUs». И нет, к сожалению, ваш инференс не станет в восемь раз быстрее (в 99% случаев). Восьмикратный рост измерен относительно FP32, который никто не использует в продакшене. Относительно реально рабочего FP16-бейзлайна это будет примерно 4x.

И это еще не все. Четырехкратный рост — это ускорение только attention, не end-to-end инференса. В реальном пайплайне attention — лишь часть времени, а есть же еще линейные слои, sampling, IO. 

Реального wall-clock времени от токена до токена в предложенной методике нет — есть только ускорение attention, а это лишь часть пайплайна. А еще сообщество намерило overhead на префил порядка 21–27 мс на квантизацию (не катастрофа, но и не бесплатно).

Все, тогда расходимся, нас всех оверхайпнули? На самом деле нет, потому что реальная ценность TurboQuant не в скорости, а в памяти. Сжать KV-кэш в пять раз — это значит впихнуть в одну GPU контекст, который раньше не влезал. Например, на Llama 3.1 70B это разница между ~109K токенов и ~536K токенов на 34 ГБ VRAM. Вот это реально полезно.

«Zero accuracy loss» с оговорками

Продолжим идти по цифрам — на бенчмарках LongBench и Needle-in-a-Haystack результаты действительно впечатляют: модель Llama-3.1-8B-Instruct при квантовании до 3,5 бит набирает 50,06 балла на LongBench (ровно столько же, сколько в оригинальном FP16), а на Needle держит показатель 0,997 на контексте вплоть до 104K токенов. 

Если коротко — на длинном контексте качество не разваливается, и это главное.

Однако с практической точки зрения картина уже не такая радужная: все замеры проводились на небольших моделях до ~12B параметров (Llama-3.1-8B, Mistral-7B, Gemma). Данных для архитектур масштаба 70B+ в исследовании нет вовсе, и это риск — переносимость на крупные модели остается открытым вопросом.

Спасает то, что комьюнити уже провело самостоятельные тесты, и первые результаты обнадеживают: на модели 104B с пресетом turbo3 прирост перплексии (PPL) составил всего +3,6%. Однако «мы тут сами проверили, вроде работает» — это не замена нормального бенчмарка.

Отдельно в исследовании режет глаз отсутствие классической базы. Метрики WikiText-2 perplexity, MMLU — это тот минимум, без которого нормально сравнить метод с конкурентами в одной системе координат не получится.

Кроме того, есть еще один нюанс: ключи и значения в KV-кэше — это не одно и то же. У Qwen2.5, например, нормы ключей на порядки больше норм значений. 

Отсюда вывод: симметричная квантизация с одинаковой разрядностью для K и V — это костыль, ключам по-хорошему нужно больше бит. Асимметричные пресеты вроде K8V4, которые появились в vLLM и в форках llama.cpp, — тому доказательство.

А что конкуренты

TurboQuant — далеко не единственный метод сжатия KV-кэша и даже не обязательно лучший для вашего конкретного сценария.

Метод KVTC строится на совершенно иной философии. Если TurboQuant работает по принципу «повернул и квантизовал», то KVTC — это своего рода аналог JPEG для KV-кэша. Разработчики заявляют о сжатии вплоть до 20 раз (против 5–6x у TurboQuant) с потерей точности менее одного процентного пункта. При этом KVTC тестировался на куда более широкой линейке моделей — от 1,5B до 70B. 

Явный минус подхода — необходимость однократной калибровки (примерно на 200K токенов). Для продакшен-сервисов с фиксированной моделью это не станет проблемой, однако для локального сценария «скачал GGUF и запустил свою модель» уже будет больно. Подробное описание метода доступно в статье, а в открытом доступе есть open-source реализация.

RotorQuant — community-проект, который решает конкретную проблему TurboQuant: умножение на полную d×d ортогональную матрицу — это 16 384 операций для d=128. RotorQuant заменяет ее на математическую хитрость, которая дает ~100 операций. 

В результате вращение выполняется в 10–31 раз быстрее, а сам алгоритм требует в 44 раза меньше параметров при сопоставимом качестве attention (косинусное сходство 0,990 против 0,991 у TurboQuant). Минус: проект пока проигрывает по качеству TurboQuant и находится на ранней стадии. Но идея красивая, и если авторы «дожмут» качество, проект может стать дефолтным выбором для мобильных и edge-сценариев. Исходный код проекта доступен на GitHub.

KIVI — проверенный бейзлайн (представленный на ICML 2024), который уже встроен в экосистему Hugging Face Transformers. Метод использует асимметричную 2-битную квантизацию (поканальную для ключей и потокеновую для значений). Такой подход сжимает KV-кэш в 16 раз, снижая пиковое потребление видеопамяти (peak memory) примерно в 2,6 раза. Для продакшена, где стабильность важнее максимального сжатия — вполне хороший вариант. Включить эту квантизацию в Transformers можно через cache_implementation="quantized" в методе generate().

Быстрая шпаргалка:

МетодСжатиеКалибровкаМодели Статус
TurboQuant~5-6xНетдо 8B15+ community-реализаций
KVTC (NVIDIA)до 20xДа (PCA)1,5B–70BOpenReview + open-source
RotorQuant~5xНетдо 7BРанний community
KIVI~16x (KV) / 2,6x peak memНетширокоВ HuggingFace

Что работает прямо сейчас и как попробовать

Комьюнити уже создало более 15 реализаций — от простых Python-пакетов, устанавливаемых через pip install, до специализированных Metal-шейдеров.

Ниже внимательнее посмотрим на самые интересные и перспективные решения: одни из них уже готовы к использованию в продакшене, другие пока остаются полем для экспериментов.

llama.cpp

Если вы прогоняете модели локально через llama.cpp, это ваш основной вариант. TheTom/turboquant_plus (GitHub) — самый зрелый форк: есть поддержка Metal, CUDA, CPU, протестирован на моделях от 1,5B до 104B.

Собираем и запускаем:


      git clone https://github.com/TheTom/turboquant\_plus.git
cd turboquant_plus
cmake -B build -DGGML_METAL=ON -DCMAKE_BUILD_TYPE=Release  # для Apple Silicon
# или -DGGML_CUDA=ON для NVIDIA
cmake --build build -j

# Симметричный turbo3 (3-bit K + 3-bit V), работает на большинстве моделей
./build/bin/llama-cli -m model.gguf \
  -ctk turbo3 -ctv turbo3 \
  -fa on -ngl 99 -c 32768

# Асимметричный — для моделей с Q4_K_M весами (Qwen2.5 и подобные)
./build/bin/llama-cli -m model.gguf \
  -ctk q8_0 -ctv turbo3 \
  -fa on -ngl 99 -c 32768

Доступные форматы KV-кэша:

  • turbo2 (2-bit) — сжатие в 6,4 раза, увеличение перплексии (PPL) на 6,5%. Подходит для экстремальной экономии памяти;
  • turbo3 (3-bit) — сжатие в 5 раз, рост PPL порядка 1%. Оптимальный выбор, с которого стоит начинать; 
  • turbo4 (4-bit) — сжатие в 3,8 раза. По точности практически неотличим от исходного формата FP16.

Бонусом идет Sparse V — это пропуск позиций с низкими attention-весами при декодинге. До +22,8% скорости декодирования на 32K контекста без потери качества.

На что стоит обратить внимание:

  • Симметричный turbo на Q4_K_M весах может выдать мусор. Это происходит, потому что квантизация весов уже снизила точность, и дополнительное сжатие KV-кэша на ключах добивает attention-маршрутизацию. Решение — использовать асимметричный режим, при котором ключи хранятся с более высокой точностью: -ctk q8_0 -ctv turbo3;
  • Модели с head_dim=64 могут падать: TurboQuant валидирован на head_dim ≥ 128;
  • Хорошая новость по масштабированию: большие модели переносят сжатие лучше, чем маленькие. 104B на turbo3 — всего +3,6% PPL, тогда как 70B — уже +11,4%.

Python + HuggingFace

back2matching/turboquant (GitHub, PyPI) — готовая интеграция для экосистемы Hugging Face Transformers. На сегодня это единственный пакет, который можно установить одной командой pip install и сразу получить сжатие KV-кэша ниже 8 бит (sub-8-bit).


      pip install turboquant
from turboquant import TurboQuantMSE

# Квантизация любых векторов — KV-кэш, эмбеддинги
tq = TurboQuantMSE(dim=128, bits=4, device='cuda')

# Квантизация
indices, norms = tq.quantize(vectors)  # vectors: (N, 128)

# Деквантизация
vectors_hat = tq.dequantize(indices, norms)
Для интеграции с генерацией:
from turboquant import TurboQuantCache

cache = TurboQuantCache(
    key_bits=4,
    value_bits=2,
    protected_layers=[0, 1, -1, -2]  # первые/последние слои в FP16 - НУЖНО для лучшего качества
)
outputs = model(**inputs, past_key_values=cache, use_cache=True)

Обратите внимание на параметр protected_layers — это найденный комьюнити костыль. Первые и последние слои модели передают основной объем сигнала через остаточные связи (residual stream), поэтому их квантизацию лучше отключать.

Важное уточнение: в текущем виде пакет остается исследовательским инструментом. Он подходит для прототипирования и проверки гипотез, но для запуска в продакшене пока рановато.

vLLM

Поддержка TurboQuant уже замержена в основной репозиторий vLLM. Если собрать vLLM из ветки main, алгоритм заработает из коробки. Для тех, у кого vLLM уже развернут в продакшене, это самый простой и прямой путь внедрения. 

Достаточно одного флага:


      # 3-bit с norm correction — рекомендуемый дефолт
vllm serve meta-llama/Llama-3.1-8B-Instruct \
  --kv-cache-dtype turboquant_3bit_nc

# Другие доступные пресеты:
# turboquant_4bit_nc  — 4-bit, самый безопасный по качеству
# turboquant_k8v4     — 8-bit ключи + 4-bit значения
# turboquant_k3v4_nc  — 3-bit ключи + 4-bit значения + norm correction

Под капотом реализован отдельный TurboQuantAttentionBackend.

Несколько цифр по емкости из бенчмарков PR с добавлением поддержки:

  • Qwen3.5-35B-A3B (гибридная MoE) — емкость KV-кэша выросла с 1,67M до 6,69M токенов, итого четырехкратный рост;
  • Gemma-3-27B (dense) — с 207K до 415K токенов, больше в два раза.

Важный урок из обсуждения в Pull Request, который стоит знать до того, как запускать в продакшн:

Дефолтный tq3 может убить reasoning. Проблема в том, что 2-bit значения оказываются слишком грубыми для задач на многошаговое рассуждение. 

Решение: используйте пресеты с коррекцией нормы (флаг _nc) либо асимметричный пресет k8v4 (8-битные ключи и 4-битные значения). Если ваша модель решает логические или вычислительные задачи, обязательно тестируйте ее на профильных бенчмарках, а не ограничивайтесь сравнением косинусного сходства. 

SGLang — еще в процессе

Поддержка метода находится в разработке (PR #21617 в состоянии Work In Progress / Draft). На данный момент уже реализованы базовая квантизация, Lloyd-Max кодбуки, выделение выбросов (outlier detection), Triton-ядра и интеграция с бэкендами FlashInfer и Triton. Все 42 юнит-теста проходят успешно, но до полноценного мержа в основную ветку ещё далеко. Отслеживать прогресс можно в Issue #21618.

Что выбрать — зависит от вашего сценария

Ваш сценарийИнструментКак запустить
Локально на Mac (скорость)turboquant_plus (Metal)-ctk turbo3 -ctv turbo3 -fa on
Локально на NVIDIAturboquant_plus (CUDA)-ctk turbo3 -ctv turbo3 -ngl 99
Python + HuggingFacepip install turboquantTurboQuantCache(key_bits=4, value_bits=2)
Продакшн (vLLM)vLLM из main--kv-cache-dtype turboquant_3bit_nc

Общие рекомендации

Собрал несколько важных советов от комьюнити.

Ключи важнее значений. Ключам нужно больше бит. Оптимальный баланс по консенсусу: K=4-8bit, V=2-3bit.

Защищайте крайние слои. Первые два и последние два слоя трансформера лучше оставлять в формате FP16.

4-bit — безопасный дефолт. Если сомневаетесь, начинайте с 4-bit KV-кэша. При таком уровне сжатия сгенерированный текст при temperature=0 на большинстве моделей побитово совпадает с FP16. Формат 3-bit — отличный рабочий вариант для моделей от 8B параметров. Режим 2-bit стоит использовать только при критическом дефиците памяти и готовности к некоторой деградации качества. 

Грубая формула для планирования VRAM. Сочетание весов 4-bit (GPTQ/AWQ) и 3-bit TurboQuant KV-кэша позволяет разместить модель 70B с контекстом 500K+ токенов примерно в 34 ГБ видеопамяти. По сути, это позволяет уместить на 1–2 видеокартах то, что раньше требовало целого вычислительного кластера.

Когда это нужно, а когда есть варианты лучше

TurboQuant решает одну конкретную проблему — чрезмерное потребление памяти KV-кэшем. Если ваш сценарий упирается именно в это ограничение, отлично, вы по адресу. В противном случае можно не тратить время.

Когда TurboQuant действительно нужен:

  • Длинный контекст от 32K+ токенов. На коротких контекстах (4K–8K) KV-кэш занимает мало места, и overhead квантизации перевешивает экономию. А вот на отрезках от 32K токенов кэш начинает доминировать в расходе VRAM, и именно здесь TurboQuant раскрывается в полной мере. 
  • RAG с большими документами. При загрузке в контекст всей кодовой базы или длинных PDF-файлов KV-кэш расходует видеопамять гораздо быстрее самих весов модели. 
  • Агентные пайплайны. Агент с инструментами, многошаговой историей и накапливающимся контекстом — идеальный клиент для TurboQuant. Без сжатия приходится обрезать историю, агент забывает, что делал, и качество падает;
  • Батчинг / высокий concurrency. Если вы обслуживаете много пользователей параллельно — KV-кэш каждого сидит в памяти;
  • Локальный инференс на ограниченном железе. На сетапах вроде Mac Mini с 24 ГБ объединённой памяти или RTX 4080 с 16 ГБ VRAM метод позволяет запустить модели и длинные контексты, которые раньше физически не помещались. 

Когда TurboQuant не поможет (или есть лучше):

Короткий контекст (< 8K токенов).

Модель не влезает по весам. TurboQuant сжимает KV-кэш, не веса.

MLA-архитектуры (DeepSeek V3, V4). Multi-head Latent Attention уже сжимает KV-кэш до латентных векторов архитектурно и убирает ~93% кэша. TurboQuant поверх MLA — это попытка сжать уже сжатое. Может дать что-то, но выигрыш будет минимальным по сравнению с обычными моделями.

Вам нужно максимальное сжатие и вы готовы к калибровке. KVTC от NVIDIA заявляет до 20x сжатия (против 5-6x у TurboQuant), но требует одноразовой PCA-калибровки. Если у вас фиксированная модель в продакшне и вы можете потратить время на калибровку, то KVTC может оказаться куда лучшим выбором.

Очень маленькие модели (< 1B). На 0.6B моделях качество деградирует заметно, модели не хватает избыточности, чтобы пережить сжатие. Начиная с 3B–4B все нормально, на 8B+ отлично.

Быстрый чеклист

Ответьте на три вопроса:

  1. Ваш контекст > 16K токенов? Если нет, то, скорее всего, не нужно.
  2. KV-кэш занимает > 30% вашего VRAM? Если нет, есть более полезные оптимизации.
  3. Модель ≥ 8B с head_dim ≥ 128? Если нет, результаты могут быть нестабильными.

Если три «да», ставьте turbo4, проверяйте качество на ваших примерах, и если все ок, то переключайтесь на turbo3 для большей экономии.

Вывод

Если коротко: TurboQuant — это рабочий практический инструмент для решения конкретной задачи: оптимизации KV-кэша при работе с длинным контекстом. Он работает без переобучения и калибровки модели, а его ограничения легко учитываются на практике. 

Если хочется погрузиться глубже — рекомендую посмотреть блог Google Research, и обязательно заглянуть в главный технический тред в llama.cpp — там сообщество в реальном времени разбирает все тонкости, с которыми можно столкнуться при реальном использовании. Для альтернативного взгляда стоит почитать про KVTC от NVIDIA: он предлагает иную философию и другие компромиссы, которые в некоторых сценариях могут оказаться предпочтительнее.