Надёжный харнесс для HEP‑бенчмарков HistFactory (pyhf и ROOT)
Сначала проверяем численную согласованность (|ΔNLL|), затем измеряем время: детерминизм, явные настройки модели, воспроизводимые входы и проверяемые JSON‑артефакты.
2026-02-08 · 10 мин. чтения
Бенчмарки легко сделать неправильно даже без злого умысла. В ФВЭ (HEP) самый опасный режим отказа устроен просто:
Можно «выиграть», если бенчмаркать не тот статистический вывод.
Если две реализации расходятся в модели правдоподобия (коды интерполяции, ограничения, маскирование, параметризация), сравнение времени становится бессмысленным, потому что вы измеряете разные вычисления.
Этот пост объясняет, как мы строим HEP-бенчмарк-харнесс, который трактует производительность как научное утверждение: сначала гейты корректности, затем явные протоколы, закрепленные окружения и артефакты, которые другие команды могут перезапустить.
- ›Спецификация публичных бенчмарков — общий контракт бенчмарк-программы
Аннотация. Мы бенчмаркаем end-to-end задачи вывода HistFactory (NLL, градиенты, фиты, сканы, тои) с использованием pyhf как основной эталонной реализации и, выборочно, ROOT/RooFit/RooStats там, где рабочий процесс можно автоматизировать воспроизводимо. Числа скорости публикуются только после прохождения гейтов корректности, а каждый прогон производит проверяемые артефакты.
1.Модель угроз: как HEP-бенчмарки вводят в заблуждение
Цель харнесса не в том, чтобы произвести впечатляющие числа. Его задача предотвратить типовые режимы отказа.
1.1 Несовпадение модели (не то же правдоподобие)
Две реализации могут расходиться «тихо», если не закрепить соглашения модели:
- ›коды интерполяции (
code4vs альтернативы) - ›ограничения и приоры
- ›соглашения о маскировании при nᵢ = 0 или νᵢ → 0
- ›имена/порядок параметров (особенно побиновые модификаторы)
- ›односторонние vs двусторонние соглашения для тестовых статистик
Если модель не идентична, сравнения времени не значат ничего.
1.2 Несовпадение оптимизатора («быстрее», потому что остановился раньше)
Для фитов и сканов можно казаться быстрее, если использовать более слабые допуски, упираться в границы и объявлять сходимость или возвращать субоптимальную точку, которая «выглядит нормально» в таблице. Поэтому харнесс рассматривает метаданные сходимости и кросс-оценку как первоклассные выходы, а не как логи.
1.3 Несовпадение warm-start (особенно для профильных сканов)
Бенчмарк профильного скана это во многом бенчмарк политики теплого старта: холодный старт каждой μ-точки от фиксированной инициализации против warm-start от соседней точки (стандартный рабочий процесс аналитика). Если политика не опубликована, это не бенчмарк.
1.4 Дрейф окружения («у меня на машине быстро»)
Бенчмарки меняются при изменении версии компилятора/тулчейна, BLAS/GPU стека, Python-зависимостей, модели CPU/GPU и поведения троттлинга. Поэтому каждый публикуемый прогон захватывает манифест окружения и хеши наборов данных.
1.5 Смещение в отчетности (театр одной цифры)
Одна цифра скрывает дисперсию и выбор измерений. Заслуживающий доверия прогон публикует сырые тайминги по повторам, явную политику агрегации и конкретные входы и настройки.
2.Что мы бенчмаркаем (workflow-first)
Мы бенчмаркаем сквозные (end-to-end) HEP-рабочие процессы, которые доминируют по wall-time:
- ›оценку NLL в фиксированной точке параметров (базовый строительный блок)
- ›градиенты (необходимо для оптимизаторов и методов типа HMC/NUTS)
- ›MLE-фиты (свободные и условные)
- ›сканы профильного правдоподобия (политика warm-start должна быть явной)
- ›ансамбли тоев (toys/sec, масштабирование с числом параметров)
3.Гейты корректности: fail fast до измерения времени
Каждый запуск набора (suite run) должен включать проверку корректности до вывода таймингов. Например, текущий харнесс pyhf vs NextStat (в репозитории):
- ›загружает pyhf workspace
- ›строит модель pyhf с явными настройками интерполяции (
code4,code4p) - ›маппит параметры по имени, а не по индексу
- ›считает NLL в обеих реализациях
- ›падает сразу, если NLL расходятся сильнее допуска
Только после этого выводятся показатели производительности.
Seed‑контракт для HEP suite зафиксирован в benchmarks/nextstat-public-benchmarks/suites/hep/run.py: пороги NLL_SANITY_ATOL = 1e-8 и NLL_SANITY_RTOL = 1e-12, а кейс считается корректным, еслиabs_diff ≤ atol или rel_diff ≤ rtol(то есть падение — только когда оба порога нарушены одновременно).
Конкретный гейт (сегодня): для каждого кейса требуем abs(NLL_nextstat − NLL_pyhf) ≤ 1e-8 или rel_diff ≤ 1e-12 до записи таймингов.
Почему это важно:
- ›это предотвращает регрессии «быстро, потому что неверно»
- ›это превращает расхождение в багрепорт с контекстом, а не в спор
4.Маппинг параметров и закрепленные соглашения модели
4.1 Маппинг параметров по имени
Разные реализации могут упорядочивать параметры по-разному (особенно побиновые модификаторы вроде ShapeSys gammas). Поэтому харнесс маппит вектора параметров по имени параметра, а не по индексу, прежде чем сравнивать NLL или измерять время фитов.
4.2 Явные коды интерполяции
У HistFactory несколько соглашений по интерполяции. Бенчмарки обязаны закреплять коды интерполяции NormSys и HistoSys, иначе вы бенчмаркаете не одну и ту же статистическую модель.
5.Профильные сканы: cold-start vs warm-start это и есть бенчмарк
Профильные сканы это классическое место, где наивные бенчмарки врут. Две реализации могут быть корректными, но измерять разные воркфлоу, если одна делает cold-start каждой точки, а другая warm-start от соседней. Поэтому харнесс должен публиковать POI-grid, политику warm-start, границы и допуски, а также соглашения о клиппинге (односторонние qμ/q₀).
6.Сравнения ROOT/RooFit: что мы будем (и не будем) утверждать
ROOT важен как независимая точка сравнения, но в публичных seed‑бенчмарках мы разделяем две вещи:валидацию корректности (может требовать тяжёлого окружения) ипубликуемые утверждения о скорости (должны быть воспроизводимыми для внешних команд).
Поэтому для ROOT‑сравнений мы публично утверждаем только то, что можно воспроизвести и диагностировать:
- ›Публиковать режимы отказов и частоты fit-status, а не только средние
- ›Публиковать кросс-проверки (вычислять NLL реализации A при параметрах из B)
- ›Сохранять «сошлось ли?» как первоклассную метрику
Строгая валидация профсканов ROOT/HistFactory vs NextStat живёт в основном репозитории:tests/validate_root_profile_scan.py. Она:
- ›экспортирует pyhf‑workspace в HistFactory XML + ROOT‑гистограммы (через
pyhf.writexml) - ›строит RooWorkspace через
hist2workspace - ›делает free‑fit и фиксированный POI‑скан в ROOT и тот же POI‑скан в NextStat
- ›сравнивает q(μ), μ̂ и значения NLL, чтобы поймать расхождения модели/оптимизации
В seed‑репозитории публичных бенчмарков ROOT‑часть сейчас оформлена как шаблон (benchmarks/nextstat-public-benchmarks/suites/hep/baselines/root/run.py) и пока не является источником «скоростных» цифр: она проверяет доступность PyROOT/версии, чтобы внешние команды могли честно зафиксировать, что ROOT‑окружение присутствует.
У нас также есть отдельный строгий разбор численной согласованности: «Численная корректность». Бенчмарки и численная корректность это две стороны одной задачи доверия.
7.От прогона харнесса к публичному снимку
Результаты производительности должны включать:
- ›сырые измерения по повторам (чтобы была видна дисперсия)
- ›политику агрегации (median, min-of-N и т.д.)
- ›манифест окружения (тулчейны, зависимости, железо)
- ›отчеты корректности, которые использовались как гейты
Это разница между скриншотом и артефактом. См. также: «Бенчмарк-снимки как продукты».
7.1 Артефакты и схемы (что именно пишет HEP suite)
В минимальном seed-харнессе (standalone публичные бенчмарки) мы фиксируем результат как машиночитаемые JSON-артефакты с версиями схем. Это важно, потому что без формата сравнение превращается в «прочитай лог и поверь».
- ›Пер-кейс артефакт:
nextstat.benchmark_result.v1(NLL паритет + тайминги + сырые повторы; опционально — fit-метаданные). - ›Suite индекс:
nextstat.benchmark_suite_result.v1(список кейсов с путями+SHA‑256 и суммарный worst-case по |ΔNLL|).
Каноничные JSON Schema для этих артефактов — часть seed‑контракта:benchmarks/nextstat-public-benchmarks/manifests/schema/benchmark_result_v1.schema.json и benchmarks/nextstat-public-benchmarks/manifests/schema/benchmark_suite_result_v1.schema.json. HEP suite пишет per‑case JSON в out_dir/cases/*.json и индексout_dir/hep_suite.json.
Когда результаты публикуются как snapshot, к ним добавляются базовые документы публикационного слоя:baseline_manifest.json (схема nextstat.baseline_manifest.v1) и snapshot_index.json (схема nextstat.snapshot_index.v1).
8.Как перезапустить (сегодня)
Сквозная sanity‑проверка и тайминг для pyhf vs NextStat (включает гейт корректности) в основном репозитории NextStat:
PYTHONPATH=bindings/ns-py/python ./.venv/bin/python \
tests/benchmark_pyhf_vs_nextstat.py --fitМинимальный воспроизводимый seed‑харнесс (single case, пишет один JSON‑артефактnextstat.benchmark_result.v1):
python3 benchmarks/nextstat-public-benchmarks/suites/hep/run.py \
--case simple_workspace_nll \
--workspace benchmarks/nextstat-public-benchmarks/suites/hep/datasets/simple_workspace.json \
--measurement-name GaussExample \
--deterministic \
--fit \
--out tmp/hep_simple_case.jsonПолный suite прогон (пишет hep_suite.json + per-case JSONs):
python3 benchmarks/nextstat-public-benchmarks/suites/hep/suite.py \
--out-dir tmp/hep \
--deterministic \
--fitКороткая сводка по suite (таблица worst-case + speedups):
python3 benchmarks/nextstat-public-benchmarks/suites/hep/report.py \
--suite tmp/hep/hep_suite.json \
--format markdownВалидация ROOT профильного скана (нужны ROOT и hist2workspace):
PYTHONPATH=bindings/ns-py/python ./.venv/bin/python tests/validate_root_profile_scan.py \
--pyhf-json tests/fixtures/simple_workspace.json \
--measurement GaussExample \
--start 0.0 --stop 5.0 --points 519.Закрытие: «перезапусти меня», а не «поверь мне»
Наш эндстейт это не «у нас хорошие числа». Наш эндстейт это:
- ›вы можете перезапустить харнесс на своей машине
- ›увидеть те же гейты корректности
- ›и сравнить результаты с полным контекстом
Так производительность становится свидетельством.
Связанное чтение
- ›Trust Offensive: публичные бенчмарки
- ›Численная корректность — ROOT vs pyhf vs NextStat
- ›Бенчмарк-снимки как продукты — CI-артефакты и базовые линии
- ›Артефакты отчета валидации
