Ollama: параллельные запросы, очередь и память сервера
На странице · 5 разделов
В Ollama параллельность запросов к одной модели задаётся `OLLAMA_NUM_PARALLEL`, число одновременно загруженных моделей — отдельной настройкой `OLLAMA_MAX_LOADED_MODELS`, а очередь ограничивается `OLLAMA_MAX_QUEUE`. Увеличение параллельности повышает потребность в памяти для контекста и само по себе не гарантирует меньшую задержку. Начните с одного и двух одновременных запросов на тестовом сервере, сохраняя модель, контекст и текст неизменными; сравните время ответа и фактическое размещение модели.
Проверено по официальной документации Ollama на Git-ревизии
948f69329 сентября 2026 года. Поведение и значения по умолчанию могут отличаться в вашей версии. Modelium не запускал Ollama или модель и не измерял чужой сервер; Python-пример ниже — инструкция для контролируемого эксперимента читателя, а не опубликованный результат производительности.
Какие три ограничения нельзя смешивать?
Одна модель, несколько запросов. OLLAMA_NUM_PARALLEL задаёт максимум одновременной обработки запросов для каждой модели; в зафиксированной FAQ значение по умолчанию — один. Это не число моделей и не универсальное обещание, что запросы действительно будут обрабатываться одновременно при недостатке памяти s1.
Несколько моделей. OLLAMA_MAX_LOADED_MODELS ограничивает число одновременно загруженных моделей, если их позволяет держать свободная RAM/VRAM. Если новую модель нельзя загрузить вместе с текущей, запросы ожидают освобождения памяти. Для GPU Ollama в этой FAQ требует, чтобы новая модель при одновременной загрузке целиком помещалась в VRAM; не путайте это с универсальным правилом для одиночного запуска s1. Чтобы проверить именно параллелизм одной модели, не меняйте состав загруженных весов в середине теста.
Ожидающие запросы. OLLAMA_MAX_QUEUE ограничивает очередь, а не ускоряет генерацию. После превышения допустимой нагрузки FAQ описывает ответ HTTP 503; значение очереди по умолчанию в проверенной редакции — 512. Это не основание бездумно отправлять сотни запросов: нагрузочный тест проводите только на выделенной машине, где нет посторонних пользователей s1.
Практическая цепочка: задача обслуживания локального чата → уже выбранная модель и формат под вашу машину → измеренный запас RAM/VRAM → Ollama → одинаковый запрос при одной и двух одновременных сессиях → сравнение задержки, ошибок и размещения. Если ещё нет работающей модели, начните с Ollama и первого запуска; не выбирайте модель только из-за красивого показателя запросов в секунду.
Почему параллельность расходует память?
Ollama объясняет: при нескольких параллельных запросах к одной модели суммарный выделенный контекст увеличивается с числом запросов. FAQ приводит иллюстрацию: контекст 2K и четыре параллельных запроса дают 8K суммарной ёмкости контекста; дополнительная память зависит и от модели, и от backend. В самой FAQ потребность в памяти описана как масштабируемая по произведению OLLAMA_NUM_PARALLEL × OLLAMA_CONTEXT_LENGTH; не умножайте размер файла весов на это число и не выдавайте его за расчёт гигабайтов s1.
Длина контекста также зависит от настроек сервера и модели; в API options.num_ctx может задать её для отдельного запроса. Проверьте фактически выделенный CONTEXT и поле PROCESSOR командой ollama ps, прежде чем сравнивать два режима: переход на CPU или иное окно делает сравнение некорректным s1s3. Поле /api/ps → size_vram и колонка SIZE помогают наблюдать загруженную модель, но не доказывают пиковое потребление RAM/VRAM всего сервера, драйвера или соседних процессов s2s3. Для общего бюджета используйте методику оценки памяти, а для длины одного агентного диалога — отдельный разбор контекста Ollama.
Как безопасно подготовить две конфигурации?
Нужны: локальная установленная Ollama, уже скачанная подходящая текстовая модель, возможность перезапустить тестовый экземпляр, Python 3 со стандартной библиотекой и наблюдение за памятью своей системы. Сначала получите точный локальный тег из ollama ls или GET /api/tags; адрес API в примерах — 127.0.0.1:11434, поэтому скрипт не отправляет запросы к удалённому серверу s2s6. Не запускайте эксперимент на общей машине без согласования нагрузки и не пересылайте клиентские документы.
На отдельном Linux-стенде с systemd службой Ollama начните с параметров сервера:
[Service]
Environment="OLLAMA_NUM_PARALLEL=1"
Environment="OLLAMA_MAX_QUEUE=4"
Environment="OLLAMA_MAX_LOADED_MODELS=1"
Environment="OLLAMA_CONTEXT_LENGTH=2048"
Ollama документирует systemctl edit ollama для environment override; настройки concurrency описаны в FAQ, контекст — в руководстве по длине окна. 2048 и очередь 4 здесь выбор для осторожного опыта, а не значения по умолчанию, не предел конкретной модели и не требования к оборудованию. Примените override и перезапустите только тестовую службу; это прерывает текущие запросы s1s3s4:
sudo systemctl daemon-reload
sudo systemctl restart ollama
curl -fsS http://127.0.0.1:11434/api/version
curl -fsS http://127.0.0.1:11434/api/tags
ollama ps
Если Ollama запущена как приложение или контейнер, настройка systemd-службы к ней не относится: переменные следует передать именно процессу ollama serve или контейнеру и перезапустить его. Не запускайте второй ollama serve поверх уже слушающего экземпляра. Не открывайте OLLAMA_HOST для всех сетевых интерфейсов ради теста s1s4s6.
После первого измерения измените только OLLAMA_NUM_PARALLEL=2, снова перезапустите тестовую службу и повторите тот же сценарий на той же версии, модели, контексте и машине. Если модель перестаёт помещаться или разгружается на CPU, верните исходное значение; падение latency при изменении остальных условий не доказывает эффект параллельности s1s3.
Как сравнить задержку без генератора фиктивных цифр?
Сохраните следующий код как compare_ollama.py; укажите точное имя уже загруженной локальной модели через OLLAMA_MODEL. Скрипт выполняет один warm-up, затем два одинаковых коротких запроса последовательно и два одновременно. Он не меняет системные настройки, не скачивает веса, не создаёт неограниченную нагрузку, не использует клиентские данные и останавливается при HTTP-ошибке. API /api/generate принимает stream:false, options.num_ctx, а в финальном JSON возвращает длительности в наносекундах и счётчик сгенерированных токенов s1s2.
import concurrent.futures
import json
import os
import time
import urllib.error
import urllib.request
model = os.environ["OLLAMA_MODEL"] # Возьмите точное имя из /api/tags.
url = "http://127.0.0.1:11434/api/generate"
request_body = json.dumps({
"model": model,
"prompt": "Одним словом назови столицу Франции.",
"stream": False,
"options": {"num_ctx": 2048, "num_predict": 32, "temperature": 0},
}).encode("utf-8")
def one():
request = urllib.request.Request(
url, data=request_body, headers={"Content-Type": "application/json"},
)
started = time.perf_counter()
try:
with urllib.request.urlopen(request, timeout=120) as response:
data = json.load(response)
status = response.status
except urllib.error.HTTPError as error:
raise RuntimeError(f"HTTP {error.code}: остановите тест и проверьте очередь/журнал") from error
wall_s = time.perf_counter() - started
if status != 200 or not data.get("done"):
raise RuntimeError(f"Ответ неполон: HTTP {status}")
return {"wall_s": round(wall_s, 3),
"server_s": round(data["total_duration"] / 1e9, 3),
"load_s": round(data["load_duration"] / 1e9, 3),
"tokens": data["eval_count"]}
print("warmup", one())
for label, run_parallel in (("serial", False), ("pair", True)):
t0 = time.perf_counter()
if run_parallel:
with concurrent.futures.ThreadPoolExecutor(max_workers=2) as pool:
results = list(pool.map(lambda _: one(), range(2)))
else:
results = [one() for _ in range(2)]
print(label, "batch_wall_s", round(time.perf_counter() - t0, 3),
"individual", results)
Проверьте каждую строку вывода, а не одну итоговую цифру. wall_s — время клиента до полного ответа; batch_wall_s — время завершения двух запросов, server_s и load_s — значения серверного API. Прогрев отделяет загрузку модели от последующих измерений, но и он не гарантирует полного отсутствия иных эффектов кеша. Разные tokens, CPU fallback, температура железа, фоновые задачи и повторение одного промпта искажают сравнение s2s3. Этот код не измеряет число запросов в очереди в каждый момент, полное потребление VRAM или статистическую p95; для эксплуатационного решения сделайте повторения и сохраните версию модели, hardware, конфиг и интервалы нагрузки.
Снимите ollama ps и /api/ps до/после; проверьте, остались ли PROCESSOR, CONTEXT, имя и size_vram сопоставимыми. Системными средствами отдельно запишите RAM процесса и память GPU, если ваш драйвер даёт такую метрику, не объявляя size_vram полным бюджетом памяти s2s3s6. Сравните четыре серии: NUM_PARALLEL=1 и 2, для каждой последовательную и одновременную пару; не смешивайте «оба клиента закончили быстрее» с «каждый запрос получил меньшую задержку».
Когда откатить настройку и что проверить при ошибке?
HTTP 503 или рост ожидания. Запишите число клиентов, статус и момент, посмотрите journalctl -u ollama --no-pager --follow --pager-end на стенде. FAQ связывает 503 с перегрузкой/очередью; увеличение OLLAMA_MAX_QUEUE лишь накапливает ожидающие запросы и может увеличить время ответа, поэтому сперва уменьшите нагрузку и проверьте память s1s5.
Ответы ушли на CPU или загрузка модели сорвалась. Сравните ollama ps, состояние GPU, журнал и фактический контекст; верните OLLAMA_NUM_PARALLEL=1 или уменьшите выбранный контекст на стенде. Размер весов не равен минимуму RAM/VRAM, а демонстрация на одной GPU-конфигурации не гарантирует работу другой s1s3s5.
После рестарта первый ответ медленнее. Сервер мог повторно загрузить модель: сравните load_duration. По FAQ время удержания регулируется keep_alive в запросе или OLLAMA_KEEP_ALIVE для сервера, причём параметр запроса имеет приоритет. Не меняйте удержание одновременно с параллельностью во время одного сравнения s1s2.
Чтобы откатить опыт, выполните sudo systemctl edit ollama, удалите только добавленные для этого эксперимента строки Environment=..., сохраните override, затем sudo systemctl daemon-reload && sudo systemctl restart ollama; если override был создан исключительно для теста, его можно убрать целиком после проверки чужих строк. Проверьте /api/version, свой обычный одиночный запрос и прежнее CPU/GPU-размещение s2s3s4. Основной следующий шаг: зафиксируйте фактический контекст и размещение Ollama перед тем, как выбирать рабочий лимит параллельных запросов.
Источники
- Ollama FAQ — concurrent requests, queue, keep alive (pinned) — revision 948f69330acf96a2310f1b53fdfc211731a386d8. Получено 29.09.2026.
- Ollama API reference — generate, tags, ps, version (pinned) — revision 948f69330acf96a2310f1b53fdfc211731a386d8. Получено 29.09.2026.
- Ollama — Context length and ollama ps (pinned) — revision 948f69330acf96a2310f1b53fdfc211731a386d8. Получено 29.09.2026.
- Ollama Linux — systemd service and override (pinned) — revision 948f69330acf96a2310f1b53fdfc211731a386d8. Получено 29.09.2026.
- Ollama — Troubleshooting and server logs (pinned) — revision 948f69330acf96a2310f1b53fdfc211731a386d8. Получено 29.09.2026.
- Ollama CLI — ps, serve, stop (pinned) — revision 948f69330acf96a2310f1b53fdfc211731a386d8. Получено 29.09.2026.