中文翻译暂不可用,显示俄语原文。
Как вы деплоите LLM на spot instances в облаке?
Краткий тезис
Деплой LLM на spot instances (прерываемых экземплярах) позволяет экономить 60–90% затрат по сравнению с on-demand instances, но требует специальной архитектуры для обработки внезапных прерываний. Оптимальная стратегия — гибридная: использовать spot для batch inference (offline) и on-demand для критических real-time API. Ключевой элемент — graceful shutdown с checkpointing состояния модели, чтобы после прерывания быстро восстановить работу на другом экземпляре. Инструменты: Kubernetes с pod priority и cluster autoscaler, Terraform для управления инфраструктурой, Docker для контейнеризации, скрипты обработки сигнала SIGTERM.
1. Термины
-
Spot instances (AWS), preemptible VMs (GCP), low-priority VMs (Azure) — вычислительные ресурсы, доступные со скидкой 60–90% по сравнению с on-demand, но которые облако может отозвать в любой момент (обычно с предупреждением за 30 секунд — 2 минуты). Идеальны для fault-tolerant, stateless или batch-задач.
-
On-demand instances — стандартные виртуальные машины, работающие непрерывно по фиксированной цене. Гарантированная доступность, но дороже.
-
Preemptible — синоним spot в GCP.
-
Graceful shutdown — корректная обработка сигнала завершения (SIGTERM) с сохранением состояния (checkpointing) и освобождением ресурсов перед остановкой.
-
Checkpointing — периодическое сохранение текущего состояния модели (весов, кэша KV) и промежуточных результатов (например, для длительных batch-инференсов) в постоянное хранилище (S3, GCS, NFS).
-
Batch inference — асинхронная обработка группы запросов без строгих требований к задержке (секунды-минуты). LLM может обрабатывать данные в режиме очереди.
-
Real-time inference — синхронные ответы с низкой задержкой (< 1 сек). Требует постоянной доступности и быстрого времени отклика.
2. Почему spot instances выгодны для LLM
LLM инференс — ресурсоёмкая задача. Использование GPU-инстансов (например, p4d, A100, H100) на on-demand может стоить $3–30+ в час. Spot предлагает скидку 60–90%:
| Тип инстанса | Цена on-demand (за час) | Цена spot (типично) | Экономия |
|---|---|---|---|
| AWS p4d.24xlarge (8×A100) | $32.77 | ~$9.83 (70%) | ~70% |
| AWS g5.2xlarge (A10G) | $1.21 | ~$0.36 (70%) | ~70% |
| GCP a2-highgpu-8g (8×A100) | ~$29.00 | ~$9.28 (preemptible) | ~68% |
Однако LLM инференс часто требует стабильности: прерывания могут нарушить ответы пользователей. Поэтому spot используют для batch inference (генерация embedding для RAG, офлайн-аналитика) или для non-critical real-time (например, для A/B тестирования). Критичные production-системы идут на on-demand.
3. Архитектура гибридного деплоя
Рекомендуемая архитектура:
- Spot pool для batch-задач (например, ночная индексация документов, массовая генерация ответов для логов).
- On-demand pool для real-time API, которые обслуживают пользователей.
При этом spot pool может быть primary, а on-demand — fallback для критических запросов (если spot прерван). Пример flow:
- Запрос приходит на API Gateway.
- Если запрос real-time (latency-critical) → маршрутизируется на on-demand кластер.
- Если запрос batch (например, большой датасет) → отправляется в очередь (SQS, RabbitMQ), обрабатывается spot-воркерами.
- При прерывании spot-воркер сохраняет checkpoint, и сообщение возвращается в очередь для повторной обработки на другом экземпляре.
4. Graceful shutdown и checkpointing
При получении сигнала SIGTERM (в облаке обычно даётся 30–120 секунд до остановки) процесс должен:
- Прекратить приём новых задач.
- Завершить текущую обработку, сохраняя промежуточные состояния.
- Сохранить checkpoint модели (если она обучалась или работала в режиме online fine-tuning) или кэш KV для длинных контекстов (если используется caching для ускорения).
- Записать метаданные (например, позицию в очереди) в постоянное хранилище (S3, Redis).
- Завершить процесс.
Пример обработчика на Python:
import signal
import sys
import boto3
def checkpoint_save(state):
s3 = boto3.client('s3')
s3.put_object(Bucket='llm-checkpoints', Key='state.pt', Body=state)
def shutdown_handler(signum, frame):
print("SIGTERM received, starting graceful shutdown...")
checkpoint_save(model.state_dict())
# save KV cache or queue position
queue.save_position()
sys.exit(0)
signal.signal(signal.SIGTERM, shutdown_handler)
# основной цикл обработки
while True:
model.infer(...)
Важно: checkpointing должно быть частым (каждые N шагов или по времени), чтобы минимизировать потери при прерывании.
5. Инструменты и конфигурация
5.1 Kubernetes + Spot
Используйте node pools с разными приоритетами:
- Spot node pool для batch workload (label: instance-type=spot)
- On-demand node pool для критических сервисов
Настройте pod priority и cluster autoscaler, чтобы при нехватке ресурсов низкоприоритетные pod'ы на spot вытеснялись первыми. Pod Disruption Budgets (PDB) можно использовать для минимального количества работающих реплик.
5.2 Terraform / Pulumi
Управление инфраструктурой:
resource "aws_eks_node_group" "spot" {
cluster_name = aws_eks_cluster.this.name
node_group_name = "spot-llm"
instance_types = ["p4d.24xlarge"]
capacity_type = "SPOT" # AWS
scaling_config {
desired_size = 2
max_size = 10
}
}
5.3 Docker-образ
Контейнер должен быть stateless (всё состояние — в volumes/сетевых хранилищах). При старте загружает последний checkpoint из S3.
6. Стратегии для batch inference
Для batch-инференса (например, генерация эмбеддингов для 10 млн документов) spot идеален:
- Запросы разбиваются на микробатчи.
- Каждый микробатч обрабатывается на spot-инстансе.
- Если инстанс прерван, микробатч возвращается в очередь и перезапускается на новом spot (или on-demand, если spot мало).
Cost-оптимизация: использование spot instance diversity (AWS Spot Fleet с несколькими типами инстансов: p4d, p3, g5) снижает шанс, что все будут прерваны одновременно.
7. Мониторинг и автоматическое восстановление
- CloudWatch / Cloud Logging — логирование событий прерывания (EC2 Spot Instance Interruption Notice).
- Lifecycle hooks (AWS Auto Scaling) — задержка перед завершением для graceful shutdown.
- Health checks — если инстанс не ответил, перезапуск на on-demand.
- Metrics: цена за инференс, частота прерываний, доля успешных batch-задач.
Пример скрипта для обработки interruption notice (метаданные инстанса):
# curl AWS metadata endpoint
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 60")
curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/spot/termination-time
# если ответ не пустой — начать graceful shutdown
8. Практические рекомендации
- Не используйте spot для сервисов с SLA > 99.9% без надёжного fallback.
- Checkpointing делайте в асинхронном режиме (даже если модель большая, сохраняйте только кэш состояния обработки, а не всю модель при каждом шаге).
- Batch inference — идеальный кандидат: потеря одного батча не критична, можно повторить.
- Training LLM (fine-tuning) также может использовать spot с checkpointing (каждые N шагов), но риск выше — потеря нескольких часов вычислений. Используйте spot for training только если есть бюджет на повторный запуск.
- Используйте managed services (AWS SageMaker Batch Transform на spot, GCP Vertex AI Batch Prediction) — они уже имеют встроенную поддержку preemption.
9. Пример расчёта экономии
Допустим, production-система требует 10 GPU-инстансов (A100) для batch-задач. On-demand цена ~$3/час за инстанс = $30/час. Spot даёт $0.9/час за инстанс = $9/час. При 8-часовом batch-окне экономия в день: (30-9)*8 = $168. В месяц ~$5000. Плюс on-demand для real-time — ещё 2 инстанса = $6/час. Итого общая стоимость ~$15/час вместо $36/час (экономия 58%).
10. Выводы
Деплой LLM на spot — это баланс между стоимостью и надёжностью. Ключевые принципы:
- Graceful shutdown с checkpointing.
- Гибридная архитектура (spot + on-demand).
- Мониторинг и автоматическое восстановление.
- Использование batch для spot и real-time для on-demand.
Пет-проект для закрепления
Задача: Развернуть эмуляцию LLM инференса на spot-подобных экземплярах локально.
Инструменты: Docker, Python, AWS CLI (или эмуляция через kill сигналы).
Шаги:
- Напишите Python-скрипт
llm_server.py, который слушает очередь (Redis/файл) и обрабатывает запросы. Каждый запрос — генерация текста (можно симулироватьtime.sleep(2)). - Добавьте обработчик SIGTERM, который сохраняет текущий запрос в JSON-файл и завершается.
- Запустите скрипт в Docker-контейнере.
- Используйте
docker kill --signal=SIGTERM <id>в случайные моменты. - Напишите скрипт-оркестратор, который при завершении контейнера запускает новый, передавая незавершённый запрос (загружает checkpoint).
- Реализуйте простой балансировщик: если запрос real-time (метка), то шёл на всегда работающий
llm-server-on-demand(другой порт).
Ожидаемый результат: Система, которая корректно обрабатывает внезапные прерывания, сохраняя прогресс, и не теряет ни одного запроса (все завершаются на другом экземпляре).
Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 250 | Общие стратегии деплоя LLM в production |
| 252 | Масштабирование LLM инференса (горизонтальное/вертикальное) |
| 248 | Инфраструктура для Agentic RAG (CI/CD, инференс, кэши) |
| 249 | CI/CD для RAG-систем |
| 253 | Мониторинг LLM (latency, throughput, cost) |
| 254 | Использование очередей (для batch inference) |
Навигация
- Предыдущий: 250
- Следующий: 252
- Индекс: 00. Индекс разборов