Skip to main content

Overview

A benchmark run evaluates every definition × solution × workload combination. For each combination it validates correctness against the reference implementation and measures kernel performance, producing a Trace with the results.

Quick Start

CLI

Python API

run_all returns a new TraceSet that contains all the definitions, solutions, and workloads from the input, plus the newly generated traces from this run.

Benchmark Config

BenchmarkConfig is a Pydantic model that controls every aspect of a benchmark run. You can configure it directly in Python or load it from a YAML file.

Loading Configuration

The FlashInfer-Bench package bundles a default eval_config.yaml that sets sensible baselines for known op types. You can provide a custom configuration via the CLI (which replaces the bundled defaults):
(CLI flags like --rtol or --iterations are applied as overrides on top of the YAML) Or via the Python API:

Configuration Structure

The configuration is divided into system-level fields (which apply to the runner) and eval config fields (which are resolved per-definition and passed to evaluators). Here is how the structure looks in Python and YAML:

System Fields

These fields control the benchmarking engine and runner behavior.

Eval Config Fields

These fields control correctness validation and performance measurement. You can set them at the top level (as global defaults), inside op_type_config, or inside definition_config. The extra dictionary is used to pass specialized parameters to specific evaluators. See the Sampling Evaluator below for an example.

Resolution Order

The final evaluation configuration for a definition is resolved from highest to lowest priority as follows. For the extra dict, layers are merged via dict.update() instead of direct replacement.
  1. Per-definition config
  2. Per-op-type config
  3. Top-level global defaults

Runners

Evaluators

Different op types use specialized evaluators: Evaluators receive a resolved evaluation configuration with all fields fully resolved from the merge chain above. The SamplingEvaluator uses statistical validation via Total Variation Distance (TVD) over multiple trials. It reads its parameters directly from the extra dictionary in the configuration:

Custom evaluators

To add a custom evaluator:
  1. Subclass Evaluator (in flashinfer_bench/bench/evaluators/evaluator.py) and implement:
    • can_evaluate(definition) — return True for definitions this evaluator handles
    • build_baseline(definition, workload, cfg, device) — build reference outputs
    • check_correctness(definition, sol_runnable, inputs, ref_outputs, cfg, ...) — validate solution correctness
    • eval_performance(definition, sol_runnable, inputs, ref_mean_latency_ms, cfg, ...) — measure performance
  2. Register it in flashinfer_bench/bench/evaluators/registry.py by appending to the _EVALUATORS list. The first evaluator whose can_evaluate returns True is used; if none match, DefaultEvaluator is used.
  3. Use the extra dict in YAML config to pass evaluator-specific parameters (see Eval Config Fields above). Read them in your evaluator via cfg.extra.get("my_param", default_value).