Как мы измеряем: стенд и протокол
Что и чем мы измеряем у открытых моделей, сколько раз повторяем, как считаем разброс и чего не измеряем.
Цифра без условий ничего не значит. «60 токенов в секунду» — на какой карте, в каком квантовании, на какой версии движка, при скольких пользователях и по скольким прогонам? Поэтому у нас правило: у каждой цифры есть условия. Нет условий — нет цифры.
Здесь описано, как устроен наш стенд. Все замеры в разделе ссылаются на этот текст. Если протокол меняется, здесь появляется новая версия с датой.
Что измеряем
- Скорость. Сколько сервер ждёт до готовности после запуска. Как быстро модель пишет ответ одному пользователю. Что происходит, когда пользователей становится 2, 4, 8 и больше.
- Память. Сколько видеопамяти занимают веса и сколько остаётся под запросы. Это мы сверяем с расчётом по формуле.
- Качество. Сколько верных ответов на открытых наборах задач. Главное — насколько квантованный вариант отличается от исходного на тех же вопросах.
Стенд
- Ресурсы замера: видеокарты NVIDIA A100 SXM4 40GB, одна или две. Две соединены NVLink.
- Движок: vLLM, образ закреплён по digest. Версия указана у каждого замера.
- Модель: закреплена по ревизии весов, то есть по хешу коммита на Hugging Face.
Один скрипт делает всё сам:
- проверяет, что карта свободна, а образ и веса именно те;
- записывает окружение;
- запускает сервер и измеряет старты;
- гоняет нагрузку;
- останавливает сервер;
- считает итог.
Руками в результаты ничего не вписывается.
Внутри одного замера параметры сервера не меняются. Другая конфигурация — это другой замер.
Нагрузка
| Профиль | Вход, токенов | Ответ, токенов | Одновременных запросов |
|---|---|---|---|
| Один поток | 1 024; 8 192; 32 768 | 512 | 1 |
| Вопрос по документу | 4 096 | 300 | 1, 2, 4, 8, 12, 16, 24, 32 |
| Поток запросов | 4 096 | 300 | Запросы приходят случайно: 0,15, 0,3 и 0,45 запроса в секунду |
«Вопрос по документу» — это типичная работа ассистента: прочитать фрагмент документа и коротко ответить. На входе 4 096 токенов, на выходе 300.
Условия нагрузки:
- Запросы синтетические. Это случайные токены нужной длины, у каждого запроса свои. Без спекулятивного декодирования скорость зависит от числа токенов, а не от смысла текста, поэтому для замера скорости этого достаточно.
- Длина ответа фиксирована. Модель пишет ровно заданное число токенов, это проверяется.
- Декодирование жадное, температура 0.
- Кэш префиксов выключен. Повторы одного и того же текста не завышают скорость, и счётчик попаданий это подтверждает.
- Клиент нагрузки —
vllm bench serveиз того же образа, что и сервер. Метрики определены в его коде, поэтому наши цифры можно сравнивать с чужими, опубликованными тем же инструментом.
Что значат цифры
- Время до первого токена — от отправки запроса до первого слова ответа. Сюда входят очередь, чтение запроса моделью и сеть.
- Скорость на пользователя — сколько токенов в секунду видит один пользователь, пока модель пишет ему ответ.
- Пропускная способность — сколько токенов ответа сервер выдаёт в секунду всем пользователям вместе.
- Полная задержка — от отправки запроса до последнего токена ответа.
Задержки приводим медианой и 95-м процентилем. 95-й процентиль — время, в которое укладываются 95 запросов из 100.
Повторы и разброс
- Прогрев. Перед замером каждая точка нагрузки прогоняется один раз, и этот прогон отбрасывается.
- Повторы. Каждая точка повторяется не меньше трёх раз. Повторы идут блоками: в блоке каждая точка по разу, в случайном порядке. Так медленный дрейф, например нагрев карты, не ложится на одну точку.
- Что показываем: среднее, стандартное отклонение и 95-процентный интервал по Стьюденту. На странице замера видно каждый прогон.
- Цена трёх повторов. При n = 3 интервал широкий: множитель Стьюдента — 4,30. Мы это не прячем.
- Когда прогон не засчитывается:
- хотя бы один запрос завершился ошибкой;
- длина ответа не совпала с заданной;
- длина запроса отличается от заданной больше чем на 1 %;
- на карте работал чужой процесс;
- клиент нагрузки завершился с ошибкой.
Такие прогоны не выбрасываются молча: они перечислены у замера вместе с причиной.
- Ограничение частоты карты по мощности или температуре прогон не отменяет. Мы записываем, какую долю времени карта работала у предела.
Старт сервера
| Старт | Условия |
|---|---|
| Холодный | Веса вытеснены из кэша ОС, кэш компиляции движка пуст, контейнер новый |
| Тёплый | Сразу после холодного: кэш компиляции есть, веса в кэше ОС, контейнер новый |
Холодный старт — не старт после перезагрузки сервера: системные библиотеки могут оставаться в памяти. Холодный и тёплый идут парами, пар не меньше трёх.
Память
- Факт берём из журнала движка (веса, память под запросы, активации) и из
nvidia-smi(занято после старта и пик под нагрузкой). - Расчёт. Веса считаем по фактическим типам тензоров в файлах модели, память под запросы — по устройству слоёв внимания.
- Гибридные модели считаем отдельно. У части их слоёв нет обычного KV-кэша, и калькуляторы, которые этого не знают, ошибаются.
- Единицы. Память — в ГиБ, это 2³⁰ байт. «A100 40GB» — это 40 ГиБ по
nvidia-smi, а CUDA видит 39,49 ГиБ.
Качество
- Наборы — открытые:
- Belebele (понимание текста);
- Global-MMLU (знания);
- MGSM (арифметика с рассуждением);
- BFCL (вызов инструментов).
Первые три — на русском, BFCL — на английском.
-
Скорость и качество измеряем на одном и том же запущенном сервере.
-
Варианты сравниваем на одних и тех же вопросах. Для каждой пары считаем:
- разность долей верных ответов;
- интервал этой разности (парный бутстреп);
-
точный тест Макнемара.
-
Расхождение распределений. Для квантованных вариантов измеряем ещё, насколько распределение следующего токена расходится с исходной моделью (KL-дивергенция). Она чувствительнее доли верных ответов.
- Судей-моделей нет. Ответ проверяется правилом набора: выбранный вариант, итоговое число, разбор вызова функции.
- Чужие правила проверяем. Стандартная оценка MGSM не понимала русскую запись чисел, и мы её поправили — подробнее в замере «Кванты на A100: сгонка веса».
Весовые категории
Модели сравниваем только внутри одного бюджета железа. Например, «одна A100 40 ГБ» или «две A100 с NVLink». Вариант, которому нужна вторая карта, переходит в другую категорию. Так устроена сводная таблица «Весовые категории».
Как определяем места
У каждого замера есть пьедестал: первое, второе и третье место в каждой весовой категории.
- Качество — основа. Места определяет средняя доля верных ответов по четырём наборам.
- Разница меньше 0,5 п.п. — шум. Тогда место решают скорость и ёмкость: сколько ток/с и сколько «вопросов по документу» одновременно. При разнице меньше 3 % место делят.
- Сравниваем только внутри весовой категории, все модели вместе.
Исправления
Старое не стираем. Если цифра оказалась неверной:
- у замера растёт номер редакции, и появляется запись: дата, что исправлено, прежнее значение;
- в тексте старая цифра остаётся зачёркнутой рядом с новой.
Если замер негоден целиком, он остаётся на сайте с пометкой «снят» и причиной.
Что не измеряем
- Качество в режиме рассуждения (thinking) и на многошаговых агентных задачах.
- Больше 32 одновременных запросов.
- Кэш префиксов и спекулятивное декодирование.
- Влияние содержания запроса на скорость.
- Задержку сети: клиент работает на том же сервере.
- Старт после перезагрузки.
- Другие параметры семплирования, кроме жадного.
- Энергопотребление как метрику: мощность записываем только как условие.
- Долговременную стабильность.
Качество на деловых документах, например на таблицах, и агентные задачи этот протокол не покрывает: для них будут отдельные замеры.