Repository navigation
Conversation
…olumns ktrain patch 0005 (first commit of PR PrismML-Eng#310): lets ggml_cuda_should_fuse_mul_mat_vec_q and ggml_cuda_mul_mat_vec_q accept the gate/up fusion for 2..4 columns when the dedicated PTQ1_0 kernel can take it (ggml_cuda_mmvq_ptq1_0_can_fuse_mc: plain 2D, K multiple of 128, shared memory within the limit). Merged with upstream's new MoE assert on the batch size. Patch 0006 (GLU output overlapping the q8 rows) is not included: it depends on prism's signed-FWHT + q8 quantizer graph fusion (ggml_cuda_try_fwht_q8), which this branch does not have yet. test-backend-ops ptq1_0: MUL_MAT 178/178, MUL_MAT_ID 85/85, MUL_MAT_VEC_FUSION 2/2; mtp_bench: all 8 output hashes identical to the commit before. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…output overlaps the q8 rows ktrain patch 0006 (PR PrismML-Eng#310, second part), applied as the net diff of pr/ptq1-gate-up-fuse-mc after 0005 (the GGML_CUDA_FWHT_GLU_POOL switch is not carried over): a gate/up pair that the mat-vec fuses with its SwiGLU writes the GLU output while other CTAs still read the q8 rows; when the allocator put the GLU output over that buffer, the fused FWHT quantizer now writes the rows to a pool block (out_aliases_in), and the fusion memory-range check ignores overlaps with inputs whose q8 rows live in a pool block (thread-local registry pointer, reset after each graph). Needs the signed-FWHT + q8 fusion of the previous commit. mtp_bench output hashes identical to the commit before. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…olumns ktrain patch 0005 (first commit of PR PrismML-Eng#310): lets ggml_cuda_should_fuse_mul_mat_vec_q and ggml_cuda_mul_mat_vec_q accept the gate/up fusion for 2..4 columns when the dedicated PTQ1_0 kernel can take it (ggml_cuda_mmvq_ptq1_0_can_fuse_mc: plain 2D, K multiple of 128, shared memory within the limit). Merged with upstream's new MoE assert on the batch size. Patch 0006 (GLU output overlapping the q8 rows) is not included: it depends on prism's signed-FWHT + q8 quantizer graph fusion (ggml_cuda_try_fwht_q8), which this branch does not have yet. test-backend-ops ptq1_0: MUL_MAT 178/178, MUL_MAT_ID 85/85, MUL_MAT_VEC_FUSION 2/2; mtp_bench: all 8 output hashes identical to the commit before. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…output overlaps the q8 rows ktrain patch 0006 (PR PrismML-Eng#310, second part), applied as the net diff of pr/ptq1-gate-up-fuse-mc after 0005 (the GGML_CUDA_FWHT_GLU_POOL switch is not carried over): a gate/up pair that the mat-vec fuses with its SwiGLU writes the GLU output while other CTAs still read the q8 rows; when the allocator put the GLU output over that buffer, the fused FWHT quantizer now writes the rows to a pool block (out_aliases_in), and the fusion memory-range check ignores overlaps with inputs whose q8 rows live in a pool block (thread-local registry pointer, reset after each graph). Needs the signed-FWHT + q8 fusion of the previous commit. mtp_bench output hashes identical to the commit before. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
bri-prism
left a comment
There was a problem hiding this comment.
Agent review: posted by the maintainer's coding agent at their request.
This needs a rebase. Against current prism (73bfe6c), the CUDA build fails:
ggml/src/ggml-cuda/mmvq.cu(1602): error: too few arguments in function call
const size_t smem = ptq1_0_pt_smem_bytes((int) (src0->ne[0] / 128), ncols_dst, (int) src0->ne[1], true);
ptq1_0_pt_smem_bytes has gained a parameter on prism since this branch was cut, and the test-backend-ops hunk no longer applies either. I'll re-run the H200 A/B (test-backend-ops MUL_MAT_VEC_FUSION, greedy identity, 2-4-column decode) once it's rebased.
…olumns ktrain patch 0005 (first commit of PR PrismML-Eng#310): lets ggml_cuda_should_fuse_mul_mat_vec_q and ggml_cuda_mul_mat_vec_q accept the gate/up fusion for 2..4 columns when the dedicated PTQ1_0 kernel can take it (ggml_cuda_mmvq_ptq1_0_can_fuse_mc: plain 2D, K multiple of 128, shared memory within the limit). Merged with upstream's new MoE assert on the batch size. Patch 0006 (GLU output overlapping the q8 rows) is not included: it depends on prism's signed-FWHT + q8 quantizer graph fusion (ggml_cuda_try_fwht_q8), which this branch does not have yet. test-backend-ops ptq1_0: MUL_MAT 178/178, MUL_MAT_ID 85/85, MUL_MAT_VEC_FUSION 2/2; mtp_bench: all 8 output hashes identical to the commit before. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…output overlaps the q8 rows ktrain patch 0006 (PR PrismML-Eng#310, second part), applied as the net diff of pr/ptq1-gate-up-fuse-mc after 0005 (the GGML_CUDA_FWHT_GLU_POOL switch is not carried over): a gate/up pair that the mat-vec fuses with its SwiGLU writes the GLU output while other CTAs still read the q8 rows; when the allocator put the GLU output over that buffer, the fused FWHT quantizer now writes the rows to a pool block (out_aliases_in), and the fusion memory-range check ignores overlaps with inputs whose q8 rows live in a pool block (thread-local registry pointer, reset after each graph). Needs the signed-FWHT + q8 fusion of the previous commit. mtp_bench output hashes identical to the commit before. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…mML-Eng#314 open Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Pn9UL41f3M8tRbqcHXFuB8
The dedicated PTQ1_0 kernel (mul_mat_vec_ptq1_0_pt) is templated for fusion with any column count, but the graph check, an assert in ggml_cuda_mul_mat_vec_q and the launcher only allowed ncols_dst == 1. So gate + up + SwiGLU ran as three kernels in every FFN block of a 2-4 token verify step (speculative decoding, small batches). Allow the fused path for the dedicated kernel (plain 2D, K multiple of 128, shared memory within the limit; the graph check calls the same helper, ggml_cuda_mmvq_ptq1_0_can_fuse_mc, which uses the per-cc rows_per_item rule of the launcher so guard and launch agree on the shared memory). With more than one column the bias tensors have to be contiguous because the kernel indexes the bias like dst. Other types keep the one-column rule. ggml_cuda_check_fusion_memory_ranges refused the fusion in 24 of 64 FFN blocks of the Bonsai 2 verify graph: the GLU output overlaps src1, the Hadamard transform output, because ggml-alloc hands it the block that src1 released. The overlap is real when the q8_1 rows written by ggml_cuda_try_fwht_q8 live in that buffer, so the check was right. Now ggml_cuda_try_fwht_q8 puts the rows into a pool block when a following GLU of a consumer pair overlaps the buffer (the mechanism it already has for out_aliases_in), and the fusion memory check ignores an overlap with an input whose q8 rows are registered in a pool block (g_fwht_q8_ctx, reset by a scope guard after the graph evaluation). All 64 FFN blocks fuse. RTX 4070, Bonsai 2 27B PTQ1_0 + MTP head (n-max 2), q4_0 K/V, greedy, 4 prompts x 256 tokens, 8 interleaved A/B pairs, base prism c96baf4: decode 115.98 -> 117.16 tok/s (+1.02 %, 95 % CI [+0.96, +1.08] %), outputs identical in all runs, acceptance 74.0 % in both. Measured earlier with environment switches on an older base: the fusion alone +1.01 %, keeping it over the overlap another +0.33 %. Removing the whole change from the full patch stack costs 0.65 % at depth 0 and 0.37 % at 114688 tokens. tests: gate fused PTQ1_0 mat-vec cases with 2 to 4 columns in MUL_MAT_VEC_FUSION (538 -> 546 cases, all pass on CUDA0 together with MUL_MAT 1669, SWIGLU 24, RMS_NORM 51). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
791eb61 to
869bc93
Compare
|
Rebased on current |
Overview
Rebased on current
prism(c96baf4ab) and squashed to one commit; this fixes the build error from the review (ptq1_0_pt_smem_byteshas a new parameter) and the test hunk that no longer applied. The environment switches are gone, the test cases are now part of the PR.The dedicated PTQ1_0 kernel (
mul_mat_vec_ptq1_0_pt) is templated for gate + up + SwiGLU fusion with any column count, but the graph check, an assert inggml_cuda_mul_mat_vec_qand the launcher only allowedncols_dst == 1. So gate + up + SwiGLU ran as three kernels in every FFN block of a 2-4 token verify step (speculative decoding, small batches).ggml_cuda_mmvq_ptq1_0_can_fuse_mc, so guard and launch agree). With more than one column the bias tensors have to be contiguous. Other types keep the one-column rule.ggml_cuda_check_fusion_memory_rangessaw the GLU output overlapsrc1(ggml-alloc hands it the blocksrc1released). The overlap is real when the q8_1 rows written byggml_cuda_try_fwht_q8live in that buffer, so the check was right. Nowggml_cuda_try_fwht_q8puts the rows into a pool block when a following GLU of a consumer pair overlaps the buffer (the mechanism it already has forout_aliases_in), and the check ignores an overlap with an input whose q8 rows are registered in a pool block. All 64 FFN blocks fuse.RTX 4070, Bonsai 2 27B PTQ1_0 + MTP head (n-max 2), q4_0 K/V: decode 115.98 -> 117.16 tok/s (+1.02 %, 95 % CI [+0.96, +1.08] %, 8 interleaved pairs), outputs identical in all runs, acceptance unchanged.
Additional information
g_fwht_q8_ctxis reset by a small scope guard after the graph evaluation (it is read only while a graph is evaluated).MUL_MAT_VEC_FUSIONcases for gate fused PTQ1_0 mat-vec with 2 to 4 columns (538 -> 546 cases).test-backend-opsexercises the fused kernel (2 to 4 columns) but not the buffer aliasing handled by the pool block, because that depends on how ggml-alloc places the tensors of a real graph. For the aliasing I rely on identical outputs of the full model. The original comment inggml_cuda_try_fwht_q8describes the failure mode (rows stored early over input that other blocks still read: sporadic garbage in the recurrent state), so please review that part with it in mind.prism.Test results
-DGGML_CUDA=ON -DCMAKE_CUDA_ARCHITECTURES=89.prismatc96baf4ab(builds without errors,test-backend-opsrun on it).--spec-type draft-mtp --spec-draft-n-max 2(the verify step runs 3 columns), q4_0 K/V cache, one slot, context 114688.prismand the branch, 4 greedy prompts x 256 tokens, alternating runs, 8 pairs, paired differences with a 95 % bootstrap interval (minimum detectable effect 0.10 %).prism): -0.65 % at depth 0 and -0.37 % at 114688 tokens.test-backend-ops test -b CUDA0:MUL_MAT_VEC_FUSION546/546 (538 onprism),MUL_MAT1669/1669,SWIGLU24/24,RMS_NORM51/51.Requirements
🤖 Generated with Claude Code