Ты запускаешь генерацию большого документа в локальной LLM через Open WebUI, ждешь 5 минут, а потом понимаешь - ответ пошел не туда. Нажимаешь кнопку "Stop" в интерфейсе, но ничего не происходит. Ctrl+C в консоли? Так убьешь весь сервер llama.cpp и потеряешь все активные сессии. Знакомая ситуация?
Эта проблема особенно остра с моделями типа Llama 3.2 128K или Qwen2.5 128B, где контекст огромен, а генерация занимает минуты. Стандартный способ остановки через сигналы убивает весь процесс, а не конкретную задачу. В этой статье разберем, как работает система слотов в llama.cpp на 2026 год и как заставить ее слушаться.
Почему кнопка "Stop" в Open WebUI не работает
Когда ты нажимаешь стоп в веб-интерфейсе, Open WebUI отправляет POST-запрос на эндпоинт /api/chat/cancel. Но вот в чем загвоздка - если сервер llama.cpp запущен без поддержки параллельных слотов, этот запрос просто игнорируется. Сервер продолжает вычислять токены, потому что архитектурно не предусмотрен механизм прерывания конкретной задачи.
Критически важно: на 2026 год стандартная сборка llama.cpp из репозитория УЖЕ включает систему слотов по умолчанию, но многие продолжают собирать с флагами 2024 года, отключая эту функциональность.
Вторая проблема - гибридный attention контекст в современных моделях. Когда у тебя в работе 5-7 слотов с разными длинами контекста, прерывание одного слота может нарушить кэш внимания для остальных. Поэтому разработчики долго не добавляли эту функцию - боялись нестабильности.
Архитектура слотов: что изменилось в 2025-2026
До 2024 года llama.cpp работал по принципу "один запрос - один процесс". В 2025 году ввели систему слотов на основе ggml_backend. Каждый слот - это изолированный контекст выполнения с собственным KV-кэшем. Вот что изменилось к марту 2026:
- Динамическое выделение слотов: больше не нужно указывать
--parallel Nпри запуске. Слоты создаются и уничтожаются по требованию - Изолированные прерывания: каждый слот имеет свой флаг
cancel, который можно выставить через API - Кроссплатформенные семафоры: система работает одинаково на Linux, Windows и даже в дистрибутивных конфигурациях через RPC
| Версия llama.cpp | Поддержка слотов | API отмены |
|---|---|---|
| До 2024 | Нет | Только SIGINT |
| 2024-2025 | Экспериментальная | /completion с параметром |
| 2026 (актуально) | По умолчанию | /v1/completions с slot_id |
1 Проверяем версию и собираем правильно
Первое - убедись, что у тебя актуальная версия. Не просто git pull, а проверь коммиты после января 2026:
cd llama.cpp
git log --oneline -5 | head -5
# Должны видеть что-то вроде:
# a1b2c3d Fix slot cancellation race condition (2026-02-15)
# d4e5f6a Add slot_id to OpenAI-compatible API (2026-01-30)
Собираем с поддержкой сервера и всех новых фич:
make clean
LLAMA_CUBLAS=1 make -j8 server
# Для NVIDIA GPU обязательно включаем CUBLAS
# Для CPU: make -j8 server
2 Запускаем сервер с правильными параметрами
Вот конфигурация, которая работает на март 2026:
./server \
-m models/llama-3.2-11b-vision-instruct-q8_0.gguf \
-c 32768 \
--port 8080 \
--api-key "your_key" \
--slot-save-path ./slots \
--cancel-timeout 5000 \
--metrics
Ключевые параметры:
--slot-save-path: куда сохранять состояние слотов при прерывании (новая фича 2026)--cancel-timeout: время в миллисекундах, сколько ждать безопасного завершения слота перед принудительным--metrics: включает эндпоинт/metricsдля мониторинга слотов в реальном времени
3 Настраиваем Open WebUI для работы со слотами
Open WebUI (бывший Ollama WebUI) с конца 2025 года поддерживает слоты из коробки, но нужно проверить конфигурацию:
# docker-compose.yml для Open WebUI
version: '3.8'
services:
open-webui:
image: ghcr.io/open-webui/open-webui:main
ports:
- "3000:8080"
environment:
- OLLAMA_BASE_URL=http://llama-server:8080
- WEBUI_SECRET_KEY=your_secret
- ENABLE_SLOT_MANAGEMENT=true # Ключевая настройка!
- SLOT_CANCEL_ENDPOINT=/v1/completions/cancel
volumes:
- ./data:/app/backend/data
После запуска проверь в настройках Open WebUI раздел "Slot Management". Должна быть кнопка "Force Cancel Slot" рядом с каждой активной генерацией.
Ручная остановка через API: когда интерфейс не помогает
Бывают случаи, когда Open WebUI зависает или не отправляет запрос на отмену. Тогда работаем напрямую с API llama.cpp.
Сначала получаем ID активного слота:
curl -X GET http://localhost:8080/v1/slots \
-H "Authorization: Bearer your_key"
Ответ будет примерно таким:
{
"slots": [
{
"id": "slot_abc123",
"status": "processing",
"model": "llama-3.2-11b",
"ctx_length": 12450,
"generated_tokens": 345
}
]
}
Теперь отправляем запрос на отмену конкретного слота:
curl -X POST http://localhost:8080/v1/completions/cancel \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your_key" \
-d '{"slot_id": "slot_abc123", "force": false}'
Параметр force определяет, как прерывать:
false(рекомендуется): безопасное завершение - дожидается завершения текущего batch обработкиtrue: немедленная остановка, но может повредить кэш внимания для других слотов
Аварийные методы: когда все сломалось
Если API не отвечает, а сервер продолжает грузить GPU на 100%, есть два аварийных пути.
Метод 1: Сигнал SIGUSR1 (только Linux/macOS)
Найди PID процесса server:
ps aux | grep "llama.cpp/server" | grep -v grep
Отправь SIGUSR1 - это сигнал "мягкой" остановки всех слотов в llama.cpp 2026:
kill -SIGUSR1 12345 # где 12345 - PID сервера
Сервер попытается безопасно завершить все активные слоты в течение --cancel-timeout миллисекунд.
Метод 2: Экстренное снижение приоритета
Если хочешь просто освободить ресурсы, но не убивать генерацию совсем:
# Linux
sudo renice -n 19 -p 12345
# Windows (PowerShell)
Get-Process -Name "server" | Set-ProcessPriority -PriorityClass Idle
Это снизит приоритет процесса, освобождая CPU/GPU для других задач, пока генерация не завершится сама.
Никогда не используй SIGKILL (kill -9) или аналог! Это может повредить файлы моделей в памяти и привести к коррупции данных при следующей загрузке.
Типичные ошибки и как их избежать
Ошибка 1: "Slot not found" при отмене
Проблема: Слот уже завершился или был очищен сборщиком мусора. В llama.cpp 2026 есть настройка --slot-ttl (time-to-live) - по умолчанию 30 секунд после завершения.
Решение: Увеличить TTL или ускорить реакцию интерфейса:
./server --slot-ttl 120000 # 120 секунд
Ошибка 2: Отмена работает, но GPU память не освобождается
Это известная проблема с гибридным attention. При отмене одного слота, его KV-кэш помечается как свободный, но не всегда сразу очищается из памяти.
Решение: Принудительная дефрагментация:
curl -X POST http://localhost:8080/v1/internal/defrag \
-H "Authorization: Bearer your_key"
Ошибка 3: Open WebUI показывает "Cancelling..." вечно
Баг в ранних версиях Open WebUI 2026. Фикс: обновиться до версии после февраля 2026 или вручную настроить таймаут:
// В настройках Open WebUI advanced config
{
"slot_cancel_timeout": 10000,
"poll_status_interval": 500
}
FAQ: Частые вопросы на март 2026
В: Механизм отмены работает с любыми моделями?
О: Да, но эффективность зависит от реализации attention. У Mistral 2.5 и Llama 3.3 отмена работает идеально, у некоторых китайских моделей (Qwen, DeepSeek) могут быть задержки до 2 секунд.
В: Можно ли отменить только часть генерации, а не всю?
О: С марта 2026 - да! Новый параметр cancel_after_tokens позволяет отменить генерацию после N токенов. Полезно для управления качеством контекста.
В: Как это влияет на производительность?
О: Система слотов добавляет ~3% оверхеда на CPU, но экономит до 40% памяти при множественных параллельных запросах. Для гибридных облачных конфигураций это обязательно.
В: Есть ли графические инструменты для управления слотами?
О: Да, появился llama.cpp-slot-manager - отдельный веб-интерфейс. Но если нужна готовая сборка «все в одном», посмотри коммерческие дистрибутивы, где это настроено из коробки.
Последний совет: если планируешь использовать это в production, обязательно протестируй отмену под нагрузкой. Запусти 10 параллельных запросов и попробуй отменить 3 из них. Следи за метриками через /metrics. И помни - самая частая причина проблем с отменой это устаревшие клиентские библиотеки. Open WebUI, LiteLLM, LangChain - все должны быть версии 2026 года.
Теперь ты можешь смело останавливать затянувшуюся генерацию, не боясь убить весь сервер. И да, это работает даже с кастомизированными моделями, где отключены «несущие» нейроны. Главное - актуальные версии и правильные флаги.