Как стать автором
Обновить

Quantization Deep Dive, или Введение в современную квантизацию

Уровень сложностиСредний
Время на прочтение16 мин
Количество просмотров17K
Всего голосов 66: ↑65 и ↓1+81
Комментарии13

Комментарии 13

Спасибо за действительно интересный обзор!

При прочтении возникла мысль, что квантизация могла бы быть дополнена дистилляцией.
То есть, сначала мы проводим квантизацию модели. Полученная модель уже близка к исходной, но при этом оптимизирована с точки зрения расхода ресурсов. Затем мы проводим дистилляцию, обучая квантизованную модель на основе исходной. Этот процесс потребует значительно меньше ресурсов, чем обучение исходной модели с нуля, и позволит минимизировать потерю информации, которая могла произойти в результате квантизации.

Спасибо за интерес к теме!

Идея частично перекликается с тем, что предложили авторы QLoRA и можно подумать в эту сторону.

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

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

Еще один вариант соблюсти требования по скорости/качеству: можно баллансировать скорость и качество по разному квантизуя разные слои сети. Например часть слоев в 8 бит, часть в 4 бита. Это скорее история не про LLM, но на более простых архитектурах могут получаться интересные результаты.

Ряд современных подходов использует дистилляцию для обучения дифференцируемых параметров. AQLM и QuIP# оптимизируют L2 лосс между выходами исходной float модели и квантизованной после каждого блока трансформера, а затем минимизируют кросс-энтропию/kl-дивергенцию между выходами квантизованной модели и исходной. Довольно неплохо накидывает в качестве, и при этом сравнительно дешево. В этих подходах - векторная квантизация, когда квантуются веса не поодиночке, а группами (обычно по 8 подряд идущих весов).

В более классических подходах, рассмотренных в статье, можно обучать скейлы квантизации (своеобразный PEFT). И еще layernorm-ы, biasы, входные эмбеддинги и голова модели обычно держат в исходной точности.

Не подскажете по обратному преобразованию, безотносительно НС? Понятно, что преобразование нелинейное и однозначного обратного отражения получить нельзя, но в принципе есть возможность сопоставить каждой квантованной точке некоторый диапазон с помощью какого-то распределения вероятностей. Не знаете литературу по подбору распределений? Моя задача для "домашнего проекта" - апскейл и улучшение изображений без использования НС.

С такой литературой не подскажу. Возможно получится вдоховиться математикой из VQ-VAE (если упростить: кодируют изображение векторами из небольшого словаря, потом восстанавливают обратно) и попробовать перенести на свою задачу. Но в таком виде не работает условие "без НС".

Спасибо за хорошую подробную статью!

"Авторы QLoRA предлагают учить факторизованные адаптеры и показывают эффективность этого метода." - тут, видимо, описка, это как раз LoRA делает.

У QLoRA три фишки: двойная квантизация (квантизация констант квантизации с первого шага), новый теоретически оптимальный тип данных NF4 и paged optimizer (чтобы не ловить CUDA OOM на длинных батчах)

  • разбивают диапазон [-1, 1] на две части, положительную и отрицательную;

  • находят 2^{k-1} квантилей слева;

  • находят 2^{k-1} + 1 квантилей справа;

  • склеивают полученные значения по нулю.

Тут не 2^{k-1} - 1 должно быть? А то ничего не понятно. Для 4-битного будет 8 слева, 9 справа, 17 значений, ещё и ноль куда-то впихнуть.

Для 4-битного будет 8 слева, 9 справа

Все так, для 4х-битного будет:

  • 8 слева, самое правое будет верхней границей диапазона - нулем;

  • 9 справа, самое левое будет нижней границей диапазона - нулем.

Дальше по этому нулю мы их "склеиваем" и говорим что представление нуля у них общее.

Получаем:

  • 7 значений меньше нуля;

  • 8 значений больше нуля;

  • представления для нуля.

16 значений, уложились в 4 бита.

Ага, теперь понятно, спасибо.

Спасибо за интересную статью. Очень классно, что есть примеры статей и их ключевые идеи.

Только жалко, что в статье не затрагивается практические вопросы запуска моделей в проде (было бы интересно узнать с какими проблемами сталкивались). Например, какими библиотеками это можно сделать. На сколько я понимаю, полной поддержки всех перечисленных выше типов данных нет в библиотеках типо Pytorch или TensorFlow. И не все идеи из статей (будем надеяться, что это пока что) можно реализовать средствами библиотек. Например, в коде к статье https://arxiv.org/pdf/2401.06118v2.pdf часть логики написана на CUDA.

Из интересного еще хотелось бы почитать про AWQ и квантизацию реализованную в llama.cpp. И если AWQ еще можно полезть в оригинальную статью, то насколько я понимаю описание того как реализована квантизация в llama.cpp существует только в коммитах репы.

Спасибо за интересную и информативную работу!
Какой метод квантизации оказался наиболее эффективным для сжатия весов и активаций в больших языковых моделях?

Спасибо за работу, было интересно узнать больше о методах квантизации больших языковых моделей :) Хотелось бы уточнить, какие конкретные методы используются в алгоритме Optimal Brain Quantization для решения задачи квантизации больших языковых моделей?

Зарегистрируйтесь на Хабре, чтобы оставить комментарий