Skip to content

metal: Q2_0 backend - #25419

Merged
ggerganov merged 1 commit into
ggml-org:masterfrom
PrismML-Eng:pr/q2_0-metal
Jul 14, 2026
Merged

ggerganov merged 1 commit into
ggml-org:masterfrom
PrismML-Eng:pr/q2_0-metal

Conversation

@khosravipasha

@khosravipasha khosravipasha commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Overview

Follow up PR after merging of Q2_0 CPU PR[#24448].
This PR adds the Metal backend support for Q2_0.

Supported Models

Supported Models: Ternary-Bonsai-{8B, 4B, 1.7B}-Q2_0_g64.gguf, more coming very soon.

Note: In our huggingface repos ggufs ending with _Q2_0_64.gguf are packed for this PR, Q2_0.gguf ones are older packing from our fork that have group 128, after all backends merge will rename and replace with the official Q2_0(group size 64)).

# downloads to models/Ternary-Bonsai-<size>-Q2_0_g64.gguf
hf download prism-ml/Ternary-Bonsai-1.7B-gguf Ternary-Bonsai-1.7B-Q2_0_g64.gguf --local-dir models
hf download prism-ml/Ternary-Bonsai-4B-gguf  Ternary-Bonsai-4B-Q2_0_g64.gguf  --local-dir models
hf download prism-ml/Ternary-Bonsai-8B-gguf  Ternary-Bonsai-8B-Q2_0_g64.gguf  --local-dir models

Correctness: Metal vs CPU logits KL

The ensure correctness we run the model twice: 1) Q2_0 CPU 2) Q2_0 Metal. We store the logits for both and compare the KL divergence. Using the standard llama-perplexity tool.

# reference logits from the CPU kernel
./build/bin/llama-perplexity -m models/Ternary-Bonsai-<size>-Q2_0_g64.gguf \
  -f datasets/wikitext-2-raw/wiki.test.raw -c 512 --chunks 20 -ngl 0 --save-all-logits cpu.bin
# Metal vs CPU
./build/bin/llama-perplexity -m models/Ternary-Bonsai-<size>-Q2_0_g64.gguf \
  -f datasets/wikitext-2-raw/wiki.test.raw -c 512 --chunks 20 -ngl 99 \
  --kl-divergence --kl-divergence-base cpu.bin
size Mean KLD Maximum KLD Same top-1
1.7B 0.000000 ± 0.000000 0.000062 99.980 %
4B 0.000000 ± 0.000000 0.000067 99.980 %
8B 0.000000 ± 0.000000 0.000056 99.980 %

Metal Q2_0 matches the CPU reference (Mean KLD ~0, top-1 ≥99.9%).

Speeds: llama-bench Metal

./build/bin/llama-bench -m models/Ternary-Bonsai-<size>-Q2_0_g64.gguf -ngl 99 -p 512 -n 128 -r 5
| model           |       size |     params | backend  | ngl |  test |               t/s |
| --------------- | ---------: | ---------: | -------- | --: | ----: | ----------------: |
| qwen3 1.7B Q2_0 | 461.79 MiB |     1.72 B | MTL,BLAS |  99 | pp512 |  2148.81 ±  4.82  |
| qwen3 1.7B Q2_0 | 461.79 MiB |     1.72 B | MTL,BLAS |  99 | tg128 |   246.01 ±  0.57  |
| qwen3 4B Q2_0   |   1.05 GiB |     4.02 B | MTL,BLAS |  99 | pp512 |   856.51 ±  0.74  |
| qwen3 4B Q2_0   |   1.05 GiB |     4.02 B | MTL,BLAS |  99 | tg128 |   124.05 ±  1.44  |
| qwen3 8B Q2_0   |   2.15 GiB |     8.19 B | MTL,BLAS |  99 | pp512 |   457.85 ±  1.45  |
| qwen3 8B Q2_0   |   2.15 GiB |     8.19 B | MTL,BLAS |  99 | tg128 |    77.31 ±  0.37  |

Requirements

  • I have read and agree with the contributing guidelines: Yes

  • AI usage disclosure: Initial boilerplate code for Metal kernels were generated with AI for Q2_0 group size 64, manually reviewed all changes, and verified correctness using KL-test as above. Have been using the packed models and its working well as expected. Tested again after rebasing with new changes to make sure model is behaving as expected.

@khosravipasha
khosravipasha requested a review from a team as a code owner July 7, 2026 22:10
@github-actions github-actions Bot added ggml changes relating to the ggml tensor library for machine learning Apple Metal https://en.wikipedia.org/wiki/Metal_(API) labels Jul 7, 2026
@khosravipasha

Copy link
Copy Markdown
Contributor Author

rebased to fix some merge conflicts, few things were moved (e.g. kernel_get_rows_q2_0)

@jeffbolznv jeffbolznv mentioned this pull request Jul 8, 2026
@ggerganov

Copy link
Copy Markdown
Member

@khosravipasha Could you rebase to latest master to see if this will fix the CI?

@ggerganov ggerganov self-assigned this Jul 13, 2026
@khosravipasha

khosravipasha commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

@ggerganov thanks, rebased with recent master.
Did not need any changes, rebased cleanly.

Running the CI on our fork as well PrismML-Eng#60

@khosravipasha

khosravipasha commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

This time more tests passed, some failures in ubuntu (x64, ubuntu-22.04). From glacing at it does not seem relate to this PR.

@ggerganov
ggerganov merged commit 14d3ba4 into ggml-org:master Jul 14, 2026
31 of 33 checks passed
RehanQasim-dev pushed a commit to aifoundry-org/llama.cpp that referenced this pull request Jul 23, 2026
RehanQasim-dev pushed a commit to aifoundry-org/llama.cpp that referenced this pull request Jul 23, 2026
ggerganov added a commit that referenced this pull request Jul 28, 2026
forforever73 pushed a commit that referenced this pull request Aug 4, 2026
satindergrewal pushed a commit to satindergrewal/llama.cpp that referenced this pull request Aug 12, 2026
abrisene pushed a commit to abrisene/llama.cpp that referenced this pull request Aug 19, 2026
forforever73 pushed a commit that referenced this pull request Aug 22, 2026
ggerganov added a commit that referenced this pull request Aug 24, 2026
* metal : per-op source split + parallel compile (#24021)

* preliminary extract common header

* op source split

* split metallib into 8 libs && load in parallel

* derive kernel->library routing from functionNames

* x-macro lib list + underscore filenames, dedup QK_NL, MRC fixes

* op source split 8 to 20

* improve robustness of source fallback

* clean up

* change bool -> atomic_bool

* only prepend headers that source actually includes

* no semaphore, use GCD global queue

* dedup library compile path, fix NSError lifetime, rename gla

* relocate upstream concat/rope_back/repeat kernel changes into split files

* move ggml-common.h from common.h into dequantize.h to shrink binary size

---------

Co-authored-by: lvyichen <lvyichen@stepfun.com>

* metal: add col2im_1d op (f32/f16/bf16) (#25176)

* metal : add set_rows with src0 f16 (#25434)

* metal : add CONV_2D_DW (depthwise convolution) support (#21565)

* metal : add Q2_0 support (#25419)

* metal: fuse snake activation (mul, sin, sqr, mul, add) (#25459)

* ggml-metal: FWHT kernel for metal backend (#25924)

* metal : port new kernels into the split sources

Move the kernels added on master after the split (lightning indexer,
DSv4 hyper-connections, silu_back, f16 bin ops, TQ2_0, the flash-attn KV
dequantization pass, rope offset/inplace, ssm_scan rollback, packed q8_0
dequantization and the tensor-API mat-mat K clamp) into the corresponding
kernels/*.metal sources. Copied verbatim, no functional change.

---------

Co-authored-by: lvyichen <lvyichen@stepfun.com>
Co-authored-by: Georgi Gerganov <ggerganov@gmail.com>
therealkenc pushed a commit to therealkenc/llama.cpp that referenced this pull request Aug 24, 2026
* metal : per-op source split + parallel compile (ggml-org#24021)

* preliminary extract common header

* op source split

* split metallib into 8 libs && load in parallel

* derive kernel->library routing from functionNames

* x-macro lib list + underscore filenames, dedup QK_NL, MRC fixes

* op source split 8 to 20

* improve robustness of source fallback

* clean up

* change bool -> atomic_bool

* only prepend headers that source actually includes

* no semaphore, use GCD global queue

* dedup library compile path, fix NSError lifetime, rename gla

* relocate upstream concat/rope_back/repeat kernel changes into split files

* move ggml-common.h from common.h into dequantize.h to shrink binary size

---------

Co-authored-by: lvyichen <lvyichen@stepfun.com>

* metal: add col2im_1d op (f32/f16/bf16) (ggml-org#25176)

* metal : add set_rows with src0 f16 (ggml-org#25434)

* metal : add CONV_2D_DW (depthwise convolution) support (ggml-org#21565)

* metal : add Q2_0 support (ggml-org#25419)

* metal: fuse snake activation (mul, sin, sqr, mul, add) (ggml-org#25459)

* ggml-metal: FWHT kernel for metal backend (ggml-org#25924)

* metal : port new kernels into the split sources

Move the kernels added on master after the split (lightning indexer,
DSv4 hyper-connections, silu_back, f16 bin ops, TQ2_0, the flash-attn KV
dequantization pass, rope offset/inplace, ssm_scan rollback, packed q8_0
dequantization and the tensor-API mat-mat K clamp) into the corresponding
kernels/*.metal sources. Copied verbatim, no functional change.

---------

Co-authored-by: lvyichen <lvyichen@stepfun.com>
Co-authored-by: Georgi Gerganov <ggerganov@gmail.com>
@khosravipasha
khosravipasha deleted the pr/q2_0-metal branch August 25, 2026 22:40
thecodacus pushed a commit to thecodacus/llama.cpp that referenced this pull request Sep 7, 2026
* metal : per-op source split + parallel compile (ggml-org#24021)

* preliminary extract common header

* op source split

* split metallib into 8 libs && load in parallel

* derive kernel->library routing from functionNames

* x-macro lib list + underscore filenames, dedup QK_NL, MRC fixes

* op source split 8 to 20

* improve robustness of source fallback

* clean up

* change bool -> atomic_bool

* only prepend headers that source actually includes

* no semaphore, use GCD global queue

* dedup library compile path, fix NSError lifetime, rename gla

* relocate upstream concat/rope_back/repeat kernel changes into split files

* move ggml-common.h from common.h into dequantize.h to shrink binary size

---------

Co-authored-by: lvyichen <lvyichen@stepfun.com>

* metal: add col2im_1d op (f32/f16/bf16) (ggml-org#25176)

* metal : add set_rows with src0 f16 (ggml-org#25434)

* metal : add CONV_2D_DW (depthwise convolution) support (ggml-org#21565)

* metal : add Q2_0 support (ggml-org#25419)

* metal: fuse snake activation (mul, sin, sqr, mul, add) (ggml-org#25459)

* ggml-metal: FWHT kernel for metal backend (ggml-org#25924)

* metal : port new kernels into the split sources

Move the kernels added on master after the split (lightning indexer,
DSv4 hyper-connections, silu_back, f16 bin ops, TQ2_0, the flash-attn KV
dequantization pass, rope offset/inplace, ssm_scan rollback, packed q8_0
dequantization and the tensor-API mat-mat K clamp) into the corresponding
kernels/*.metal sources. Copied verbatim, no functional change.

---------

Co-authored-by: lvyichen <lvyichen@stepfun.com>
Co-authored-by: Georgi Gerganov <ggerganov@gmail.com>
zbrad pushed a commit to zbrad/llama.cpp that referenced this pull request Sep 10, 2026
zbrad pushed a commit to zbrad/llama.cpp that referenced this pull request Sep 10, 2026
* metal : per-op source split + parallel compile (ggml-org#24021)

* preliminary extract common header

* op source split

* split metallib into 8 libs && load in parallel

* derive kernel->library routing from functionNames

* x-macro lib list + underscore filenames, dedup QK_NL, MRC fixes

* op source split 8 to 20

* improve robustness of source fallback

* clean up

* change bool -> atomic_bool

* only prepend headers that source actually includes

* no semaphore, use GCD global queue

* dedup library compile path, fix NSError lifetime, rename gla

* relocate upstream concat/rope_back/repeat kernel changes into split files

* move ggml-common.h from common.h into dequantize.h to shrink binary size

---------

Co-authored-by: lvyichen <lvyichen@stepfun.com>

* metal: add col2im_1d op (f32/f16/bf16) (ggml-org#25176)

* metal : add set_rows with src0 f16 (ggml-org#25434)

* metal : add CONV_2D_DW (depthwise convolution) support (ggml-org#21565)

* metal : add Q2_0 support (ggml-org#25419)

* metal: fuse snake activation (mul, sin, sqr, mul, add) (ggml-org#25459)

* ggml-metal: FWHT kernel for metal backend (ggml-org#25924)

* metal : port new kernels into the split sources

Move the kernels added on master after the split (lightning indexer,
DSv4 hyper-connections, silu_back, f16 bin ops, TQ2_0, the flash-attn KV
dequantization pass, rope offset/inplace, ssm_scan rollback, packed q8_0
dequantization and the tensor-API mat-mat K clamp) into the corresponding
kernels/*.metal sources. Copied verbatim, no functional change.

---------

Co-authored-by: lvyichen <lvyichen@stepfun.com>
Co-authored-by: Georgi Gerganov <ggerganov@gmail.com>
pl752 pushed a commit to pl752/llama.cpp that referenced this pull request Sep 15, 2026
pl752 pushed a commit to pl752/llama.cpp that referenced this pull request Sep 15, 2026
* metal : per-op source split + parallel compile (ggml-org#24021)

* preliminary extract common header

* op source split

* split metallib into 8 libs && load in parallel

* derive kernel->library routing from functionNames

* x-macro lib list + underscore filenames, dedup QK_NL, MRC fixes

* op source split 8 to 20

* improve robustness of source fallback

* clean up

* change bool -> atomic_bool

* only prepend headers that source actually includes

* no semaphore, use GCD global queue

* dedup library compile path, fix NSError lifetime, rename gla

* relocate upstream concat/rope_back/repeat kernel changes into split files

* move ggml-common.h from common.h into dequantize.h to shrink binary size

---------

Co-authored-by: lvyichen <lvyichen@stepfun.com>

* metal: add col2im_1d op (f32/f16/bf16) (ggml-org#25176)

* metal : add set_rows with src0 f16 (ggml-org#25434)

* metal : add CONV_2D_DW (depthwise convolution) support (ggml-org#21565)

* metal : add Q2_0 support (ggml-org#25419)

* metal: fuse snake activation (mul, sin, sqr, mul, add) (ggml-org#25459)

* ggml-metal: FWHT kernel for metal backend (ggml-org#25924)

* metal : port new kernels into the split sources

Move the kernels added on master after the split (lightning indexer,
DSv4 hyper-connections, silu_back, f16 bin ops, TQ2_0, the flash-attn KV
dequantization pass, rope offset/inplace, ssm_scan rollback, packed q8_0
dequantization and the tensor-API mat-mat K clamp) into the corresponding
kernels/*.metal sources. Copied verbatim, no functional change.

---------

Co-authored-by: lvyichen <lvyichen@stepfun.com>
Co-authored-by: Georgi Gerganov <ggerganov@gmail.com>
zsogitbe pushed a commit to zsogitbe/llama.cpp that referenced this pull request Sep 17, 2026
* metal : per-op source split + parallel compile (ggml-org#24021)

* preliminary extract common header

* op source split

* split metallib into 8 libs && load in parallel

* derive kernel->library routing from functionNames

* x-macro lib list + underscore filenames, dedup QK_NL, MRC fixes

* op source split 8 to 20

* improve robustness of source fallback

* clean up

* change bool -> atomic_bool

* only prepend headers that source actually includes

* no semaphore, use GCD global queue

* dedup library compile path, fix NSError lifetime, rename gla

* relocate upstream concat/rope_back/repeat kernel changes into split files

* move ggml-common.h from common.h into dequantize.h to shrink binary size

---------

Co-authored-by: lvyichen <lvyichen@stepfun.com>

* metal: add col2im_1d op (f32/f16/bf16) (ggml-org#25176)

* metal : add set_rows with src0 f16 (ggml-org#25434)

* metal : add CONV_2D_DW (depthwise convolution) support (ggml-org#21565)

* metal : add Q2_0 support (ggml-org#25419)

* metal: fuse snake activation (mul, sin, sqr, mul, add) (ggml-org#25459)

* ggml-metal: FWHT kernel for metal backend (ggml-org#25924)

* metal : port new kernels into the split sources

Move the kernels added on master after the split (lightning indexer,
DSv4 hyper-connections, silu_back, f16 bin ops, TQ2_0, the flash-attn KV
dequantization pass, rope offset/inplace, ssm_scan rollback, packed q8_0
dequantization and the tensor-API mat-mat K clamp) into the corresponding
kernels/*.metal sources. Copied verbatim, no functional change.

---------

Co-authored-by: lvyichen <lvyichen@stepfun.com>
Co-authored-by: Georgi Gerganov <ggerganov@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Apple Metal https://en.wikipedia.org/wiki/Metal_(API) ggml changes relating to the ggml tensor library for machine learning

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants