Repository navigation
Conversation
iq_mmvq, native_gu_kernel and native_down_kernel called the format's dot once per column (or group entry), re-reading the weight words and redoing the grid lookups and sign unpacking each time. Each dot is now split into load (weight side) and apply (activation side, same integer chain and float expression), as native_mmvq.cu's multi-column traits are: the dense kernel takes 1, 2, 4 or 8 columns per pass (8 at a time past 8), the grouped ones 4 entries per pass (~48 registers; the default verify window, --spec 4 with the split off, fits in one pass). Every column keeps the same calls, lane stride, summation order and warp_sum, so results are bitwise equal to the old kernels, which STRATA_OLD_IQ_MMVQ=1 (or iq_set_old_kernels) keeps for A/B timing. Tests: iq_multi_parity (ctest, GPU, synthetic, no model) checks old vs new bitwise for every format, ncols 1..8 and 11, groups of 0..11 entries; --bench times both. iq_parity (real rows from tools/iq_fixture.py) now runs the dot for 1 to 8 columns and requires every column of a multi-column call to equal a one-column call on it bitwise (exact layout, the default). native_expert_parity runs the GPU expert with both the decode-once and the per-entry kernels on real blobs and requires the same bits.
Contributor
|
Confirmed bitwise equal on an RTX 4080 SUPER (sm_89, Windows 11; IQ3_S, 262K; 0.1.30 + this PR): with and without |
Niko1221
added a commit
that referenced
this pull request
Oct 1, 2026
…_XL), per-role format lists, native_expert_supported at startup, Q8_0 embedding and PLE key - Dots: llama.cpp's vec_dot_q4_K / q5_K / q8_0_q8_1 transcribed (VDR 2), via eddoursul/Strata 8029fa9 and #255 (gopinath87607, Q8_0), which agree. Q5_1's min term multiplies the sum of the QUANTIZED activations (ggml-cpu's convention, as the fork does), not llama.cpp CUDA's ds.y. - Dequantizers dq_q4_k / dq_q5_k / dq_q5_1 / dq_q8_0 (llama.cpp's formulas) for the prompt path's FP16 fallback, f32 dumps and the Q8_0 embedding; iq_row_bytes / is_iq know the four types; iq_dequant_gu_f16 now refuses an unknown type instead of leaving its output unwritten. - The grouped gate/up, down and iq_mmvq switches are generated from STRATA_GU_FMTS / STRATA_D_FMTS / STRATA_MMVQ_FMTS; the existing entries launch the same kernels as before. - native_expert_supported(gu, d, n_embd, n_ff): generate checks every layer of a native pack right after expert_layout_load and refuses an unsupported pair by name before anything is allocated (it used to exit from inside the first verify window). - Native PLE key: Q8_0 accepted (NativeDense, generate, ple.cu); native_mmvq already runs it. - native_expert_parity: --synthetic GU/DOWN (random ggml-quantized blobs at 2560/640; port of the fork's mode), GPU dequant f32/f16 and embedding rows vs ggml to_float bit for bit, split models via GgufModel, --q5_1-min. CTests: q4_K/q5_1, q4_K/q8_0, q5_K/q8_0, q8_0/q8_0, the Q5_1 min term, and q6_K refused. RTX 5070: GPU and CPU within 1.25-1.37e-2 of the float reference for all three real pairs; every dequantized value identical; Q5_1 GPU vs ggml-cpu 7.5e-5 (vs 1.95e-2 for the ds.y variant); IQ3_XXS/IQ4_NL and IQ2_XS/Q2_0 unchanged. - Not yet: #242's decode-once traits for the new types (they take the per-entry kernel; see phaseA-tests/s5_cs3_design.md), prompt MMQ for Q4_K/Q5_K/Q5_1, identity gates. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0154bwiad8gY7wRehCXy27pN
Owner
|
Released in 0.1.31: bitwise identical on all four quants ( |
Hardin22
added a commit
to Hardin22/Strata-DualGPU
that referenced
this pull request
Oct 3, 2026
A decode window on this model is a long chain of small kernels, and on a fast card many of them are over before the next one has fetched its weights. These changes cut launches and let the next kernel start early. Every one keeps the arithmetic of the path it replaces (checked with per-layer hashes of the MoE inputs and the final residual over full requests: identical windows), and each has an off switch for A/B runs. - Programmatic dependent launch on sm_90+ (STRATA_DF_PDL, default on): the verify kernels trigger their dependents early, and the dependents prefetch their weight rows into L2 before waiting for the activations. Off on older cards. - Two side streams inside the verify graph (STRATA_DF_BRANCH): the query side (q, the indexer query) runs beside the K/V side and joins before attention. - A Q4_0 KV cache batches too (STRATA_DF_QB_Q4, STRATA_DF_KVAPP): the query rotation is row-wise, so the window's rows go in one launch, and the window's K/V cells are appended in one launch. - PLE: the per-token post-ops of a window in one kernel (STRATA_DF_PLE). - A layer split's hand-off copies (3 x T) in one launch (STRATA_DF_HANDOFF). - native mmvq: a warp per row for large outputs (STRATA_DF_MMVQW): 10-30% less time on 6144..248320-row IQ4_XS on both cards (slower at 640 rows, so it starts at 2048). - Attention loops with their loads batched (STRATA_DF_ATTN), SwiGLU folded into the shared expert's down quantization (STRATA_DF_SHARED). - copy_rows_strided replaces a per-token cudaMemcpy2DAsync for the q/gate split. - An L2 prefetch of the next layer's weights on a side stream, opt-in (STRATA_DF_L2PF_MB=n, STRATA_DF_L2PF_MIN_SM). It did not help on the 5080 + 4060 Ti. Upstream's staged hyper-connection read (Niko1221#315) and decode-once multi-column IQ kernels (Niko1221#242) do what two earlier parts of this change did, so those parts were dropped in favour of upstream's.
Niko1221
added a commit
that referenced
this pull request
Oct 6, 2026
…_XL), per-role format lists, native_expert_supported at startup, Q8_0 embedding and PLE key - Dots: llama.cpp's vec_dot_q4_K / q5_K / q8_0_q8_1 transcribed (VDR 2), via eddoursul/Strata 8029fa9 and #255 (gopinath87607, Q8_0), which agree. Q5_1's min term multiplies the sum of the QUANTIZED activations (ggml-cpu's convention, as the fork does), not llama.cpp CUDA's ds.y. - Dequantizers dq_q4_k / dq_q5_k / dq_q5_1 / dq_q8_0 (llama.cpp's formulas) for the prompt path's FP16 fallback, f32 dumps and the Q8_0 embedding; iq_row_bytes / is_iq know the four types; iq_dequant_gu_f16 now refuses an unknown type instead of leaving its output unwritten. - The grouped gate/up, down and iq_mmvq switches are generated from STRATA_GU_FMTS / STRATA_D_FMTS / STRATA_MMVQ_FMTS; the existing entries launch the same kernels as before. - native_expert_supported(gu, d, n_embd, n_ff): generate checks every layer of a native pack right after expert_layout_load and refuses an unsupported pair by name before anything is allocated (it used to exit from inside the first verify window). - Native PLE key: Q8_0 accepted (NativeDense, generate, ple.cu); native_mmvq already runs it. - native_expert_parity: --synthetic GU/DOWN (random ggml-quantized blobs at 2560/640; port of the fork's mode), GPU dequant f32/f16 and embedding rows vs ggml to_float bit for bit, split models via GgufModel, --q5_1-min. CTests: q4_K/q5_1, q4_K/q8_0, q5_K/q8_0, q8_0/q8_0, the Q5_1 min term, and q6_K refused. RTX 5070: GPU and CPU within 1.25-1.37e-2 of the float reference for all three real pairs; every dequantized value identical; Q5_1 GPU vs ggml-cpu 7.5e-5 (vs 1.95e-2 for the ds.y variant); IQ3_XXS/IQ4_NL and IQ2_XS/Q2_0 unchanged. - Not yet: #242's decode-once traits for the new types (they take the per-entry kernel; see phaseA-tests/s5_cs3_design.md), prompt MMQ for Q4_K/Q5_K/Q5_1, identity gates.
anon761
pushed a commit
to anon761/Strata-upstream
that referenced
this pull request
Oct 6, 2026
…_XL), per-role format lists, native_expert_supported at startup, Q8_0 embedding and PLE key - Dots: llama.cpp's vec_dot_q4_K / q5_K / q8_0_q8_1 transcribed (VDR 2), via eddoursul/Strata 8029fa9 and Niko1221#255 (gopinath87607, Q8_0), which agree. Q5_1's min term multiplies the sum of the QUANTIZED activations (ggml-cpu's convention, as the fork does), not llama.cpp CUDA's ds.y. - Dequantizers dq_q4_k / dq_q5_k / dq_q5_1 / dq_q8_0 (llama.cpp's formulas) for the prompt path's FP16 fallback, f32 dumps and the Q8_0 embedding; iq_row_bytes / is_iq know the four types; iq_dequant_gu_f16 now refuses an unknown type instead of leaving its output unwritten. - The grouped gate/up, down and iq_mmvq switches are generated from STRATA_GU_FMTS / STRATA_D_FMTS / STRATA_MMVQ_FMTS; the existing entries launch the same kernels as before. - native_expert_supported(gu, d, n_embd, n_ff): generate checks every layer of a native pack right after expert_layout_load and refuses an unsupported pair by name before anything is allocated (it used to exit from inside the first verify window). - Native PLE key: Q8_0 accepted (NativeDense, generate, ple.cu); native_mmvq already runs it. - native_expert_parity: --synthetic GU/DOWN (random ggml-quantized blobs at 2560/640; port of the fork's mode), GPU dequant f32/f16 and embedding rows vs ggml to_float bit for bit, split models via GgufModel, --q5_1-min. CTests: q4_K/q5_1, q4_K/q8_0, q5_K/q8_0, q8_0/q8_0, the Q5_1 min term, and q6_K refused. RTX 5070: GPU and CPU within 1.25-1.37e-2 of the float reference for all three real pairs; every dequantized value identical; Q5_1 GPU vs ggml-cpu 7.5e-5 (vs 1.95e-2 for the ds.y variant); IQ3_XXS/IQ4_NL and IQ2_XS/Q2_0 unchanged. - Not yet: Niko1221#242's decode-once traits for the new types (they take the per-entry kernel; see phaseA-tests/s5_cs3_design.md), prompt MMQ for Q4_K/Q5_K/Q5_1, identity gates.
anon761
pushed a commit
to anon761/Strata-upstream
that referenced
this pull request
Oct 6, 2026
…_XL), per-role format lists, native_expert_supported at startup, Q8_0 embedding and PLE key - Dots: llama.cpp's vec_dot_q4_K / q5_K / q8_0_q8_1 transcribed (VDR 2), via eddoursul/Strata 8029fa9 and Niko1221#255 (gopinath87607, Q8_0), which agree. Q5_1's min term multiplies the sum of the QUANTIZED activations (ggml-cpu's convention, as the fork does), not llama.cpp CUDA's ds.y. - Dequantizers dq_q4_k / dq_q5_k / dq_q5_1 / dq_q8_0 (llama.cpp's formulas) for the prompt path's FP16 fallback, f32 dumps and the Q8_0 embedding; iq_row_bytes / is_iq know the four types; iq_dequant_gu_f16 now refuses an unknown type instead of leaving its output unwritten. - The grouped gate/up, down and iq_mmvq switches are generated from STRATA_GU_FMTS / STRATA_D_FMTS / STRATA_MMVQ_FMTS; the existing entries launch the same kernels as before. - native_expert_supported(gu, d, n_embd, n_ff): generate checks every layer of a native pack right after expert_layout_load and refuses an unsupported pair by name before anything is allocated (it used to exit from inside the first verify window). - Native PLE key: Q8_0 accepted (NativeDense, generate, ple.cu); native_mmvq already runs it. - native_expert_parity: --synthetic GU/DOWN (random ggml-quantized blobs at 2560/640; port of the fork's mode), GPU dequant f32/f16 and embedding rows vs ggml to_float bit for bit, split models via GgufModel, --q5_1-min. CTests: q4_K/q5_1, q4_K/q8_0, q5_K/q8_0, q8_0/q8_0, the Q5_1 min term, and q6_K refused. RTX 5070: GPU and CPU within 1.25-1.37e-2 of the float reference for all three real pairs; every dequantized value identical; Q5_1 GPU vs ggml-cpu 7.5e-5 (vs 1.95e-2 for the ds.y variant); IQ3_XXS/IQ4_NL and IQ2_XS/Q2_0 unchanged. - Not yet: Niko1221#242's decode-once traits for the new types (they take the per-entry kernel; see phaseA-tests/s5_cs3_design.md), prompt MMQ for Q4_K/Q5_K/Q5_1, identity gates. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0154bwiad8gY7wRehCXy27pN
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.
IQ kernels: decode each weight part once for every column and entry, bitwise identical
Rebased on v0.1.29. One commit:
iq_kernels.cuand its header, a new parity test (iq_multi_parity), and additions toiq_parityandnative_expert_parity.What it does
iq_mmvq,native_gu_kernelandnative_down_kernelcalled the format's dot once per column (or group entry), re-reading the weight words and redoing the grid lookups and sign unpacking each time. Each dot is now split into a load (weight side) and an apply (activation side, same integer chain and same float expression), the waynative_mmvq.cu's multi-column traits already work. The dense kernel takes 1, 2, 4 or 8 columns per pass (8 at a time beyond 8), the grouped ones 4 entries per pass (about 48 registers; the default verify window fits in one pass).Every column keeps the same calls, lane stride, summation order and
warp_sum, so results are bitwise equal to the old kernels.Default path is identical to the byte
Measured on an RTX 5090 (sm_120, Windows, MSVC 2022, CUDA 13.4), Release build, v0.1.29 as the base.
iq_multi_parity(new, in ctest, synthetic, no model): old against new bitwise for iq2_xxs, iq2_xs, iq3_xxs, iq4_nl, iq3_s, iq2_s, iq4_xs, iq1_m and q2_0,iq_mmvqwith 1 to 8 and 11 columns, andnative_expert_groupedwith 9 groups and 35 entries for the 24 pairings of 8 gate/up formats with IQ4_NL, Q2_0 and IQ4_XS down. 0 failures.native_expert_parityon the real IQ3_S shard (layers 0, 1, 2, 3, 20, 47): 0 failures, and for each layer "gpu decode-once vs per-entry kernels: bitwise equal".iq_paritynow also requires every column of a 1 to 8 columnnative_mmvqcall to equal a one-column call bitwise.tools/iq_fixture.pyis not in the tree, so I ran it on fixtures built locally from gguf-py (random valid blocks, 64 x 512, dequantized by gguf-py from the pinned llama.cpp): 8 IQ formats and Q3_K pass, dequant error 0, dot within 6e-3 of the float product, and the multi-column check holds. Q2_0 has no gguf-py fixture and reports "missing fixture", exactly as v0.1.29 does.ple_parity,expert_parity,pool_test.--spec 4 --expert-cache 8000 --prefill 2048 --max-new 256, three prompts (32, 2 520 and 23 020 tokens), two passes each: all 256 output tokens are identical in every run, and identical withSTRATA_OLD_IQ_MMVQ=1on the shortest and longest prompt.Gain
Kernel micro-benchmark (
iq_multi_parity --bench, RTX 5090, idle GPU), microseconds per call, old / new:iq_mmvq8192 x 2560iq_mmvq8192 x 2560iq_mmvq8192 x 2560Grouped, 16 groups of m entries (IQ3_S gate/up with Q2_0 down): m=1 39.9 / 40.1, m=4 76.0 / 54.1, m=8 129.4 / 90.2. Across the six formats benchmarked, m=8 goes from 109 to 129 us down to 82 to 90 us.
End to end, no gain shows on the IQ3_S model with the default
--spec 4window: decode is 142.8 tok/s for v0.1.29 and 142.8 / 143.3 for this branch on the 23K prompt, and 137.5 / 136.9 against 138.8 / 138.1 on the 2.5K one, within run to run noise. Most of the win is at 3 or more columns or entries per call, which the default window rarely reaches on this model.Switch back
STRATA_OLD_IQ_MMVQ=1(oriq_set_old_kernels) keeps the per-column kernels.Not tested
--specwindow where the multi-column path is hit more often.