-
Notifications
You must be signed in to change notification settings - Fork 292
perf: HiCache tuning for glm5.2-fp4-b300-sglang-agentic-mtp / 性能:glm5.2-fp4-b300-sglang-agentic-mtp HiCache 调优 #2651
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
08c8e43
b9e7a46
d687864
b54bc0b
d42d6a3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -59,33 +59,35 @@ if require_agentic_kv_offload_backend hicache; then | |
| # conc 8 (TP8) / 64 (DP8) and the radix hit rate collapses to <0.1 | ||
| # against a ~0.97 theoretical ceiling, so every turn re-prefills its | ||
| # whole history; the host tier restores those hits at C2C bandwidth. | ||
| # GLM-5.2 is DSA/MLA-family (attention_backend=dsa): every rank holds | ||
| # complete per-token KV (169.98 GB device pool per rank, replicated on | ||
| # all 8 ranks), so host capacity is controlled through the host/device | ||
| # token-capacity ratio like the DSv4 recipe, NOT a per-rank | ||
| # --hicache-size. A GB-based size of TOTAL_CPU_DRAM_GB/TP pinned the | ||
| # whole 0.80-DRAM budget (8 x 299 GB) at init on top of 465 GB of | ||
| # weights and OOM-killed the node (run 29678598595); DSv4's own | ||
| # ratio=2 default pins 2 x 170 GB x 8 = 2.7 TB here and OOMs too | ||
| # (GLM-5.2's device pool is far larger than DSv4's). Fractional 0.75 | ||
| # = ~128 GB/rank = ~1.0 TB total, matching the cluster's proven ~1 TB | ||
| # host-pool envelope; validated on-node 2026-07-19 (boot + 4.2M-token | ||
| # overflow bench forcing eviction through the DSA KV+INDEXER pools). | ||
| # The ratio is relative to the device pool, so MTP's slightly smaller | ||
| # device pool (the nextn layer takes its own KV) only shrinks it. | ||
| DEFAULT_HICACHE_RATIO=0.75 | ||
| HICACHE_RATIO="${HICACHE_RATIO:-$DEFAULT_HICACHE_RATIO}" | ||
| if awk -v r="$HICACHE_RATIO" -v cap="$DEFAULT_HICACHE_RATIO" 'BEGIN { exit !(r > cap) }'; then | ||
| echo "Error: HICACHE_RATIO=$HICACHE_RATIO exceeds configured limit $DEFAULT_HICACHE_RATIO" >&2 | ||
| # GLM-5.2 is DSA/MLA-family (attention_backend=dsa): every TP rank holds | ||
| # complete per-token KV. Use an absolute main-pool size so all points get | ||
| # the same host token capacity even if the HBM pool changes. In SGLang | ||
| # v0.5.16, --hicache-size directly sizes only the target KV host pool; | ||
| # the DSA indexer and MTP draft pools inherit its token-slot count and use | ||
| # their own smaller bytes/token. A 270 GB target pool was measured as | ||
| # 270.00 + 61.88 + 3.46 = 335.34 GB/rank, or 2.683 TB across TP8, with | ||
| # 6,009,728 slots in each pool. This is larger than the ratio-1.50 c16 | ||
| # configuration whose full run improved from 76.26 / 10,311.95 to | ||
| # 100.49 tok/s/user / 12,120.27 tok/s/GPU and retained ~1.74 TiB minimum | ||
| # node MemAvailable. | ||
| DEFAULT_HICACHE_SIZE=270 | ||
| MAX_HICACHE_SIZE=270 | ||
| HICACHE_SIZE="${HICACHE_SIZE:-$DEFAULT_HICACHE_SIZE}" | ||
| if ! [[ "$HICACHE_SIZE" =~ ^[0-9]+$ ]]; then | ||
| echo "Error: HICACHE_SIZE must be a positive integer, got $HICACHE_SIZE" >&2 | ||
| exit 1 | ||
| fi | ||
| if awk -v s="$HICACHE_SIZE" -v cap="$MAX_HICACHE_SIZE" 'BEGIN { exit !(s <= 0 || s > cap) }'; then | ||
| echo "Error: HICACHE_SIZE=$HICACHE_SIZE must be in (0, $MAX_HICACHE_SIZE]" >&2 | ||
| exit 1 | ||
| fi | ||
| HICACHE_WRITE_POLICY="${HICACHE_WRITE_POLICY:-write_back}" | ||
| HICACHE_IO_BACKEND="${HICACHE_IO_BACKEND:-direct}" | ||
| HICACHE_MEM_LAYOUT="${HICACHE_MEM_LAYOUT:-page_first_direct}" | ||
| echo "HiCache CPU tier: ratio=$HICACHE_RATIO, capacity=${TOTAL_CPU_DRAM_GB} GB, write_policy=$HICACHE_WRITE_POLICY, io_backend=$HICACHE_IO_BACKEND, mem_layout=$HICACHE_MEM_LAYOUT" | ||
| echo "HiCache CPU tier: conc=$CONC, target_size=$HICACHE_SIZE GB, total_capacity=${TOTAL_CPU_DRAM_GB} GB, write_policy=$HICACHE_WRITE_POLICY, io_backend=$HICACHE_IO_BACKEND, mem_layout=$HICACHE_MEM_LAYOUT" | ||
| CACHE_ARGS=( | ||
| --enable-hierarchical-cache | ||
| --hicache-ratio "$HICACHE_RATIO" | ||
| --hicache-size "$HICACHE_SIZE" | ||
| --hicache-write-policy "$HICACHE_WRITE_POLICY" | ||
|
Comment on lines
+75
to
91
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 The 270 GB/rank Extended reasoning...What the bug is: |
||
| --hicache-io-backend "$HICACHE_IO_BACKEND" | ||
| --hicache-mem-layout "$HICACHE_MEM_LAYOUT" | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟡 sweep:BEGIN { exit !(.||.) }
The awk subprocess here performs a plain-integer bounds check that bash can do natively, since HICACHE_SIZE is already validated as a non-negative integer by the
^[0-9]+$regex on the preceding line. E.g. inbenchmarks/single_node/agentic/glm5.2_fp4_b300_sglang_mtp.sh:80,awk -v s="$HICACHE_SIZE" -v cap="$MAX_HICACHE_SIZE" 'BEGIN { exit !(s <= 0 || s > cap) }'can become[ "$HICACHE_SIZE" -eq 0 ] || [ "$HICACHE_SIZE" -gt "$MAX_HICACHE_SIZE" ], matching the native-bash pattern already used by sibling recipes (e.g.qwen3.5_fp4_b200_sglang_mtp.sh:61).Extended reasoning...
The awk invocation at
benchmarks/single_node/agentic/glm5.2_fp4_b300_sglang_mtp.sh:80—awk -v s="$HICACHE_SIZE" -v cap="$MAX_HICACHE_SIZE" 'BEGIN { exit !(s <= 0 || s > cap) }'— is a leftover from the oldHICACHE_RATIOcheck this PR replaces. That old check validated a fractional value (DEFAULT_HICACHE_RATIO=0.75), and bash has no native floating-point comparison, so shelling out to awk was the right call there.This PR switches the variable to an integer-only
HICACHE_SIZE, and critically, the line immediately above the awk call (benchmarks/single_node/agentic/glm5.2_fp4_b300_sglang_mtp.sh:76) already gates entry with[[ "$HICACHE_SIZE" =~ ^[0-9]+$ ]], so by the time execution reaches the awk line,HICACHE_SIZEis guaranteed to be a plain non-negative integer string. At that point the awkBEGIN { exit !(s <= 0 || s > cap) }reduces to a pure integer bounds check, which is exactly what bash's[ ]/testinteger comparison operators (-eq,-gt, etc.) are built to do without spawning a subprocess.Step-by-step proof:
[[ "$HICACHE_SIZE" =~ ^[0-9]+$ ]]fails (and the script exits 1) for anything that is not a sequence of digits — no negative numbers, no decimals, no non-numeric strings can reach line 80.s(=HICACHE_SIZE) andcap(=MAX_HICACHE_SIZE).awk 'BEGIN { exit !(s <= 0 || s > cap) }'with two plain integers is behaviorally identical to[ "$HICACHE_SIZE" -eq 0 ] || [ "$HICACHE_SIZE" -gt "$MAX_HICACHE_SIZE" ](bash'stestdoes base-10 integer comparison for these operators, with no octal reinterpretation of leading zeros, so there is no edge case where the two diverge for a digit-only string).qwen3.5_fp4_b200_sglang_mtp.sh:61andqwen3.5_fp4_b300_sglang_mtp.sh:61both doif [ "$HICACHE_SIZE_GB" -lt 1 ] || [ "$HICACHE_SIZE_GB" -gt "$MAX_HICACHE_SIZE_GB" ]. Theawk BEGIN{exit ...}idiom appears nowhere else inbenchmarks/except this file and its B200 sibling's fractional-ratio check (where awk is still required).Existing code does not prevent this because nothing here is incorrect — the awk call works fine, it is just an unnecessary subprocess spawn and a less-idiomatic form for what is now a trivial integer comparison, carried over unchanged from the pre-PR fractional-ratio logic. The impact is negligible (one extra
fork/execat script startup, no correctness or performance issue in the benchmark run itself), so this is a pure readability/cleanliness nit, not something that blocks merging.Fix: replace the awk call with the native bash form shown above. As a secondary, weaker observation,
DEFAULT_HICACHE_SIZEandMAX_HICACHE_SIZE(lines 73-74) are both hardcoded to the literal270; the prior code avoided this duplication by reusingDEFAULT_HICACHE_RATIOitself as the cap. This is a minor, defensible stylistic choice (separating "default" from "hard cap" is a reasonable pattern) rather than a bug, but collapsing them to one constant would remove the duplication if desired.