Сравнить 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

Если нет реального облачного провайдера — симулируем:

  1. Установите локально эмулятор облачных API (например, LocalStack для AWS).
  2. Используйте симулятор прерываний spot (скрипт, который случайным образом "убивает" процесс с вероятностью 20-30% каждые 5 минут).
  3. Для стоимости используйте таблицы публичных цен (AWS pricing API в офлайн-режиме) — загрузите CSV с ценами для выбранного региона и типа инстанса.
  4. Для метрик времени выполнения используйте timeit в Python — эмулируйте разное время инференса.

3. Технологический стек

КомпонентИнструментыНазначение
Облачный провайдерAWS EC2 (или GCE / Azure VMs)Запуск инстансов для batch inference
Оркестрация инфраструктурыTerraform, AWS CLI / SDKСоздание и управление инстансами
Batch job runnerPython (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 часа)

Действия

  1. Выберите лёгкую предобученную модель (например, distilbert-base-uncased для NLP или resnet18 для CV).

  2. Подготовьте датасет из 10 000 образцов — загрузите и сохраните в Parquet/JSON.

  3. Напишите Python-скрипт batch_inference.py, который:

    • Читает датасет порциями (batch size = 64).
    • Запускает инференс на CPU или GPU.
    • Сохраняет результаты в CSV.
    • Логирует время выполнения каждого батча.
  4. Оберните скрипт в 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")
    
  5. Проверьте локально — скрипт должен выполниться за <30 минут на CPU.

Ожидаемый результат этапа Рабочий Docker-образ с batch_inference, тестовый датасет, измерено baseline-время выполнения на локальной машине.

Этап 2: Запуск на on-demand инстансах (2–3 часа)

Действия

  1. Создайте Terraform-конфигурацию для запуска одной VM on-demand:
    • Выберите тип (например, t3.medium в AWS).
    • Укажите AMI с предустановленным Docker.
    • Добавьте user-data скрипт, который загружает образ из Docker Hub и запускает batch.
  2. Запустите инстанс и дождитесь завершения задачи.
  3. Зафиксируйте метрики
    • Время выполнения (сек).
    • Стоимость (часы * почасовая ставка).
    • Использование CPU/памяти (через CloudWatch).
  4. Повторите 3 раза для статистики.

Таблица цен (пример для t3.medium в us-east-1):

ТипOn-demand ($/ч)Spot ($/ч)
t3.medium0.0416~0.0125

Ожидаемый результат этапа Среднее время выполнения на on-demand, базовая стоимость.

Этап 3: Запуск на spot инстансах и измерение прерываний (2–3 часа)

Действия

  1. Добавьте в Terraform ресурс aws_spot_instance_request с максимальной ценой = on-demand.
  2. Увеличьте количество попыток — запустите 10 parallel spot инстансов (или последовательно с разными seed для прерываний).
  3. Измерьте
    • Количество инстансов, прерванных до завершения (preempted).
    • Время работы до прерывания.
    • Общую стоимость (оплаченное время).
  4. Напишите скрипт мониторинга который логирует статус инстанса каждые 30 секунд.

Ожидаемый результат этапа Данные о надёжности spot: процент успешных завершений, среднее время жизни до preemption.

Этап 4: Разработка стратегии fallback (2–4 часа)

Действия

  1. Спроектируйте комбинированный pipeline

    • 90% батчей отправляются на spot.
    • Если spot прерван — оставшиеся данные перенаправляются на on-demand.
  2. Реализуйте координатор coordinator.py:

    • Запускает N spot инстансов, каждый обрабатывает свой сегмент датасета.
    • Мониторит их завершение по сигналу SIGTERM (или по heartbeat).
    • При обнаружении прерывания: запускает новый on-demand инстанс с той же сегментом данных (read from checkpoint).
  3. Добавьте 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)
    # При старте проверять, есть ли чекпоинт, и продолжать с него
    
  4. Запустите полный тест с симуляцией 30% прерываний — проверьте, что итоговая reliability >99%.

Ожидаемый результат этапа Работающий pipeline с автоматическим fallback, измеренная итоговая стоимость и доля успешных задач.

Этап 5: Анализ и оформление результатов (1–2 часа)

Действия

  1. Сведите все метрики в таблицу
КонфигурацияTotal cost ($)Время выполнения (мин)Success rate
100% on-demandXY100%
100% spot (без fallback)X*0.3Y (частично)~50%
Комбинированная (spot+fallback)X*0.4Y+10%99%+
  1. Рассчитайте экономию относительно on-demand: (cost_on_demand - cost_combined) / cost_on_demand * 100%.
  2. Оцените reliability = (число успешных сегментов) / (общее число сегментов).
  3. Подготовьте одно-двухстраничный отчёт в формате 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 inference2–3 часа
Этап 2: Запуск на on-demand2–3 часа
Этап 3: Запуск на spot2–3 часа
Этап 4: Разработка fallback2–4 часа
Этап 5: Анализ и оформление1–2 часа
Итого9–15 часов

Примечание Для первого выполнения рекомендуется выделить 2–3 дня (вечерние сессии). Если используется симуляция вместо реального облака, время сокращается на 30–40% за счёт отсутствия ожидания создания инстансов.


9. Связанные вопросы из базы знаний

ВопросТема
112Оптимизация затрат на inference в облаке
145Spot instances: best practices
203Batch inference pipeline design
267Cost-aware auto-scaling для ML
381Мониторинг и алертинг для batch jobs
402Preemption handling strategies
519Terraform для ML-инфраструктуры
604Checkpointing в длительных задачах
738Сравнение pricing моделей облачных провайдеров
815Reliability 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 задачи, очень короткие джобы).