Repository navigation
Conversation
|
Pushed
Still to do before review: gates 1-4 for the new kernels against |
|
Thanks @BHCC2025. The same-bits parts read as same-bits to us. The mid-M kernels and
Then we'll run |
|
Thanks for the careful read. All four are addressed in be7c2a7:
Receipt for be7c2a7, on one GB10 (sm_121, nvcc 13.0.88, driver 580.178.04):
Same-bits parts alone against #1465, same checkpoint, prompts and settings as before:
Exactness on this build: window == step and tree == step (48 steps, 64.0 ms a step); alone and serial 20/20 equal, 0 failed; drafted = |
|
Thanks @BHCC2025. On One contract gap is left. |
|
Thanks. The gap was wider than 3 and 5 bits, so I checked the whole dispatch rather than only those two widths. Fixed in 59123e5. What was missing. I listed every kernel form
The fix.
Receipt for 59123e5, on one GB10 (sm_121, nvcc 13.0.88, driver 580.178.04):
The served path is unchanged: no family fixes a plan, so every 27B projection takes the same launch as on be7c2a7, and that receipt still applies. |
|
@BHCC2025, good news and one ask. Our last run of this on a GB10 (the cut-down head, with the dense EXL3 27B at 4.00 bpw) was GREEN: replies equal to main and no cell slower. It was ready to land. Since then #1475 landed. It zeroes the split-K counters once as they grow, on the calls' stream ( Could you rebase onto current main and keep main's |
59123e5 to
4285a31
Compare
|
Rebased onto current main (94b90c9) and pushed (4285a31).
Gates on 4285a31: |
…ows, projection groups, PDL (same bits) The Python engine's EXL3 speed series (ashhart#260) on the native Dense module. Weight.sk/wk let a family fix a shape's plan (K splits, warps); the mid-M kernels and linear_wc give the linear's bits at 17-128 rows; matmulGroup runs up to three layers of one K over the same rows in one rotation and one linear launch; the rotations and decode-row linears launch with programmatic dependent launch (TF_EXL3_PDL=0: plain), and counters are zeroed once. tf-cuda-test exl3-plans, exl3-midm and exl3-shapes check and time them.
… (same bits) At decode rows an EXL3 engine's projMany puts its EXL3 members in one cuda.exl3 group launch where groupable (q/k/v, qkv/z, and gate/up through projMany); each member's bits are its own launch's. Dense.reserveGroup sizes a group's scratch at load, before any graph capture, and Dense.reserve sizes split-K scratch by planOf, so a fixed plan's splits are reserved too. The loader fixes (K splits, warps) for the Qwen3.8-27B projection shapes.
…ntract records for the new launches pdl_wait and pdl_trigger compile to nothing below sm_90, and Linear.load turns dependent launches on only for compute capability 9.0 and newer. tf_exl3_group_8_2_4 and _8 are written out, so kernel_symbols finds their names. The registry takes the 2-warp linears, the mid-M kernels, linear_wc, the groups and rot_group (exl3_dense_records.zig), with usage from nvcc 13.0.88 fatbins for sm_80, 86, 89, 120 and 121, and the existing exl3_linear records refreshed.
…ch and the fixed one (exl3-plan-f64)
… MLP, group counters through grownCounters, the replacements in the kernel contract - The 27B's fixed plans and exl3-plan-f64 are gone: every projection takes plan()'s launch (Weight.sk/wk stay). - reserveGroups runs after the layer's MLP is set; a host test checks a dense layer's gate/up group decodes 1-16 rows without allocating. - A group's counters come from main's grownCounters (ashhart#1475) with its members' summed bytes; scratch() never zeroes. - contract_exl3.zig registers the mid-M kernels, linear_wc, the groups and rot_group in gates 1-4 as byte-equal replacements of linear_body (rot_in), each with a planted control; host tests for groupable, wcPick and planOf.
… in the kernel contract - contract_exl3 registers the mid-M kernels at 3 and 5 bits too, each with a control, and its served shapes reach every form plan() gives a width: both row passes, 4 and 8 warps, split and unsplit K, every linear_wc tile. The groups gain 4 warps unsplit. - exl3.pick is matmul's dispatch alone. A host test sweeps K and N to 16384 through it and groupable, and fails on a form no registration's gate-3 shapes run. A family's fixed plan keeps the linear. - Gate 4's stress weights are all-ones states, one weight at every width (0xaaaa decodes to two at 3 and 5 bits).
…ig stays under 600 lines on main ashhart#1475's grownCounters and its test took exl3.zig past the lean check's 600 lines; the variant tables, wcShared, wcPick and mpgIndex move as they are (exl3.zig re-exports what other files name).
…s.zig stays under 600 lines
4285a31 to
c7e0435
Compare
|
Rebased onto current main (fdd8b6d) and pushed (c7e0435). The No GPU run on 4285a31 failed only in lean_check. Merged with main, Gates on c7e0435: |
Stacked on #1465 (its commit comes first here; this PR's own commits are the last six). It carries #260's EXL3 speed series, from the Python engine, onto the native
Densemodule, as the closing note on #260 suggested once the native engine had an EXL3 reader.What this changes
exl3 cuda, kernels.Weight.sk/wklet a family fix a shape's plan (K splits, warps). No family here fixes one: every launch isplan()'s. A fixed plan keeps the linear.linear_wccover 17-128 rows (prompt rows and wide verify windows) withlinear_body's bits.exl3.pickismatmul's choice among them and the linear.matmulGroupruns up to three layers of one K over the same rows in one rotation and one launch.TF_EXL3_PDL=0: plain). Below sm_90 the waits compile to nothing and the launches are plain.tf-cuda-test exl3-midm,exl3-plansandexl3-shapescheck and time them;exl3-contractruns their kernel-contract registrations alone.qwen3_5 cuda, family.projManyputs an EXL3 engine's decode-row members in one group launch (q/k/v, qkv/z, gate/up).Dense.reserveGroupsizes a group's scratch at load (after the layer's MLP is set), before graph capture.Dense.reservesizes split-K scratch byplanOf. A grown counter buffer is zeroed on the call's stream.The arithmetic
linear_wc, the group launch androt_groupreturn the bytes of the one-weightlinear_body(androt_in) launch atplan()'s plan. Every projection keepsplan()'s launch, so no summation order changes.Receipt
Environment.
mainatb30d5b9d, plus qwen3_5 cuda: dense EXL3 checkpoints (Qwen3.8-27B), with DFlash2 drafts #1465, plus this. One DGX Spark (GB10, sm_121, 128 GB unified memory), Ubuntu 24.04.5, driver 580.178.04, nvcc 13.0.88, Zig 0.17.0,zig build install native -Dsm=121.turboderp/Qwen3.8-27B-exl3@113cf7ab(4.00bpw), drafterz-lab/Qwen3.8-27B-DFlash2@50307d4c.--context 131072; greedy unless stated. Same machine, prompts and settings as qwen3_5 cuda: dense EXL3 checkpoints (Qwen3.8-27B), with DFlash2 drafts #1465's receipt.Same bits (
tf-cuda-test, synthetic weights at every 27B shape, mul1 4-bit; the head 6-bit).exl3-midm: the mid-M kernels andlinear_wcequal the linear byte for byte at 17, 24, 32, 33, 48, 49, 64, 100 and 128 rows, and the mid-M kernels alone at 24, 48, 64 and 128. The group launches (q k v, gate up, qkv z) equal each member's own launch at 1, 7 and 16 rows.PASS exl3.midm,PASS exl3.group.exl3: 20 pass, 0 fail. The 9 skips are the Python engine's fixture checks (no fixture directory given).exl3-tiles: 5 pass, 0 fail.Exactness, served.
tf-qwen35-cuda ... step|window|treeover 48 ids: window logits equal step logits byte for byte, and so do tree logits.bench_concurrent.py --alone --serial --levels 1,4 --temperatures 0,1.0(drafts on): alone 20/20 equal, serial 20/20 equal, 0 failed."draft": false: an 8,020-token chat, 256 reply tokens. Fresh, the cached repeat and"draft": falsegive one reply hash./healthstaysok.Speed, against qwen3_5 cuda: dense EXL3 checkpoints (Qwen3.8-27B), with DFlash2 drafts #1465 alone on the same machine:
bench_openaidrafts on,fibonacci-raw/gpu-chat-no-thinkbench_openai, no drafterbench_concurrent4 streams, code / chat, greedybench_concurrent4 streams, code / chat, temperature 1.0Cold prefill:
bench_cache.py --require-cold --prompt-file,--prompt-cache-gib 0, a fresh server per length. These are qwen3_5 cuda: dense EXL3 checkpoints (Qwen3.8-27B), with DFlash2 drafts #1465's exact token arrays (this repository'szig/src/**/*.zigunder the checkpoint's tokenizer). All four qualified cold.Kernel contract.
registry.zig(exl3_dense_records.zig), and 60 existingexl3_linearrecords are refreshed. All come fromkernel-contract-limitsover fatbins for sm_80/86/89/120/121 with nvcc 13.0.88; the audit has no stale or failing EXL3 record.zig build kernel-contracton the GB10 (sm_121), this branch:SUMMARY 426 kernels: 426 pass gates 1-4, 0 fail, 5 known findings; 318 controls: 318 red as planted, 0 missed; 195 limit problems.qwen35/qwen35_kv8attention,qwen4_hc,qwen4_ple,qwen4_projection,qwen4_gdnandnvfp4_experts_tilerecords, which this PR does not touch. On qwen3_5 cuda: dense EXL3 checkpoints (Qwen3.8-27B), with DFlash2 drafts #1465's branch the run lists the same gate and control findings up to the limits section (322 identical FAIL/KNOWN lines).zig/tests/cuda/contract_exl3.zig): eight replacements oflinear_body, each with a planted control that goes red at gate 3, plusrot_groupagainstrot_in.linear_wcat 4 and 6 bits, at 1 to 128 rows. Their served shapes reach every formplan()gives those widths: both row passes, 4 and 8 warps, split and unsplit K, and everylinear_wctile.exl3-contract:SUMMARY exl3 8 kernels: 8 pass gates 1-4, 0 fail; 6 controls: 6 red as planted, 0 missed.exl3.pickandgroupable. It fails on any form the dispatch reaches that no registration's gate-3 shapes run.Tests run.
zig build teston Linux x86_64: 0 failed.zig fmt --checkis clean.python3 tools/zig/lean_check.py: 428 problems, the same asmain. Zero new.Not run, and why.
Checklist
"draft": false, a resumed prompt equals a fresh one, and concurrent equals solo.plan()'s summation order.