English translation is not available yet. Showing Russian content.
Сравнить inference schedulers (FCFS vs Priority)
ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Сравнить inference schedulers (FCFS vs Priority)
1. Цель задачи
Научиться проектировать и сравнивать два подхода к планированию инференса в многотенантной среде: First-Come-First-Served (FCFS) и Priority Queuing. Смоделировать двух тенантов с разными приоритетами, измерить latency (задержку) для high-priority запросов и убедиться, что priority scheduler снижает эту задержку на 80% по сравнению с FCFS.
Ключевой результат Экспериментально подтверждённый вывод о том, при каких условиях (нагрузка, размер burst) priority scheduler даёт выигрыш.
2. Исходные данные
| Что нужно | Откуда взять |
|---|---|
| Python окружение (3.10+) | Локальная установка / Google Colab |
| asyncio (встроенный) | Входит в стандартную библиотеку Python |
| Библиотеки для замеров и визуализации | time, pandas, matplotlib |
| Понимание модели инференса LLM | Описание в документации (время обработки ~ длина токенов) |
| Симуляция двух тенантов | Написать генератор запросов (Poisson / burst) |
Если нет реального инструмента — симулируем:
- Создать класс
InferenceRequestс полями: tenant_id, priority (0 — low, 1 — high),arrival_time,processing_time(симулируется как asyncio.sleep(random.expovariate(rate))). - Генератор запросов: один генератор для high-priority (средняя интенсивность λ_high, burst-интервалы 5x), другой для low-priority (λ_low, постоянная нагрузка).
- Эмуляция GPU: один «воркер» (единое ядро asyncio), обрабатывающий по одному запросу за раз.
3. Технологический стек
| Компонент | Инструменты | Назначение |
|---|---|---|
| Язык симуляции | Python 3.10+ | Реализация schedulers и генераторов |
| Асинхронная очередь | asyncio.Queue / asyncio.PriorityQueue | Базовая структура для FCFS и Priority |
| Случайная генерация | random / numpy | Распределения времени между запросами и длительности обработки |
| Измерения | time.perf_counter | Замер latency для каждого запроса |
| Анализ | pandas (опционально) | Группировка метрик по тенантам |
| Визуализация | matplotlib / seaborn | Графики CDF latency и boxplot по приоритетам |
4. Этапы выполнения
Этап 1: Создание базовой симуляции (1 час)
Действия
- Определить классы данных
@dataclass class InferenceRequest: tid: int # tenant id (0=low, 1=high) priority: int # 0 (low) or 1 (high) arrival_time: float processing_time: float start_time: float = None finish_time: float = None - Написать генератор запросов асинхронная функция request_generator(tid, priority, lam, sim_duration), которая каждые
expovariate(lam)секунд создаёт запрос сprocessing_time = expovariate(1/mean_time). Параметрlamдля high-priority тенанта сделать в 2 раза ниже, чем low, но добавить burst-режим – каждые 10 секунд генерировать 5 запросов подряд с задержкой 0.001. - Реализовать класс Worker в нём метод run(queue: asyncio.Queue), который бесконечно берёт запрос из очереди, устанавливает
start_time, await asyncio.sleep(processing_time), устанавливаетfinish_time, сохраняет в список завершённых. - Запустить симуляцию с asyncio.Queue (FCFS): два генератора (high, low) + один воркер. Длительность симуляции 30 секунд. Собрать список завершённых запросов.
Ожидаемый результат этапа Работающий скрипт с FCFS scheduling, собирающий для каждого запроса: tenant, priority, arrival, start, finish, latency (finish - arrival).
Этап 2: Реализация Priority scheduler (1 час)
Действия
- Заменить asyncio.Queue на asyncio.PriorityQueue В PriorityQueue элементы должны быть кортежем (priority, arrival_time, request), где priority – целое число (0 – high, 1 – low). Воркер должен извлекать элемент с наименьшим приоритетом (т.е. high-priority запросы будут первыми вне зависимости от времени прибытия).
- Учесть, что обработка запроса невытесняющая – если начался low-priority запрос, он не прерывается. Priority выбирает следующий только после завершения текущего.
- Модифицировать генераторы для high-priority запросов использовать priority=0, для low – priority=1.
- Запустить ту же симуляцию (те же параметры, seed random) и собрать завершённые запросы.
Ожидаемый результат этапа Скрипт, который запускает ту же нагрузку с priority очередью, результаты записаны в отдельный CSV или список.
Этап 3: Сбор метрик и расчет (30 минут)
Действия
- Написать функцию compute_metrics(records, percentile=95):
- Рассчитать относительное снижение
(lat_high_fcfs - lat_high_priority) / lat_high_fcfs * 100%. - Построить графики
- Проверить целевой признак снижение latency high-priority >= 80%. Если нет – скорректировать параметры (увеличить нагрузку low-priority тенанта, уменьшить частоту high, изменить burst).
Ожидаемый результат этапа Таблица с метриками, графики, проверка гипотезы.
Этап 4: Анализ и отчёт (1 час)
Действия
- Сформулировать выводы
- Написать короткий markdown-отчёт (10–15 строк) с таблицей метрик, ключевым графиком и интерпретацией.
- Добавить раздел «Что изменится, если: preemptive, multiple workers, batching».
Ожидаемый результат этапа Готовый отчёт в файле report.md с ссылками на код, графики метрики.
Этап 5 (опционально): Ручное тестирование с разными параметрами (30 минут)
Действия
- Провести sweep по параметрам соотношение интенсивностей (λ_low / λ_high = 2, 5, 10), размер burst (3, 5, 10), длительность симуляции.
- Построить heatmap выигрыша в latency high-priority от параметров.
- Сформулировать рекомендации для production: при каком уровне загрузки (utilization) priority scheduler даёт значимый эффект.
Ожидаемый результат этапа Устойчивый эксперимент с тремя конфигурациями, зафиксированными в коде.
5. Критерии приемки (Definition of Done)
- Скрипт симуляции FCFS и Priority воспроизводится с фиксированным seed.
- Каждый запрос имеет уникальный
tid,arrival_time,processing_time, и метки времени старта/конца. - Для high-priority тенанта средняя или p95 latency при Priority scheduler снижена не менее чем на 80% по сравнению с FCFS при одинаковой нагрузке.
- Построены и сохранены графики CDF и boxplot сравнения.
- Результаты собраны в pandas DataFrame и сохранены в CSV.
- Написан отчёт (markdown) с таблицей метрик и интерпретацией.
- Код размещён в репозитории (GitHub Gist или папка) с инструкцией по запуску.
6. Ожидаемый результат
Основной артефакт Папка проекта, содержащая:
simulate.py– основной скрипт симуляции (с возможностью выбора scheduler через аргумент командной строки--scheduler fcfs|priority).results/– подпапка с CSV-файлами записей и PNG-графиками.report.md– краткий отчёт с метриками и выводами.requirements.txt– список зависимостей (можно пустой, если использует только стандартную библиотеку).
Дополнительные результаты
- График CDF latency по приоритетам для FCFS и Priority.
- Таблица сравнения p50, p95, средняя latency.
- Вывод о том, какой scheduler рекомендуется для сценария с двумя тенантами разного приоритета.
7. Возможные сложности и их решение
| Сложность | Решение |
|---|---|
| Priority scheduler не даёт улучшения | Увеличить нагрузку low-priority (сделать λ_low больше, добавить burst для high). Проверить, что очередь FCFS не пуста (utilization >80%). |
| Симуляция слишком медленная | Сократить длительность до 20–30 секунд, использовать time.perf_counter вместо datetime. |
| Генерация random недетерминированная | Установить random.seed(42) и numpy.random.seed(42) до запуска. |
| Нужно считать latency только завершённых | Отфильтровать записи, где finish_time не None. |
| Графика нет на CI | Использовать matplotlib с агрессивным plt.savefig без показа окна. |
| PriorityQueue не поддерживает сравнение по кортежу | Использовать (priority, arrival_time, request) – встроенные кортежи Python корректно сравниваются лексикографически. |
8. Бюджет времени (оценка)
| Этап | Время |
|---|---|
| Этап 1: Базовая симуляция (FCFS) | 1 ч |
| Этап 2: Priority scheduler | 1 ч |
| Этап 3: Сбор метрик и графики | 30 мин |
| Этап 4: Отчёт | 1 ч |
| Этап 5 (опционально): Sweep параметров | 30 мин |
| Итого | 4 ч (основной) |
Примечание Для первого раза (незнакомый инструментарий) заложить +50% времени.
9. Связанные вопросы из базы знаний
| Вопрос | Тема |
|---|---|
| 42 | Как работают очереди в asyncio? |
| 87 | Разница между FCFS и Priority Queuing |
| 153 | Эмуляция времени инференса LLM |
| 204 | Сбор метрик latency в Python |
| 311 | Построение CDF с matplotlib |
| 422 | Статистические тесты для сравнения latency (Mann-Whitney) |
| 509 | Влияние burst traffic на latency |
| 611 | Невытесняющее планирование (non-preemptive) |
| 720 | Multi-tenant архитектура AI сервисов |
| 833 | Вычислительные ограничения GPU (batch size, VRAM) |
| 899 | Использование asyncio.PriorityQueue |
10. Чек-лист самопроверки
- Я реализовал FCFS через стандартную
asyncio.Queueи Priority черезasyncio.PriorityQueue. - Для каждого запроса я правильно записал
arrival_time,start_time,finish_time. - Я использовал общий seed для random (random.seed(42)), чтобы результаты были воспроизводимы.
- Я проверил, что latency high-priority при FCFS значительно выше (хотя бы в 3 раза), чем при Priority.
- Я построил минимум два графика (CDF и boxplot) и сохранил их.
- Я рассчитал относительное снижение latency и убедился, что оно >=80%.
- Я написал отчёт с таблицей метрик и выводами.
- Я закоммитил код, результаты и отчёт в репозиторий.
- Мой код работает без ошибок при повторном запуске.