Настроить continuous batching в vLLM и измерить прирост пропускной способности

ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Настроить continuous batching в vLLM и измерить прирост пропускной способности

1. Цель задачи

Научиться включать и настраивать механизм continuous batching в vLLM (vLLM) для инференса больших языковых моделей. Понять влияние параметра --max-num-batched-tokens на пропускную способность (throughput) и задержку (latency). В результате вы должны получить конфигурацию, которая обеспечивает прирост throughput не менее чем в 4 раза по сравнению с базовым без continuous batching.

Ключевой результат Запуск vLLM с continuous batching, измерение throughput и latency, подтверждение прироста в 4+ раза.


2. Исходные данные

Перед началом необходимо иметь:

Что нужноОткуда взять
Сервер с GPU (минимум 8 GB VRAM)Локальная машина, облачный инстанс (AWS p3.2xlarge, GCP L4) или Colab Pro
vLLM (версия ≥0.4.0)Установка через pip install vllm или из исходников
LLM модель для тестовНапример, microsoft/phi-2 или Qwen/Qwen2.5-1.5B-Instruct (малая, влезает в VRAM)
Тестовый датасет запросовСгенерировать самостоятельно – 500–2000 строк текста разной длины
Скрипты для нагрузочного тестированияPython + asyncio / aiohttp + time / vllm benchmark script
Инструмент для сбора метрик vLLMЭндпоинт /metrics (Prometheus) или логи сервера

Если нет реального GPU — симулируем:

  1. Используйте CPU-версию vLLM (медленно, но можно) с моделью EleutherAI/pythia-70m.
  2. Ограничьте батч-размер до 1 для baseline, затем увеличьте до 8 и более – разница будет заметна.
  3. Вместо настоящего GPU можно взять облачный Jupyter Notebook с T4 (бесплатно на Kaggle или Colab).

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

КомпонентИнструментыНазначение
LLM серверvLLM + OpenAI-compatible APIОбработка запросов с continuous batching
МодельPhi-2 (2.7B) / Qwen2.5-1.5B / Pythia-70mТестовая модель
Генерация запросовPython (random, datasets)Подготовка тестовых данных
Нагрузочное тестированиеPython asyncio + aiohttp / vllm.entrypoints.openai.benchmarkОтправка параллельных запросов
МониторингPrometheus endpoint / встроенные метрики vLLMСбор latency, throughput, scheduler stats
АнализPython + matplotlib / pandasПостроение графиков, расчёт прироста

4. Этапы выполнения

Этап 1: Базовая настройка vLLM и запуск без continuous batching (30 минут)

Действия

  1. Установите vLLM:

    pip install vllm
    

    Для GPU — убедитесь, что CUDA и драйверы совместимы. Для CPU — установите vllm[cpu] (экспериментально).

  2. Запустите сервер в режиме без continuous batching (отключить динамический батчинг, явно выставить --max-num-batched-tokens=0 – это отключит continuous batching, vLLM будет ждать полный батч):

    python -m vllm.entrypoints.openai.api_server \
        --model microsoft/phi-2 \
        --max-num-batched-tokens 0 \
        --max-model-len 1024 \
        --disable-log-stats
    

    Примечание: --max-num-batched-tokens=0 означает, что vLLM не будет объединять запросы в динамические батчи – каждый запрос обрабатывается отдельно.

  3. Напишите скрипт для отправки одиночных последовательных запросов (через curl или Python requests). Убедитесь, что сервер отвечает корректно.

  4. Подготовьте набор тестовых запросов (например, 100 строк длиной 50–200 токенов). Сохраните в файл requests.txt.

Ожидаемый результат этапа Работающий vLLM без continuous batching, готовый к нагрузочному тесту.


Этап 2: Измерение baseline latency и throughput (40 минут)

Действия

  1. Напишите скрипт нагрузочного тестирования (benchmark_baseline.py):
    import asyncio
    import aiohttp
    import time
    import json
    
    async def send_request(session, prompt):
        async with session.post(
            "http://localhost:8000/v1/completions",
            json={
                "model": "microsoft/phi-2",
                "prompt": prompt,
                "max_tokens": 50,
                "temperature": 0
            }
        ) as resp:
            result = await resp.json()
            return result
    
    async def main():
        with open("requests.txt") as f:
            prompts = [line.strip() for line in f][:100]
    
        async with aiohttp.ClientSession() as session:
            tasks = [send_request(session, p) for p in prompts]
            start = time.time()
            results = await asyncio.gather(*tasks)
            total_time = time.time() - start
    
        print(f"Total time: {total_time:.2f}s")
        print(f"Throughput: {len(prompts)/total_time:.2f} req/s")
        # Также измерьте latency: min, max, p50, p95
    
    asyncio.run(main())
    
  2. Запустите тест 3 раза и запишите средний throughput (запросов в секунду) и среднюю latency. Сохраните в baseline_metrics.json.

Ожидаемый результат этапа Численные значения throughput (req/s) и latency (ms) для baseline.


Этап 3: Включение continuous batching и настройка max-num-batched-tokens (40 минут)

Действия

  1. Остановите сервер (Ctrl+C).

  2. Запустите сервер с continuous batching:

    python -m vllm.entrypoints.openai.api_server \
        --model microsoft/phi-2 \
        --max-num-batched-tokens 4096 \
        --max-model-len 1024 \
        --disable-log-stats
    

    --max-num-batched-tokens определяет максимальное количество токенов, которые могут быть объединены в один батч. Значение 4096 подходит для малой модели.

  3. Проверьте метрики vLLM: откройте http://localhost:8000/metrics. Обратите внимание на vllm:num_requests_running – во время нагрузки должно быть >1 (когда несколько запросов обрабатываются одновременно).

Ожидаемый результат этапа vLLM работает с динамическим объединением запросов.


Этап 4: Измерение throughput и latency с continuous batching (40 минут)

Действия

  1. Запустите тот же тестовый скрипт benchmark_baseline.py (можно переименовать в benchmark_cb.py). Убедитесь, что нагрузка аналогична baseline.

  2. Повторите тест 3 раза, запишите throughput и latency в cb_metrics.json.

  3. Проведите дополнительный эксперимент: измените --max-num-batched-tokens на 2048 и 8192, повторите измерения. Занесите результаты в таблицу:

    max-num-batched-tokensThroughput (req/s)P95 latency (ms)
    0 (baseline)......
    2048......
    4096......
    8192......

Ожидаемый результат этапа Данные о зависимости throughput и latency от max-num-batched-tokens.


Этап 5: Анализ результатов и достижение 4x прироста (30 минут)

Действия

  1. Рассчитайте прирост throughput:

    speedup = throughput_cb / throughput_baseline
    

    Если speedup < 4, попробуйте увеличить количество параллельных запросов в скрипте (сейчас 100 последовательных) – используйте параллельную отправку (не gather для всех сразу, а с ограничением concurrency, чтобы не перегрузить сервер).

  2. Используйте оптимальную нагрузку: для continuous batching важна высокая степень параллелизма. Измените скрипт: отправляйте 10–20 запросов одновременно с помощью asyncio.Semaphore, подождите их завершения, и так циклически, чтобы поддерживать постоянную нагрузку (например, 4 concurrent workers).

  3. Постройте графики (опционально): throughput vs max-num-batched-tokens, latency vs throughput.

  4. Сделайте выводы: При каком значении max-num-batched-tokens достигается максимальный throughput? Почему latency может расти?

Ожидаемый результат этапа Значение throughput, превышающее baseline в 4+ раза, и обоснование выбора параметра.


5. Критерии приемки (Definition of Done)

  • Установлен и настроен vLLM, запущен в двух режимах (без / с continuous batching).
  • Написан и выполнен скрипт нагрузочного тестирования для замера throughput и latency.
  • Снят baseline (без continuous batching) – не менее 3 прогонов, средний throughput зафиксирован.
  • Запущено не менее 3 конфигураций continuous batching (min-batched-tokens 2048, 4096, 8192).
  • Получен прирост throughput не менее чем в 4 раза относительно baseline.
  • Собраны метрики vLLM (количество активных запросов, время обработки) через /metrics хотя бы для одного прогона.
  • Оформлен отчёт (README или Jupyter Notebook) с таблицами, графиками и выводами.

6. Ожидаемый результат

Главный артефакт Файл report.md (или report.ipynb) в репозитории, содержащий:

  • Описание конфигураций vLLM.
  • Таблицу с результатами всех экспериментов (throughput, latency).
  • График зависимости throughput от max-num-batched-tokens.
  • Вывод о достижении 4x ускорения.
  • Дополнительно скрипты benchmark.py и requests.txt.

7. Возможные сложности и их решение

СложностьРешение
Недостаточно VRAM для модели + continuous batchingИспользуйте меньшую модель (Pythia-410M) или уменьшите --max-model-len до 512.
Throughput не растёт в 4 раза, хотя continuous batching включёнУвеличьте степень параллелизма в нагрузочном скрипте (concurrent requests). Для больших моделей разница может быть меньше – попробуйте модель побольше (Llama-7B) на мощном GPU.
vLLM вылетает с ошибкой CUDA out of memoryУменьшите max-num-batched-tokens до 1024 и/или используйте --gpu-memory-utilization 0.9.
latency резко растёт при высоком throughputЭто нормально для continuous batching: сервер жонглирует батчами, latency увеличивается, но throughput растёт. Укажите в отчёте trade-off.
На CPU сервер работает слишком медленноИспользуйте облачный GPU (Colab, RunPod) или сократите запросы до 20 штук для демонстрации относительного прироста.

8. Бюджет времени (оценка)

ЭтапВремя
Этап 1: Базовая настройка и запуск без CB30 мин
Этап 2: Измерение baseline40 мин
Этап 3: Включение continuous batching40 мин
Этап 4: Измерение с CB40 мин
Этап 5: Анализ и отчёт30 мин
Итого3 часа

Примечание для первого раза: может потребоваться дополнительное время на отладку установки vLLM и адаптацию скриптов. Рекомендуется заложить 4 часа.


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

ВопросТема
105Как настроить параллелизм в vLLM?
112Как работает continuous batching в LLM серверах?
201Как измерить задержку LLM инференса?
203Как выбрать размер батча для инференса?
207Как настроить continuous batching в vLLM? (текущая задача)
212Какие метрики vLLM доступны через /metrics?
310Trade-off между latency и throughput в LLM serving
451Как провести нагрузочное тестирование LLM API?
612Оптимизация LLM инференса на GPU с помощью пакетной обработки

10. Чек-лист самопроверки

  • Я запустил vLLM в двух режимах и убедился, что сервер отвечает.
  • Я создал тестовый набор запросов одинаковой длины для корректного сравнения.
  • Я измерил throughput минимум 3 раза для каждой конфигурации и взял среднее.
  • Я убедился, что continuous batching активен (проверил vllm:num_requests_running > 1 под нагрузкой).
  • Я задокументировал все параметры запуска, результаты и сделал вывод о достижении 4x прироста.