cuda: tune the mmvq/mmq crossover for Turing
Turing had no entry in ggml_cuda_should_use_mmvq and fell through to the generic ne11 <= 8, while Ada, Blackwell, DGX Spark and Orin all have measured switch points. MMQ overtakes MMVQ far earlier than n=8 on SM75. Measured on a CMP 50HX (cc 7.5, CUDA 13.3) with test-backend-ops perf, medians of 4 reps after a discarded warmup, forcing each path via an instrumentation build. MMQ speedup over MMVQ at n=8: q2_K 2.57x q3_K 2.13x q4_K 1.96x iq4_xs 1.93x q5_K 1.79x q6_K 1.74x End to end on Qwen3.5-9B-UD-Q4_K_XL, llama-bench, medians of 3 interleaved rounds at -r 20: pp1 -0.2% pp2 0.0% pp3 0.0% pp4 +3.2% pp5 +12.1% pp8 +47.6% q6_K is deliberately 3 rather than the 2 the synthetic sweep suggested. That sweep had a single shape for q6_K and MMQ won it by only 1.02x, the weakest margin measured. With the threshold at 2 the model regressed 2% at pp3, reproducibly across three rounds: its 24 q6_K tensors were the only ones switching path at that batch size. The synthetic margin did not survive on the model's real q6_K shapes, so mmvq keeps n=3 for that type. q4_K was measured across five m/k shapes; at n=3 mmvq wins 1.19x/1.09x/1.08x on three and loses 1.01x on two, geometric mean 1.065 in mmvq's favour. At n=4 mmq wins on all five. The n=512 cases act as a control: above MMVQ_MAX_BATCH_SIZE neither mode can select mmvq, and both measure within 1.00x-1.01x of each other. Only the measured types are listed; everything else keeps the default. q2_K and q3_K rest on a single shape each and are not present in the model used for the end-to-end check, so they are less well evidenced than the rest.
This commit is contained in:
1 parent
6f65493dde
commit
85ff4657cb
1 file changed
+19
@@ -367,6 +367,25 @@ bool ggml_cuda_should_use_mmvq(enum ggml_type type, int cc, int64_t ne11) {
|
||||
return ne11 <= MMVQ_MAX_BATCH_SIZE;
|
||||
}
|
||||
}
|
||||
if (GGML_CUDA_CC_IS_NVIDIA(cc) && cc == GGML_CUDA_CC_TURING) {
|
||||
// Tuned on a CMP 50HX. Turing had no entry here and fell through to
|
||||
// ne11 <= 8, but MMQ overtakes MMVQ much earlier than that: by n=8 it
|
||||
// is 1.7x-2.6x faster depending on the type. Only the types measured
|
||||
// are listed; the rest keep the default.
|
||||
switch (type) {
|
||||
case GGML_TYPE_Q2_K:
|
||||
case GGML_TYPE_Q3_K:
|
||||
return ne11 <= 2;
|
||||
case GGML_TYPE_Q4_K:
|
||||
case GGML_TYPE_Q5_K:
|
||||
case GGML_TYPE_Q6_K:
|
||||
case GGML_TYPE_IQ4_XS:
|
||||
return ne11 <= 3;
|
||||
default:
|
||||
return ne11 <= MMVQ_MAX_BATCH_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
if (GGML_CUDA_CC_IS_NVIDIA(cc) && cc == GGML_CUDA_CC_VOLTA) {
|
||||
switch (type) {
|
||||
case GGML_TYPE_Q2_K:
|
||||
|
||||
Reference in new issue
Block a user