examples(glm5.2 1P1D): accuracy evaluation, Mooncake trace replay, per-role torch profiling - #140
Open
ChengYao-amd wants to merge 4 commits into
Open
examples(glm5.2 1P1D): accuracy evaluation, Mooncake trace replay, per-role torch profiling#140ChengYao-amd wants to merge 4 commits into
ChengYao-amd wants to merge 4 commits into
Conversation
ChengYao-amd
requested review from
JohnQinAMD,
jiejingzhangamd,
limou102 and
xiaobochen-amd
as code owners
August 27, 2026 03:30
ChengYao-amd
force-pushed
the
dev/yaoc/profile
branch
from
August 28, 2026 07:55
b1f7b20 to
a7728e3
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
examples(glm5.2 1P1D): accuracy evaluation, Mooncake trace replay, per-role torch profiling
Branch
dev/yaoc/profile→main· Base96bfe72(0 behind) · 18 files, +1975 / −25Summary
Three opt-in capabilities for the GLM-5.2 1P1D kit, plus one sglang DSA patch
that fixes a warm-up crash on the v0.5.17 engine base.
engine/lm_eval.shengine/trace_replay.shengine/capture.shpatches/sglang_dsa/dsa_indexer_idle_metadata.diffServing defaults are unchanged. With
PROFILE_*andAIPERF_TRACEunset,up → smoke → bench → downbehaves exactly as onmain.1. Accuracy
smokeproves the features are on andbenchproves the stack is fast; neitherreads an answer. MXFP4 weights,
fp8_e4m3KV, ROCm sparse attention, mooncakeKV transfer, EAGLE speculation and a shared radix cache are six independent ways
to serve fast, fluent, wrong tokens, all green in the existing checks.
lm_eval.shdrivessglang.test.run_eval, already inside the engineimage, over OpenAI
/v1/chat/completions. Nothing is installed into$CTR.probe(~40 s) →quick(GSM8K 200, ~2 min) →full(gsm8k+mixed_prefix_gsm8k, ~13 min).--thinking-mode glm-45is load-bearing: theleg runs
--reasoning-parser glm45, and without the matchingchat_template_kwargsevery eval scores 0.00 on a healthy deployment.tools/probe_accuracy.pygates the rest, because the failures it catchesproduce a number rather than an error. ~30 requests covering: both legs
registered,
contentactually arriving, the same question giving the sameanswer (not the same bytes — at
temperature=0completion lengths ranged214–289 tokens across ten identical repeats), and a shared prefix not changing
the answer behind it. That last check is the only one in the kit that can see a
radix-cache / kvd / kv-aware lookup return the wrong block.
tools/summarise_eval.pyputs a 95% Wilson interval on every score, and incompare mode estimates the interval of the difference directly (Newcombe)
rather than checking whether two intervals overlap — overlap is too
conservative and hides real regressions.
--gateexits non-zero on a drop.Calibration measured on
rocm/infera:sglang-v0.2.10/ MI355X: GSM8K 200 spans0.940–0.965 over six unchanged runs; GSM8K full 0.945, 95% CI [0.932, 0.956],
1314 scored;
mixed_prefix_gsm8k0.945 over 1299; prefix-reuse delta +0.000.2. Trace replay
bench.shsweeps--dataset-name random, so it has no shared prefix byconstruction.
trace_replay.shreplays a Mooncake trace through AIPerf at therecorded timestamps;
hash_idsexpand to real token blocks, so the radix cache,kvd and kv-aware routing are all on the path.
prepareis read-only: image, trace, tokenizer,AIPERF_OUTand router allchecked from the node that generates load, then an
analyze-traceshapereport.
runsends with--fixed-schedule.aiperf:0.12.0, 255 MB) — the engineimage ships Python 3.10 and AIPerf needs ≥ 3.11.
ignore_eos:trueby default: themooncake_traceloader setsmax_tokensfrom
output_lengthbut nomin_tokens, so a reasoning model emitting EOSearly would replay short. This makes decode-side numbers incomparable to
bench, which the README states.aiperf_compat/sitecustomize.py(commite43ae95) works around AIPerf0.12 sending existing local directories through
snapshot_download, whichHF_HUB_OFFLINE=1turns into a startup failure. Injected viaPYTHONPATHinto the AIPerf container only.
3. Profiling
Prefill and decode overlap in wall-clock time, so one trace cannot be split by
role afterwards — the router's role selector is what keeps them apart.
up.shgainsPROFILE_PREFILL/PROFILE_DECODE(both 0), which append--enable-profilingto the newROUTER_EXTRA_ARGS.start_router()flips the backendrust→pythonon that flag, becauselaunch_rust.pyraisesSystemExitrather than degrading. Throughput from aprofiling run is therefore not comparable to a normal one.
PROFILE_DECODE=1also setsCUDA_GRAPH=0on the decode leg. A replayedgraph is one opaque launch: measured 134 decode steps in a window with 1
carrying GPU operators. The cost is real (TPOT 35.6 → 137.2 ms), hence not a
default;
DECODE_CUDA_GRAPH=1overrides.start_container()gains two optional mounts:TRACE_OUT(same absolute pathinside and out, so traces need no
docker cp/SSH fetch) andINFERA_SRC(devoverlay at
/opt/infera:ro, asserted live by importinginferaafter start).capture.shverifies the bind mount withdocker inspectbefore profiling,probes the control plane with an invalid role (400 = enabled, 403 = not),
starts both roles from one in-container script so their windows are sub-ms
apart, pins
with_stack=false(SGLang defaults toTrue: 122 MB vs 14 MB perrank), stops with a single call, and polls
du -sbuntil the files stopgrowing.
LOAD_KIND=bench|trace_replaypicks where the load probe looks.4. DSA patch 05
EAGLE eager IDLE skips
draft_attn_backend.init_forward_metadata(), thendraft_forward()selects a per-step backend the generic IDLE runner neverupdated, so its first IDLE use raises:
The existing empty-
seq_lensguard returns the right tensor but sits hundreds oflines after
get_indexer_metadata()on v0.5.17. The patch returns the sameall-invalid top-k before the metadata lookup, keeping
_broadcast_indexer_topk_from_rank0since IDLE ranks still need the DPsynchronization primitive.
v0.5.17 / mi35x only — joins the
fullarm, marker count 7 → 8. The gfx942v0.5.16 arm is untouched. Upstream #32209
carries the same strategy for CUDA; #31683
widens the later guard, which is too late on this base. Both OPEN.
Commits
156e3e207063e1e43ae95b1f7b20Test plan
bash -nclean on all eight shell scripts;ruff format/ruff checkclean onthe three Python files; file modes match
engine/.Profiling run should show the router logging the
rust→pythonswap, thedecode leg logging
cuda_graph=0, both$TRACE_OUT/<ts>/{prefill,decode}/filling, and the flush stage reporting a stable byte count per role.