Repository navigation
Conversation
…_DENSE_MMQ=1), the K-quant instances on the HIP build
The prompt path's dense projections (attention qkv/gate, the PLE key, the shared
experts, the router, the head) run dequantize-to-FP16 + cuBLAS: on the RDNA2
cards that is 68% of the prefill GPU time at ~25% of the card's fp32-accumulate
rate, while the same shapes through llama.cpp's int8 MMQ run ~7x faster
(measured with bench_dense_gemm). This wires Gemm::native's beta = 0 products
through the MMQ path the MoE experts already take: quantize the FP16 activations
to q8_1 (they are converted to FP32 in the dequant scratch, which the old path
only fills afterwards) and run one mul_mat_q product per 1024-row chunk. It is
opt-in (STRATA_DENSE_MMQ=1; unset, nothing changes) and falls back silently to
the old path on any shape MMQ does not take.
- STRATA_MMQ_KQUANTS also compiles the Q4_K / Q5_K / Q5_1 / Q6_K instances on
the HIP branch (the mixed-quant packs' dense tensors are K-quants: this
model's attention/PLE matrices are IQ4_XS/IQ3_S/Q4_K/Q5_K/Q6_K), adds Q6_K to
the CUDA list, and defines STRATA_MMQ_KQUANTS for the HIP target.
- Gemm::native_mmq: one MMQ context, xq/ident/bounds buffer (~9.5 MB) and a
failed-flag per Gemm; fp16->fp32 and the {0, rows} bounds helper join
moe_mmq's kernel set.
- K must be a full 256-value multiple. MMQ loads the weights in 256-value K
chunks, and past a partial row the chunk reads bytes past the row - the next
row's, or for the last weight row bytes past the tensor, which no caller
guarantees to be zeros (the MoE path is safe because its gather buffers end
in a zeroed tail). On this pack the 640-value IQ4_NL shared-expert down
picked up a NaN scale from the next tensor's blocks and zeroed the output;
the odd shapes stay on the dequantize + cuBLAS path.
Measured on the RX 6900 XT (gfx1030), swift-1.5-iq3_xxs, WORKERS=15 ADAPT=1
PREFILL=8192, bench_prefill.py fresh medians: 4K prefill 436.1 -> 757.2 tok/s,
8K fresh 447.7 -> 773.9 tok/s, 8K followup 163.9 -> 206.1 tok/s; decode within
noise (40.6 vs 40.3 tok/s at --pcie-frac 0, 52.7 vs 49.9 at the 0.55 default).
Greedy output: bit-identical for the first 200 tokens of a short prompt; a 4K
prompt's greedy text diverges at token ~26 (the q8_1 activation rounding) and
stays coherent.
DTU-travelpals
pushed a commit
to DTU-travelpals/Strata
that referenced
this pull request
Oct 5, 2026
|
Holy moly I'm getting probably like 4x-5x the prefill on my RX6800, ~600tok/s |
Niko1221
added a commit
that referenced
this pull request
Oct 6, 2026
…CUDA builds (#820) Gemm::native_mmq, its call, the f16_to_f32/set_bounds kernels and the Q6_K case are under __HIPCC__; the CUDA type list loses q6_k. The K % 256 != 0 out-of-bounds read is already refused in native_mmq (kept). Still opt-in: STRATA_DENSE_MMQ=1 on a STRATA_MMQ_KQUANTS=ON HIP build. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Owner
|
Taken for 0.1.40 as opt-in (STRATA_DENSE_MMQ=1, needs a HIP build with STRATA_MMQ_KQUANTS=ON), HIP only. The CUDA build gets no q6_k instance and the K % 256 read is refused in native_mmq. We could not reproduce the gain on gfx1151 (UD-Q4_K_XL, 8K prompt, 10 interleaved pairs): median prefill 806 vs 797 tok/s, and the output differs (KL against the default path 0.008-0.09 on 6 prompts, mean 0.03). So it stays opt-in. On gfx1030 without a hipBLASLt table it may still win, as you measured. |
Niko1221
added a commit
that referenced
this pull request
Oct 6, 2026
…CUDA builds (#820) Gemm::native_mmq, its call, the f16_to_f32/set_bounds kernels and the Q6_K case are under __HIPCC__; the CUDA type list loses q6_k. The K % 256 != 0 out-of-bounds read is already refused in native_mmq (kept). Still opt-in: STRATA_DENSE_MMQ=1 on a STRATA_MMQ_KQUANTS=ON HIP build.
anon761
pushed a commit
to anon761/Strata-upstream
that referenced
this pull request
Oct 6, 2026
…CUDA builds (Niko1221#820) Gemm::native_mmq, its call, the f16_to_f32/set_bounds kernels and the Q6_K case are under __HIPCC__; the CUDA type list loses q6_k. The K % 256 != 0 out-of-bounds read is already refused in native_mmq (kept). Still opt-in: STRATA_DENSE_MMQ=1 on a STRATA_MMQ_KQUANTS=ON HIP build.
Niko1221
pushed a commit
that referenced
this pull request
Oct 7, 2026
…5 (PR #917) Interactive Q2_0 and UD-IQ4_XS chats against llama.cpp Vulkan, then controlled A-E runs of the gfx1151 hipBLASLt tuning table (250.9 to 528.9 prompt tok/s), dense MMQ (+0.2%) and the shared-expert decode stream (+2.5%, 8 requests). The build is 0.1.39 plus then-unmerged PRs (#895, #820, a tuning table adapted from #755), not the 0.1.40 release; the index line in COMMUNITY_BENCHMARKS.md says so and notes that 0.1.40 turned the shared-expert stream off on HIP (#826).
sskver
pushed a commit
to sskver/Strata
that referenced
this pull request
Oct 7, 2026
…CUDA builds (Niko1221#820) Gemm::native_mmq, its call, the f16_to_f32/set_bounds kernels and the Q6_K case are under __HIPCC__; the CUDA type list loses q6_k. The K % 256 != 0 out-of-bounds read is already refused in native_mmq (kept). Still opt-in: STRATA_DENSE_MMQ=1 on a STRATA_MMQ_KQUANTS=ON HIP build.
0xrjman
pushed a commit
to 0xrjman/Strata
that referenced
this pull request
Oct 7, 2026
…5 (PR Niko1221#917) Interactive Q2_0 and UD-IQ4_XS chats against llama.cpp Vulkan, then controlled A-E runs of the gfx1151 hipBLASLt tuning table (250.9 to 528.9 prompt tok/s), dense MMQ (+0.2%) and the shared-expert decode stream (+2.5%, 8 requests). The build is 0.1.39 plus then-unmerged PRs (Niko1221#895, Niko1221#820, a tuning table adapted from Niko1221#755), not the 0.1.40 release; the index line in COMMUNITY_BENCHMARKS.md says so and notes that 0.1.40 turned the shared-expert stream off on HIP (Niko1221#826).
svgop
added a commit
to svgop/Strata
that referenced
this pull request
Oct 17, 2026
…__CUDACC__ (STRATA_PREFILL_MMQ is already PUBLIC on strata_prefill in the CUDA branch - CMake:1517), moe_mmq f16_to_f32/set_bounds + kernels un-gated (Niko1221#820 note updated), STRATA_DENSE_MMQ_MAXT T-gate added (MMQ = bandwidth regime small-T, cuBLAS FP16 tensor cores = compute regime large-T). Build reconfigured STRATA_MMQ_KQUANTS=ON (libstrata_kq.so 14.5MB deployed to engine/). ENGAGEMENT confirmed (K-quant kernels opened + dense MMQ on). Paired probes BOTH boot orders: 21k-tok -2% SLOWER (real, warm-bias favored arm), 2.7k-tok +3.1% FASTER, 1k +0.45% - the a1444e3 curve shape, crossover ~4k. Gated arm (MAXT=4096) 3v3 + MMLU 2x chain running
samnolak
added a commit
to samnolak/Strata
that referenced
this pull request
Nov 2, 2026
…pt projections as int8 MMQ Gemm::native_mmq was HIP-only. On a GeForce Ada card FP16 x FP16 -> FP32 runs at half the FP16 rate (RTX 4080: 97.5 TFLOPS) while int8 runs at 389.9 TOPS, and the FP16 path dequantizes every dense weight again for every chunk. UD-Q6_K_XL keeps its dense projections in Q8_0 (attn_qkv / attn_gate / ssm_out, attn_q / k / v / output, the shared expert's gate / up): ~2.9 G weights, ~55 % of a prompt token's GEMM work, while the routed experts already run on MMQ. - gemm.cu: the native_mmq guards are STRATA_PREFILL_MMQ only (CUDA builds define it with the native experts); STRATA_DENSE_MMQ=1 as on HIP, plus STRATA_DENSE_MMQ_MIN_T=N (only products of >= N rows); not with STRATA_DEQUANT_SIDE (its side dequant into the scratch would not wait for this product's FP32 rows there). - moe_mmq.cu: f16_to_f32 / set_bounds on CUDA too (Niko1221#820 had kept them HIP-only). - dense_mmq_rules.hpp + dense_mmq_rules_test (CPU): the switch parse, the K rule (K % 256 == 0, K <= 8192: the 640-wide shared-expert down stays on cuBLAS), the row passes. Not bit-identical to the FP16 path (W8A8, q8_1 activations, as the routed experts and decode's MMVQ): off by default, KL gate before use. Unset: p55/final's paths, unchanged bits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Notes
This repository is being on the move constantly so its hard to catch up to the
currentbranch, but i'll be trying to keep this up to date.. i don't have anai subscription though so sometimes the update speed is too demanding :')
What
The prompt path's dense GGUF projections run dequantize-to-FP16 + cuBLAS. On the
AMD cards (checked with rocprof on an RX 6900 XT) that is 68% of the prefill GPU
time at ~25% of the card's fp32-accumulate rate, while the same shapes through
llama.cpp's int8 MMQ run ~7x faster. This PR wires them through the MMQ path the
MoE experts already take, opt-in:
Gemm::native'sbeta == 0products with a covered type, a K that is amultiple of 256 values, and a matrix whose tile fits the card's shared memory
run
mmq::quantize+ onemul_mat_qper 1024-row chunk (the FP16 activationsare widened to FP32 in the dequant scratch, which the old path only fills
afterwards).
STRATA_DENSE_MMQ=1opts in; unset, nothing changes. Thefirst dense call prints
prefill gemm: dense MMQ on.STRATA_MMQ_KQUANTSnow also compiles theq4_k q5_k q5_1 q6_kinstances anddefines
STRATA_MMQ_KQUANTSon the HIP branch (the mixed-quant packs' densetensors are K-quants: this model's attention/PLE matrices are
IQ4_XS/IQ3_S/Q4_K/Q5_K/Q6_K), and adds
q6_kto the CUDA list (the usualattention weight of plain i-quant GGUFs).
moe_mmqgrows two small helpers:f16_to_f32and a{0, rows}boundswriter.
hip_prefill_mmq_paritygains synthetic Q4_K/Q5_K/Q6_K/Q5_1 passes (skippedwhen the build does not have the instances).
Why K must be a full 256-value multiple
llama.cpp's MMQ loads the weights in 256-value K chunks; the chunk past a
partial row reads bytes past the row - the next row's, or, for the last weight
row, past the whole tensor. The MoE path is safe because its expert gather
buffers end in a zeroed tail; a dense GGUF tensor is passed as-is, so what
follows it is the next tensor's blocks in the mapping. On swift-1.5-iq3_xxs the
640-value IQ4_NL shared-expert down picked a NaN scale out of those bytes and
produced a whole NaN output column, which zeroed the model output - found and
minimized with a type-bisect env knob and an operand-capture replay harness. The
odd shapes stay on the dequantize + cuBLAS path.
Testing (RX 6900 XT, gfx1030, ROCm 7.2.3, i7-13700KF)
-DSTRATA_MMQ_KQUANTS=ON -DSTRATA_ENABLE_HIP=ON, swift-1.5-iq3_xxs, the user'sknobs
(
--pool-workers 15 --adapt-every 1 --prefill 8192 --kv-resident 32768 --vram-reserve-mib 1024),bench_prefill.pyfresh medians of two ~4K and two ~8K trials:+73-74% fresh prefill; decode within noise. Greedy output is bit-identical for
the first 200 tokens of a short prompt; longer greedy runs diverge around token
~26 (the q8_1 activation rounding) and stay coherent.
hip_prefill_mmq_paritypasses with the new K-quant passes (rel_l2 ≤ 0.005 vs ggml's own dequantizer on
the host).
Not tested: CUDA builds (the instance list change is mechanical), other AMD
archs, the q6_k CUDA instance end to end.