Repository navigation
hip flashnext: an eight-row verify window, so a lone stream's copies land up to seven tokens a round - #2730
hip flashnext: an eight-row verify window, so a lone stream's copies land up to seven tokens a round#2730gilby wants to merge 10 commits into
Conversation
|
GREEN at 8a95f64 — opencode-go/glm-5.3-flash as routed by Main (model id unverifiable); implementer model unverified. Host-verified with inert kernels through the build's own HIP engineModules wiring: the flashnext HIP family suite is 28 pass / 0 fail at this head, including the new eight-row snapshot pin. Red-first: reverting only max_window 8→4 fails exactly that test (27/1), nothing else in the family suite moves. Diff read: the width is one constant with max_depth following, shared rounds pinned to the CUDA shape by first_copy_rows = 4 via the lane core's existing first_rows rule, MTP cap untouched, extra device memory through the existing streamBytes(max_window) admission. No HIP device run on this host, so the lone-stream 7/round gain and the ~0.5 GiB at four streams are your hardware receipts; the queued matched A/B remains the final word on the shared-round cost. |
|
Thanks @gilby. Letting a lone stream's copies grow while shared rounds keep main's three-token shape is a neat use of the lane core's existing rule, and the gain on edit-style text with every arm token-equal is a strong result. Some asks:
|
|
Thanks @ashhart. All six points, on a new head
Receipt. One Strix Halo iGPU (gfx1151), fresh servers with the page cache dropped before each, in the order main, this, this, main; main is
Checks on Environment: Zig 0.17.0, |
|
Thanks @gilby. All six are done on
The merge of main changes only Thanks again for a careful change and a thorough receipt.
|
|
CI on |
|
Item 4, the cells on #2728 and #2730 together: posted at #2728 (comment). Every |
|
The raw files behind the receipt above (the tools' JSON for all four arms: |
2e51ea8 to
41707ea
Compare
|
Rebased onto today's main and pushed to your branch, keeping your seven commits as they were. The landing gate's lean check failed on it twice: main's
|
|
GPU check on the rebased head Kernel tests. Served sanity check after the rebase (one fresh server per build, page cache dropped before each,
Per-request token hashes of this head equal main's in all 42 requests, 0 unequal, 0 failed; concurrent equals alone and alone equals Binary sha256: main |
…o seven tokens a round
… copies grow to the window
…lane core's setup
… three-draft cap has a test
…ys under 600 lines on today's main
41707ea to
f7ac2a7
Compare
…p.zig stays within 600 lines
What this changes
Flash Next's HIP verify window held four rows (
cache.max_window = 4): the pending token and up to three drafts. MTP drafts at most three, so that was enough for the head, but it also capped copy drafts at three tokens a round, and on text that repeats its context (editing a file, rewriting a function) the copies land almost every token: a lone stream reached 3.77 tokens a round against a ceiling of 4. The window now holds eight rows, so a lone stream's copies grow (the lane core's own rule,2 × width + 1while a copy lands whole) up to seven tokens a round.Rounds shared by several streams keep three-token copies: the lane config sets
first_copy_rows = 4(as CUDA Flash Next sets it to its MTP chain), so a shared round's copy windows and a lone stream's first copy are exactly main's. Without it, every stream in a shared round proposed seven-token copies, and on 16 distinct prompts that cost 2% at two and four streams for no landed tokens.MTP drafts stay at three: the HIP head's cap is a named constant (
mtp_max_draftsinlanes.zig) the facts obey, and--mtp-draftsis still refused past 3; only copies use the extra width.A stream's window snapshots and n-gram input grow with the window: about 0.5 GiB of device memory at four streams on
unigilby/Qwen3.8-Flash-Next-oQ4e-HIP, counted in admission as before (streamBytesreadsmax_window). Four streams of 131,072 positions still fit on a 128 GB Strix Halo, and the cold cells below are unchanged.No kernel changes: the window kernels already take any row count, and the token-identity checks below run at the new width.
Issue: n/a.
Stacked on: main.
atc overlap --jsonagainst main (000b534a2): incomplete (pullFilesLimit,timeLimit); the file shared with most open PRs isCHANGELOG.md. hip flashnext: verify windows run their DeltaNet from the round's plan, with no state snapshot a row #2728 touches the same family's verify window and is tested together with this one (see the comments).Checks on this head
2e51ea822, on a merge of main000b534a2(conflict inCHANGELOG.mdonly): the eight-row window and its test (95647404f), shared rounds' copy width (4b94571df), the facts helper and its host test (9665335db), the named MTP cap (4c741020f), the--mtp-drafts 4refusal test (2e51ea822) and the changelog line (f88e015ea).python3 tools/zig/lean_check.py: 345 problems on the base and 345 on this head, 0 new findings.python3 tools/pr_check.py --base origin/main --pr 2730: 0 errors, 0 warnings.zig build test -Dhip=true --summary all: 889 of 891 steps succeeded, 13,646 of 13,760 tests passed, 113 skipped, 1 failed; the failure isdashboard_test"dashboard page polls the public stats snapshot without private details", which fails the same way on main000b534a2.zig build hip-kernel-teston gfx1151: 20 of 20 steps, 159 of 165 tests passed, 6 skipped, the same as main.cache.zig"a window's snapshots hold eight rows at tp 4" (fails on main);facts.zig"the shared round's copy window: the lane core takes three copies, a lone stream the whole window" (expected 3, found 7without.first_copy_rows = shared_copy_rows);lanes.zig"MTP stays at three: the constant, the cap and the facts never report more" (expected 3, found 7with the constant at 7);native/hip.zig"--mtp-drafts past three is refused by name before any load; three and fewer are not" (expected error.Refused, found voidwith the limit raised).Receipt
Main (
000b534a2) against branch, arms in the order main, this, this, main, a fresh server an arm with the page cache dropped, greedy and sampled (--temperatures 1.0,0). Both arms of each side are shown.tools/bench_concurrent.py --prompts <that file> --alone --serial --temperatures 1.0,0, two reps): sampled 57.3 / 57.4 (main) vs 72.2 / 72.2 (this) tok/s, +26%, 3.71 vs 5.89 tokens a round; greedy 58.6 / 58.6 vs 74.2 / 74.1, +27%, 3.77 vs 6.10 tokens a round.tools/bench_concurrent.py --levels 1,2,4 --reps 3 --prompts tools/bench_prompts.json --alone --serial --temperatures 1.0,0(16 distinct prompts, 256 tokens), aggregate tok/s at 1 / 2 / 4 streams. Greedy: 51.5 / 67.4 / 67.2 and 51.5 / 67.1 / 66.5 (main) vs 51.8 / 67.5 / 67.0 and 51.7 / 66.5 / 67.0 (this). Sampled: 45.2 / 59.5 / 64.6 and 45.1 / 59.2 / 63.8 (main) vs 45.1 / 59.6 / 64.3 and 45.0 / 59.5 / 64.4 (this). The differences are inside the spread between arms of one build.tools/bench_openai.py --tokens 256 --reps 3: code 46.25 / 46.19 vs 46.29 / 46.19 tok/s, chat 40.08 / 40.03 vs 40.09 / 40.04.tools/bench_cache.py --require-cold, 7,377-token prompt, first token 12.04 s on main's first arm vs 12.00 / 11.96 s, repeat 9.57 / 9.56 vs 9.56 / 9.53 s (main's last arm read 23.35 s on its first request and 9.56 s on the repeat, taken as a one-off on that server start).000b534a2plus this change, Zig 0.17.0,zig build native-hip -Dhip=true -Dhip-arch=gfx1151 -Doptimize=ReleaseFastwith the system hipcc (HIP 7.1, clang 21), one Strix Halo iGPU (gfx1151), Linux 7.0,unigilby/Qwen3.8-Flash-Next-oQ4e-HIP(revision5a0fb414),--context 131072 --parallel 4 --prompt-cache-gib 0, MTP 3 drafts.token_sha256equals main's in each arm (42 of 42 warm, 8 of 8 cold, 4 of 4 edit);--alone --serialequal in every arm, cell and workload (drafted equals"draft": false, concurrent equals solo), including the edit workload where lone streams run seven-token copies; the cold prompt'stoken_sha25625c0728f9043in every arm.Checklist
"draft": false, a resumed prompt equals a fresh one, and concurrent equals solo. (--alone --serialabove; resume is not touched by the window width.)