Введение: когда модель ломается на ровном месте
Пользователь запускает GLM-5.2 на сервере с 4-сокетным Xeon, 1 ТБ ОЗУ и RTX 3060. Контекст 8 000 токенов обрабатывается стабильно. При увеличении до 32 000 или 64 000 токенов генерация падает на первом же токене: логиты превращаются в NaN. Проблема воспроизводится при каждом запуске.
Причина - переполнение f16 в пути DSA/indexer на GPU. Динамическое разреженное внимание (Dynamic Sparse Attention) использует половинную точность для вычислений на видеокарте. При росте длины последовательности аккумулируемые значения выходят за пределы диапазона f16, и модель выдаёт числовой мусор.
Решение существует. Перенос вычислений экспертов на CPU или отключение DSA устраняет NaN. В этой статье разобраны протестированные конфигурации, даны конкретные команды запуска и метод проверки стабильности.
Архитектура DSA в GLM-5.2: почему длинный контекст становится проблемой
Dynamic Sparse Attention - механизм, который вычисляет внимание не для всех токенов последовательности, а только для подмножества, отбираемого indexer'ом. Indexer определяет, какие позиции релевантны текущему запросу. Это снижает вычислительные затраты и объём памяти KV-кэша. Плата за эффективность - дополнительный слой вычислений, чувствительный к точности.
В GLM-5.2 indexer работает на GPU в формате f16. При коротких контекстах (8k) значения укладываются в допустимый диапазон. При 32k и выше суммарные attention scores выходят за 65 504 - максимальное представимое число в f16. Результат - NaN, который распространяется через softmax и портит все последующие вычисления.
Роль f16 и численная нестабильность
Формат f16 (half precision float) хранит числа в диапазоне от -65 504 до +65 504 с минимальным положительным значением около 6×10⁻⁸. Когда attention score умножается на value и суммируется по 32 000 позиций, промежуточные аккумуляторы легко превышают 65 504. Процессор в f32 имеет запас до ~3.4×10³⁸ - переполнения не происходит.
Indexer DSA вычисляет scores для отбора релевантных позиций. Если на вход подаётся длинная последовательность, scores накапливаются, и умножение матриц даёт значения за границей f16. GPU молча конвертирует переполнение в inf, а последующая нормализация превращает inf в NaN.
Почему 8k работает, а 32k - нет: порог переполнения
Эмпирический порог стабильности для RTX 3060 с DSA включённым - около 8 192 токенов. При 16 384 токенах ошибка возникает нестабильно: иногда модель выдаёт 2-3 токена до падения. При 32 768 токенах NaN появляется на первом же шаге декодирования.
Грубая оценка: суммарный attention score пропорционален длине последовательности. При 8k максимальное значение ~10 000-15 000, что влезает в f16. При 32k оно достигает 50 000-70 000 - за гранью. Точный порог зависит от инициализации весов indexer'а и конкретного входного текста.
Тест конфигураций: что мы пробовали и что сработало
Тестовый стенд: 4-сокетный Intel Xeon (суммарно 88 ядер), 1 ТБ DDR4, NVIDIA RTX 3060 12 ГБ. Модель GLM-5.2 в квантовании Q4_K_M. Использовался llama.cpp с поддержкой DSA. Контекст фиксировался на 32 768 токенов для всех тестов, кроме контрольного на 8 192.
Результаты сведены в таблицу:
| Конфигурация | Результат | Скорость декодинга |
|---|---|---|
| dsa=on, fa=on, KV на GPU, ub=512 | NaN на 1-м токене | — |
| dsa=on, fa=off, KV на GPU, ub=512 | NaN на 1-м токене | — |
| dsa=off, fa=on, KV на GPU, ub=512 | Стабильно | 8.2 токен/с |
| dsa=off, fa=off, KV на GPU, ub=512 | Стабильно | 7.5 токен/с |
| dsa=on, fa=off, KV на CPU, ub=512 | NaN на 1-м токене | — |
| dsa=on, fa=off, эксперты на CPU, KV на GPU, ub=512 | Стабильно | 6.8 токен/с |
| dsa=on, fa=off, эксперты на CPU, KV на CPU, ub=512 | Стабильно | 5.1 токен/с |
| dsa=on, fa=off, эксперты на CPU, KV на GPU, ub=256 | Стабильно | 7.1 токен/с |
| dsa=on, fa=off, эксперты на CPU, KV на GPU, ub=128 | Стабильно | 6.3 токен/с |
Флаги DSA и Flash Attention: влияние на стабильность
Отключение DSA (dsa=off) полностью устраняет NaN независимо от состояния Flash Attention. Indexer не запускается на GPU, и переполняться нечему. Цена - полное внимание по всем токенам, что увеличивает объём вычислений и памяти KV-кэша. На RTX 3060 с 32k контекстом это даёт 7.5-8.2 токен/с на декодинге.
Flash Attention (fa=on/off) на стабильность не влияет. FA оптимизирует доступ к памяти при вычислении attention, но не меняет диапазон значений. С dsa=on падение происходит и с FA, и без него.
Перенос KV-кэша и экспертов на CPU: ключ к стабильности
Перенос только KV-кэша на CPU не спасает. Indexer DSA всё ещё выполняется на GPU и переполняется на длинных последовательностях. Проблема в вычислениях, а не в хранении.
Перенос экспертов MoE на CPU решает проблему радикально. Эксперты GLM-5.2 - это feed-forward слои, которые обрабатывают токены после attention. При размещении на CPU вычисления идут в f32, переполнения нет. DSA остаётся включённым, indexer работает на GPU, но scores передаются экспертам на CPU, где аккумуляция безопасна.
Команда для llama.cpp с экспертами на CPU:
./llama-cli \
-m glm-5.2-q4_k_m.gguf \
-c 32768 \
--dsa 1 \
--flash-attn 0 \
--no-kv-offload \
--num-experts-per-token 8 \
--expert-device cpu \
-ngl 20 \
-ub 256 \
-p "Your prompt here"
Ключевые параметры: --expert-device cpu переносит экспертов на процессор, --no-kv-offload оставляет KV-кэш в оперативной памяти, -ngl 20 загружает 20 слоёв на GPU (всё, кроме экспертов). DSA включён флагом --dsa 1.
Размер micro-batch (ub): неожиданный фактор
Параметр ub (micro-batch size) управляет количеством токенов, обрабатываемых параллельно на GPU. При dsa=on и экспертах на CPU изменение ub с 512 до 256 или 128 влияет на стабильность, хотя механизм неочевиден.
При ub=512 модель падает с NaN, при ub=256 и ub=128 - работает стабильно. Вероятная причина: меньший размер батча снижает пиковое потребление памяти GPU и изменяет порядок вычислений в indexer'е, из-за чего промежуточные значения не достигают порога переполнения. Скорость декодинга при ub=256 составила 7.1 токен/с - выше, чем при ub=512 с экспертами на CPU (6.8 токен/с), потому что меньший батч уменьшает latency синхронизации CPU-GPU.
Практическое руководство: как запустить GLM-5.2 на длинном контексте без NaN
По итогам тестов определены две рабочие стратегии. Выбор зависит от приоритетов: скорость или сохранение DSA.
Рекомендованная конфигурация для RTX 3060
Вариант 1: максимальная скорость (DSA отключён).
./llama-cli \
-m glm-5.2-q4_k_m.gguf \
-c 32768 \
--dsa 0 \
--flash-attn 1 \
-ngl 40 \
-ub 512 \
-p "Your prompt here"
Ожидаемая скорость: 8.2 токен/с на декодинге. Контекст стабилен до 32k. При 64k возможно снижение скорости из-за объёма KV-кэша, но NaN не возникает.
Вариант 2: DSA включён, эксперты на CPU.
./llama-cli \
-m glm-5.2-q4_k_m.gguf \
-c 65536 \
--dsa 1 \
--flash-attn 0 \
--no-kv-offload \
--num-experts-per-token 8 \
--expert-device cpu \
-ngl 20 \
-ub 256 \
-p "Your prompt here"
Ожидаемая скорость: 7.1 токен/с. Контекст стабилен до 64k. DSA сохраняет эффективность разреженного внимания, но узким местом становится передача данных между GPU и CPU для экспертов. Подробный разбор производительности GLM-5.2 на гибридных конфигурациях доступен в бенчмарке 3-битной версии на системе за $900.
Диагностика: как убедиться, что NaN больше нет
Самый надёжный способ - проверка логитов после каждого шага декодирования. В llama.cpp можно включить отладочный вывод или использовать скрипт-обёртку:
#!/bin/bash
# run_stable_test.sh
./llama-cli \
-m glm-5.2-q4_k_m.gguf \
-c 32768 \
--dsa 1 \
--expert-device cpu \
-ngl 20 \
-ub 256 \
-p "Explain quantum computing in detail." \
2>&1 | tee output.log
# Проверка на NaN в выводе
if grep -q "nan" output.log; then
echo "FAIL: NaN detected in output"
else
echo "PASS: No NaN in output"
fi
Для мониторинга в реальном времени можно добавить флаг --logits-all (если поддерживается сборкой) и фильтровать вывод через grep -i nan. Стабильная генерация 100+ токенов без NaN подтверждает, что конфигурация работает.
Аналогичная проблема потери стабильности на длинных контекстах разбирается в статье про Qwen 3.6 27B и потерю инструкций - там чек-лист конфигурации llama.cpp применим и к диагностике GLM-5.2.
Ограничения и альтернативы: когда GLM-5.2 с DSA не стоит использовать
Перенос экспертов на CPU решает проблему NaN ценой скорости. На RTX 3060 декодинг падает с 8.2 до 7.1 токен/с. На более слабых процессорах падение будет значительнее. Для задач, требующих быстрой генерации на длинных контекстах (чат-боты, потоковая обработка), такая конфигурация неприемлема.
Отключение DSA даёт максимальную скорость, но отказывается от ключевой фичи модели - динамического разреженного внимания. При контексте 64k полное внимание требует O(n²) памяти для attention matrix, что на 12 ГБ VRAM невозможно. Модель вынуждена использовать KV-кэш на CPU, и скорость падает до 3-4 токен/с.
Альтернативы для длинных контекстов:
- Другие модели. Qwen 3.6 27B стабильно работает на 32k с Flash Attention и не страдает от переполнения f16. DeepSeek-V4-Flash показывает 770 токен/с на B300, но требует тюнинга MoE-ядер - детали в разборе оптимизации инференса DeepSeek-V4-Flash.
- GLM-5.2 без DSA на мощном GPU. На RTX 4090 24 ГБ или A100 40 ГБ полное внимание влезает в VRAM до 32k контекста, и скорость остаётся приемлемой.
- CPU-инференс. Полный запуск на CPU в f32 полностью исключает переполнение. Скорость будет низкой (5-9 токен/с на топовых Xeon), но стабильность гарантирована. Проблемы CPU-инференса GLM-5.2 и способы их решения разобраны в статье о запуске на AMD EPYC.
GLM-5.2 с DSA оправдан, когда важна эффективность внимания на сверхдлинных контекстах (64k+), а скорость некритична. Для большинства практических задач на бюджетном оборудовании лучше отключить DSA или выбрать другую модель.
Заключение: длинный контекст без компромиссов?
Проблема NaN в GLM-5.2 с DSA локализована: переполнение f16 в indexer'е на GPU при контексте более 8 192 токенов. Решение есть - перенос экспертов на CPU или отключение DSA. Оба варианта требуют компромисса по скорости.
Будущие версии DSA могут получить опцию вычислений indexer'а в f32 даже на GPU, что снимет проблему без потери производительности. Пока этого нет, конфигурации из этой статьи позволяют запускать GLM-5.2 на длинных контекстах стабильно.
Если вы тестировали другие комбинации флагов или нашли способ удержать DSA на GPU без NaN - сообщите о результатах. Практические находки сообщества помогают быстрее находить рабочие решения для всех.