Если вам не хватает памяти под нужный контекст, есть ровно две настройки, которые стоит включить прежде всего остального. Они не требуют менять модель, не портят качество заметным образом и включаются одной строкой.
Нужны они не всем: если модель и контекст помещаются с запасом, оставьте всё как есть — выигрыш в скорости от Flash Attention существует, но он скромнее, чем выигрыш в памяти, ради которого сюда обычно приходят.
#Что понадобится
- Сборка движка с поддержкой этих режимов. В llama.cpp они есть давно; конкретное поведение флагов между версиями менялось, и
--helpвашей сборки — единственный надёжный источник. - Понимание, сколько памяти у вас уходит на контекст. Считается по формуле объёма KV-кэша: удвоенное произведение слоёв, KV-голов и размера головы, умноженное на длину контекста. Разбор — в материале о том, почему большой контекст съедает видеопамять.
#Шаг 1. Понять, что делает каждая настройка
Flash Attention — другой способ вычислять внимание. Обычная реализация строит промежуточную матрицу размером «контекст на контекст» и держит её в памяти; Flash Attention считает результат блоками, не материализуя эту матрицу целиком. Экономятся и обращения к памяти, и сама память — причём выигрыш растёт с длиной контекста.
Важно: результат математически эквивалентен обычному вниманию. Это не приближение и не упрощение, качество ответов не меняется. Что вообще такое механизм внимания — в справке об attention.
Квантизация KV-кэша — хранение ключей и значений с пониженной точностью: восемь бит вместо шестнадцати, иногда четыре. Здесь потеря качества уже есть, но на восьми битах она очень мала. Это ровно та же идея, что и квантизация весов, применённая к другому массиву данных. Что за массив — в справке о KV-кэше.
Связь между ними практическая: в llama.cpp квантизация кэша значений требует включённого Flash Attention. Поэтому включают их вместе.
#Шаг 2. Включить в llama.cpp
./build/bin/llama-cli -m models/llama-3.1-8b-instruct-q4_k_m.gguf -ngl 99 -c 32768 -fa -ctk q8_0 -ctv q8_0
Разбор: -fa включает Flash Attention, -ctk q8_0 задаёт восьмибитное хранение ключей, -ctv q8_0 — значений. Допустимые типы: f16 (по умолчанию), q8_0, q4_0.
В свежих сборках -fa принимает явное значение (on, off, auto) — проверьте --help. Остальные флаги разобраны в гайде по llama.cpp без магии.
#Шаг 3. Включить в Ollama
Здесь это переменные окружения, а не параметры модели:
OLLAMA_FLASH_ATTENTION=1 OLLAMA_KV_CACHE_TYPE=q8_0 ollama serve
Для постоянной работы переменные задаются в конфигурации сервиса. На Linux с systemd:
systemctl edit ollama
и добавить строки Environment="OLLAMA_FLASH_ATTENTION=1" и Environment="OLLAMA_KV_CACHE_TYPE=q8_0". На Windows — через переменные окружения пользователя с последующим перезапуском службы. Где задаются остальные параметры — в материале о параметрах Ollama, которые действительно влияют на результат.
#Шаг 4. Посчитать выигрыш
Таблица ниже — расчёт по формуле объёма KV-кэша, а не замер на конкретной машине: восьмибитное хранение вдвое сокращает байт на элемент, четырёхбитное — вчетверо. Экономия от самого Flash Attention сверх этого зависит от реализации и длины контекста и в таблицу не включена.
| Модель и контекст | Кэш f16 | Кэш q8_0 | Кэш q4_0 | Экономия на q8_0 |
|---|---|---|---|---|
| Llama 3.1 8B, 8k | 1,0 ГиБ | 0,5 ГиБ | 0,25 ГиБ | 0,5 ГиБ |
| Llama 3.1 8B, 32k | 4,0 ГиБ | 2,0 ГиБ | 1,0 ГиБ | 2,0 ГиБ |
| Qwen2.5 14B, 32k | 6,0 ГиБ | 3,0 ГиБ | 1,5 ГиБ | 3,0 ГиБ |
| Qwen2.5 32B, 32k | 8,0 ГиБ | 4,0 ГиБ | 2,0 ГиБ | 4,0 ГиБ |
Что здесь смотреть: последний столбец на длинном контексте. Два-четыре освободившихся гигабайта — это разница между «модель 14B не влезает в карту на 12 ГБ» и «влезает с рабочим контекстом». Ни одна другая настройка не даёт столько без потери качества.
На коротком контексте выигрыш скромный — половина гигабайта. Поэтому включать эти настройки ради принципа смысла нет: они окупаются там, где контекст велик.
#Проверка результата
Проверка первая: память действительно освободилась. Запустите модель с прежними параметрами, запишите занятую видеопамять, затем с новыми:
nvidia-smi --query-gpu=memory.used --format=csv
Разница должна примерно совпасть с расчётом из таблицы. Если не совпала — флаг не применился.
Проверка вторая: скорость не упала. Замерьте до и после:
./build/bin/llama-bench -m models/llama-3.1-8b-instruct-q4_k_m.gguf -ngl 99 -c 32768 -p 512 -n 128 -fa
Обычно скорость с Flash Attention растёт, особенно на длинном контексте. Падение — повод проверить, поддерживает ли ваш бэкенд этот режим эффективно.
Проверка третья: качество на ваших задачах. Дайте модели три-четыре типичных для вас задания с одинаковыми параметрами сэмплинга до и после включения квантизации кэша. На восьми битах разницы вы, скорее всего, не увидите. На четырёх — можете, особенно на длинных рассуждениях.
#Что может пойти не так
Флаг не поддерживается сборкой. Не все бэкенды реализуют Flash Attention одинаково: на CUDA и Metal он зрелый, на других — зависит от версии. Если движок ругается на флаг, проверьте --help.
Квантизация значений не работает без Flash Attention. В llama.cpp это связанные настройки. Включайте -fa вместе с -ctv.
Скорость упала после включения. Встречается на бэкендах, где режим реализован не оптимально. Замерьте оба варианта и оставьте лучший: экономия памяти не стоит двукратной потери скорости.
Четырёхбитный кэш испортил ответы. Ожидаемо: q4_0 для кэша заметно агрессивнее, чем q8_0, и на длинных рассуждениях это проявляется. Практическое правило — останавливаться на восьми битах, а к четырём переходить только если иначе модель не запускается вовсе.
В Ollama переменные не применились. Они читаются сервисом при старте, а не при запросе. После изменения службу нужно перезапустить, а не просто выполнить ollama run.
#Частые вопросы
#Портит ли Flash Attention качество ответов?
Нет. Это другой способ вычислить тот же результат, математически эквивалентный обычному вниманию. Разница только в том, сколько промежуточных данных при этом хранится в памяти.
#Насколько ухудшает качество квантизация KV-кэша?
На восьми битах — очень слабо, в обычной работе разница незаметна. На четырёх — заметно, особенно на длинном контексте и в задачах с рассуждением. Восьмибитный вариант можно включать по умолчанию, четырёхбитный — только при острой нехватке памяти.
#Почему эти настройки не включены по умолчанию?
Потому что поддержка неодинакова на разных бэкендах и в разных версиях, а квантизация кэша всё-таки меняет результат. Умолчания в инструментах со временем меняются — проверьте, что фактически включено у вас.
#Что включать первым, если памяти не хватает?
Сначала Flash Attention с восьмибитным кэшем — они почти бесплатны по качеству. Только если этого мало, переходите к сокращению контекста, более жёсткой квантизации весов и смене модели.
#Есть ли смысл включать это на коротком контексте?
Ради памяти — почти нет, выигрыш составит сотни мегабайт. Ради скорости — можно попробовать и замерить: на некоторых связках Flash Attention даёт прирост и на коротком контексте, на других разница в пределах погрешности.