# llama.cpp в Docker: CPU, CUDA и проверка локального API

Источник: https://modelium.tech/zhurnal/llama-cpp-v-docker/

Для запуска llama.cpp в Docker используйте официальный образ server на CPU или server-cuda при совместимом NVIDIA GPU и настроенном контейнерном runtime. Подключите проверенный GGUF только для чтения, опубликуйте порт на localhost и проверьте не только готовность сервера, но и ответ модели. GPU-образы разработчики собирают, но не тестируют в CI сверх сборки; совместимость и сетевую изоляцию нужно проверить на своём хосте.

По состоянию на 6 октября 2026 года документация llama.cpp описывает отдельные Docker-образы `server` для CPU и `server-cuda`/`server-cuda13` для CUDA 12/13. Это инструкция для Linux-хоста с локальным GGUF и loopback API. Docker-образ не гарантирует ускорение: авторы прямо предупреждают, что GPU-варианты проходят сборку CI, но не тестируются CI как рабочий инференс. У Modelium нет собственного прогона контейнера. [s1](#src-s1) [s2](#src-s2)

## Какой Docker-образ выбрать под своё железо

Для проверки самой цепочки контейнер → GGUF → HTTP достаточно `ghcr.io/ggml-org/llama.cpp:server`: это серверный образ без отдельного GPU backend. Для NVIDIA выберите `:server-cuda` или, при совместимом драйвере, `:server-cuda13`; на хосте нужен настроенный NVIDIA Container Toolkit. Поддержка конкретной видеокарты, драйвера и архитектуры хоста должна проверяться отдельно, а не выводиться из имени тега. Есть также варианты `server-rocm`, `server-vulkan` и `server-intel`; они требуют своего устройства и конфигурации, поэтому CUDA-команду ниже на них просто заменой тега переносить нельзя. [s1](#src-s1) [s2](#src-s2) [s8](#src-s8)

`server` содержит именно `llama-server`, а `light` и `full` рассчитаны на другие исполняемые программы. Теги образов могут обновляться: для повторяемого рабочего окружения сохраните полученный digest и версию движка Docker после собственного совместимого теста. Не считайте зафиксированный Git-коммит документации пином бинарного Docker-образа. [s1](#src-s1) [s2](#src-s2)

Контрольная текстовая модель — `Qwen/Qwen3-0.6B-GGUF`, файл `Qwen3-0.6B-Q8_0.gguf` на ревизии Hugging Face `23749fefcc72300e3a2ad315e1317431b06b590a`. Наличие файла и метка `apache-2.0` видны в репозитории; условия применения читайте в приложенном LICENSE. Небольшой демонстрационный вариант не обещает размещение в определённом объёме RAM/VRAM или качество ответа на бизнес-данных. Перед тестом скачайте файл именно с указанной ревизии в заранее созданный каталог `models` на своём хосте и проверьте имя и целостность по данным репозитория; Modelium файл не скачивал. [s6](#src-s6) [s7](#src-s7)

## Как запустить сервер с закрытым хостовым портом

Сначала убедитесь, что Docker Engine работает и ваш каталог `models` действительно содержит выбранный GGUF: опция `--mount` не создаёт отсутствующую исходную папку автоматически. При запуске из каталога проекта для **CPU-проверки** используйте одну команду: `docker run --rm --name llama-cpp-local -p 127.0.0.1:8080:8080 --mount type=bind,src="$PWD"/models,dst=/models,readonly ghcr.io/ggml-org/llama.cpp:server -m /models/Qwen3-0.6B-Q8_0.gguf --host 0.0.0.0 --port 8080 --n-gpu-layers 0 --no-webui`. Путь внутри контейнера `/models/...` соответствует bind mount; `readonly` защищает исходный каталог от записи из контейнера. `0.0.0.0` здесь — интерфейс *внутри* контейнера, тогда как `127.0.0.1:8080:8080` привязывает опубликованный порт на хосте к loopback. [s1](#src-s1) [s3](#src-s3) [s4](#src-s4) [s5](#src-s5)

Для **NVIDIA GPU** после установки и настройки NVIDIA Container Toolkit, проверки драйвера и совместимости CUDA замените образ на `ghcr.io/ggml-org/llama.cpp:server-cuda`, добавьте Docker-опцию `--gpus all` перед именем образа и замените `--n-gpu-layers 0` на `--n-gpu-layers all`. Это не универсальное требование «вся модель должна помещаться в VRAM»: число выгруженных слоёв и фактическое размещение сверяйте с логом llama-server и выбранным устройством; если запуск с `all` не помещается, экспериментируйте с числом слоёв без обещаний скорости. Не используйте `--privileged`, host network или публикацию `-p 8080:8080` для локального теста. [s1](#src-s1) [s3](#src-s3) [s5](#src-s5) [s8](#src-s8)

## Как подтвердить ответ модели, а не только доступность порта

После загрузки на *том же хосте* проверьте `curl -f http://127.0.0.1:8080/health`: по документации код 503 означает загрузку, 200 — готовность. Затем получите `curl -f http://127.0.0.1:8080/v1/models` и посмотрите `data[0].id`; обычно он соответствует пути из `-m`, но может быть задан `--alias`. Эти два запроса не доказывают генерацию. [s3](#src-s3)

Отправьте JSON на `POST http://127.0.0.1:8080/v1/chat/completions` с `model` **точно из** `data[0].id`, `messages` с ролью `user` и текстом `Ответь одним словом: привет /no_think`, `max_tokens` 128. Проверьте код HTTP и содержательное `choices[0].message.content`; если поле пустое, изучите `reasoning_content`, ответ сервера и лимит токенов, затем повторите контролируемый тест. Карточка Qwen описывает `/no_think`, а llama-server — chat endpoint и варианты обработки reasoning. Сверьте полученный ответ с заданием, а не принимайте статус HTTP 200 за доказательство качества. Modelium не отправлял этот запрос и не наблюдал ответа. [s3](#src-s3) [s6](#src-s6)

Для GPU-теста дополнительно сверяйте лог с реально обнаруженным CUDA-устройством и числом выгруженных слоёв; отсутствие ошибки от `--gpus all` или успешный CPU-ответ не доказывают GPU-offload. При ошибке загрузки проверяйте точное имя файла, путь монтирования, права чтения и доступную память; при недоступном GPU — драйвер хоста, runtime NVIDIA и выбранный вариант CUDA-образа. Размер GGUF на диске не равен требуемой памяти при выбранном контексте и настройках сервера. [s1](#src-s1) [s3](#src-s3) [s4](#src-s4) [s8](#src-s8)

## Когда Docker не даёт изоляции и как убрать тест

`127.0.0.1` на опубликованном порту — необходимая граница для локального примера, но не подтверждение отсутствия сетевого выхода контейнера или полного закрытия API. Docker отдельно предупреждает: в Engine старше 28.0.0 хосты в том же L2-сегменте могли подключаться даже к localhost-порту. У llama-server есть флаг `--api-key`, однако `/health` остаётся публичным; для сетевых клиентов нужны отдельные правила доступа и реальный тест с другого хоста. Если нужен офлайн-контур, контролируйте исходящие соединения и предварительную загрузку весов отдельно — этот текст не подтверждает такую изоляцию. [s3](#src-s3) [s5](#src-s5)

Остановите интерактивный контейнер Ctrl+C; `--rm` удалит его при остановке, но каталог с GGUF на хосте останется. Следующий шаг — [проверить совместимость GGUF и параметры llama.cpp](/zhurnal/llama-cpp/), затем провести собственный тест ответа и GPU backend на вашем железе. Это руководство по первоисточникам, а не отчёт о запуске Modelium. [s1](#src-s1) [s4](#src-s4)

## Источники

1. [llama.cpp: Docker images, usage and caveat for GPU CI](https://github.com/ggml-org/llama.cpp/blob/5e03bdd8700948b9c41c54dd1b00f28a2aebc03f/docs/docker.md) — получено 2026-10-06
2. [llama.cpp: GitHub Actions Docker build matrix](https://github.com/ggml-org/llama.cpp/blob/5e03bdd8700948b9c41c54dd1b00f28a2aebc03f/.github/workflows/docker.yml) — получено 2026-10-06
3. [llama.cpp: llama-server endpoints and options](https://github.com/ggml-org/llama.cpp/blob/5e03bdd8700948b9c41c54dd1b00f28a2aebc03f/tools/server/README.md) — получено 2026-10-06
4. [Docker Docs: bind mounts and readonly](https://docs.docker.com/engine/storage/bind-mounts/) — получено 2026-10-06
5. [Docker Docs: publishing to localhost and L2 caveat](https://docs.docker.com/engine/network/port-publishing/) — получено 2026-10-06
6. [Qwen3-0.6B-GGUF: model card pinned to HF commit](https://huggingface.co/Qwen/Qwen3-0.6B-GGUF/blob/23749fefcc72300e3a2ad315e1317431b06b590a/README.md) — получено 2026-10-06
7. [Qwen3-0.6B-GGUF: repository LICENSE](https://huggingface.co/Qwen/Qwen3-0.6B-GGUF/blob/23749fefcc72300e3a2ad315e1317431b06b590a/LICENSE) — получено 2026-10-06
8. [NVIDIA Container Toolkit: install and configure Docker runtime](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) — получено 2026-10-06
