Адаптация открытого симулятора InferSim для оценки загрузки промышленных GPU
Планирование аппаратных ресурсов под обслуживание больших языковых моделей — задача с высоким порогом ошибки. Потратишь лишнего — получишь неоправданные расходы. Сэкономишь — столкнёшься с деградацией пользовательского опыта. На российском рынке, где доступ к современным ускорителям ограничен, эта задача становится особенно острой.
Мы остановились на открытом симуляторе InferSim от Alibaba. Он умеет считать TTFT, TPOT и пропускную способность без запуска реального инференса. Но из коробки поддерживает только несколько топовых GPU и фиксированный набор моделей — для наших сценариев этого было недостаточно. Пришлось дорабатывать.
Как устроен InferSim
В основе симулятора — двухфазная схема. Сначала на целевом железе запускаются микро-бенчмарки: измеряется реальная производительность на типовых операциях внимания и матричных умножениях. Получается таблица коэффициентов Model FLOPs Utilization (MFU) — сколько процентов от теоретического максимума выдаёт конкретная карта на конкретной операции. Затем, уже без доступа к GPU, симулятор на основе этих MFU и аналитической модели вычисляет задержки. Именно такой подход даёт более точные предсказания, чем оценка по паспортной пропускной способности памяти.
Добавляем своё железо
Первым делом мы внесли в hardware/gpu.py поддержку MetaX C500 64GB. Характеристики добавляются через dataclass-экземпляры:
После этого c500 попадает в словарь gpu_map, и симулятор запускается с ключом --device-type C500 --world-size 2. Значения FLOPS и пропускной способности пришлось оценивать по косвенным источникам — производитель не публикует точных цифр. Позже планируем уточнить их через бенчмаркинг на реальном оборудовании. Таким же способом добавили Nvidia 1xH100 и A100.
Конфигурация моделей и одна болезненная ошибка
Симулятор ожидает стандартный config.json в формате Hugging Face. Для Qwen3-32B подготовили файл qwen3_32b_config.json:
Ключевой момент — правильное значение head_dim. У Qwen3-32B оно равно hidden_size / num_attention_heads = 5120 / 64 = 80. У нас ушло некоторое время, чтобы понять, почему симулятор выдаёт невалидные результаты: изначально в конфиге стояло значение 128. Пока не исправили — KV-кеш переоценивался, и метрики улетали в неадекватные цифры. После исправления всё встало на свои места.
Позже добавили поддержку Qwen3.5‑9B с её гибридной архитектурой, построенной на чередовании Gated DeltaNet и Gated Attention. Главная особенность модели в том, что около трёх четвертей слоёв не создают привычного KV‑кеша, а используют линейное внимание – компактное скрытое состояние, которое лишь обновляется с каждым новым токеном, не увеличиваясь в объёме. Это кардинально снижает расход памяти на длинных контекстах, но привносит и свою цену: на коротких дистанциях такая модель проигрывает в скорости Prefill, потому что Gated DeltaNet работает последовательно и хуже утилизирует матричные вычисления GPU.
Симулятор изначально не умел различать слои двух типов и считал весь KV‑кеш одинаково. Чтобы поддержать Qwen3.5, пришлось доработать расчёт задержек в классе HybridModel: теперь он отдельно обсчитывает full‑attention‑слои с полным кешем и linear‑attention‑слои без кеша, используя параметры num_full_attn_layers и num_linear_attn_layers из конфигурации. В директорию проекта models добавили hybrid_model.py, в котором сделали дополнительные расчёты:
Без такой дифференциации симулятор для Qwen3.5‑9B показывал E2E порядка 2 500 секунд вместо реальных нескольких секунд – та ошибка, которую мы долго отлавливали.
Визуализация и эксплуатация
Чтобы не разбирать каждый раз текстовый вывод InferSim, сделали веб-интерфейс на Streamlit. Симулятор дёргается через subprocess, результаты парсятся из stdout и визуализируются:
- тепловые карты задержек (Prefill, Decode, E2E Total) для разных длин входных и выходных токенов;
- анализ RPS с расчётом требуемой параллельности и сравнением с доступной памятью;
- информация о занятой памяти в формате «X ГБ из Y ГБ».
Кэширование через @st.cache_data позволило избежать повторных запусков симуляции при неизменных параметрах. Интерфейс получился достаточно удобным, чтобы даже коллеги без погружения в командную строку могли осмысленно сравнивать конфигурации.
Приложение упаковано в Docker и лежит в репозитории на GitHub. Сервисы — сам Streamlit и Nginx в качестве обратного прокси с SSL-терминацией и базовой HTTP-аутентификацией. Деплой на VDS автоматизирован через GitHub Actions: собрали образ, отправили на сервер, перезапустили контейнеры. SSL-сертификаты Let's Encrypt обновляются по cron.
Что в итоге
Адаптированный InferSim не претендует на абсолютную точность — она ограничена качеством бенчмарков и коэффициентов MFU. Но инструмент позволяет избежать грубых ошибок при планировании, что в условиях ограниченного доступа к GPU и их высокой стоимости само по себе немало. Мы продолжаем калибровку симулятора и готовим обновлённые конфигурации для следующих моделей.
Репозиторий проекта открыт, будем рады замечаниям и предложениям от тех, кто решает схожие задачи.