HelloSun commited on
Commit Β·
176ef13
1
Parent(s): 5482b0f
experiments: fix -nr methodology (llama-bench needs --repack 0), re-measure #27590 (-nr +0.7%/+1.4%); record #27032 (kernels subset, no gain, not merged) and corrected #18698 incremental (-4.1%/-2.1%, not merged); note -nr vs default on this machine
Browse files
README.md
CHANGED
|
@@ -248,7 +248,16 @@ host is noisy, each candidate is measured with an **alternating A/B
|
|
| 248 |
protocol**: two binaries built from the same source tree (baseline vs
|
| 249 |
baseline + candidate patch) are run interleaved in the same session
|
| 250 |
(`llama-bench -t 16 -r 3 -p 512 -n 128`, default settings, 3β8 rounds each);
|
| 251 |
-
the table reports the medians over all rounds.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 252 |
|
| 253 |
Only candidates that win beyond the run-to-run noise are merged into the
|
| 254 |
patch (β
ζεΉ«ε©); candidates without a real gain are recorded here with
|
|
@@ -259,8 +268,9 @@ their data and are **not** merged (β ζ²εΉ«ε©).
|
|
| 259 |
| upstream PR [#27024](https://github.com/ggml-org/llama.cpp/pull/27024) by [@jinzihao](https://github.com/jinzihao) | ggml-cpu/amx: fix the (dead) `block_q8_K` VNNI quantization and enable the VNNI path | β
ζεΉ«ε© β merged | 57.25 β 59.20 (**+3.4 %**) | 10.94 β 11.24 (**+2.7 %**) |
|
| 260 |
| upstream PR [#22525](https://github.com/ggml-org/llama.cpp/pull/22525) by [@HyeongiJeon](https://github.com/HyeongiJeon) | ggml-cpu: optimize `ggml_gemm_q4_K_8x8_q8_K` interleaving/staging for AVX-512 (and AVX2) | β
ζεΉ«ε©οΌprefillοΌβ merged | 55.78 β 57.42 (**+2.9 %**) | 10.70 β 10.87 (+1.5 %, neutral) |
|
| 261 |
| upstream PR [#19706](https://github.com/ggml-org/llama.cpp/pull/19706) by [@Manogna-Sree](https://github.com/Manogna-Sree) | Q6_K block interleaving for x86 SIMD (AVX-512/AVX2) | β ζ²εΉ«ε© β not merged | 58.16 β 58.34 (+0.3 %) | 11.06 β 11.07 (+0.1 %) |
|
| 262 |
-
| upstream PR [#27590](https://github.com/ggml-org/llama.cpp/pull/27590) by [@SongXiaoXi](https://github.com/SongXiaoXi) | ggml-cpu: add AVX-512/VNNI paths for Q5_K/Q6_K dot products | β
ζεΉ«ε©οΌ`-nr`οΌβ merged | `-nr`:
|
| 263 |
-
| upstream PR [#18698](https://github.com/ggml-org/llama.cpp/pull/18698) by [@zzjianhui](https://github.com/zzjianhui) | ggml-cpu: repack weights in parallel (OpenMP, NUMA-local thread placement) | β ζ²εΉ«ε©οΌζ¨θ«
|
|
|
|
| 264 |
|
| 265 |
Round-by-round for #27024 (candidate vs baseline, t/s):
|
| 266 |
|
|
@@ -316,59 +326,88 @@ noise. The base `Q3_K_M` model contains only **one** single `Q6_K` tensor,
|
|
| 316 |
so a faster Q6_K kernel has almost no weight to act on. The PR is *not*
|
| 317 |
merged; the data is recorded here for the record. Measured 2026-10-16.
|
| 318 |
|
| 319 |
-
Round-by-round for #27590 (candidate vs baseline, t/s), `-nr` mode
|
| 320 |
-
Q5_K/Q6_K dots this PR changes are used on
|
| 321 |
-
`-nr`; with default repacking those weights go
|
| 322 |
-
kernels instead
|
| 323 |
-
|
| 324 |
|
| 325 |
| round | pp512 | tg128 |
|
| 326 |
|---|---:|---:|
|
| 327 |
-
| 1 |
|
| 328 |
-
| 2 |
|
| 329 |
-
| 3 |
|
| 330 |
-
| 4 |
|
| 331 |
-
|
| 332 |
-
|
| 333 |
-
|
| 334 |
-
|
| 335 |
-
**Verdict β
ζεΉ«ε© (`-nr` 樑εΌ, +2.9 % prefill / +2.5 % decode medians,
|
| 336 |
-
5 of 7 rounds won on both).** In this model the PR affects Q5_K (2 tensors,
|
| 337 |
the dense `ffn_down` of layers 0β1) and Q6_K (1 tensor β `output.weight`,
|
| 338 |
-
the 388 M-param head that is read on every token)
|
| 339 |
-
|
| 340 |
-
review), so it received extra
|
|
|
|
| 341 |
|
| 342 |
- perplexity on a fixed corpus: 1.0354 β 1.0354 (identical)
|
| 343 |
- `test-backend-ops -b CPU -o MUL_MAT -p 'type=q5_K|type=q6_K'` passes
|
| 344 |
|
| 345 |
-
Merged.
|
|
|
|
| 346 |
|
| 347 |
-
Round-by-round for #18698 (candidate vs baseline
|
| 348 |
-
|
| 349 |
-
|
| 350 |
-
|
|
|
|
| 351 |
|
| 352 |
| round | pp512 | tg128 |
|
| 353 |
|---|---:|---:|
|
| 354 |
-
| 1 |
|
| 355 |
-
| 2 |
|
| 356 |
-
| 3 |
|
| 357 |
-
|
| 358 |
-
|
| 359 |
-
|
| 360 |
-
|
| 361 |
-
|
| 362 |
-
|
| 363 |
-
|
| 364 |
-
|
| 365 |
-
|
| 366 |
-
page cache) from 24 s (2/2 runs) to 10 s (2/2 runs) β but the inference phase
|
| 367 |
-
itself gains nothing, so per the merge rule (real tok/s gains) the candidate
|
| 368 |
-
is **not** merged. Correctness: perplexity 1.0361 β 1.0361 (identical), i.e.
|
| 369 |
the parallel repack produces identical weights; the regression is presumably
|
| 370 |
a NUMA page-placement effect, not a data error. Measured 2026-10-16.
|
| 371 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 372 |
## License
|
| 373 |
|
| 374 |
This project (the patch set, `patch.sh` and documentation) is licensed
|
|
|
|
| 248 |
protocol**: two binaries built from the same source tree (baseline vs
|
| 249 |
baseline + candidate patch) are run interleaved in the same session
|
| 250 |
(`llama-bench -t 16 -r 3 -p 512 -n 128`, default settings, 3β8 rounds each);
|
| 251 |
+
the table reports the medians over all rounds. Every number is
|
| 252 |
+
**incremental**: each candidate is compared against the **previous merged
|
| 253 |
+
state**, not against the original port.
|
| 254 |
+
|
| 255 |
+
> Methodology fix (2026-10-16): a first attempt measured `-nr` via the
|
| 256 |
+
> `LLAMA_ARG_REPACK=0` env var. `llama-bench` ignores that variable (it has
|
| 257 |
+
> its own parser; only common-arg tools such as `llama-cli` /
|
| 258 |
+
> `llama-perplexity` honor it), so those runs were silently default-mode.
|
| 259 |
+
> The `-nr` entry for #27590 was re-measured with `llama-bench --repack 0`,
|
| 260 |
+
> the flag the tool actually supports.
|
| 261 |
|
| 262 |
Only candidates that win beyond the run-to-run noise are merged into the
|
| 263 |
patch (β
ζεΉ«ε©); candidates without a real gain are recorded here with
|
|
|
|
| 268 |
| upstream PR [#27024](https://github.com/ggml-org/llama.cpp/pull/27024) by [@jinzihao](https://github.com/jinzihao) | ggml-cpu/amx: fix the (dead) `block_q8_K` VNNI quantization and enable the VNNI path | β
ζεΉ«ε© β merged | 57.25 β 59.20 (**+3.4 %**) | 10.94 β 11.24 (**+2.7 %**) |
|
| 269 |
| upstream PR [#22525](https://github.com/ggml-org/llama.cpp/pull/22525) by [@HyeongiJeon](https://github.com/HyeongiJeon) | ggml-cpu: optimize `ggml_gemm_q4_K_8x8_q8_K` interleaving/staging for AVX-512 (and AVX2) | β
ζεΉ«ε©οΌprefillοΌβ merged | 55.78 β 57.42 (**+2.9 %**) | 10.70 β 10.87 (+1.5 %, neutral) |
|
| 270 |
| upstream PR [#19706](https://github.com/ggml-org/llama.cpp/pull/19706) by [@Manogna-Sree](https://github.com/Manogna-Sree) | Q6_K block interleaving for x86 SIMD (AVX-512/AVX2) | β ζ²εΉ«ε© β not merged | 58.16 β 58.34 (+0.3 %) | 11.06 β 11.07 (+0.1 %) |
|
| 271 |
+
| upstream PR [#27590](https://github.com/ggml-org/llama.cpp/pull/27590) by [@SongXiaoXi](https://github.com/SongXiaoXi) | ggml-cpu: add AVX-512/VNNI paths for Q5_K/Q6_K dot products | β
ζεΉ«ε©οΌ`-nr`οΌβ merged | `-nr`: 65.91 β 66.35 (+0.7 %) | `-nr`: 11.16 β 11.32 (**+1.4 %**) |
|
| 272 |
+
| upstream PR [#18698](https://github.com/ggml-org/llama.cpp/pull/18698) by [@zzjianhui](https://github.com/zzjianhui) | ggml-cpu: repack weights in parallel (OpenMP, NUMA-local thread placement) | β ζ²εΉ«ε©οΌζ¨θ«ιεοΌβ not merged | 56.93 β 54.58 (**β4.1 %**) | 10.67 β 10.45 (**β2.1 %**) |
|
| 273 |
+
| draft PR [#27032](https://github.com/ggml-org/llama.cpp/pull/27032) by [@lexasub](https://github.com/lexasub) | CPU optimizations (GET_ROWS+ADD fusion, `get_rows` fast paths, tokenizer, KV-cell rework) β only the ggml-kernel subset is portable onto this tree | β ζ²εΉ«ε©οΌδΈι©η¨ζΌζ¬ζ¨‘εοΌβ not merged | 56.64 β 56.88 (+0.4 %) | 10.82 β 10.73 (β0.8 %) |
|
| 274 |
|
| 275 |
Round-by-round for #27024 (candidate vs baseline, t/s):
|
| 276 |
|
|
|
|
| 326 |
so a faster Q6_K kernel has almost no weight to act on. The PR is *not*
|
| 327 |
merged; the data is recorded here for the record. Measured 2026-10-16.
|
| 328 |
|
| 329 |
+
Round-by-round for #27590 (candidate vs baseline, t/s), `-nr` mode
|
| 330 |
+
(`llama-bench --repack 0`). The Q5_K/Q6_K dots this PR changes are used on
|
| 331 |
+
the plain CPU path selected by `-nr`; with default repacking those weights go
|
| 332 |
+
through the repack gemv/gemm kernels instead (default-mode incremental
|
| 333 |
+
measured ~neutral, within noise):
|
| 334 |
|
| 335 |
| round | pp512 | tg128 |
|
| 336 |
|---|---:|---:|
|
| 337 |
+
| 1 | 67.88 vs 67.80 | 11.17 vs 11.15 |
|
| 338 |
+
| 2 | 66.08 vs 66.46 | 11.46 vs 11.18 |
|
| 339 |
+
| 3 | 66.01 vs 65.34 | 11.32 vs 11.19 |
|
| 340 |
+
| 4 | 66.63 vs 65.36 | 11.33 vs 11.12 |
|
| 341 |
+
|
| 342 |
+
**Verdict β
ζεΉ«ε© (`-nr` 樑εΌ, +0.7 % prefill / +1.4 % decode medians;
|
| 343 |
+
decode won 4 of 4 rounds).** In this model the PR affects Q5_K (2 tensors,
|
|
|
|
|
|
|
|
|
|
| 344 |
the dense `ffn_down` of layers 0β1) and Q6_K (1 tensor β `output.weight`,
|
| 345 |
+
the 388 M-param head that is read on every token), so the consistent decode
|
| 346 |
+
win matches the expectation. One caveat: the upstream PR is *closed but never
|
| 347 |
+
merged* (only an automated AI-content flag, no review), so it received extra
|
| 348 |
+
local validation before merging:
|
| 349 |
|
| 350 |
- perplexity on a fixed corpus: 1.0354 β 1.0354 (identical)
|
| 351 |
- `test-backend-ops -b CPU -o MUL_MAT -p 'type=q5_K|type=q6_K'` passes
|
| 352 |
|
| 353 |
+
Merged. Re-measured 2026-10-16 with the correct `--repack 0` flag (see
|
| 354 |
+
methodology note above).
|
| 355 |
|
| 356 |
+
Round-by-round for #18698 (candidate vs baseline = current HEAD i.e. all
|
| 357 |
+
merged patches, t/s), default settings. This PR repacks the quantized
|
| 358 |
+
weights in parallel with OpenMP and pins each repack thread NUMA-local.
|
| 359 |
+
(Ported by hand: the year-old PR conflicts with the current tree and depends
|
| 360 |
+
on the never-merged PR #18239.)
|
| 361 |
|
| 362 |
| round | pp512 | tg128 |
|
| 363 |
|---|---:|---:|
|
| 364 |
+
| 1 | 54.24 vs 56.40 | 10.48 vs 10.35 |
|
| 365 |
+
| 2 | 55.50 vs 57.92 | 10.37 vs 10.67 |
|
| 366 |
+
| 3 | 54.58 vs 56.93 | 10.45 vs 10.87 |
|
| 367 |
+
|
| 368 |
+
**Verdict β ζ²εΉ«ε© (clear prefill regression, not merged).** Medians:
|
| 369 |
+
prefill β4.1 % (0 W / 3 L) and decode β2.1 % (1 W / 2 L); an earlier 5-round
|
| 370 |
+
block against the same effective baseline agreed on prefill (β2.7 %,
|
| 371 |
+
1 W / 4 L) with noisy decode. Side effect worth recording: the parallel
|
| 372 |
+
repack cuts model **load** wall time (load + tiny bench, warm page cache)
|
| 373 |
+
from 24 s (2/2 runs) to 10 s (2/2 runs) β but the inference phase itself
|
| 374 |
+
gets slower, so per the merge rule (real tok/s gains) the candidate is
|
| 375 |
+
**not** merged. Correctness: perplexity 1.0361 β 1.0361 (identical), i.e.
|
|
|
|
|
|
|
|
|
|
| 376 |
the parallel repack produces identical weights; the regression is presumably
|
| 377 |
a NUMA page-placement effect, not a data error. Measured 2026-10-16.
|
| 378 |
|
| 379 |
+
Round-by-round for draft #27032 (candidate vs baseline = current HEAD, t/s),
|
| 380 |
+
default settings. The draft bundles several optimizations (GET_ROWS+ADD
|
| 381 |
+
fusion, `get_rows` fast paths, tokenizer, KV-cell rework). The KV/batch and
|
| 382 |
+
tokenizer parts are either **not portable** (rooted in a pre-refactor
|
| 383 |
+
KV-cell design that conflicts with this tree) or not measurable with this
|
| 384 |
+
protocol; only the disjoint ggml CPU-kernel subset could be ported and
|
| 385 |
+
tested:
|
| 386 |
+
|
| 387 |
+
| round | pp512 | tg128 |
|
| 388 |
+
|---|---:|---:|
|
| 389 |
+
| 1 | 57.49 vs 56.64 | 10.73 vs 10.82 |
|
| 390 |
+
| 2 | 56.88 vs 58.68 | 10.85 vs 10.75 |
|
| 391 |
+
| 3 | 55.71 vs 56.50 | 10.35 vs 10.95 |
|
| 392 |
+
|
| 393 |
+
**Verdict β ζ²εΉ«ε© (not applicable to this model, not merged).** βΒ±1 % on
|
| 394 |
+
both metrics, PPL identical (1.0361). The reason follows from the graph and
|
| 395 |
+
kernel dispatch: (1) the GET_ROWS+ADD fusion needs an ADD node immediately
|
| 396 |
+
after a GET_ROWS node β this model's graph has no such pattern; (2) the
|
| 397 |
+
optimized Q4_K dequant path is not used (`token_embd` is Q3_K); (3) the
|
| 398 |
+
remaining `get_rows` cache-hit path only helps repeated 1-row gathers, which
|
| 399 |
+
this workload barely has. Recorded for the record. Measured 2026-10-16.
|
| 400 |
+
|
| 401 |
+
### `-nr` vs default on this machine
|
| 402 |
+
|
| 403 |
+
Side observation from the re-anchoring session: on this AMX machine the
|
| 404 |
+
plain-CPU (`-nr`) path is clearly faster than the default repack path.
|
| 405 |
+
HEAD (all merged patches): pp512 56.93 β 66.35 (**+16.6 %**) and tg128
|
| 406 |
+
10.67 β 11.32 (**+6.1 %**) with `--repack 0` (3β4 interleaved rounds each,
|
| 407 |
+
2026-10-16). The repack kernels used by default have no AMX path, while the
|
| 408 |
+
plain Q4_KΓQ8_K kernels use AMX (boosted further by #27024). On AMX-class
|
| 409 |
+
machines it is worth testing `-nr` for ~+15 % prefill.
|
| 410 |
+
|
| 411 |
## License
|
| 412 |
|
| 413 |
This project (the patch set, `patch.sh` and documentation) is licensed
|