Сравнить spot vs on-demand для batch inference
ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Сравнить spot vs on-demand для batch inference
1. Цель задачи
Научиться проектировать cost-эффективные batch inference pipelines, выбирая тип вычислительных инстансов в зависимости от критичности задачи. Практически сравнить стоимость и надёжность выполнения batch-задач на spot instances (прерываемые) и on-demand instances (гарантированные) на примере инференса ML-модели. Разработать стратегию автоматического переключения на on-demand при прерывании spot.
Ключевой результат Снижение затрат на batch inference на 60% при обеспечении 99% успешных завершений задач (reliability) за счёт комбинированного использования spot (90% задач) и on-demand (10% + fallback).
2. Исходные данные
Перед началом необходимо иметь:
| Что нужно | Откуда взять |
|---|---|
| Batch-задача инференса (Python + ML-модель) | Собственный pet-проект или открытый репозиторий (например, Hugging Face example) |
| Тестовый датасет (10–100 тыс. запросов) | Open dataset (например, IMDB, CIFAR-10) или сгенерированный синтетический |
| Учётная запись облачного провайдера (AWS/GCP/Azure) | Личный аккаунт с ограниченным бюджетом или бесплатный tier |
| Базовые знания Terraform / Cloud SDK | Документация провайдера |
| Скрипты для мониторинга и логирования | Prometheus + Grafana (опционально), CloudWatch / Stackdriver / Azure Monitor |
Если нет реального облачного провайдера — симулируем:
- Установите локально эмулятор облачных API (например, LocalStack для AWS).
- Используйте симулятор прерываний spot (скрипт, который случайным образом "убивает" процесс с вероятностью 20-30% каждые 5 минут).
- Для стоимости используйте таблицы публичных цен (AWS pricing API в офлайн-режиме) — загрузите CSV с ценами для выбранного региона и типа инстанса.
- Для метрик времени выполнения используйте timeit в Python — эмулируйте разное время инференса.
3. Технологический стек
| Компонент | Инструменты | Назначение |
|---|---|---|
| Облачный провайдер | AWS EC2 (или GCE / Azure VMs) | Запуск инстансов для batch inference |
| Оркестрация инфраструктуры | Terraform, AWS CLI / SDK | Создание и управление инстансами |
| Batch job runner | Python (multiprocessing / asyncio) + Bash | Запуск инференса на удалённых машинах |
| Мониторинг | CloudWatch (AWS), Prometheus + node_exporter | Сбор метрик CPU, памяти, времени работы |
| Логирование | Loki + Grafana (или CloudWatch Logs) | Анализ прерываний и перезапусков |
| Симулятор (если нет облака) | LocalStack + custom Python scripts | Эмуляция spot preemption и стоимости |
| Модель для инференса | PyTorch / TensorFlow / ONNX Runtime | Лёгкая модель (например, ResNet-18) |
4. Этапы выполнения
Этап 1: Подготовка тестового batch inference (2–3 часа)
Действия
-
Выберите лёгкую предобученную модель (например, distilbert-base-uncased для NLP или resnet18 для CV).
-
Подготовьте датасет из 10 000 образцов — загрузите и сохраните в Parquet/JSON.
-
Напишите Python-скрипт
batch_inference.py, который:- Читает датасет порциями (batch size = 64).
- Запускает инференс на CPU или GPU.
- Сохраняет результаты в CSV.
- Логирует время выполнения каждого батча.
-
Оберните скрипт в Docker-образ (если планируется запуск на облаке).
Пример структуры:
# batch_inference.py import time, json, torch from transformers import AutoModelForSequenceClassification, AutoTokenizer model_name = "distilbert-base-uncased-finetuned-sst-2-english" model = AutoModelForSequenceClassification.from_pretrained(model_name) tokenizer = AutoTokenizer.from_pretrained(model_name) def process_batch(texts): inputs = tokenizer(texts, padding=True, truncation=True, return_tensors="pt") with torch.no_grad(): outputs = model(**inputs) return outputs.logits.argmax(dim=-1).tolist() # Основной цикл t_start = time.time() results = [] for i, batch in enumerate(data_loader): preds = process_batch(batch["text"]) results.extend(preds) if i % 10 == 0: print(f"Batch {i}, elapsed {time.time()-t_start:.2f}s") -
Проверьте локально — скрипт должен выполниться за <30 минут на CPU.
Ожидаемый результат этапа Рабочий Docker-образ с batch_inference, тестовый датасет, измерено baseline-время выполнения на локальной машине.
Этап 2: Запуск на on-demand инстансах (2–3 часа)
Действия
- Создайте Terraform-конфигурацию для запуска одной VM on-demand:
- Запустите инстанс и дождитесь завершения задачи.
- Зафиксируйте метрики
- Время выполнения (сек).
- Стоимость (часы * почасовая ставка).
- Использование CPU/памяти (через CloudWatch).
- Повторите 3 раза для статистики.
Таблица цен (пример для t3.medium в us-east-1):
| Тип | On-demand ($/ч) | Spot ($/ч) |
|---|---|---|
| t3.medium | 0.0416 | ~0.0125 |
Ожидаемый результат этапа Среднее время выполнения на on-demand, базовая стоимость.
Этап 3: Запуск на spot инстансах и измерение прерываний (2–3 часа)
Действия
- Добавьте в Terraform ресурс
aws_spot_instance_requestс максимальной ценой = on-demand. - Увеличьте количество попыток — запустите 10 parallel spot инстансов (или последовательно с разными seed для прерываний).
- Измерьте
- Количество инстансов, прерванных до завершения (preempted).
- Время работы до прерывания.
- Общую стоимость (оплаченное время).
- Напишите скрипт мониторинга который логирует статус инстанса каждые 30 секунд.
Ожидаемый результат этапа Данные о надёжности spot: процент успешных завершений, среднее время жизни до preemption.
Этап 4: Разработка стратегии fallback (2–4 часа)
Действия
-
Спроектируйте комбинированный pipeline
- 90% батчей отправляются на spot.
- Если spot прерван — оставшиеся данные перенаправляются на on-demand.
-
Реализуйте координатор
coordinator.py:- Запускает N spot инстансов, каждый обрабатывает свой сегмент датасета.
- Мониторит их завершение по сигналу
SIGTERM(или по heartbeat). - При обнаружении прерывания: запускает новый on-demand инстанс с той же сегментом данных (read from checkpoint).
-
Добавьте checkpointing в
batch_inference.py— каждые 50 батчей сохранять промежуточные результаты в S3/локальный файл.# checkpointing example import pickle CHECKPOINT_FILE = f"checkpoint_{segment_id}.pkl" def save_checkpoint(processed_batches, results): with open(CHECKPOINT_FILE, "wb") as f: pickle.dump({"processed": processed_batches, "results": results}, f) # При старте проверять, есть ли чекпоинт, и продолжать с него -
Запустите полный тест с симуляцией 30% прерываний — проверьте, что итоговая reliability >99%.
Ожидаемый результат этапа Работающий pipeline с автоматическим fallback, измеренная итоговая стоимость и доля успешных задач.
Этап 5: Анализ и оформление результатов (1–2 часа)
Действия
- Сведите все метрики в таблицу
| Конфигурация | Total cost ($) | Время выполнения (мин) | Success rate |
|---|---|---|---|
| 100% on-demand | X | Y | 100% |
| 100% spot (без fallback) | X*0.3 | Y (частично) | ~50% |
| Комбинированная (spot+fallback) | X*0.4 | Y+10% | 99%+ |
- Рассчитайте экономию относительно on-demand:
(cost_on_demand - cost_combined) / cost_on_demand * 100%. - Оцените reliability = (число успешных сегментов) / (общее число сегментов).
- Подготовьте одно-двухстраничный отчёт в формате PDF или Markdown: график стоимости, выводы.
Ожидаемый результат этапа Файл comparison_report.md с итогами, графиками, рекомендациями.
5. Критерии приемки (Definition of Done)
- Скрипты batch_inference.py и coordinator.py работают и выложены в Git-репозиторий.
- Настроен Terraform для создания spot и on-demand инстансов (или их симуляция).
- Проведено не менее 10 запусков на spot с регистрацией прерываний.
- Реализован механизм checkpoint и fallback на on-demand.
- Итоговая reliability (доля успешно завершённых батчей) >= 99%.
- Снижение стоимости относительно 100% on-demand >= 60%.
- Подготовлен отчёт с таблицей сравнения и графиками.
- Каждый этап задокументирован в README (шаги, команды, ожидаемый результат).
6. Ожидаемый результат
Основной артефакт Файл comparison_report.md, содержащий:
- Описание архитектуры комбинированного pipeline.
- Таблицу сравнения трёх конфигураций (on-demand, spot, hybrid).
- График распределения времени выполнения и стоимости.
- Ключевые выводы: рекомендуемая доля spot инстансов, ожидаемая экономия, оговорки (например, для GPU spot может быть менее доступен).
Дополнительные результаты
- Docker-образ с batch_inference и checkpointing.
- Terraform-конфигурации для воспроизведения.
- Python-скрипты для симуляции (если не использовалось реальное облако).
7. Возможные сложности и их решение
| Сложность | Решение |
|---|---|
| Spot инстанс прерывается в середине длительного батча (без checkpoint) | Добавить checkpoint каждые N батчей; при перезапуске продолжать с последнего сохранённого состояния. |
| Стоимость переключения может свести экономию на нет | Оптимизировать порог: переключать на on-demand только если оставшееся время > времени старта нового spot. |
| Spot не доступен в текущем регионе / типе инстанса | Использовать несколько типов инстансов (flexible) или fallback на on-demand той же спецификации. |
| Симуляция не отражает реальные паттерны прерываний | Использовать исторические данные AWS (Spot interruption rate by instance type) или задать консервативный уровень 20% прерываний. |
| Сложно точно измерить cost в симуляции | Ведите лог времени работы каждого инстанса, умножайте на price из официального прайс-листа. |
8. Бюджет времени (оценка)
| Этап | Время |
|---|---|
| Этап 1: Подготовка тестового batch inference | 2–3 часа |
| Этап 2: Запуск на on-demand | 2–3 часа |
| Этап 3: Запуск на spot | 2–3 часа |
| Этап 4: Разработка fallback | 2–4 часа |
| Этап 5: Анализ и оформление | 1–2 часа |
| Итого | 9–15 часов |
Примечание Для первого выполнения рекомендуется выделить 2–3 дня (вечерние сессии). Если используется симуляция вместо реального облака, время сокращается на 30–40% за счёт отсутствия ожидания создания инстансов.
9. Связанные вопросы из базы знаний
| Вопрос | Тема |
|---|---|
| 112 | Оптимизация затрат на inference в облаке |
| 145 | Spot instances: best practices |
| 203 | Batch inference pipeline design |
| 267 | Cost-aware auto-scaling для ML |
| 381 | Мониторинг и алертинг для batch jobs |
| 402 | Preemption handling strategies |
| 519 | Terraform для ML-инфраструктуры |
| 604 | Checkpointing в длительных задачах |
| 738 | Сравнение pricing моделей облачных провайдеров |
| 815 | Reliability vs cost trade-off в ML-системах |
10. Чек-лист самопроверки
- Я понимаю разницу между spot, on-demand и reserved instances.
- Я написал batch-скрипт с checkpointing и протестировал его локально.
- Я развернул (или симулировал) хотя бы один on-demand инстанс и зафиксировал стоимость.
- Я запустил серию spot инстансов и собрал статистику прерываний.
- Реализован автоматический fallback: при прерывании spot задача не теряет данные и завершается на on-demand.
- Итоговая экономия ≥60%, reliability ≥99%.
- Все скрипты и конфигурации лежат в Git, отчёт сформирован.
- Я могу объяснить, в каких случаях использовать spot невыгодно (критичные real-time задачи, очень короткие джобы).