agentsclimarketplace

Inference spec decode tune

Skill cfregly/gpu-perf-tune/plugins/profile-and-optimize/skills/inference-spec-decode-tune

Tune a speculative-decoding DRAFT head's TRAINING hyperparameters (global batch, learning rate, accumulation, warmup) for a target LLM, optimizing the TRUE serving in-engine acceptance length (vLLM spec_decode counters) with a cheap training-acc proxy for triage. Reuses the search ALGORITHMS (hyperband/grid/random natively. Bayesian-TPE via optuna if installed) wired to a GB300/managed K8s pod launcher + an offline EAGLE3/DFlash trainer (distinct from the MLPerf ai_tuning contract, which does not map to draft training). The draft-training analog of inference-tune-sweep (which tunes vLLM SERVING config). Triggers on "tune the draft head", "tune eagle3 / dflash training", "bayesian/hyperband tune the draft", "search global batch and LR for the speculator", "spec-decode hyperparameter sweep", "draft-training tuner", or any combination of "tune / sweep / optimize / search / bayesian / hyperband" with "eagle3 / dflash / draft / speculator / spec-decode".From its SKILL.md

Install
npx -y skills add cfregly/gpu-perf-tune --skill inference-spec-decode-tune

Assembled 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

10.3 KB, ~2.4k tokens by cl100k_base, as published. Nobody here has run it

inference-spec-decode-tune

Purpose

Find the draft head's best training hyperparameters by searching {global_batch, learning_rate[, accum, warmup]} instead of hand-picking one config, optimizing the measured serving acceptance length (the metric that actually determines speculative-decode speedup) with a cheap training-acc proxy for early triage.

It is the draft-training counterpart to inference-tune-sweep (which tunes vLLM serving config) and the tuning loop around inference-spec-decode-train (which trains a single head). It is the realization of the --optimizer bayesian|hyperband hook that inference-tune-sweep documents as a stub.

Why a separate tuner (not the MLPerf ai_tuning MCP)

The profile_and_optimize ai_tuning_* family ships the engines we want (random / bayesian tpe,gp / multifidelity hyperband,bohb) but is coupled to MLPerf training: config_patches validated against an extracted shell config (config_DGXB200_*.sh), a ~/.hypertune ledger, and submit via a Slurm launcher. Draft training has no shell-config template and runs as a GB300/managed K8s pod, so this skill reuses the search algorithms (natively for hyperband/grid/random. Optuna for TPE) wired to the draft launcher, and keeps the ai_tuning_* MCP as the cousin for the training side.

When to use

  • A draft head trains stably (via inference-spec-decode-train) and you want its acceptance-optimal training config, not just one hand-picked point.
  • A coarse batch-size / LR sweep (e.g. global-batch 8/16/32/128 arms) showed the metric is still moving and you want an adaptive search to find the knee.

Do not use for: vLLM serving config (use inference-tune-sweep). The first stable-training pass on a brand-new draft (use inference-spec-decode-train).

Inputs / artifacts (EAGLE3 reference layout)

The reference implementation (a GLM-5.1 EAGLE3 tuner) lays these artifacts down in the deploy bundle (e.g. under deploy/gb300/):

  • tuning-space.eagle3-draft.json - the search space + objective (serving acceptance) + proxy (training acc) + hyperband rungs (in samples-consumed).
  • tune-trial.sh - one trial: maps global_batch -> (BS, accum) on the 4-GPU node (BS<=4. BS=8 OOM'd), launches a training arm (e3bs-arm.yaml), reads proxy-acc at a matched-sample cap (read-acc0.sh), promotes to serving eval.
  • tune-driver.py - the loop: --strategy hyperband (default) | grid | random | tpe (optuna), --seed-from prior arms, durable tune-ledger.json, --dry-run (zero cluster spend).
  • serving objective: eagle3_vllm_eval.py + deploy/gb300/eagle3-accept-eval.yaml (vLLM method=eagle3, vllm:spec_decode_num_accepted_tokens / num_drafts -> mean accept length).

Workflow

Phase 0 - state objective + space + strategy

  • Objective of record = measured serving acceptance length (NOT the proxy).
  • Proxy = training acc= at matched samples (drives the cheap hyperband rungs).
  • Strategy (all selectable via --strategy. Pick by search-space size):
    • hyperband (default) - successive-halving bandit. Best GPU-efficiency (early-kills weak arms). Use it unless you have a reason not to.
    • grid - exhaustive over the categorical grid, random - uniform-draw baseline. Both dependency-free.
    • tpe - Bayesian, model-based search. Sample-efficient on LARGER / continuous spaces. Opt-in: needs pip install optuna (the other three are dependency-free. Tpe exits with a clear message if optuna is absent).

Phase 1 - dry-run the plan (no spend)

tune-driver.py --strategy hyperband --seed-from <prior-arms.json> --dry-run

Prints the bracket, the per-config (BS, accum, lr) mapping, and the rung read-caps. Confirm the bracket before any GPU spend.

Phase 2 - run the proxy search (cheap rungs)

tune-driver.py --strategy hyperband --seed-from <prior-arms.json>

Launches the bracket as experiment-isolated training pods, reads proxy-acc at each rung from the SAME run's log, early-kills the bottom (1 - 1/eta) to save GPU, lets survivors train on. Every rung read is appended to tune-ledger.json (durable across churn).

Phase 3 - promote survivors to measured serving acceptance (the objective)

For the top-K survivors, run eagle3_vllm_eval.py against the GB300 serving deploy and read vllm:spec_decode_* -> mean acceptance length. The champion is decided here, on measured serving acceptance - the proxy only ranked candidates for promotion.

Phase 4 - gate + record

Gate the champion vs the standing config with perf_baseline_diff. On a real win, record the new champion baseline + publish to the perf-lake (serving acceptance/throughput IS perf-lake-eligible). On a within-noise tie, report "no improvement" - never round a proxy win up to a serving win.

Verdict rigor (DRAFT vs VERDICT)

  • proxy-acc rung results are DRAFT (a surrogate, single-trial).
  • The champion is a VERDICT only on measured serving acceptance, with a same-config repeat for noise, against the production-representative baseline.

Full-context reporting (no bare numbers)

Per the methodology canon "Every performance number carries its full context (no bare numbers)" (docs/METHODOLOGY.md, "Full-context reporting"): every number this skill emits (throughput, latency, TPOT/ITL, BW, %SoL, speedup, efficiency, goodput, acceptance rate, scaling efficiency, thermal/failure rate - whatever it reports) MUST carry its full measurement-context descriptor, and every comparison MUST be matched on it. A bare number 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, bench backend, serving engine.
  • Grounding: %SoL (+ ceiling key from configs/sol-ceilings.yaml - never inline a peak), sol_rigor (L1-L4), trials n (mean±std), same-node, baseline named. (If the metric is not roofline-bound - e.g. accuracy/acceptance - omit %SoL but keep the rest of the descriptor.)
  • 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").

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 (docs/METHODOLOGY.md, "Always be grinding"). 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.

Safety

  • Experiment isolation: every trial pod is experiment-prefixed (e.g. <slug>-e3bs-<run-id>) + experiment=<run-id> label. Teardown by label. Never reuse standing names. Never touch a parallel session's pods (workstream= label check first).
  • Durability: stream each trial's head + log to object storage before pod delete (emptyDir is ephemeral).
  • Ack-gated: any submit/serving-deploy step fails closed without its ack. The --dry-run is the safe preview.
  • Cost honesty: serving eval is expensive (train -> convert -> deploy -> eval), so hyperband triages on the proxy and only promoted survivors pay for serving.

Source-of-truth references

  • inference-tune-sweep - the serving-config sibling + the --optimizer hook this skill realizes.
  • inference-spec-decode-train - the single-head trainer this loops around.
  • The ai_tuning_* MCP family - the MLPerf-training cousin (same engines, different contract).

Contact

Open an issue in this repository.

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,750. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.