Основы ИИ
Ваша кэш KV не имеет проблемы с битами. У нее есть проблема с геометрией.

При одинаковой точности 2 бит одно решение о том, по какому оси квантовать, меняет балл бенчмарка с 2,88 до 63,53. Ключи и значения требуют противоположного подхода — и причина этого кроется в уравнении внимания, а не в аппаратуре.
Возьмем Llama-2-13B. Группируем кэш ключей и значений по размеру квантовой группы 32 в два бита, оставляя все остальное на месте — ту же модель, тот же бюджет битов, те же размеры групп, те же бенчмарки.
В зависимости от одного элемента решения реализации, результаты точности CoQA составляют либо 2,88, либо 63,53. Балл при полной точности составляет 66,37.
Решение не заключается в том, сколько битов используется в общей сложности. Вопрос заключается просто в том, по какой оси вы выбираете группировку при вычислении каждого коэффициента масштабирования? Когда вы решаете использовать канал в качестве размера группировки (ключи) и токен в качестве размера группировки (значения), вы оказываетесь где-то в четырех пунктах от результатов полной точности. Если вы измените любой из этих выборов, вы испытаете потерю качества. Если вы измените оба этих выбора, модель больше не работает.

Четыре способа потратить те же 2 бита на один и тот же кэш. Результаты из KIVI абляции на Llama-2-13B при размере группы 32.
Квантование обычно рассматривается как один регулятор: 8 битов, 4 бита, 2 бита, с гладкой стоимостью точности. Внутри кэша KV все не так. Это выбор систем координат, и разные системы применяются к ключам и значениям. Эта статья объясняет, почему. Кратко: ошибка квантования зависит от диапазона значений внутри групп; ключи и значения имеют очень разную структуру; и люди часто спотыкаются, потому что вы не можете вывести правильную ось из распределения значений вообще. Вам нужно посмотреть, как меняется ошибка после того, как внимание потребляет ее. Это дает общий принцип для сжатия промежуточных активаций и хорошую причину сомневаться в ошибке реконструкции как в прокси для качества.
Почему кэш KV — это то место, где это кусается
Во время фазы генерации трансформер хранит все данные проекции ключа и значения (KV) токенов, которые он ранее обработал, в кэше, чтобы не пришлось пересчитывать эти данные снова. Этот кэш растет линейно с длиной контекста и размером пакета. В конце концов, это приведет к тому, что кэш вырастет больше, чем сама модель.
Этот рост можно легко определить, глядя на потребление памяти различных частей модели. В анализе KVQuant LLaMA-7B веса составляют примерно 98 процентов памяти при длине последовательности 512, а активации — 2 процента. При контексте 128K соотношение меняется на примерно 16 процентов весов и 84 процента кэша KV. Когда мы смотрим на анализ OPT-175B, цитируемый авторами KIVI, они обнаружили аналогичные результаты. Конкретно, при размере пакета 512 с запуском 512-токенов кэш KV достигает 1,2 ТБ — несколько раз больше размера весов модели.
Однако емкость — это только половина проблемы. GPU должен прочитать весь кэш KV из памяти устройства для каждого сгенерированного токена. Это означает, что пока GPU читает кэш KV, вычислительные ядра простаивают. Таким образом, уменьшение общего размера кэша увеличивает доступную вычислительную емкость и уменьшает время, потраченное на ожидание передачи данных.
Из чего на самом деле состоит ошибка квантования
Униформенная целочисленная квантовация математически проста. Для группы чисел вы записываете наименьшее число как нулевую точку, а затем делите диапазон этой группы на количество уровней, которые можно представить, чтобы получить размер шага. Затем вы округляете каждый элемент до ближайшего шага. Два немедленных результата следуют. Первый: ошибка на элемент ограничена половиной шага. Второй: размер шага — это диапазон группы, разделенный на 2^Б — 1. При 2 битах у вас есть только 4 уровня, чтобы покрыть любой существующий диапазон внутри этой группы. Итак, элемент, который в сто раз больше по сравнению с соседями, не просто работает плохо. Он увеличивает размер шага для всех других элементов, делящих одну и ту же группу, и все они становятся вместе более грубыми. Группа — это единица ущерба. Выбор оси означает решение, какие элементы страдают вместе. Формулируя вопрос по-другому, это уже не «сколько битов я могу себе позволить?», а «где экстремальные значения и могу ли я их изолировать?»
Ключи: аутсайдеры живут в фиксированных каналах
Большие языковые модели содержат активации, которые необычно велики по сравнению с большинством активаций. Сан и коллеги каталогизировали эти очень большие активации в разных семьях моделей: в Mixtral 8x7B наибольшая величина находится рядом с 7000, а медианная величина признака составляет около 0,3 — примерно четыре порядка величины друг от друга. Они очень редки; они остаются фиксированными в размерах, которые редко меняются с входом, и они не случайны. Они действуют как неявные предубеждения, и они являются тем, что фокусирует внимание на нескольких токенах: поведение внимания. В кэше ключей эта структура очень ясна: определенные каналы постоянно несут очень большие величины через каждый токен в последовательности. Группируя по токенам, каждая группа содержит эти аутсайдер-каналы, поэтому размер шага каждой группы задается аутсайдерами, и все обычные каналы платят за это. Группируя по каналам, аутсайдер-каналы образуют свои собственные группы. Их внутренний диапазон большой, но самодостаточный; обычные каналы остаются в покое. Результаты совпадают. В среднем по слоям и головам на Llama-2-13B KIVI сообщает об ошибке реконструкции ключа 13,67 при группировке по токенам против 4,55 при группировке по каналам, и — что более важно — ошибку счета внимания 47,00 против 9,60. Квантование ключей по токенам производит примерно в пять раз больше ошибки счета. Счета тогда согласуются с осмысленными метриками для ключей; квантование каналов превосходит на обоих фронтах.
Значения: где интуиция ломается
Кэш значений не показывает канал-аутсайдер-паттерн. Он кажется довольно плоским. Сам по себе, по аргументу диапазона, мы могли бы ожидать, что любая из этих осей произведет схожее качество сжатия.
Они не делают этого. Независимо от того, как реализуется управление ключами (результаты 2,80 и 2,88), сжатие по каналу значений сводит модель к нулю.
И вот в чем подвох: если вы измерите эту потерю с помощью сырой ошибки реконструкции на исходном тензоре, для которого каждое значение было сжато, квантование значений по каналу на самом деле выглядит немного лучше, с 3,73 против 4,57. Если вы проверите сжатие очевидным способом, вы выберете конфигурацию, которая уничтожает модель.

Ошибка квантования кэша значений на Llama-2-13B, измеренная двумя способами. Метрика хранимого тензора и метрика потребляемого вывода не согласуются более чем на порядок величины.
Решение заключается в том, что кэш значений никогда не читается напрямую. Он потребляется матричным произведением: выход внимания — это взвешенная сумма векторов значений по токенам, с весами softmax-внимания. Из-за этого актуальна ошибка, введенная во время этого процесса, а не внутри тензоров самих. Измеренная по выходу внимания, порядок был полностью обращен. Относительная ошибка, сообщенная KIVI для выхода внимания из-за квантования векторов значений по токенам, составила 3,55 по сравнению с 49,89 для квантования по каналу — более чем в 14 раз выше для того, что казалось лучшим выбором на основе того, насколько хорошо оно было сжато.
Объяснение заключается в скудности внимания, которую они измерили как 84,3 процента. Большинство информации, содержащейся в выходе, можно отнести к небольшому количеству очень важных токенов. Квантование по токенам ограничивает ошибку каждого токена этим токеном, поэтому ошибки на не重要ных токенах умножаются на веса внимания, близкие к нулю, и фактически исчезают. Квантование по каналу размазывает ошибку каждого токена по общей шкале канала, поэтому плохо представленные токены загрязняют представление тех, которые имеют значение. Скудность, которая делает внимание эффективным, — это то же свойство, которое делает квантование по токенам безопасным.
Переносимый урок шире, чем кэш KV: измеряйте ошибку сжатия там, где тензор потребляется, а не там, где он хранится. Неявное предположение, сделанное ошибкой реконструкции, заключается в том, что каждый компонент тензора имеет равный вес при вкладе в окончательный выход. Внимание явно не делает этого. Любая операция вниз по потоку, которая взвешивает, ограничивает или скудит свой вход, нарушает это предположение. Читателям, знакомым с моей предыдущей статьей о слепых пятнах в метриках оценки в системах извлечения, эти результаты будут похожи на ранее описанные неудачи: легко вычисляемые метрики, которые сообщают о чем-то другом, чем то, что было задумано.
Ротари-инжекции усложняют ключи
Есть некоторые проблемы с использованием ротари-позиционных инжекций (RoPE). RoPE поворачивает пары каналов на основе относительной позиции каждого токена. Это смешивание частично растворяет фиксированную структуру канала, которая сделала квантование ключей по каналу работать в первую очередь — аутсайдер-канал поворачивается в своих соседей, и соседи наследуют диапазон. Ответ KVQuant — упорядочение: квантовать ключи до применения поворота, и применять RoPE после деквантования. Вместе с квантованием ключей по каналу, неуниформными типами данных и изоляцией небольшой доли аутсайдеров это получает их ниже 0,1 деградации перплексии при 3 битах и позволяет обслуживать LLaMA-7B до 1 миллиона токенов контекста на одном A100-80GB.
Также важно понять уровень влияния от RoPE. Авторы статьи «RotateKV» сообщили об увеличении на 145 процентов ошибок квантования после добавления RoPE и отметили, что аутсайдер-каналы различаются между головами внимания — поэтому применение одной общей матрицы поворота везде недостаточно, и адаптивные повороты голов работают лучше.
Налог системы и почему это не деталь
Квантование по токенам подходит для декодирования. Каждый токен прибывает; вы квантуете его, добавляете его в последовательность (по размеру токена), ничего другого не движется.
Однако квантование по каналу не подходит. Поскольку статистика канала охватывает токены, которые еще не были сгенерированы, вы не можете вычислить коэффициент масштабирования, когда токен прибывает. Обход KIVI заключается в том, чтобы сохранить наиболее недавние токены — до 128 — в полной точности в буфере остатка и квантовать в группах, когда накопится достаточно.
Как оказалось, буфер остатка становится нагрузочным, а не просто случайным. На GSM8K с Llama-2-7B полная точность дает 13,50. Полностью квантованное до 2 бит с правильными осями, оно дает 5,76. Те же оси и те же биты, плюс буфер остатка недавно сгенерированных токенов в полной точности, дают 12,74. Скользящее окно недавно сгенерированных токенов в полной точности восстановит большую часть того, что было потеряно из-за агрессивного квантования на трудных многоступенчатых задачах — что имеет смысл, если мы рассмотрим, какие токены были вниманием цепочки арифметических операций.
Есть значительная выгода от правильного выполнения всех этих действий — как сообщает KIVI, 2,6 раза меньше пикового использования памяти для Llama-2-7B, что позволяет увеличивать размеры пакетов до 4 раз, а также на 2,35-3,47 раза лучше пропускная способность на реальном сервисном задании.
Что делать с этим
- Никогда не используйте один квантоватор для обоих. Используйте разные квантоваторы для ключей (по каналу) и для значений (по токену). Конвейер, который применяет один квантоватор к «кэшу KV», вероятно, уже пожертвовал большей частью возможного качества при использовании небольшого количества битов для представления каждого значения.
- Квантовать ключи до RoPE. Это вопрос правильности, а не вопрос предпочтения.
- Храните окно полной точности недавно сгенерированных токенов. Хотя хранение такого окна занимает очень мало памяти по сравнению с тем, насколько большой может быть кэш, это именно та область, которая генерирует большую часть точности для трудных задач.
- Не проверяйте на ошибку реконструкции. Всегда проверяйте на основе выхода внимания или на основе конечной производительности задачи. Метрика хранения не просто шумная — для значений она указывает в неправильном направлении.
- Не проверяйте на короткие контекстные многообразные бенчмарки. Авторы KIVI намеренно избегают закрытых задач, таких как MMLU, для этой оценки, потому что один шаг декодирования, читающий выходные логиты, едва упражняет кэш вообще. Любая оценка, которая не строит кэш во времени и не выполняет генерацию из него, никогда не сможет наблюдать неудачи, присущие вашему дизайну системы.
Куда движется работа
Хотя еще осталось сделать некоторую работу, касающуюся геометрической природы проблемы, многие исследователи продолжают изучать, как аутсайдер-каналы распределены среди различных голов трансформера, и как ограничения аппаратуры влияют на то, какие группировки являются наиболее дешевыми: InnerQ сворачивает нормализацию ключа по каналу в веса ключа и запроса во время предварительного заполнения. Следовательно, не возникает дополнительных накладных расходов во время выполнения. Кроме того, InnerQ хранит окна высокой точности как для недавно сгенерированных токенов, так и для токенов-аттеншн-синков. Таким образом, InnerQ устраняет возможность того, что аутсайдеры в канале-синке загрязнят соседние каналы.
Другие предлагают, что вместо хранения всего кэша мы должны хранить только достаточно информации, чтобы восстановить ключ и/или значение(я) по требованию из меньшего кэшированного представления.
Наконец, важно помнить, что точность — это не единственный параметр, который затрагивает квантование. Недавно опубликованные исследования продемонстрировали деградацию выравнивания, вызванную квантованием кэшей KV. Более того, это исследование задокументировало деградацию выравнивания даже в производственных средах обслуживания vLLM, использующих кэши FP8 вместе с протоколом восстановления без обучения, который восстановил до 97 процентов того, что было потеряно в терминах выравнивания. Таким образом, хотя конфигурация может удерживать свои результаты бенчмарка, это не обязательно означает, что она сохраняет все другие важные параметры, которые вы заботитесь.
Общий принцип
Идея квантования была сформулирована как «бюджет точности»: сколько битов я могу себе позволить пожертвовать? Кэш KV показывает, что более полезный вопрос — структурный. Точность распределяется в группах; группа — это единица ущерба, и ось, по которой вы группируете, определяет, какие элементы делят свою судьбу. Правильная ось — это та, по которой ваш тензор потребляется, т. е. то, как вы используете свой тензор, а не то, как ваш тензор появляется при хранении в памяти. Ключи используются через вычисление скалярного произведения против запроса. Один испорченный канал отравит все счета. Значения потребляются через скудно-взвешенную-среднюю-композицию по токенам. Следовательно, один испорченный токен просто взвешен.
Два тензора одинаковых размеров и сгенерированных двумя последовательными слоями обрабатываются по-разному. Стоит спросить о любой активации, которую вы планируете сжать: какая операция сокращает это, и уважает ли моя группировка это?












