Чтобы получить чистое содержимое этой страницы в формате Markdown, добавьте .md к этому URL. Полный индекс документации см. на https://docs.nvidia.com/dynamo/llms.txt. Полное содержимое, включая справочник API и примеры SDK, см. на https://docs.nvidia.com/dynamo/llms-full.txt.
Корректное завершение работы
В этом документе описано, как компоненты Dynamo обрабатывают сигналы завершения работы, чтобы текущие запросы успешно завершались, а ресурсы корректно освобождались.
Обзор
Корректное завершение работы в Dynamo обеспечивает следующее:
- Маршрутизация быстро останавливается - конечные точки сначала снимаются с регистрации в discovery
- Текущие запросы могут завершиться - рабочие процессы продолжают обслуживать запросы в течение короткого льготного периода
- Конечные точки осушаются - после льготного периода конечные точки становятся недействительными и, при необходимости, ожидают завершения текущей работы
- Ресурсы освобождаются - движки, соединения и временные файлы освобождаются
- Pods перезапускаются корректно - коды выхода сигнализируют Kubernetes о правильном поведении при перезапуске
Обработка сигналов
Все компоненты Dynamo обрабатывают сигналы Unix для корректного завершения работы:
| Сигнал | Триггер | Поведение |
|---|---|---|
SIGTERM | Завершение pod в Kubernetes | Запускается корректное завершение работы |
SIGINT | Ctrl+C / ручное прерывание | Запускается корректное завершение работы |
Реализация
Каждый компонент регистрирует обработчики сигналов при запуске:
def signal_handler():
asyncio.create_task(graceful_shutdown(runtime, endpoints))
for sig in (signal.SIGTERM, signal.SIGINT):
loop.add_signal_handler(sig, signal_handler)
Функция graceful_shutdown():
- Записывает сигнал завершения работы в журнал
- Снимает все конечные точки с регистрации в discovery
- Ожидает настраиваемый льготный период (
DYN_GRACEFUL_SHUTDOWN_GRACE_PERIOD_SECS, по умолчанию 5 с) - Вызывает
runtime.shutdown(), чтобы сделать конечные точки недействительными и прекратить прием новых запросов - Ожидает текущие запросы (на основе
graceful_shutdownдля каждой конечной точки) - Возвращает управление, чтобы можно было продолжить очистку
Осушение конечных точек
После льготного периода runtime.shutdown() делает конечные точки недействительными, поэтому новые запросы больше не принимаются. Поведение для текущих запросов зависит от параметра graceful_shutdown при обслуживании конечной точки.
Конфигурация
При регистрации конечной точки параметр graceful_shutdown управляет поведением при осушении:
generate_endpoint.serve_endpoint(
handler.generate,
graceful_shutdown=True, # Wait for all requests to finish
metrics_labels=[("model", model_name)],
health_check_payload=health_check_payload,
)
graceful_shutdown | Поведение |
|---|---|
True | Ожидать завершения всех текущих запросов перед возвратом |
False | Вернуться немедленно, не ожидая запросы |
Поведение отдельных компонентов
| Компонент | Поведение по умолчанию | Обоснование |
|---|---|---|
| Frontend | Н/Д (HTTP server) | HTTP server самостоятельно обрабатывает свое завершение работы |
| Prefill Workers | graceful_shutdown=True | Операции prefill должны завершиться, чтобы избежать напрасных вычислений |
| Decode Workers | graceful_shutdown=True | Операции decode должны завершиться, чтобы избежать напрасных вычислений |
| Router | graceful_shutdown=True | Гарантирует завершение решений по маршрутизации |
Интеграция с миграцией
Backend workers всегда используют graceful_shutdown=True, то есть ожидают завершения текущих запросов до остановки движка. Миграция запросов настраивается на уровне frontend через --migration-limit:
- Когда миграция включена на frontend, отключенные потоки от отказавших workers автоматически повторяются на исправных workers
- Workers не должны знать о конфигурации миграции - они просто завершают свою работу или сигнализируют о незавершенных потоках
- Подробнее о работе миграции см. в разделе Архитектура миграции запросов
Очистка ресурсов
После осушения конечных точек компоненты очищают свои ресурсы в блоках finally:
Очистка vLLM Worker
finally:
logger.debug("Cleaning up worker")
handler.cleanup()
Метод cleanup() обработчика:
- Удаляет временные каталоги (адаптеры LoRA и т. д.)
- Освобождает ресурсы движка
Очистка SGLang Worker
def cleanup(self) -> None:
# Cancel pending consume tasks
for task in self._consume_tasks:
if not task.done():
task.cancel()
self._consume_tasks.clear()
# Shutdown engine
self.engine.shutdown()
Очистка TensorRT-LLM Worker
async def cleanup(self):
if self._llm:
try:
self._llm.shutdown()
except Exception as e:
logging.error(f"Error during cleanup: {e}")
finally:
self._llm = None
Завершение работы, инициированное ошибкой
Workers могут инициировать корректное завершение работы при возникновении фатальных ошибок:
Мониторинг работоспособности движка (vLLM)
VllmEngineMonitor непрерывно проверяет работоспособность движка:
async def _check_engine_health(self):
while True:
try:
await self.engine_client.check_health()
await asyncio.sleep(HEALTH_CHECK_INTERVAL) # 2 seconds
except EngineDeadError as e:
logger.error(f"Health check failed: {e}")
self._shutdown_engine()
self.runtime.shutdown()
os._exit(1)
Конфигурация:
HEALTH_CHECK_INTERVAL: 2 секунды между проверкамиENGINE_SHUTDOWN_TIMEOUT: не более 30 секунд на завершение работы движка
Обработка фатальных ошибок (TensorRT-LLM)
async def _initiate_shutdown(self, error: Exception):
logging.warning(f"Initiating graceful shutdown due to: {error}")
try:
if self.runtime:
self.runtime.shutdown()
if self.engine:
await self.engine.cleanup()
except Exception as cleanup_error:
logging.error(f"Error during graceful shutdown: {cleanup_error}")
finally:
logging.critical("Forcing process exit for restart")
os._exit(1)
Интеграция с Kubernetes
Процесс завершения pod
- Kubernetes отправляет
SIGTERMв pod - Dynamo инициирует корректное завершение работы
- У pod есть
terminationGracePeriodSecondsна завершение (по умолчанию 30 с) - Если pod не завершился, Kubernetes отправляет
SIGKILL
Рекомендуемая конфигурация
Для production-развертываний настройте достаточный льготный период завершения:
apiVersion: nvidia.com/v1alpha1
kind: DynamoGraphDeployment
spec:
services:
VllmWorker:
extraPodSpec:
terminationGracePeriodSeconds: 60 # Allow time for request draining
Интеграция с проверками работоспособности
Kubernetes использует health endpoints, чтобы определить готовность pod:
- Во время завершения работы: конечные точки становятся недоступными
- Readiness probe fails: трафик перестает направляться в pod
- Graceful draining: существующие запросы завершаются
Рекомендации
1. Задавайте подходящие льготные периоды
Согласуйте terminationGracePeriodSeconds с ожидаемым временем завершения запросов:
- Короткие запросы (< 10 с): льготный период 30 с
- Долгая генерация (> 30 с): льготный период 120 с и больше
2. Включите миграцию запросов
Включите миграцию на frontend, чтобы запросы могли восстанавливаться при завершении работы workers:
python3 -m dynamo.frontend ... --migration-limit 3 # Allow up to 3 migration attempts
Это позволяет frontend автоматически повторять отключенные потоки на исправных workers.
3. Отслеживайте метрики завершения работы
Отслеживайте поведение при завершении работы по журналам:
INFO Received shutdown signal, shutting down DistributedRuntime
INFO DistributedRuntime shutdown complete
DEBUG Cleaning up worker
4. Обрабатывайте ошибки очистки
Убедитесь, что методы очистки корректно обрабатывают ошибки:
def cleanup(self):
for resource in self.resources:
try:
resource.cleanup()
except Exception as e:
logger.warning(f"Cleanup failed: {e}")
# Continue with other resources
Связанная документация
- Миграция запросов - как запросы мигрируют во время завершения работы
- Отмена запросов - отмена текущих запросов
- Проверки работоспособности - liveness- и readiness-пробы