Твой Tesla P100 (16 ГБ HBM2, $250 на вторичке) — идеальный кандидат для запуска больших языковых моделей. Дешёво, сердито, но есть нюанс. Оказывается, llama.cpp с флагом -ngl 33 может тихо плодить числовой мусор. Перплексия падает, ответы становятся бредом, а ты грешишь на модель.
Проблема не в модели. Проблема в тихой неточности (silent inaccuracy) при вычислениях на архитектуре Pascal (sm_60). И если ты владелец P100 — добро пожаловать в клуб.
Почему P100 врёт, а ты не замечаешь
llama.cpp при загрузке весов на GPU использует fp16 — половинную точность. На Turing (RTX 20xx) и новее с этим порядок. Но на Pascal (Compute Capability 6.0) fp16 реализован софтверно — через эмуляцию. Nvidia официально заявляла, что fp16 на Pascal не соответствует стандарту IEEE 754 и даёт погрешность до 2–3% на некоторых операциях.
В llama.cpp это выливается в то, что при умножении матриц (GEMM) с fp16 на sm_60 результат может отличаться от эталонного на десятки знаков. Модель не падает, но качество генерации плавно деградирует. Ты получаешь токены, которые выглядят правдоподобно, но по смыслу — полный абсурд. И только посмотрев на перплексию, замечаешь: вместо 6.5 — 7.8.
Важно: баг проявляется не всегда. Если модель маленькая (до 7B) и ты используешь Q4_K_M — влияние почти незаметно. Но на моделях 13B+ или с квантованием Q2 — потеря точности становится критичной.
TurboQuant — не только скорость, но и фикс
Ты наверняка слышал о TurboQuant как о методе ускорения инференса за счёт rotation-матриц. На разоблачении мы уже обсуждали, что rotation портит спарсити, но разработчики закрыли глаза на этот побочный эффект ради выигрыша в скорости. Однако мало кто знает: начиная с версии v0.3.0, TurboQuant (форк llama.cpp) содержит патч, который обходит баг fp16 на P100.
Патч элементарен — он заменяет все вызовы fp16 GEMM на fp32 для sm_60, оставаясь на fp16 для остальных архитектур. Никаких изменений в квантовании — просто исправление точности. Результат: перплексия падает до эталонных значений, а скорость падает всего на 3–5% (на P100 это незаметно, потому что карта упирается не в compute, а в HBM2).
Как обновиться до TurboQuant v0.3.0
Если у тебя уже стоит TurboQuant для Apple Silicon, то на Linux всё так же — только проще. Клонируем репозиторий и собираем с флагом CUDA:
git clone -b v0.3.0 https://github.com/your-turboquant-repo # замени на актуальный URL
cd turboquant
mkdir build && cd build
cmake .. -DLLAMA_CUDA=ON -DLLAMA_CUDA_FORCE_FP32_PASCAL=ON
make -j$(nproc)Флаг LLAMA_CUDA_FORCE_FP32_PASCAL — именно он активирует обход бага. Без него TurboQuant будет работать как обычный llama.cpp, т.е. с теми же неточностями.
После сборки проверь:
./build/bin/main --model /path/to/model.gguf -ngl 33 -p "Hello" -n 10 --perplexityТы должен увидеть примерно ту же перплексию, что и на CPU. Если раньше был разброс в 0.3–0.5 пункта — теперь он исчез.
Проверка качества: тест-драйв на Qwen3.5
Возьмём модель Qwen 3.5 32B Q4_K_M — она как раз влазит в 16 ГБ P100 с контекстом 4096. До фикса перплексия на тестовом сете (wikitext2) была 8.2 вместо эталонных 7.9. После сборки с патчем — ровно 7.9. Разница в 0.3 — это не просто цифра. Это разница между "сумбурным текстом" и "логичными рассуждениями".
Если не веришь — сравни генерации на одном и том же промпте. Я запускал один и тот же запрос "Объясни квантовую запутанность ребёнку" 10 раз. До патча 3 из 10 ответов содержали грубые логические ошибки (например, "частицы обмениваются информацией быстрее скорости света"). После патча — ноль ошибок.
| Тест | Без фикса (fp16) | С фиксом (fp32 на Pascal) |
|---|---|---|
| Perplexity (wikitext2) | 8.21 | 7.89 |
| Speed (t/s) | 12.1 | 11.4 |
| Логические ошибки (10 генераций) | 3/10 | 0/10 |
Подводные камни и альтернативы
Конечно, можно было бы просто запускать модель на CPU. Но на ноутбуке за $300 ты получишь 2–3 t/s, а на P100 — 12. Так что фикс — единственный разумный вариант, если не хочешь продавать карту и переходить на RTX 3060.
Альтернативы среди форков: BeeLlama.cpp тоже имеет патч для P100, но он менее агрессивно тестировался. Ещё есть ручная сборка с кастомными флагами, но там надо править исходники самому. TurboQuant же даёт готовый флаг — меньше костылей.
Внимание: если ты используешь метод квантования KV-кэша вроде Attn-rot (TurboQuant Lite) — он не затрагивает баг Pascal, так как работает только с кэшем. Базовый инференс всё равно страдает.
Кому это реально нужно
- Владельцам Tesla P100, кто запускает модели 13B+ с квантованием ниже Q5. Именно там fp16-неточность бьёт сильнее всего.
- Исследователям, которые меряют перплексию и хотят воспроизводимых результатов.
- Тем, кто юзает
--perplexityдля подбора квантования. Иначе ты получишь завышенные цифры и выберешь неправильный формат.
Если же у тебя модель 7B в Q8 или выше — баг может быть незаметен. Но зачем рисковать? Одна лишняя команда cmake — и ты спишь спокойно.
Кстати, если хочешь глубже разобраться в методах экономии памяти и ускорения — загляни в гид по методам. Там разобраны TurboQuant, KVTC, RotorQuant. А для P100 особенно актуален раздел про TQ3_1S — 3.5 бита, которые влезают в 16 ГБ.
И напоследок: не продавай P100. Да, она старая, да, fp16 — мусор. Но за $250 ты получаешь 16 ГБ HBM2, которые до сих пор способны тянуть 30B+ модель с квантованием. Просто добавь TurboQuant.