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.

Quellinformationen

Repository
NVIDIA/TensorRT-LLM
Letzte Quellaktivität
22. September 2026 um 07:12
Erkannte Sprache von SKILL.md
Englisch
Sterne
14.826
Forks
2.823

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
49 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
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.).
Auf GitHub ansehen