llm-inference-benchmark: как выбрать бэкенд LLM за часы
Команда, которая выбирает бэкенд для инференса LLM, обычно проходит через один и тот же цикл: написать скрипт, запустить на vLLM, потом на llama.cpp, потом на ONNX Runtime, записать результаты в таблицу, понять, что числа несопоставимы, и начать заново. Разработчик под псевдонимом Happynood опубликовал на Habr статью и выложил в открытый доступ инструмент, который закрывает эту проблему. Репозиторий llm-inference-benchmark (версия 1.8.3) позволяет описать эксперимент в YAML, прогнать одну и ту же нагрузку через разные бэкенды, получить CSV и JSON-манифест, а затем автоматически найти Pareto-оптимальную конфигурацию под заданные ограничения по VRAM и latency. Для команды, которая выбирает бэкенд или квантизацию под конкретное железо, это означает возможность получить воспроизводимый результат за часы, а не за недели, и зафиксировать его в CI.
Источник: Habr
Что изменилось: от одноразовых скриптов к воспроизводимому харнессу
Проблема, которую решает инструмент, знакома каждому, кто хотя бы раз пытался сравнить производительность LLM на разных бэкендах. Готовые бенчмарки измеряют не то, что нужно на практике. Разработчику приходится держать в голове четыре оси: p95-latency, throughput в токенах в секунду, пиковый VRAM и то, что модель не сходит с ума под нагрузкой. Главный практический вопрос — какая конфигурация влезает в бюджет по видеопамяти и при этом держит p95 ниже порога — не имел готового ответа.
Автор собрал харнесс, который работает так: вы описываете эксперимент в YAML, инструмент гоняет одну и ту же нагрузку через разные бэкенды и конфиги, складывает результаты в CSV и JSON-манифест, а затем сам определяет, какая конфигурация оптимальна при заданных ограничениях. К инструменту прилагается браузерный дашборд, чтобы не работать с голым CSV.
Поддерживаемые бэкенды на версии 1.8.3:
| Бэкенд | Особенность |
|---|---|
| mock | Детерминированный, для CI модель не нужна |
| transformers | AutoModelForCausalLM от Hugging Face, CUDA |
| llama-cpp | GGUF-квантизация, pre-built CUDA-wheel без nvcc |
| openai | Любой сервер с /v1/chat/completions (Ollama, LM Studio, vLLM) |
| onnx | ONNX Runtime через Optimum, INT8/FP16 |
| vllm | High-throughput движок, только Linux |
Как это работает: YAML, Run Matrix и Sweep
Базовая единица работы — конфиг одного прогона. Никакой магии, просто декларация того, что измеряется. Пример конфига для llama.cpp на GPU:
backend: llama-cpp
model: ~/models/Llama-3.2-3B-Instruct-Q4_K_M.gguf
requests: 20
warmup_requests: 2
prompts_file: data/prompts/smoke.txt
repeats: 3
llama_cpp:
n_ctx: 2048
n_gpu_layers: 99
max_tokens: 50
temperature: 0.0
Запуск одной командой: uv run llm-bench --config configs/llama-cpp-gpu.yaml --output results/run.csv. Любое поле можно переопределить из CLI, не трогая YAML — это удобно, когда нужно быстро изменить один параметр.
Run Matrix позволяет запустить несколько конфигов за один проход и получить сравнительные результаты в общей папке. Каждая комбинация даёт свой CSV и JSON-манифест, имена прогонов валидируются — ошибка возникает на этапе парсинга, а не в середине часового прогона.
Sweep — это декартово произведение параметров из коробки. Вместо того чтобы вручную перебирать комбинации n_gpu_layers, квантизации и размера контекста, вы описываете диапазоны, и инструмент сам генерирует все комбинации, запускает их и собирает результаты.
Почему это меняет стоимость и время выбора бэкенда
Для команды, которая выбирает бэкенд под конкретное железо, основная статья затрат — не стоимость GPU-часов, а время инженеров на написание и отладку одноразовых скриптов. Каждый новый эксперимент требует нового скрипта, и числа между экспериментами несопоставимы, потому что каждый раз меняется методика замера.
Инструмент решает три бизнес-задачи:
- Воспроизводимость. Через месяц можно доказать, откуда взялась цифра. Конфиг лежит в репозитории, результат — в CSV и JSON-манифесте.
- Автоматизация выбора. Pareto-фронт показывает, какие конфигурации оптимальны при заданных ограничениях. Не нужно вручную строить графики и искать компромиссы.
- CI-гейт на регрессии. Можно добавить прогон в пайплайн и ловить регрессии производительности при смене версии бэкенда или модели.
Для команды из трёх инженеров, которая тратит две недели в квартал на ручное сравнение бэкендов, внедрение инструмента может сократить эту работу до двух дней и дать воспроизводимый результат, который можно защитить перед руководством.
Что проверить до внедрения: риски и ограничения
Инструмент новый, версия 1.8.3. Это означает, что возможны нестабильности, и перед продакшеном требуется тестирование на стенде. Автор — один разработчик (Happynood), долгосрочная поддержка и развитие не гарантированы. Рекомендуется мониторить репозиторий на предмет активности.
Поддержка бэкендов ограничена списком из шести вариантов. Если ваша команда использует другой бэкенд, потребуется доработка инструмента. Для CI-гейта требуется настройка окружения и эталонных метрик — возможны ложные срабатывания при изменении железа или драйверов.
Чек-лист для проверки перед внедрением:
- Убедитесь, что ваш бэкенд есть в списке поддерживаемых (v1.8.3: mock, transformers, llama-cpp, openai, onnx, vllm).
- Проверьте, что инструмент запускается на вашем железе — тестовый прогон с mock-бэкендом не требует модели.
- Сравните результаты прогона на вашем стенде с ожидаемыми метриками — убедитесь, что инструмент корректно измеряет p95-latency и пиковый VRAM.
- Настройте эталонные метрики для CI-гейта на стабильном окружении.
- Оцените активность репозитория: есть ли коммиты за последний месяц, отвечает ли автор на issues.
Что может пойти не так
Основные риски связаны не с инструментом, а с контекстом его использования. Если команда внедрит llm-inference-benchmark без проверки на своём железе, результаты могут быть несопоставимы с реальной нагрузкой. Инструмент измеряет синтетические запросы, а не реальный пользовательский трафик.
Если репозиторий перестанет обновляться, команда останется с инструментом, который не поддерживает новые версии бэкендов. Это не критично, если конфиги уже зафиксированы и CI-гейт работает, но потребует форка и самостоятельной поддержки.
Для CI-гейта важно понимать, что изменение железа или драйверов может вызвать ложные срабатывания. Эталонные метрики нужно пересчитывать после каждого обновления GPU-драйвера или CUDA-тулкита.
Что сделать на этой неделе
Если ваша команда выбирает бэкенд или квантизацию под конкретное железо, вот минимальный план действий:
- Склонировать репозиторий и запустить тестовый прогон с mock-бэкендом — это займёт 15 минут и не требует модели.
- Подготовить YAML-конфиги для ваших бэкендов и моделей.
- Запустить Run Matrix для сравнения двух-трёх вариантов.
- Посмотреть Pareto-фронт и выбрать конфигурацию, которая влезает в бюджет по VRAM и держит p95 ниже порога.
- Зафиксировать конфиги и результаты в репозитории команды.
Инструмент не требует глубоких знаний DevOps — достаточно уметь работать с YAML и запускать команды через uv. Для команды, которая устала писать bench_v3_final_FINAL.py, это прямой путь к воспроизводимым и сопоставимым результатам.
Источники
Генерация изображения
- Модель:
flux-schnell - Провайдер:
replicate
Темы журнала
Что почитать дальше
- OpenAI Jalapeño ASIC для инференса LLM: как рассчитать переход с GPU и не попасть в lock-in
- OpenAI Jalapeño: как собственный ASIC-чип меняет экономику инференса LLM и ставку на Nvidia
- seotitle: Агентный ИИ вместо чата: что данные OpenAI о Codex значат для ваших процессов | metatitle: Отчёт OpenAI о
- FeFET-чип для ИИ: один чип вместо двух снижает стоимость инференса
- OpenAI GPT-5.6 Sol ограничения: что делать бизнесу и разработчикам