Skip to content

perf(dflash): add MMID dispatch telemetry#519

Open
cheese-cakee wants to merge 3 commits into
Luce-Org:mainfrom
cheese-cakee:perf/mmid-dispatch-telemetry
Open

perf(dflash): add MMID dispatch telemetry#519
cheese-cakee wants to merge 3 commits into
Luce-Org:mainfrom
cheese-cakee:perf/mmid-dispatch-telemetry

Conversation

@cheese-cakee

@cheese-cakee cheese-cakee commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a default-off DFLASH_MMID_TELEMETRY diagnostic that reports, for every
MUL_MAT_ID (MoE expert matmul): the dispatch path chosen, the MMVQ variant
taken, and per-node CUDA-graph compatibility. It exists to make the grouped-MMID
work and the MoE graph-capture gate measurable without a debugger or a custom
build. Zero cost and no behavior change when the variable is unset.

Changes

  • ggml/src/ggml-cuda/ggml-cuda.cu (ggml_cuda_mul_mat_id): event=dispatch
    line naming the path taken (mmvq / mmvf / mmq / mmf / sync_fallback)
    with type, width (ne2), pairs, expert count, top_k, and the MMVQ ceiling.
  • ggml/src/ggml-cuda/ggml-cuda.cu (ggml_cuda_graph_check_compability):
    event=graph line for every MUL_MAT_ID node with the MMVQ/MMQ eligibility
    used to decide graph capture. Reports mmvq_max=0 for non-quantized nodes.
    The scan's early exit is skipped while telemetry is on so a node that disables
    graphs does not suppress later nodes' lines.
  • ggml/src/ggml-cuda/mmvq.cu (ggml_cuda_mul_mat_vec_q): event=mmvq line
    reporting the variant that actually runs: grouped, single (width-1
    single-column MMVQ), or, for the ungrouped multi-token path, the downstream
    kernel mul_mat_vec_q_switch_type selects (moe / tokenwise / generic)
    with a reason.
  • server/docs/ENVIRONMENT.md: document the variable in the table and the
    generated inventory.

How it works

The flag is read via function-local static getenvs (evaluated once each), and
every emit site is guarded by one, so an unset flag is a predictable no-op. The
event=mmvq variant is derived from the same env statics
mul_mat_vec_q_switch_type uses, so the label matches the kernel that runs. When
the flag is off the graph-compatibility scan keeps its original early exit, so the
graph-capture decision and its cost are unchanged; only with the flag on does it
keep scanning to log every node. The one always-on change (from the base commit)
is hoisting the mmvq_mmid_max computation, whose value is identical where used.
Output is byte-identical with the flag set or unset.

Performance

None intended. Diagnostics only; no kernel selection or dispatch logic changes.

Limitations

  • CUDA/HIP ggml-cuda backend only.
  • Plain stderr text lines, not a structured/machine-readable sink.
  • event=graph lines are emitted from the graph-compatibility check, so they
    appear only when CUDA graphs are enabled for the graph.

Verification

Hardware: RTX 4050 Laptop GPU (Ada, sm_89), CUDA 12.6 (nvcc V12.6.85), WSL2
Ubuntu, g++ 13.3.0. ggml built with GGML_CUDA=ON GGML_CUDA_GRAPHS=ON, arch
sm_89 (graphs on so the event=graph path is compiled in).

A standalone harness issues MUL_MAT_ID at widths {1, 2, 8} for Q4_K/Q6_K plus a
non-quantized (F16) node, across the dispatch modes, all with
DFLASH_MMID_TELEMETRY=1. Representative captured lines:

# width-1: single-column MMVQ, not the multi-token launch (any mode)
[dflash-mmid] event=mmvq type=q4_K width=1 pairs=8 variant=single
# grouped on (DFLASH_MMID_GROUPED=1 / CUDA default)
[dflash-mmid] event=mmvq type=q4_K width=8 pairs=64 variant=grouped
# ungrouped, dedicated MoE kernel (DFLASH_MMID_GROUPED=0)
[dflash-mmid] event=mmvq type=q4_K width=8 pairs=64 variant=moe reason=flag_off
# ungrouped, tokenwise (DFLASH_CUDA_MMVQ_MOE_TOKENWISE=1)
[dflash-mmid] event=mmvq type=q4_K width=8 pairs=64 variant=tokenwise reason=flag_off
# ungrouped, generic per-ncols (DFLASH_CUDA_MMVQ_MOE_KERNEL=0)
[dflash-mmid] event=mmvq type=q4_K width=8 pairs=64 variant=generic reason=flag_off
# one graph, F16 node (disables graphs) BEFORE a Q4_K node: both are logged
[dflash-mmid] event=graph name=node_0 type=f16  ne11=1 width=8 mmvq_max=0  mmvq_ok=0 mmq_ok=0 node_eligible=0
[dflash-mmid] event=graph name=node_1 type=q4_K ne11=1 width=8 mmvq_max=16 mmvq_ok=1 mmq_ok=1 node_eligible=1

Assertions, all passing: the variant label matches the mode selected in each run
(grouped / moe / tokenwise / generic), variant=single for width-1, and
variant=legacy_moe never appears (0 occurrences); in a graph where the F16 node
precedes the Q4_K node, both emit event=graph (the later node is no longer
dropped by the compatibility scan's early exit), with the F16 node reporting
mmvq_max=0 and the Q4_K node mmvq_max=16. The diagnostic writes only to stderr
and touches no tensor data or dispatch decision, so generated output is unchanged
whether the variable is set or unset.

@cheese-cakee cheese-cakee marked this pull request as ready for review July 13, 2026 21:19

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 3 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread server/docs/ENVIRONMENT.md
Comment thread server/deps/llama.cpp/ggml/src/ggml-cuda/mmvq.cu Outdated
Comment thread server/deps/llama.cpp/ggml/src/ggml-cuda/ggml-cuda.cu
@cheese-cakee cheese-cakee marked this pull request as draft July 13, 2026 21:27
…uant paths

- mmvq.cu: width-1 MUL_MAT_ID now reports variant=single instead of
  variant=legacy_moe. The single-column MMVQ case is not the multi-token
  legacy MoE launch, so the old label conflated single-token decode with
  grouping-rejected batches.
- ggml-cuda.cu: graph telemetry reports mmvq_max=0 for non-quantized nodes
  instead of the type-independent ceiling get_mmvq_mmid_max_batch returns,
  matching the mmvq_ok=0 eligibility already reported for those nodes.
- ENVIRONMENT.md: add DFLASH_MMID_TELEMETRY to the generated inventory list.

Diagnostics stay default-off; no inference-path behavior change.
@cheese-cakee cheese-cakee marked this pull request as ready for review July 14, 2026 17:34

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 3 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread server/deps/llama.cpp/ggml/src/ggml-cuda/mmvq.cu Outdated
Comment thread server/deps/llama.cpp/ggml/src/ggml-cuda/ggml-cuda.cu
- mmvq.cu: the ungrouped MUL_MAT_ID path now labels the kernel that actually
  runs (moe / tokenwise / generic), derived from the same env flags
  mul_mat_vec_q_switch_type reads, instead of always variant=legacy_moe. The
  DFLASH_CUDA_MMVQ_MOE_TOKENWISE and DFLASH_CUDA_MMVQ_MOE_KERNEL modes are now
  reported accurately.
- ggml-cuda.cu: the graph-compatibility scan no longer breaks on the first
  graph-incompatible node when telemetry is on, so event=graph is emitted for
  every MUL_MAT_ID node. The early exit is preserved when telemetry is off, so
  the graph-capture decision is unchanged either way.

Diagnostics stay default-off; no inference-path behavior change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants