Два критических бага в стандартном конвертере: как «lossless» бейзлайн проигрывает кванту
Команда AtomicChat провела глубокое квантование модели DeepSeek V4 0731 и сразу столкнулась с аномалией: так называемый «lossless»-бейзлайн размером 162 ГБ показывал худшее качество, чем квантованная версия на 118 ГБ. Причина - два критических бага в стандартном конвертере llama.cpp. Без их исправления любое квантование начинается с заведомо искажённой модели. Разберём оба бага и покажем, как получить бит-экзактную основу для дальнейшей работы.
Баг №1: NaN в эмбеддингах и флаг --no-lazy
Первый баг проявляется при стандартном запуске конвертера: веса токен-эмбеддингов превращаются в NaN. Внешне это выглядит как бесконечная перплексия (PPL) и генерация бессвязного текста - модель выдаёт мусор на выходе. Проблема связана с ленивой загрузкой тензоров: без явного указания флага --no-lazy конвертер не инициализирует часть весов корректно, оставляя в памяти «мусорные» значения.
Исправление тривиально. При запуске скрипта конвертации достаточно добавить флаг:
python convert_hf_to_gguf.py --no-lazy /path/to/model
Без этого флага любые метрики качества бессмысленны - вы оцениваете не квантование, а повреждённую на старте модель. Проверьте свои пайплайны: если вы квантовали DeepSeek V4 0731 без --no-lazy, результаты требуют пересчёта.
Баг №2: Хардкод FP8→Q8_0 и систематическое искажение модели
Второй баг глубже и коварнее. В файле conversion/deepseek.py жёстко прописано преобразование тензоров из формата FP8 в Q8_0. Это происходит на этапе конвертации, ещё до применения целевого метода квантования. Результат: исходная модель искажается систематически, с Kullback-Leibler Divergence (KLD) равной 0.219 относительно настоящих весов.
KLD 0.219 - это много. Для контекста: хорошие кванты обычно дают KLD в диапазоне 0.001–0.01. Значение 0.219 означает, что распределение вероятностей токенов существенно смещено. Именно поэтому 162-гигабайтный «lossless» бейзлайн оказался менее точным, чем 118-гигабайтный квант: первый уже был испорчен хардкодом, второй - нет.
Решение: замена FP8-тензоров на BF16 на этапе загрузки. AtomicChat модифицировали скрипт конвертации так, чтобы все вычисления велись в BF16, минуя принудительное Q8_0. Это дало бит-экзактную базовую модель - ту самую, которую авторы DeepSeek V4 0731 реально выложили в открытый доступ. Детали исправления непубличны, но принцип ясен: убрать хардкод, дать конвертеру работать с исходной точностью весов.
Практический вывод: перед любым квантованием DeepSeek V4 0731 проверьте, что ваша базовая модель не прошла через FP8→Q8_0. Иначе вы стартуете с дельтой KLD 0.219, и никакой метод квантования этого не исправит.
Методология честного бенчмарка: одна машина, один датасет, 38 квантов
Исправив оба бага и получив бит-экзактную основу, AtomicChat протестировали 38 различных квантов на одной физической машине. Конфигурация: 8× NVIDIA RTX 5090, датасет wikitext-2, единая версия llama.cpp. Это принципиально: кросс-платформенные сравнения PPL для квантованных моделей несостоятельны.
Почему нельзя сравнивать PPL с разных GPU: эффект MXFP4
Одни и те же веса модели дают разный PPL на разных GPU. Причина - аппаратный путь MXFP4 (Microscaling FP4), который задействуется на GPU с поддержкой этого формата и меняет порядок вычислений с плавающей запятой. Результат: расхождение перплексии на идентичных квантах может достигать десятых долей, что сопоставимо с разницей между соседними уровнями квантования.
MXFP4 - это не ошибка, а особенность архитектуры: разные поколения GPU по-разному обрабатывают низкоточные вычисления. RTX 5090 использует один путь, RTX 4090 - другой, A100 - третий. Сравнивать цифры PPL, полученные на разном железе - всё равно что сравнивать результаты забегов на дорожках с разным покрытием. Только тесты на идентичной машине дают сопоставимые результаты. AtomicChat жёстко зафиксировали конфигурацию: одна машина, один драйвер, одна версия CUDA.
Этот подход резко контрастирует с распространённой практикой, когда пользователи выкладывают PPL своих квантов, полученные на произвольном железе. Доверять таким цифрам нельзя. Если вы сравниваете кванты - тестируйте их на одной машине.
Результаты: от 154 ГБ и выше - все кванты неотличимы, но оптимум найден
Главный вывод бенчмарка: кванты размером от 154 ГБ и выше практически неотличимы друг от друга по качеству. Причина - использование QAT (Quantization-Aware Training) при обучении DeepSeek V4 0731. Модель изначально тренировалась с учётом последующего квантования, поэтому умеренное снижение точности весов не вызывает заметной деградации.
Это важный практический результат: гнаться за максимальным размером кванта бессмысленно. 162-гигабайтный «lossless» бейзлайн не даёт измеримого выигрыша перед 154-гигабайтным квантом. Разница в 8 ГБ на диске есть, разницы в качестве нет.
AD-IQ2_M: 104 ГБ и 83.6% top-1 - лучший выбор для 128 ГБ
Для систем с 128 ГБ суммарной памяти (VRAM + RAM) оптимумом оказался квант AD-IQ2_M размером 104 ГБ. Его ключевая метрика - 83.6% top-1 на wikitext-2. Это означает, что в 83.6% случаев самый вероятный токен, предсказанный квантованной моделью, совпадает с выбором полновесной версии.
Что такое AD-IQ2_M? Это смешанный квант: большая часть весов сжата до 2 бит методом IQ2 (с imatrix-калибровкой), но критические слои - attention projection и output projection - оставлены в 8-битном формате (Q8). Такой подход даёт радикальное сжатие без обвала качества на ключевых операциях. Модель занимает 104 ГБ вместо 162 ГБ, экономия - 58 ГБ, или 36% исходного размера.
Сравнение с соседними квантами:
| Квант | Размер (ГБ) | Top-1 (%) | Примечание |
|---|---|---|---|
| FP16 baseline | 162 | 100 (референс) | Бит-экзактный, после исправления багов |
| Q8_0 | 154 | ~99.5 | Неотличим от бейзлайна |
| Q6_K | 138 | ~98.7 | Минимальные потери |
| Q4_K_M | 118 | ~95.2 | Хороший баланс |
| AD-IQ2_M | 104 | 83.6 | Оптимум для 128 ГБ |
| IQ2_XXS | 78 | ~71.3 | Заметная деградация |
Почему именно 128 ГБ? Потому что 104 ГБ модель + 16–20 ГБ под KV-кэш и системные нужды как раз укладываются в этот бюджет. Для 64 ГБ систем придётся смотреть на более агрессивные кванты вроде IQ2_XXS, но там потери качества уже ощутимы. Для конфигураций с 256 ГБ и выше разумно брать Q6_K или Q8_0 - запас по памяти позволяет не экономить на точности.
Проблема стандартов именования квантов на Hugging Face: одинаковый битрейт - разные названия
Бенчмарк AtomicChat вскрыл системную проблему экосистемы: на Hugging Face отсутствует стандарт именования квантованных моделей. Одинаковые битрейты скрываются под разными названиями, сравнение по именам файлов бессмысленно, а пользователи вынуждены гадать, что именно они скачивают.
Примеры путаницы: как один и тот же квант скрывается за разными именами
Возьмём 4-битное квантование DeepSeek V4 0731. На Hugging Face можно встретить такие названия для моделей с идентичным или почти идентичным битрейтом:
DeepSeek-V4-0731-Q4_K_M.ggufDeepSeek-V4-0731-IQ4_XS.ggufdeepseek_v4_0731_q4_km.ggufDS4-0731-4bit-128g.gguf
Все четыре файла - это 4-битные кванты, но методы квантования разные: K-Quant, IQ-Quant, групповое квантование с размером группы 128. Качество различается, размеры тоже. Пользователь, не знакомый с нюансами, видит четыре «4-битных» варианта и не понимает, какой выбрать. Более того, названия вроде Q4_K_M и IQ4_XS не говорят ничего о реальном битрейте: первый может весить 4.2 бит/параметр, второй - 4.5 бит/параметр, а в названии этого не отражено.
Ситуация усугубляется тем, что разные авторы загружают кванты под собственными нейминг-схемами. Один использует нотацию llama.cpp, другой - свою, третий - сокращения. Результат: хаос, в котором невозможно ориентироваться без скачивания и тестирования каждого файла.
Предложение по унифицированной номенклатуре
AtomicChat предложили простой и воспроизводимый стандарт именования. Три обязательных компонента в названии файла:
- Базовое имя модели - без сокращений, точно как в официальном репозитории:
DeepSeek-V4-0731. - Метод квантования и битрейт - например,
IQ2_MилиQ4_K_M. Нотация llama.cpp де-факто стала стандартом, и её стоит придерживаться. - Размер в гигабайтах - округлённый до целого:
104GB. Это самый важный для пользователя параметр: он сразу понимает, влезет ли модель в его память.
Пример полного имени: DeepSeek-V4-0731-IQ2_M-104GB.gguf. Без вариантов, без двусмысленности. Пользователь видит: это DeepSeek V4 0731, метод IQ2_M, размер 104 ГБ. Можно сравнивать с другими квантами осмысленно: DeepSeek-V4-0731-Q4_K_M-118GB.gguf - тот же метод оценки размера, другой метод квантования, сразу видна разница в 14 ГБ.
Внедрение такого стандарта - вопрос договорённости сообщества. Hugging Face как платформа может добавить валидацию названий при загрузке или хотя бы рекомендованную схему. Пока этого нет, пользователям остаётся ориентироваться на размер файла в гигабайтах как на единственный надёжный индикатор - и требовать от авторов квантов указывать его в названии.
Проблема именования - не косметическая. Она напрямую влияет на воспроизводимость бенчмарков. Когда в статье указано «модель Q4_K_M», а под этим названием на Hugging Face лежат три разных файла от разных авторов, результаты тестов невозможно воспроизвести. Стандарт именования - это стандарт воспроизводимости.