Почему Ollama тормозит на хорошей видеокарте и что менять в настройках

Почему Ollama тормозит на хорошей видеокарте и что менять в настройках

Ollama я держу на тестовой машине с 16 ГБ видеопамяти. Модель на 8 млрд параметров в Q4 влезает целиком, отвечает быстро, и первое время кажется, что настраивать там нечего. Потом к серверу подключается агент, контекст вырастает, и та же модель начинает думать по 30 секунд над коротким вопросом. Модель и железо те же, но настройки, которые Ollama выставляет сама, изменились.

Ollama это локальный сервер на порту 11434

Команда ollama run выглядит как запуск обычной программы в терминале. Под ней работает постоянный HTTP-сервер. Он слушает 127.0.0.1:11434, держит модели в памяти и отвечает на запросы. Терминальный чат, приложение, скрипт и агент вроде Claude Code обращаются к одному и тому же процессу. Поэтому настройки сервера важнее того, как вы запустили модель.

Ollama поддерживает несколько движков для запуска LLM-моделей. На Apple Silicon с версии 0.40 поддерживаемые модели по умолчанию идут через MLX. На остальных платформах работает сборка llama.cpp, та же, что в llama-server, с ускорением через CUDA, ROCm или Vulkan. Ollama добавляет к ней библиотеку моделей, распределение по памяти, очередь запросов и единый API.

Ставится одной командой или установщиком. На 16 октября 2026 актуальна версия 0.40.6. С 0.30.x многое изменилось: появились MLX, Anthropic-совместимый слой, ollama launch и decision-модели.

Переменные окружения меняют поведение сервера целиком. Параметры в Modelfile закрепляются за конкретной моделью. Почти любая такая правка означает перезагрузку модели в память.

Сколько памяти займёт модель и что такое частичный оффлоад

Веса в Q4_K_M занимают около 0,67 ГБ на 1 млрд параметров. qwen3:8b в библиотеке весит 5,2 ГБ, qwen3:14b около 9,3 ГБ, qwen3:32b около 20 ГБ. Это только веса, без KV-кэша и буферов движка. В 0.40.6 добавили квант q2_0.

Ollama сама решает, сколько слоёв отправить на видеокарту, и пробует уместить модель целиком. Если помещается, все слои уходят на GPU. Если нет, часть остаётся в оперативной памяти, и ollama ps показывает это в колонке PROCESSOR, например 100% GPU или 48%/52% CPU/GPU. 8 ГБ хватает на 8B с коротким контекстом, 16 ГБ на 14B или на 8B с длинным, 24 ГБ на 32B.

Раньше я думал, что при нехватке памяти модель просто переезжает в RAM. На самом деле слои делятся между видеопамятью и оперативной, и каждый токен проходит через все слои, включая те, что остались на процессоре. Скорость зависит от доли слоёв на GPU. 50% слоёв на CPU делает генерацию медленной настолько, что проще взять модель поменьше.

Сколько слоёв уйдёт на видеокарту, можно задать вручную. В опциях загрузки остался num_gpu, по умолчанию -1, то есть автоматический выбор. 0 означает только процессор, положительное число задаёт количество слоёв на видеокарте. В документации Modelfile его больше не расписывают, но API принимает параметр, и планировщик его обрабатывает.

Про выбор железа я писал в статье про компьютер для нейросетей.

Контекст и KV-кэш съедают память быстрее весов

По умолчанию Ollama выбирает длину контекста по объёму видеопамяти. До 24 ГБ это 4 тыс. токенов, от 24 до 48 ГБ уже 32 тыс., выше 48 ГБ до 256 тыс. На домашней карте на 8 или 16 ГБ вы почти всегда получаете 4 тыс.

Для агента 4 тыс. токенов это мало. Агентам, поиску по документам и кодовым помощникам документация советует не меньше 64 тыс. токенов. На 4 тыс. токенов длинный промпт обрезается, и модель теряет начало разговора. Выглядит это как глупость модели, хотя ей просто не передали часть запроса.

Лимит поднимается переменной OLLAMA_CONTEXT_LENGTH при запуске сервера или командой /set parameter num_ctx 64000 в интерактивном чате. Контекст живёт в KV-кэше, и чем длиннее контекст, тем больше памяти он занимает. Считается он по конфигурации модели: 2 тензора, K и V, умножаются на число слоёв, число групп ключей и значений (KV) и размерность каждой группы.

Посчитаем на примере qwen3:8b. У неё 36 слоёв, 8 KV-групп, размерность 128. На 1 токен контекста в f16 уходит 144 КБ. На 4 тыс. токенов это 0,56 ГБ, на 32 тыс. 4,5 ГБ, а на 40 тыс., до которых модель обучена, 5,6 ГБ. На длинном контексте кэш весит почти столько же, сколько веса. Про память и оффлоад я писал отдельно, в разборе инференса локальных моделей.

После OLLAMA_CONTEXT_LENGTH=64000 модель уезжает частично на процессор по той же причине. Веса остались прежними, но KV-кэш вырос, и памяти теперь нужно в 2 раза больше.

Память можно сократить квантованием кэша. OLLAMA_KV_CACHE_TYPE=q8_0 уменьшает его примерно в 2 раза почти без потери качества, q4_0 в 4 раза, но с заметной потерей на длинных контекстах. Квантование работает вместе с Flash Attention, а он включается сам на поддерживаемом железе. Есть и способ проще, не ставить 64 тыс. там, где хватает 16.

Результат виден в ollama ps. Колонка CONTEXT показывает фактическое окно. Оно может отличаться от запрошенного, потому что при значении больше обученного максимума Ollama молча урезает число.

Параллельные запросы и время жизни модели в памяти

OLLAMA_NUM_PARALLEL задаёт, сколько запросов сервер обрабатывает одновременно. По умолчанию 1: запросы идут по очереди. Для Open WebUI на несколько пользователей или агента с параллельными вызовами этого мало.

Поднять счётчик можно, но память расходуется на каждый одновременный запрос: у него свой контекст. Общий расход считается так: OLLAMA_NUM_PARALLEL * OLLAMA_CONTEXT_LENGTH. 4 одновременных запроса по 64 тыс. токенов дают в 4 раза больше кэша, чем 1 запрос на 64 тыс. Очередь по умолчанию 512 запросов, дальше сервер отвечает 503.

keep_alive задаёт, сколько модель живёт в памяти после последнего запроса. По умолчанию 5 минут, потом она выгружается. Для чата это нормально. Для агента, который обращается раз в 10 минут, каждая пауза означает холодный старт и чтение нескольких гигабайт с диска.

Можно передавать keep_alive в запросе, например -1 или "24h", а можно выставить OLLAMA_KEEP_ALIVE для сервера целиком. Для прогрева годится пустой запрос к /api/chat или ollama run модель "".

Modelfile закрепляет настройки за моделью

Флаги неудобны, когда к серверу ходят разные клиенты. Modelfile позволяет собрать модель с нужными параметрами и обращаться к ней по имени.

FROM qwen3:8b PARAMETER num_ctx 16384 PARAMETER temperature 0.4 SYSTEM "Отвечай кратко и по делу."

Собрать модель можно командой ollama create my-qwen -f ./Modelfile. Посмотреть исходный файл любой модели можно через ollama show --modelfile. Внутри есть TEMPLATE, SYSTEM, параметры сэмплирования и требуемая версия Ollama.

Клиенты на OpenAI-совместимом API не умеют передавать длину контекста. Документация Ollama прямо советует собрать модель с num_ctx в Modelfile. То же с системным промптом и температурой, один раз записали в сборку, и все клиенты получают одинаковое поведение.

API и совместимость с OpenAI и Anthropic

Родной API живёт по адресам /api/chat и /api/generate. Через него передаются все параметры, включая num_ctx и keep_alive, и он же возвращает тайминги. По полям prompt_eval_count, eval_count и eval_duration удобно сравнивать настройки между собой.

Поверх родного API подняты совместимые слои. /v1/chat/completions, /v1/responses и /v1/embeddings принимают клиентов OpenAI, /v1/messages принимает клиентов Anthropic. В коде достаточно поменять base_url, ключ может быть любым, локальный сервер его игнорирует.

Совместимость с OpenAI и Anthropic частичная. Из OpenAI-набора нет tool_choice, картинок по URL и logprobs. Responses API работает только без состояния. Из Anthropic-набора нет cache_control, подсчёта токенов, PDF-документов и батчей, а budget_tokens принимается, но не соблюдается.

Для агентов есть ollama launch, он настраивает Claude Code, Codex, OpenCode, VS Code и Droid на локальный сервер.

Сервер при этом не проверяет ничего, ни ключи, ни пользователей. Пока он слушает 127.0.0.1, это нормально. Как только OLLAMA_HOST меняется на 0.0.0.0, порт 11434 открыт всем в сети, и любой в ней может гонять ваши модели. Ставьте перед ним прокси с паролем.

Где Ollama не подходит

Есть сценарии, где Ollama лучше не мучить.

Общий сервер на команду. При параллельных запросах контекст дублируется, поэтому пропускная способность упирается в видеопамять. Для 10 человек, которые одновременно задают вопросы, нужен vLLM с непрерывной пакетной обработкой и общим кэшем.

Большие модели на нескольких видеокартах. Ollama раскладывает слои по картам последовательно, через PCIe. Для модели, которая не влезает в одну карту, это работает, но тензорного параллелизма с обменом внутри слоя там нет. На сервере с NVLink разница будет огромной.

Тонкая настройка и замеры. Если нужно крутить размер батча и планировщик, честнее взять llama.cpp напрямую или vLLM. Автоматика Ollama удобна в типовых задачах, но здесь она только мешает.

Долгие агентские цепочки. В Anthropic-совместимом слое cache_control не поддерживается, а именно он экономит время на повторяющемся префиксе.

Итог

Если модель одна, машина одна и запросы идут по очереди, Ollama в этом случае хватает. Поставили, скачали, поправили контекст и кэш, подключили клиент. Другой инструмент не даст этого за 10 минут.

Если у вас общий сервер, несколько пользователей или модель, которой тесно в одной карте, смотрите в сторону vLLM. Если нужен полный контроль над движком и вы готовы читать флаги llama.cpp, берите его напрямую. Ollama в этих двух случаях будет посредником, который прячет нужные настройки.

Прежде чем покупать видеокарту под локальные модели, проверьте, что упёрлись именно в память. Может оказаться, что всё дело в 4 тыс. токенов контекста по умолчанию.

Если своей видеокарты нет, её можно арендовать по часам. У Selectel есть облачные и выделенные серверы с NVIDIA B300, H200, RTX 6000 Pro и RTX 4090, запуск за 2 минуты и оплата в рублях. Конфигурации и цены смотрите на странице GPU, а зарегистрироваться можно по партнёрской ссылке.

У Timeweb Cloud есть карты от GTX 1080 до H200, но топовые модели заказывают отдельно, вот серверы с GPU. Если нужен не сервер, а API, у Timeweb есть AI Gateway с оплатой в рублях, я разбирал его в статье.

Аренда и новая карта подождут. Сначала проверьте OLLAMA_CONTEXT_LENGTH и OLLAMA_KV_CACHE_TYPE.