geko-hipblaslt-tuning · git:20261105.0d95dc2 · 2026-11-05 · sha256 2eb24b86248b2281

geko-hipblaslt-tuning git:20261105.0d95dc2A

Immutable. This exact content never changes and is served at /api/v1/blob/2eb24b86248b2281.

---
name: geko-hipblaslt-tuning
description: >-
  Set up and run geko hipBLASLt GEMM tuning for DeepSeek-V4.1-Flash + vLLM/AgentX serving on AMD gfx950
  (MI355X), then verify and interpret the result. Use when installing geko in a container, applying the
  hipBLASLt 1.5.0 msgpack + scale_type patches, building a merged device library, running geko --tune,
  confirming the tuned kernels actually fire in serving, or deciding whether hipBLASLt tuning is the right
  lever (vs aiter). Triggers: "install geko", "geko --tune", "hipBLASLt tuning", "tune decode GEMMs",
  "verify tuned kernels fire", "geko full_libs", "why is my tune flat".
allowed-tools: Bash(docker *), Bash(sbatch *), Bash(squeue *), Bash(scancel *)
---

# geko hipBLASLt tuning for DSV4.1-Flash serving (gfx950)

Tune the critical decode hipBLASLt GEMMs for DeepSeek-V4.1-Flash on vLLM/AgentX, deploy them, and **prove the
tuned kernels are actually used** — apple-to-apple against the stock library.

## When to use
- Installing geko into a fresh ROCm vLLM container and running `geko --tune`.
- Hitting `geko --tune` end-to-end errors (msgpack / scale_type — see the 3 patches below).
- A tune produced big GEMM-level uplift but **no e2e change** → verify the kernels fire + check the budget.
- Deciding whether hipBLASLt tuning is worth it for this workload (short answer below).

## Decision first: is hipBLASLt tuning even the lever?
In the GPU-kernel-time budget for DSV4.1-Flash AgentX serving, **hipBLASLt `Cijk_*` is a small share**. Most
of the cost is the **aiter** umbrella (MoE experts `mfma_moe*_afp8_wfp4`, dense `_mxfp8_linear`) plus TP
all-reduce. So geko hipBLASLt tuning is **flat end-to-end at every concurrency even with tuned kernels
verified firing (and faster at GEMM level)**. If the goal is e2e throughput, tune **aiter** (its native autotuner),
not hipBLASLt. Still proceed below if you specifically want the hipBLASLt tune + a rigorous usage proof.

## The 3 critical `geko --tune` patches (hipBLASLt 1.5.0)
`geko --tune` fails e2e without these. Idempotent; resolve `$TENSILE` (tensilelite `Tensile/` dir) and
`$GEKO` (`python3 -c "import geko,os;print(os.path.dirname(geko.__file__))"`) first.
1. **Tensile/Tensile.py** — `--library-format` default `yaml → msgpack` (1.5.0 loads **msgpack** device libs).
2. **Tensile/GenerateSummations.py** — hardcoded `--library-format=yaml → msgpack` (+ `Common/GlobalParameters.py` default).
3. **geko/library/library.py** — `create_bench_input()` must set `common["scale_type"] = compute_type`
   (1.5.0 bench requires `scale_type`). Already present at ~line 427 in recent geko; verify, add only if missing.

Full copy-paste block + why-each: **[references/install.md](references/install.md)** (Step 3).

## Workflow (one change per step; validate each)
1. **Install** geko in the container — `[references/install.md](references/install.md)` (and run `scripts/geko_install.sh` inside the container; needs `apt install llvm-14-dev libomp5-14` for the client build).
2. **Profile the decode shapes** at your TARGET concurrency: launch with `--enforce-eager` + `HIPBLASLT_LOG_MASK=32`, drive the load, take the dominant M among K=5120 GEMMs. **Copy the exact types verbatim** — DSV4.1 decode is bf16-in / **f32-out** (`c_type=d_type=f32_r`); a bf16-out workload silently never fires (PITFALL #0).
3. **Tune**: `geko --tune --workload-log <shapes.yaml>` → `full_libs`. Merge into the full stock gfx950 logic and rebuild via `TensileCreateLibrary` → a complete `merged_devlib` (deploying `full_libs` alone is a sparse library that regresses). See `[references/tune-run.md](references/tune-run.md)`.
4. **Deploy + serve**: `HIPBLASLT_TENSILE_LIBPATH=<merged_devlib>/library/gfx950` on BOTH baseline(stock) and tuned so only the library differs.
5. **Verify + record** — below.

## Verifying the tuned kernels actually fire (do this every time)
Two independent checks — the deterministic one is complete, the trace one is a cross-check:
- **Deterministic selection (window-independent):** `OUTDIR=<run> scripts/verify_selection.sh` benches each kept shape merged-vs-stock with the exact serving types. Healthy = `tuned-selected = N of N`.
- **Serving-trace firing:** `python3 scripts/verify_kernels_in_trace.py` — the exact `kernel_tuned` names appear as `Cijk_*` events in the tuned trace, 0 in baseline. A partial count is fine (short window). **Do NOT** use the bare `_UserArgs_` tag — stock kernels carry it too.

Worked result (f32 workload): every kept shape tuned-selected (`N of N`), a partial count in the trace → PASS; e2e flat. With the wrong (bf16-out) workload: none selected — the canonical signature-mismatch failure.

## Pitfalls & scale gotchas (read before a long run)
- **Signature-exact match** (PITFALL #0): geko kernels are `Equality` — they fire only on an exact
  `(M,N,K,transA/B,a/b/c/d_type,compute)` match. Tune the M of your target concurrency **and** the real
  output dtype. Details + the dtype trap: **[references/pitfalls.md](references/pitfalls.md)**.
- **A tune degrades the node → serve on a FRESH node** (same-node server crashes at cudagraph capture).
- VRAM drain between serving phases; NFS build races / stale `build/`; run scripts from `/tmp`; bad nodes
  (`/dev/dri`); `pkill -f geko` self-kill. All in **[references/pitfalls.md](references/pitfalls.md)**.
- Container must be `--ipc=host`; client build needs LLVM. Known issues: **[references/issues.md](references/issues.md)**.

## Files
- `references/install.md` — container + geko install + the 3 patches (Steps 1–3).
- `references/tune-run.md` — smoke, full tune, merged-lib build, save/deploy (Steps 4–6).
- `references/pitfalls.md` — PITFALL #0 (M + output dtype), verification, scale gotchas, "is geko the lever".
- `references/issues.md` — known setup issues + a reference run.
- `scripts/geko_install.sh`, `scripts/verify_selection.sh`, `scripts/verify_kernels_in_trace.py`
  (set `WS` to the geko_agentx workspace root; run inside the container).