Skip to main content

perf-optimization-casebook

Casebook of past successful and classic TensorRT-LLM optimizations (runtime/execution and kernel level) recorded as reusable decision precedents. Consult when deciding which optimization to apply for a classified bottleneck or a given config/model/hardware, to find prior art and adapt a proven approach instead of guessing. Each case records applicability signals, mechanism, how to apply, expected effect, accuracy risk, verification, and rollback.

Datos de origen

Repositorio
NVIDIA/TensorRT-LLM
Última actividad en el origen
22 de septiembre de 2026 a las 07:12
Idioma detectado de SKILL.md
inglés
Estrellas
14.826
Forks
2823

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Explorador de archivos
49 archivos

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
perf-optimization-casebook
description
Casebook of past successful and classic TensorRT-LLM optimizations (runtime/execution and kernel level) recorded as reusable decision precedents. Consult when deciding which optimization to apply for a classified bottleneck or a given config/model/hardware, to find prior art and adapt a proven approach instead of guessing. Each case records applicability signals, mechanism, how to apply, expected effect, accuracy risk, verification, and rollback.
tags
["optimization","casebook","precedents","decision-support"]
license
Apache-2.0
metadata
{"author":"NVIDIA Corporation"}
# Performance Optimization Casebook A curated library of **classic and previously-successful TensorRT-LLM optimizations**, written as decision precedents. Use it to answer "for *this* bottleneck / config / model / hardware, what has worked before, and how do I adapt it?" — instead of inventing an approach from scratch. This skill is **reference material, not a coordinator.** It does not run profiling, edit code, or route to specialists by itself. It is consulted *by* the coordinators (`perf-analysis` after a bottleneck is classified, `perf-optimization` before prioritizing/routing) and by the `perf-sweep` system when choosing what to try next. Implementation always goes through the relevant specialist/skill named in each case. ## When to Consult - A bottleneck has been classified (compute / memory / launch / communication / sync) and you need candidate optimizations for that class. - You are about to prioritize or route an optimization and want to check for prior art, known pitfalls, and the right specialist. - You are choosing the next config to try in a serving sweep. - You just landed a verified win and want to record it for future reuse. ## How to Use a Case — the loop 1. **Classify.** Know the current bottleneck class and the workload context (model arch, hardware/SM, ISL/OSL, concurrency, current config). If you do not have this, get it from `perf-analysis` / profiling first. 2. **Match.** Search wide with free text, then rank — never let the query vocabulary narrow what is reachable: - **Recall (grep the whole case files, free text):** grep the case bodies with your own natural query terms — model name, knob, mechanism word, deployment feature — over the full files, not just structured fields: grep -ril "lora" references/ # any term, whole file grep -ril "chunked prefill" references/ Every concept a case covers lives in its prose (**Applies when** / **Generalizes to** / mechanism), so a free-text grep over the whole file is recall-complete on its own. Frontmatter is **additive** structure layered on top — it never removes a word grep could already find. Do **not** pre- translate the query into canonical vocabulary before searching; that is what would make grep miss LoRA / beam search / a reasoning model's thinking phase and other concepts that have no canonical signal. Browse the family **index** too if you want a curated table, but grep alone does not miss. - **Rank (optional accelerator):** among the hits, optionally use the frontmatter fields (canonical `signals`/pattern grep — see "Frontmatter fields" below) to decide which case file(s) to open first. This only *reorders* the free-text hits — it never defines or bounds them. - Then open **only** the winning case file(s). Match on signals, not on the optimization name. 3. **Adapt — do not copy.** A case is a precedent, not a guaranteed config. Adjust knob values to the current model/hardware; read the nearest checked-in config and the model's deployment guide before setting numbers. 4. **Verify.** Apply through the named specialist/skill, then measure. Numbers come from real measurement only (see Principles). A precedent's expected *direction* of effect does not excuse skipping measurement. 5. **Record.** If the change is a verified win (or a clear, instructive failure), add or update a case so the next decision is better informed (see "Adding a New Case"). ### Frontmatter fields (optional precision — not a search step) Cases carry YAML frontmatter (vocabulary: `data/tags.yaml`; spec: `references/case-template.md`). It is **additive structure for ranking and judging** the free-text hits from Match step 2 — never a second search you must run, and never a filter that bounds what grep already found. Use it as needed: grep a canonical `signals`/pattern id (`data/patterns.yaml`) to rank hits, and read a candidate's `eligibility:` / `interactions:` before recommending (respect `incompatible-with`; follow `depends-on` to the producer case first). A synonym won't hit these fields (they store canonical terms only) — that is fine, because the free-text grep already found the case; never emit `no-match` from an empty field grep. Legacy (not-yet-migrated) cases have no frontmatter — for those, fall back to the family index tables. When adding or editing a migrated case, keep the contract by hand: frontmatter values must be canonical terms from `data/tags.yaml` (never synonyms), and case↔pattern pointers must stay bidirectionally consistent (`patterns:` in the case ↔ `instances:` in `data/patterns.yaml`). ### Consultation trace (machine-parseable — always emit) Every consultation MUST end with exactly ONE trace line in your visible reply text, as soon as the Match step resolves: CASEBOOK: matched=<family>/<case-slug> confidence=<high|medium|low> adapted="<one-line adaptation>" or, when no precedent fits: CASEBOOK: no-match query="<bottleneck class / signals you searched for>" `<case-slug>` is the case file name without `.md`. Emit the line even when the consultation is a dead end: it is the join key for automated audit trails (which precedents were consulted vs cited vs hallucinated), and the no-match rate is the casebook's coverage metric for maintainers. One line per consulted question; never summarize multiple matches into one line. A `no-match` line asserts your free-text recall grep over the whole case files (Match step 2) turned up nothing relevant — it must never be emitted merely because a canonical-field grep returned empty. ## Case Families — routing table Open the family **index** relevant to your classified situation, then drill into a single case file from its case table (each family is a directory of one-file-per-case behind an `index.md` of patterns + a case-picker table). | Family | Index | Covers | |--------|-------|--------| | Runtime / execution | [references/runtime-execution/](references/runtime-execution/index.md) | Overlap scheduler, PDL, CUDA graphs (piecewise/padding, split-op-for-capture), multi-stream overlap, MLA KV-cache reuse & activation freeing, auxiliary-cache management, online-EPLB overlap, chunked prefill (aligned auxiliary), sparse-attention path selection, host-overhead & sync-free, batching/scheduler knobs, speculative decoding / MTP | | Kernel & fusion | [references/kernel-and-fusion/](references/kernel-and-fusion/index.md) | Op/epilogue fusion (AR+residual+norm+quant, add+norm+quant, QK-norm+RoPE, pre-pass folding, data-movement+quant), fused attention & MLA kernels, sparse-MLA top-k attention & top-k selection kernels, MoE grouped-GEMM backends (trtllm-gen / DeepGEMM / MegaMoE), low-precision GEMM (FP8 block-scale / W4A8 / NVFP4), ranking-only precision, routing kernels, custom Triton/CuTe/TileIR, GEMM tactics | | Communication | [references/communication/](references/communication/index.md) | EP all-to-all (DeepEP, low-precision dispatch/combine), TP AllReduce (MNNVL two-shot kernel, UserBuffers / symmetric memory, shape-aware autotune), collective kernel & strategy selection | | Case schema + template | [references/case-template.md](references/case-template.md) | The field schema and a worked example for adding cases | Many runtime/kernel/communication cases were distilled from the TRT-LLM DeepSeek-R1/V3 serving stack (MLA attention, fine-grained MoE, MTP, attention-DP + expert-parallel), where these levers cluster — but each is recorded as a **transferable pattern** (see *Generalizes to*); match on signals, not on the DeepSeek origin. Each carries a `Commits` line so you can `git show` the source. ### Quick index — bottleneck signal → where to look Routing shortcut once the bottleneck is classified. Match the signal, open the family index, then match a case's **Applies when** / **Generalizes to** in its case table and open that case file. | Profile signal | Bottleneck | Family → candidate patterns | |---|---|---| | GPU idle between steps; host prep on critical path | launch / host | runtime → overlap scheduler · move per-step bookkeeping into C++/fused op · piecewise CUDA graph · CUDA-graph padding | | Many small **dependent** kernels, SM≥90 | launch | runtime → PDL · kernel → mega-fuse MoE / fuse collective epilogue | | Residual + Norm (+quant) chain of small kernels | memory / launch | kernel → fuse AR epilogue · fuse local add+norm+quant · QK-Norm+RoPE | | AllReduce / all-to-all a large share at TP/EP>1 | communication | communication → DeepEP · low-precision dispatch/combine · MNNVL two-shot kernel · UserBuffers · shape-aware autotune | | Low MFU under data-parallel with ragged load | host / compute | runtime → eliminate attention-DP padding · CUDA-graph padding | | KV reads dominate decode (long ctx / high concurrency) | memory | kernel → FP8 MLA KV · runtime → MLA KV-cache reuse · free MLA intermediates | | Sparse-attention model (DeepSeek V3.2 / DSA): full-seq attention wasteful; lightning-indexer + top-k on the hot path | compute / launch / memory | kernel → sparse-MLA top-k attention · specialize top-k selection kernel · ranking-only TF32 · fuse data-movement+quantize · runtime → skip sparse when short-seq degenerate · chunked prefill (aligned auxiliary) · auxiliary cache in KV manager · split custom op for piecewise capture | | MoE grouped-GEMM dominates the step | compute | kernel → trtllm-gen FP4 MoE · mega-fuse MoE · HW-matched low-precision GEMM · optimize routing kernel | | Expert load imbalanced across EP ranks | comm / sync | runtime → online-EPLB + overlap rebalance | | Spec-decode accept rate low / draft forward exposed | compute / launch | runtime → relaxed acceptance · two-model MTP-Eagle overlap | | OOM caps batch / KV budget | memory | runtime → free MLA intermediates · kernel → low-precision GEMM/KV | ## Case Schema Every case records these fields (see `references/case-template.md` for the canonical form): - **Commits** *(optional)* — primary `<hash> subject (#PR)` plus folded-in `related:` follow-ups, when the case is distilled from specific commits, so a reader can `git show` the source. Omit when there is no upstream commit. - **Applies when** — bottleneck class + signals (model arch, hardware/SM, workload shape, current config) that make the case relevant. - **Counter-signals** — when NOT to apply: auto-disable regimes, degenerate shapes, negligible-share workloads, unmet requirements. Check this before recommending a matched case. - **Mechanism** — why it helps, in one or two lines. - **Generalizes to** — the transferable *pattern* this case instantiates and the adjacent situations it carries to (other model/arch, neighbouring op-chains, different knob values), plus what to change when adapting. This is what an agent matches on when it does **not** hit the exact instance — the casebook's main job. Match on this pattern, not the case title. - **Apply via** — the exact config knob and/or the specialist/skill to delegate implementation to. Never a hand-written runnable config invented here. - **Expected effect** — qualitative direction and the metric that should move. Quantitative deltas only when measured (cite the run) — see Principles. - **Accuracy risk** — `lossless`, `lossy`, or `mixed` (a case bundling moves of differing risk — it must state which part is lossy). Lossy cases require an on-disk accuracy record plus a rollback criterion before being promoted as a "best" config (mirrors the perf-sweep correctness gate). - **Verify** — what to measure to confirm the win and (for lossy) parity. - **Rollback** — how to revert and the regression trigger that mandates it. - **Prior art** — pointers to the owning skill, TRT-LLM repo docs, or PRs. ## Principles 1. **Adapt, don't copy.** Cases are precedents. Knob values, hardware constraints, and model arch differ — re-derive numbers from the nearest checked-in config and the model guide. Treat any value carried over from a case as unverified until measured here. 2. **Never fabricate numbers.** Quantitative before/after figures must come from real profiling/benchmark output, with the source cited. A case states the *direction* of effect and the *metric to watch*; it does not assert a speedup that was not measured. Do not present casebook expectations as achieved results. 3. **Respect the accuracy gate.** Optimizations split into: - **Lossless** (output-equivalent): scheduling/batching/graph knobs, and backend *selection* (`attn_backend`, `moe_config.backend` — same math, different implementation). Safe to evaluate on throughput/latency alone. - **Lossy** (output-affecting): KV-cache quant (`kv_cache_dtype` fp8/int8/ nvfp4), weight/GEMM quant (`quant_algo`), low-precision MoE combine, low-precision EP dispatch/combine, **relaxed spec-decode acceptance** — and **PDL** (`TRTLLM_ENABLE_PDL`), which changes inter-kernel ordering/visibility and has produced real NaN/accuracy regressions per kernel (verify per kernel). Spec/MTP is output-equivalent *by design* but can drift on acceptance/draft bugs, so verify on first enable. Lossy wins need an accuracy record + rollback criterion, never promoted as "best" without it. This split matches `perf-sweep-workflow` `core/gate.py` — keep them aligned. 4. **One change at a time, measure each.** Combined changes hide regressions and confound attribution. Roll back on >5% slowdown or any accuracy regression outside tolerance. 5. **Interface facts are as-of their pinned commit.** Knob names, config bounds, file paths, and function names in a case describe the code at the case's `commits:` — they are historical anchors, not present-tense truths. Before acting on them (especially machine-evaluable `eligibility:` entries), re-verify against YOUR TRT-LLM checkout; cases point to where the live value lives (e.g. a `file::symbol` guard). A mismatch means the code moved since the pin — prefer the live source. Mechanism and pattern statements ("why it helps") are not version-bound; only interface facts are. ## Adding a New Case After a verified win (or an instructive failure): 1. Pick the family directory (`references/<family>/`); if none fits, propose a new family dir + `index.md` and add a row to the routing table above. 2. Create `references/<family>/<slug>.md` from the schema in `references/case-template.md` — H1 title + the breadcrumb line + every field bullet — then add one row to that family index's case table (Case → file, Applies-when, Generalizes-to, Risk), and, if it instantiates a listed pattern, link it from that pattern's `_(Instance: …)_`. Put real measured deltas with the source run; otherwise write "measured Δ to be recorded from <run>". 3. Keep it a *decision precedent* — applicability, mechanism, knob/specialist, risk, verification, rollback. Fill **Generalizes to** with the pattern the case instantiates and 2–4 adjacent situations it carries to: this is what lets an agent reuse the case when its situation is a *variation*, not the exact instance (match on the pattern, not the title). Do **not** re-explain subsystem architecture (how MoE/attention/KV cache work); link to the TRT-LLM repo developer guides for that (see `docs/design/agent_toolkit_organization.md` §2.3). 4. Cross-link the owning specialist/skill so implementation stays delegated. ### Ingestion discipline (agent-scanned corpus) This corpus is scanned and written by agents. Selection — "is this a transferable optimization precedent?" — stays with the writing agent's judgment; the rules below target known agent failure modes (fabricated detail, plausible over-generalization, cross-run divergence), not judgment. - **Trace, don't recall.** Every number in a case (bounds, caps, shapes, dims) must be traceable to a specific line in a cited commit's diff or the pinned source; every model/arch applicability claim must be checked against the modeling source (e.g. the routing-method enum), never inferred from model-family resemblance. If you didn't look it up, don't write it. - **Fold vs. new.** A follow-up PR that iterates the *same decision* (same pattern, same knob/kernel surface) folds into the existing case as a `related:` commit — a PR series refining one optimization is ONE case. A new case requires new applicability signals or a new pattern. - **Stub threshold.** If the four core slots (applicability signals, mechanism, transferable pattern, apply-via) can be at least roughly filled, record the case with `maturity: stub` so it enters the match surface. If not even roughly — skip it entirely; do not park half-guesses in the corpus. - **Verify before landing.** A case is added or upgraded only after an independent fact-check pass against its cited commits (quantitative claims, knob names, file paths, model-applicability claims). The writing agent's recall is not evidence. - **Scan cursor.** Sweeps of TRT-LLM main record the last commit scanned here and resume from it. Deduplicate against the corpus by grepping the hash across case `commits:`/`Commits:` fields before distilling. Current cursor: *not yet recorded — the pre-pilot corpus was swept ad hoc; set this at the next sweep.* ## Relationship to Other Skills - **perf-analysis** classifies the bottleneck → this casebook supplies candidate optimizations for that class. - **perf-optimization** prioritizes and routes → consult this casebook for prior art and the right specialist before delegating. - **perf-sweep-workflow** chooses configs to try → cases inform hypotheses; the deterministic core still validates and the challenger still gates. - **Implementation** is always delegated to the specialist/skill named in the case (kernel-*, perf-torch-cuda-graphs, perf-torch-sync-free, perf-host-optimization, trtllm-serve-config-guide, etc.).
Ver en GitHub