Inference perf baseline bridge
Skill cfregly/gpu-perf-tune/plugins/profile-and-optimize/skills/inference-perf-baseline-bridge
Bridge between the inference-perf-bench / ai-bench output bundle and the profile-and-optimize perf-baseline registry. Knows the canonical inference perf metric shape (TTFT p50/p95/p99, ITL p50, throughput, tok/s/user, request latency p50, prefix cache hit rate delta, GPU cache utilization peak), records it under inference_perfbench_v1 schema, and on diff applies per-metric tolerances tuned for inference workloads (TTFT regressions <5 percent, throughput <3 percent, cache hit rate <2 absolute points). Wraps the existing perf-baseline-record and perf-baseline-diff MCP verbs, no new MCP verbs introduced. Triggers on "register inference baseline", "inference perf-baseline", "diff inference perf", "is this inference regression real", "perf-bench baseline", "ai-bench baseline", or any combination of "register / record / diff / compare" with "inference / ai-bench / perf-bench / vllm / kimi / glm / deepseek / minimax".From its SKILL.md
npx -y skills add cfregly/gpu-perf-tune --skill inference-perf-baseline-bridgeAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
19.7 KB, ~5.0k tokens by cl100k_base, as published. Nobody here has run it
inference-perf-baseline-bridge
Purpose
Translate the output of an
inference-perf-bench (or its
colloquial alias ai-bench) run into the
shape the workload-agnostic
perf-baseline-record /
perf-baseline-diff registry
expects. The bridge fixes three pain points:
- The upstream
perf-benchskill's report is a markdown table per model - not a JSON payload the registry can hash and diff. - The metric set (TTFT p50/p95/p99, ITL p50, tok/s, tok/s/user, request latency p50, prefix cache hit rate delta, GPU cache utilization peak) needs a stable schema name so future diffs find apples-to-apples baselines.
- Per-metric regression tolerances differ - TTFT regressions of 5% are usually real, throughput regressions of 3% may be capacity contention, prefix cache hit rate movements should be expressed as absolute percentage points (not percent-of-percent).
This bridge does NOT add a new MCP verb. It wraps the existing
mcp__profile_and_optimize__perf_baseline_record and
mcp__profile_and_optimize__perf_baseline_diff verbs with a fixed schema kind
(inference_perfbench_v1) and operator-tunable per-metric tolerances.
Schema: inference_perfbench_v1
{
"schema": "inference_perfbench_v1",
"model": "<served-model-name>",
"model_path": "<HF-org/repo>",
"deployment": {
"namespace": "<k8s-namespace>",
"cluster": "<kube-context>",
"service": "<svc-name>",
"vllm_version": "<v0.NN.M>",
"tensor_parallel_size": <int>,
"quantization": "<NVFP4 | FP8 | BF16 | FP4 | INT4>",
"kv_cache_dtype": "<fp8_e4m3 | bf16 | ...>",
"speculative_decoding": "<eagle3 | mtp | none>"
},
"workload": {
"dataset": "<hf-org>/replay-playback",
"split": "<2025_07 | 2025_04 | 2025_01 | all>",
"conversation_num": <int>,
"concurrency_sweep": [<int>, ...],
"input_token_band": "<1k | 10k | 100k | mixed>",
"output_token_band": "<1k | 1.5k | 2k | mixed>"
},
"metrics": {
"<concurrency>": {
"throughput_toks_per_s": <float>,
"ttft_p50_ms": <float>,
"ttft_p95_ms": <float>,
"ttft_p99_ms": <float>,
"itl_p50_ms": <float>,
"tps_per_user": <float>,
"request_latency_p50_ms": <float>,
"errors": <int>
}
},
"server_metrics_delta": {
"prefix_cache_hit_rate_pre": <float>,
"prefix_cache_hit_rate_post": <float>,
"gpu_cache_usage_perc_peak": <float>,
"num_requests_running_peak": <int>,
"avg_generation_throughput_toks_per_s": <float>
},
"kernel_class_gpu_pct": {
"fp8_bmm": <float|null>,
"tp_all_reduce": <float|null>,
"cuda_event_sync": <float|null>,
"mla_attention": <float|null>,
"moe_routing_finalize": <float|null>,
"per_token_group_quant": <float|null>,
"<other-class>": <float|null>
},
"cpu_spinpoll_pct": <float|null>
}
Optional fields
The two top-level fields kernel_class_gpu_pct and cpu_spinpoll_pct
are optional. They surface profile-grade signals that the upstream
perf-bench runbook does not produce on its own - they are populated
when the operator also captures a zymtrace
or Nsight-Systems profile against the same time window.
Field shapes and origins:
kernel_class_gpu_pctis an open map of kernel-class name to percent of GPU time. The canonical class set is the one typically observed in a plain-FP8 MoE serving profile:fp8_bmm,tp_all_reduce,cuda_event_sync,mla_attention,moe_routing_finalize,per_token_group_quant. Classes outside this set go under arbitrary<other-class>keys (free-form). The map is derived from a GPU-sideevent_kind = 'cuda'zymtrace query grouped by kernel-name regex. The source bucket-rules live in the zymtrace-anchored-query skill's "Kernel-class bucketing" appendix.cpu_spinpoll_pctis a single scalar: the percent of CPU on-cpu samples that fall inside vLLM's spin-poll IPC path (shm_broadcast.py::{acquire_read,wait,memory_fence,timeout_ms,should_warn,dequeue}utils.py::sched_yield). Populated from the same zymtrace bundle's CPU-sideevent_kind = 'on_cpu'query.
Diff semantics on null: when either side of a per-metric comparison
is null, the bridge skips that metric in Phase 2: per-metric diff with tolerances and emits a NULL_LEGACY_BASELINE row in the diff
output so the operator can see which fields were unmeasured. This keeps
existing inference_perfbench_v1 baselines registered before these
fields existed diff-compatible with new bundles that include them - the
registry never breaks.
When a true breaking change is needed (e.g. metric-shape restructure of
metrics.<concurrency>), the schema name will bump to
inference_perfbench_v2. Additive-only changes stay on _v1.
Default per-metric tolerances
| Metric | Default tolerance | Direction | Rationale |
|---|---|---|---|
throughput_toks_per_s | 3% | regression = current < baseline | Throughput is the headline metric. Small regressions are real |
ttft_p50_ms | 5% | regression = current > baseline | TTFT is sensitive to scheduler / cache cold-start, 5% is the usual signal floor |
ttft_p95_ms | 10% | regression = current > baseline | Tail latency wider band - outlier-prone |
ttft_p99_ms | 15% | regression = current > baseline | Same |
itl_p50_ms | 3% | regression = current > baseline | ITL is decode-bound. Small regressions are real |
tps_per_user | 3% | regression = current < baseline | Per-user throughput. Same band as overall throughput |
request_latency_p50_ms | 5% | regression = current > baseline | Same as TTFT p50 |
prefix_cache_hit_rate_post | 2 absolute pts | regression = current < baseline | Cache hit rate moves in absolute pts, not percent-of-percent |
gpu_cache_usage_perc_peak | 5 absolute pts | regression = current > baseline | Capacity ceiling proxy |
kernel_class_gpu_pct.<any> | 3 absolute pts | regression = current > baseline | Kernel-class %-of-GPU drift, 3pp is the usual signal floor for hot kernels (e.g. TP all-reduce drifting from an expected ~10% to an observed ~15% is an actionable 5pp delta) |
cpu_spinpoll_pct | 5 absolute pts | regression = current > baseline | CPU spin-poll waste, >5pp jump indicates VLLM_USE_SHM_BROADCAST_BLOCKING=1 regressed off, or a new vLLM release re-introduced busy-wait IPC |
Operator can override any of these via --tolerance.<metric> <value>
on the command line. The two optional fields' tolerances are only
evaluated when both sides of the diff have non-null values. Otherwise
the metric is reported as NULL_LEGACY_BASELINE and skipped (see
"Optional fields" above).
When to use
- After an
inference-perf-benchrun completes (Phase 9 of the upstream runbook). - Periodic regression sweep - weekly cron diffs each registered baseline against the most recent run.
- Pre-promotion gate - block staging or prod promotion if the diff verdict is RED.
- Pairing perf vs quality - register the baseline with
--notes "GPQA=<score>. MMLU-Pro=<score>"from theinference-model-evalrun so future diffs can confirm the regression is not masked by a quality gain (or vice versa).
Do not use this skill for:
- MLPerf training step-time / MFU baselines - use
perf-baseline-recorddirectly with--family <bench>and a custom schema. - One-off diagnostic measurements - register a baseline only when the measurement is worth remembering.
Example prompts
- "Register the kimi-k25 perf-bench result as the new baseline."
- "Diff this morning's deepseek-v4 ai-bench against last week's baseline."
- "Inference perf regression check on glm-5-fp8 with tolerance.tps=5%."
/inference-perf-baseline-bridge record --model kimi-k25 --source experiments/artifacts/inference-perf-bench/<run-id>//inference-perf-baseline-bridge diff --baseline experiments/artifacts/perf-baselines/inference/kimi-k25/2026-05-19T20:00:00Z/ --current experiments/artifacts/inference-perf-bench/<run-id>/
Prerequisites
- Source bundle path -
--source <path>pointing at anexperiments/artifacts/inference-perf-bench/<run-id>/directory. - Model name -
--model <served-model-name>(matches the value returned by the model's/v1/modelsendpoint). PROFILE_AND_OPTIMIZE_REPO_ROOTfor the registry path.
Interaction style
Mostly autonomous. One pause: confirm the per-metric tolerances and the registry path before write (record) or before computing the diff verdict (diff).
Workflow
Mode 1: record
Phase 1: parse the perf-bench bundle into the schema shape
Read the upstream perf-bench output:
experiments/artifacts/inference-perf-bench/<run-id>/perf-bench-report-*.md- parse the per-concurrency rows.experiments/artifacts/inference-perf-bench/<run-id>/aiperf-c<N>.log- extract the headline metrics per concurrency.experiments/artifacts/inference-perf-bench/<run-id>/<model>-metrics-pre.promand<model>-metrics-post.prom- extractvllm:prefix_cache_hit_rate,vllm:gpu_cache_usage_perc,vllm:num_requests_running,vllm:avg_generation_throughput_toks_per_s.
If the operator also captured a paired profile bundle (zymtrace or Nsight) against the same window, source the two optional fields:
experiments/artifacts/zymtrace-bundles/<run-id>/response.json(or any sibling bundle that follows the zymtrace-anchored-query layout) - derivekernel_class_gpu_pctfrom the GPU-sideevent_kind = 'cuda'query response, bucketed per the kernel-class regex appendix in that skill. Derivecpu_spinpoll_pctfrom the CPU-sideevent_kind = 'on_cpu'response by summing samples whosepy_filematchesshm_broadcast.pyorutils.py::sched_yield.- If no paired profile bundle exists, emit
nullfor both optional fields. The diff verb will skip them per the "Optional fields" rule above. The registry record stays valid.
Emit inference_perfbench_v1.json to a scratch path, sha256sum it.
Phase 2: register
mcp__profile_and_optimize__perf_baseline_record with:
args: ["--family", "inference",
"--measurement", "<model>-perfbench-v1",
"--source", "<scratch-path-to-inference_perfbench_v1.json>",
"--unit", "structured-json",
"--notes", "<operator-supplied notes; e.g. GPQA + MMLU-Pro scores from inference-model-eval>",
"--json"]
The verb writes the registry entry under
experiments/artifacts/perf-baselines/inference/<model>-perfbench-v1/<UTC-ts>/
(per the registry layout the upstream verb already implements).
Phase 3: report
Print:
- Registry path.
- Source SHA-256.
- Headline metrics at concurrency 16 (the canonical operating point for routine comparison).
- Cross-link to
inference-perf-baseline-bridgedifffor future regression checks.
Mode 2: diff
Phase 1: resolve baseline + current
Read <baseline>/baseline.json- confirmfamily == "inference"andmeasurement == "<model>-perfbench-v1".Read <baseline>/source-snapshot.<ext>- load the baseline'sinference_perfbench_v1.json.- Parse the current bundle into the same schema shape (Phase 1 of record mode).
Phase 2: per-metric diff with tolerances
For every concurrency cell in metrics.<concurrency>, compute:
delta = current - baselinedelta_pct = 100 * delta / baseline(for percent metrics)delta_abs = current - baseline(for absolute metrics: cache hit rate)- Per-metric verdict: GREEN if
|delta|is within the tolerance for that metric (regression direction respected), RED otherwise.
For server_metrics_delta, apply the tolerances at the absolute
level: a prefix_cache_hit_rate_post drop of more than 2 percentage
points is RED. A peak gpu_cache_usage_perc rise of more than 5
percentage points is RED.
Phase 3: overall verdict
- GREEN: every metric at every concurrency is within tolerance.
- YELLOW: 1-2 metrics exceed tolerance OR exactly one concurrency level shows multiple regressions.
- RED: 3+ metrics exceed tolerance OR the headline metric
(
throughput_toks_per_sat concurrency 16) regresses by more than its tolerance.
Phase 4: write the diff bundle
Delegate to mcp__profile_and_optimize__perf_baseline_diff (the existing verb
already writes the diff under
experiments/artifacts/perf-baseline-diffs/inference/<model>-perfbench-v1/<UTC-ts>/):
mcp__profile_and_optimize__perf_baseline_diff with:
args: ["--baseline", "<baseline-registry-entry-dir>",
"--current", "<scratch-path-to-current-inference_perfbench_v1.json>",
"--tolerance-percent", "5",
"--json"]
The wrapper supplies 5 as the umbrella tolerance for the underlying
verb's structured-JSON shape. The per-metric verdict above is the
authoritative classification this skill returns.
Phase 5: recommend
- GREEN: "no inference perf regression detected. Safe to promote."
- YELLOW: "spot regression on N metrics. Recommend re-running the perf-bench against the same dev cluster cohort to rule out noise, then re-diff."
- RED:
- If headline
throughput_toks_per_sregressed: prompt the operator to check for cohort contention viaprometheus-anchored-queryonvllm:num_requests_runningfor the same time window. - If TTFT regressed but throughput didn't: suggest checking
scheduler / queue depth (
vllm:num_requests_runningpeak +vllm:gpu_cache_usage_percpeak deltas). - If prefix cache hit rate regressed: suggest the
--connection-reuse-strategy sticky-user-sessionsflag - a hit-rate drop is often a routing problem (cross-region hops breaking session affinity), not a model-side issue.
- If headline
Safety
- Read-only on the registry. Diff mode never writes to
experiments/artifacts/perf-baselines/. It writes only toexperiments/artifacts/perf-baseline-diffs/. - No new MCP verbs. This skill wraps existing
mcp__profile_and_optimize__perf_baseline_recordandmcp__profile_and_optimize__perf_baseline_diffverbs. The bundled MCP surface tool count stays unchanged. - Schema mismatch fails fast. If the baseline's
schemafield is notinference_perfbench_v1, diff mode stops and asks. No cross-schema fuzzy diffing. - Provenance preserved. Every record / diff carries the perf-bench
bundle's source SHA-256 + operator + cluster + profile_and_optimize SHA, per
the
server/CLAUDE.mdreproducibility-grade-evidence rule.
Full-context reporting (no bare numbers)
Per the methodology canon "Every performance number carries its full context (no bare numbers)"
(docs/METHODOLOGY.md): every number this
skill emits MUST carry its full measurement-context descriptor, and every comparison MUST be
matched on it. A bare tok/s / TPOT / BW / %SoL / speedup is a defect - it cannot set a
default, ship a config, or appear in a report.
- Identity: model (+HF path), hardware (exact ceiling token
GB300/B200), quant, kv-cache dtype. - Parallelism: TP, DP (replicas), PP, EP, parallel_strategy.
- Serving cfg: max-num-seqs, max-num-batched-tokens, gpu-memory-utilization, max-model-len, cudagraph_mode/enforce_eager, async_scheduling, prefix-caching.
- Workload: dataset, ISL/OSL (or mean in/out tokens), concurrency, num-prompts.
- Regime: warm vs cold. Latency vs throughput tier.
- Stack: image/vllm commit, delivery (image|overlay|patchedVllm|infr-patch), bench backend, serving engine. A number is evidence only for its own
delivery-- never cite cross-tier. - Grounding:
%SoL(+ ceiling key fromconfigs/sol-ceilings.yaml- never inline a peak), sol_rigor (L1-L4), trials n (mean±std), same-node, baseline named. - Per-number exact shape (no smoothing): when reporting more than one number, keep EACH with its own exact shape (ISL/OSL, concurrency, dataset, regime) - never normalize a set to one uniform descriptor that hides per-point variation (e.g.
c=1 @ ISL1024/OSL256+c=64 @ ISL4096/OSL512, NOT one shared "random").
See server/CLAUDE.md "Speed-of-light framing". When this bridge
records / diffs a perf-bench run, the baseline record SHOULD carry a
sol_pct field per the
perf-baseline-record schema, and
the diff SHOULD report SoL delta alongside the absolute throughput /
latency delta. Peaks are sourced from
configs/sol-ceilings.yaml - never inlined.
Next lever / BREAKTHROUGH (Grind Mandate)
If this skill emits a measured result, its output MUST end by naming the next perf lever,
its expected unlock (direction + rough magnitude), and the gate that proves/refutes it,
per "The Grind Mandate" (server/CLAUDE.md + docs/METHODOLOGY.md). A
measured win is the new floor, not the finish -- so do everything we can to find the next
BREAKTHROUGH: the highest-EV unlock toward Speed-of-Light (a new champion / kernel / router /
quant / parallelism / spec-decode win, or an unblocked stack), not just the next micro-lever.
Rank the candidate breakthrough levers by value x cost (the GRIND FRONTIER, perftunereport value_view), pursue the top, bank the rest with evidence. Record WHY a refuted lever loses,
update the standing frontier in the active bundle's HANDOFF.md. Never conclude
"exhausted/optimal/done" without an explicit next-lever frontier (an empty frontier AND a
documented SoL wall only). Delete this section ONLY if the skill produces no measurements.
Source-of-truth references
- The pair this bridge wraps:
perf-baseline-record,perf-baseline-diff. - Perf-bench input:
inference-perf-bench(also reachable via theai-benchcolloquial alias). - Quality counterpart:
inference-model-eval. server/CLAUDE.md- fail-fast + provenance rules.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.