Skip to content

HIP: use hipBLAS for dense prefill on gfx900, keep MMQ for MoE - #24588

Merged
JohannesGaessler merged 4 commits into
ggml-org:masterfrom
DEV-DUFORD:gfx900-mmq
Jun 30, 2026
Merged

HIP: use hipBLAS for dense prefill on gfx900, keep MMQ for MoE#24588
JohannesGaessler merged 4 commits into
ggml-org:masterfrom
DEV-DUFORD:gfx900-mmq

Conversation

@DEV-DUFORD

@DEV-DUFORD DEV-DUFORD commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Overview

gfx900 (Vega 10) has no native dp4a. The current code forces MMQ for all GCN. This routes dense matmuls to dequant + hipBLAS on gfx900 while keeping MMQ for MoE, where hipBLAS is much slower.

Overall Performance Gains:

  • Qwen3.5 4B: +36.1%
  • Qwen3.6 27B: +18.9%
  • Gemma4 12B: +65.1%
  • Overall average: ~40%

Additional information

Before (Qwen3.5 4B):

nerd-dell@nerd-dell:~/llama.cpp$ ./build/bin/llama-bench -m ~/gguf_store/qwen3.5-4B/Qwen_Qwen3.5-4B-Q8_0.gguf -ngl 999 -sm tensor
 -p 16,32,64,128,256,512,1024,2048 -n 128
ggml_cuda_init: found 4 ROCm devices (Total VRAM: 32704 MiB):
  Device 0: AMD Radeon Graphics, gfx900:xnack- (0x900), VMM: no, Wave Size: 64, VRAM: 8176 MiB
  Device 1: AMD Radeon Graphics, gfx900:xnack- (0x900), VMM: no, Wave Size: 64, VRAM: 8176 MiB
  Device 2: AMD Radeon Graphics, gfx900:xnack- (0x900), VMM: no, Wave Size: 64, VRAM: 8176 MiB
  Device 3: AMD Radeon Graphics, gfx900:xnack- (0x900), VMM: no, Wave Size: 64, VRAM: 8176 MiB
| model                          |       size |     params | backend    | ngl |     sm |            test |                  t/s |
| ------------------------------ | ---------: | ---------: | ---------- | --: | -----: | --------------: | -------------------: |
| qwen35 4B Q8_0                 |   4.29 GiB |     4.33 B | ROCm       | 999 | tensor |            pp16 |       181.59 ± 73.88 |
| qwen35 4B Q8_0                 |   4.29 GiB |     4.33 B | ROCm       | 999 | tensor |            pp32 |       232.12 ± 69.22 |
| qwen35 4B Q8_0                 |   4.29 GiB |     4.33 B | ROCm       | 999 | tensor |            pp64 |       254.99 ± 19.22 |
| qwen35 4B Q8_0                 |   4.29 GiB |     4.33 B | ROCm       | 999 | tensor |           pp128 |        384.78 ± 4.11 |
| qwen35 4B Q8_0                 |   4.29 GiB |     4.33 B | ROCm       | 999 | tensor |           pp256 |        420.97 ± 1.74 |
| qwen35 4B Q8_0                 |   4.29 GiB |     4.33 B | ROCm       | 999 | tensor |           pp512 |        474.99 ± 0.68 |
| qwen35 4B Q8_0                 |   4.29 GiB |     4.33 B | ROCm       | 999 | tensor |          pp1024 |        458.11 ± 0.97 |
| qwen35 4B Q8_0                 |   4.29 GiB |     4.33 B | ROCm       | 999 | tensor |          pp2048 |        448.79 ± 1.31 |
| qwen35 4B Q8_0                 |   4.29 GiB |     4.33 B | ROCm       | 999 | tensor |           tg128 |         35.84 ± 1.60 |

build: 717920bf9 (9623)

After (Qwen3.5 4B):

nerd-dell@nerd-dell:~/llama.cpp$ ./build/bin/llama-bench -m ~/gguf_store/qwen3.5-4B/Qwen_Qwen3.5-4B-Q8_0.gguf -ngl 999 -sm tensor -p 16,32,64,128,256,512,1024,2048 -n 128
ggml_cuda_init: found 4 ROCm devices (Total VRAM: 32704 MiB):
  Device 0: AMD Radeon Graphics, gfx900:xnack- (0x900), VMM: no, Wave Size: 64, VRAM: 8176 MiB
  Device 1: AMD Radeon Graphics, gfx900:xnack- (0x900), VMM: no, Wave Size: 64, VRAM: 8176 MiB
  Device 2: AMD Radeon Graphics, gfx900:xnack- (0x900), VMM: no, Wave Size: 64, VRAM: 8176 MiB
  Device 3: AMD Radeon Graphics, gfx900:xnack- (0x900), VMM: no, Wave Size: 64, VRAM: 8176 MiB
| model                          |       size |     params | backend    | ngl |     sm |            test |                  t/s |
| ------------------------------ | ---------: | ---------: | ---------- | --: | -----: | --------------: | -------------------: |
| qwen35 4B Q8_0                 |   4.29 GiB |     4.33 B | ROCm       | 999 | tensor |            pp16 |       181.04 ± 73.63 |
| qwen35 4B Q8_0                 |   4.29 GiB |     4.33 B | ROCm       | 999 | tensor |            pp32 |      303.10 ± 114.31 |
| qwen35 4B Q8_0                 |   4.29 GiB |     4.33 B | ROCm       | 999 | tensor |            pp64 |      434.39 ± 126.31 |
| qwen35 4B Q8_0                 |   4.29 GiB |     4.33 B | ROCm       | 999 | tensor |           pp128 |       516.05 ± 68.64 |
| qwen35 4B Q8_0                 |   4.29 GiB |     4.33 B | ROCm       | 999 | tensor |           pp256 |        605.60 ± 7.74 |
| qwen35 4B Q8_0                 |   4.29 GiB |     4.33 B | ROCm       | 999 | tensor |           pp512 |        657.86 ± 4.46 |
| qwen35 4B Q8_0                 |   4.29 GiB |     4.33 B | ROCm       | 999 | tensor |          pp1024 |        623.32 ± 2.13 |
| qwen35 4B Q8_0                 |   4.29 GiB |     4.33 B | ROCm       | 999 | tensor |          pp2048 |        607.57 ± 0.68 |
| qwen35 4B Q8_0                 |   4.29 GiB |     4.33 B | ROCm       | 999 | tensor |           tg128 |         35.81 ± 1.77 |

build: 717920bf9 (9623)

Before (Qwen3.6 27B):

nerd-dell@nerd-dell:~/llama.cpp$ ./build/bin/llama-bench -m ~/gguf_store/Qwen3.6-27B-Q4_1.gguf -ngl 999 -sm tensor -p 16,32,64,128,
256,512,1024,2048 -n 128
ggml_cuda_init: found 4 ROCm devices (Total VRAM: 32704 MiB):
  Device 0: AMD Radeon Graphics, gfx900:xnack- (0x900), VMM: no, Wave Size: 64, VRAM: 8176 MiB
  Device 1: AMD Radeon Graphics, gfx900:xnack- (0x900), VMM: no, Wave Size: 64, VRAM: 8176 MiB
  Device 2: AMD Radeon Graphics, gfx900:xnack- (0x900), VMM: no, Wave Size: 64, VRAM: 8176 MiB
  Device 3: AMD Radeon Graphics, gfx900:xnack- (0x900), VMM: no, Wave Size: 64, VRAM: 8176 MiB
| model                          |       size |     params | backend    | ngl |     sm |            test |                  t/s |
| ------------------------------ | ---------: | ---------: | ---------- | --: | -----: | --------------: | -------------------: |
| qwen35 27B Q4_1                |  16.33 GiB |    27.32 B | ROCm       | 999 | tensor |            pp16 |        50.45 ± 15.02 |
| qwen35 27B Q4_1                |  16.33 GiB |    27.32 B | ROCm       | 999 | tensor |            pp32 |         70.16 ± 9.65 |
| qwen35 27B Q4_1                |  16.33 GiB |    27.32 B | ROCm       | 999 | tensor |            pp64 |         83.38 ± 0.74 |
| qwen35 27B Q4_1                |  16.33 GiB |    27.32 B | ROCm       | 999 | tensor |           pp128 |        101.40 ± 0.35 |
| qwen35 27B Q4_1                |  16.33 GiB |    27.32 B | ROCm       | 999 | tensor |           pp256 |        116.66 ± 0.29 |
| qwen35 27B Q4_1                |  16.33 GiB |    27.32 B | ROCm       | 999 | tensor |           pp512 |        121.73 ± 0.27 |
| qwen35 27B Q4_1                |  16.33 GiB |    27.32 B | ROCm       | 999 | tensor |          pp1024 |        119.38 ± 0.22 |
| qwen35 27B Q4_1                |  16.33 GiB |    27.32 B | ROCm       | 999 | tensor |          pp2048 |        118.03 ± 0.73 |
| qwen35 27B Q4_1                |  16.33 GiB |    27.32 B | ROCm       | 999 | tensor |           tg128 |         19.05 ± 0.98 |

build: 597b6672e (9621)

After (Qwen 3.6 27B):

nerd-dell@nerd-dell:~/llama.cpp$ ./build/bin/llama-bench -m ~/gguf_store/Qwen3.6-27B-Q4_1.gguf -ngl 999 -sm tensor -p 16,32,64,128,256,512,1024,2048 -n 128
ggml_cuda_init: found 4 ROCm devices (Total VRAM: 32704 MiB):
  Device 0: AMD Radeon Graphics, gfx900:xnack- (0x900), VMM: no, Wave Size: 64, VRAM: 8176 MiB
  Device 1: AMD Radeon Graphics, gfx900:xnack- (0x900), VMM: no, Wave Size: 64, VRAM: 8176 MiB
  Device 2: AMD Radeon Graphics, gfx900:xnack- (0x900), VMM: no, Wave Size: 64, VRAM: 8176 MiB
  Device 3: AMD Radeon Graphics, gfx900:xnack- (0x900), VMM: no, Wave Size: 64, VRAM: 8176 MiB
| model                          |       size |     params | backend    | ngl |     sm |            test |                  t/s |
| ------------------------------ | ---------: | ---------: | ---------- | --: | -----: | --------------: | -------------------: |
| qwen35 27B Q4_1                |  16.33 GiB |    27.32 B | ROCm       | 999 | tensor |            pp16 |        53.54 ± 16.04 |
| qwen35 27B Q4_1                |  16.33 GiB |    27.32 B | ROCm       | 999 | tensor |            pp32 |        81.12 ± 17.83 |
| qwen35 27B Q4_1                |  16.33 GiB |    27.32 B | ROCm       | 999 | tensor |            pp64 |        109.17 ± 6.03 |
| qwen35 27B Q4_1                |  16.33 GiB |    27.32 B | ROCm       | 999 | tensor |           pp128 |        126.48 ± 1.99 |
| qwen35 27B Q4_1                |  16.33 GiB |    27.32 B | ROCm       | 999 | tensor |           pp256 |        140.36 ± 0.17 |
| qwen35 27B Q4_1                |  16.33 GiB |    27.32 B | ROCm       | 999 | tensor |           pp512 |        144.66 ± 0.07 |
| qwen35 27B Q4_1                |  16.33 GiB |    27.32 B | ROCm       | 999 | tensor |          pp1024 |        140.14 ± 0.42 |
| qwen35 27B Q4_1                |  16.33 GiB |    27.32 B | ROCm       | 999 | tensor |          pp2048 |        138.09 ± 0.77 |
| qwen35 27B Q4_1                |  16.33 GiB |    27.32 B | ROCm       | 999 | tensor |           tg128 |         19.15 ± 0.93 |

build: 717920bf9 (9623)

Before (Gemma4 12B):

nerd-dell@nerd-dell:~/llama.cpp$ ./build/bin/llama-bench -m ~/gguf_store/gemma-4-12b-it-Q8_0.gguf -ngl 999 -sm layer -p 16,32,64,128,256,512,1024,2048 -n 128
ggml_cuda_init: found 4 ROCm devices (Total VRAM: 32704 MiB):
  Device 0: AMD Radeon Graphics, gfx900:xnack- (0x900), VMM: no, Wave Size: 64, VRAM: 8176 MiB
  Device 1: AMD Radeon Graphics, gfx900:xnack- (0x900), VMM: no, Wave Size: 64, VRAM: 8176 MiB
  Device 2: AMD Radeon Graphics, gfx900:xnack- (0x900), VMM: no, Wave Size: 64, VRAM: 8176 MiB
  Device 3: AMD Radeon Graphics, gfx900:xnack- (0x900), VMM: no, Wave Size: 64, VRAM: 8176 MiB
| model                          |       size |     params | backend    | ngl |            test |                  t/s |
| ------------------------------ | ---------: | ---------: | ---------- | --: | --------------: | -------------------: |
| gemma4 ?B Q8_0                 |  11.78 GiB |    11.91 B | ROCm       | 999 |            pp16 |         56.55 ± 0.56 |
| gemma4 ?B Q8_0                 |  11.78 GiB |    11.91 B | ROCm       | 999 |            pp32 |         66.28 ± 0.22 |
| gemma4 ?B Q8_0                 |  11.78 GiB |    11.91 B | ROCm       | 999 |            pp64 |         60.04 ± 0.07 |
| gemma4 ?B Q8_0                 |  11.78 GiB |    11.91 B | ROCm       | 999 |           pp128 |         68.76 ± 0.03 |
| gemma4 ?B Q8_0                 |  11.78 GiB |    11.91 B | ROCm       | 999 |           pp256 |         80.16 ± 0.07 |
| gemma4 ?B Q8_0                 |  11.78 GiB |    11.91 B | ROCm       | 999 |           pp512 |         78.86 ± 0.07 |
| gemma4 ?B Q8_0                 |  11.78 GiB |    11.91 B | ROCm       | 999 |          pp1024 |        107.79 ± 0.13 |
| gemma4 ?B Q8_0                 |  11.78 GiB |    11.91 B | ROCm       | 999 |          pp2048 |        118.01 ± 0.37 |
| gemma4 ?B Q8_0                 |  11.78 GiB |    11.91 B | ROCm       | 999 |           tg128 |         17.58 ± 0.04 |

build: f05cf4676 (9625)

After (Gemma-4 12B)

nerd-dell@nerd-dell:~/llama.cpp$ ./build/bin/llama-bench -m ~/gguf_store/gemma-4-12b-it-Q8_0.gguf -ngl 999 -sm layer -p 16,32,
64,128,256,512,1024,2048 -n 128
ggml_cuda_init: found 4 ROCm devices (Total VRAM: 32704 MiB):
  Device 0: AMD Radeon Graphics, gfx900:xnack- (0x900), VMM: no, Wave Size: 64, VRAM: 8176 MiB
  Device 1: AMD Radeon Graphics, gfx900:xnack- (0x900), VMM: no, Wave Size: 64, VRAM: 8176 MiB
  Device 2: AMD Radeon Graphics, gfx900:xnack- (0x900), VMM: no, Wave Size: 64, VRAM: 8176 MiB
  Device 3: AMD Radeon Graphics, gfx900:xnack- (0x900), VMM: no, Wave Size: 64, VRAM: 8176 MiB
| model                          |       size |     params | backend    | ngl |            test |                  t/s |
| ------------------------------ | ---------: | ---------: | ---------- | --: | --------------: | -------------------: |
| gemma4 ?B Q8_0                 |  11.78 GiB |    11.91 B | ROCm       | 999 |            pp16 |         56.90 ± 0.53 |
| gemma4 ?B Q8_0                 |  11.78 GiB |    11.91 B | ROCm       | 999 |            pp32 |         66.42 ± 2.63 |
| gemma4 ?B Q8_0                 |  11.78 GiB |    11.91 B | ROCm       | 999 |            pp64 |        104.60 ± 0.45 |
| gemma4 ?B Q8_0                 |  11.78 GiB |    11.91 B | ROCm       | 999 |           pp128 |        149.50 ± 0.29 |
| gemma4 ?B Q8_0                 |  11.78 GiB |    11.91 B | ROCm       | 999 |           pp256 |        171.98 ± 0.39 |
| gemma4 ?B Q8_0                 |  11.78 GiB |    11.91 B | ROCm       | 999 |           pp512 |        148.20 ± 0.79 |
| gemma4 ?B Q8_0                 |  11.78 GiB |    11.91 B | ROCm       | 999 |          pp1024 |        182.33 ± 0.52 |
| gemma4 ?B Q8_0                 |  11.78 GiB |    11.91 B | ROCm       | 999 |          pp2048 |        185.39 ± 0.39 |
| gemma4 ?B Q8_0                 |  11.78 GiB |    11.91 B | ROCm       | 999 |           tg128 |         17.97 ± 0.04 |

build: 717920bf9 (9623)

Requirements

  • I have read and agree with the contributing guidelines

  • AI usage disclosure:

    • Yes, I used Opus 4.8 with the Copilot CLI harness for initial investigation to see what I could do about the lack of dp4a. This led me to adding this -DGGML_CUDA_FORCE_CUBLAS=ON to my build and running tests to see how speeds compared, which is then when I noticed dense models in particular were consistently speeding up, but not MoE. Used that as a springboard for adding this conditional block, then did manual work to ensure it wasn't being too assuming (like how it assumed Q8_0 would regress, I doubted that and validated by hand).

@DEV-DUFORD
DEV-DUFORD requested a review from a team as a code owner June 13, 2026 17:39
@github-actions github-actions Bot added Nvidia GPU Issues specific to Nvidia GPUs ggml changes relating to the ggml tensor library for machine learning labels Jun 13, 2026

@sanmai sanmai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's pretty cool! I hope this eventually gets reviewed 🤞

@IMbackK IMbackK left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MMQ is not "emulated" when there is no dp4a, its just a slower path. Please remove the misleading comment. Otherwise this is fine, you could try tuneing mmq better for gfx900, but then again im not sure its worth the effort for an architecture this old.

For the record, did you test this on an old rocm version where amd still compiled gfx900, the new preview builds where amd again re-added support for gfx900 or distro/self compiled rocm?

@DEV-DUFORD

DEV-DUFORD commented Jun 15, 2026

Copy link
Copy Markdown
Contributor Author

Removed comment, thanks!

Yeah, I'd agree, so architecture is so old I also don't know if it's worth the effort to explore.

I tested using the official AMD 6.3.3 build from their repo, I installed using this on a fresh install of Ubuntu 22.04 LTS: https://repo.radeon.com/rocm/installer/rocm-linux-install-offline/rocm-rel-6.3.3/ubuntu/22.04/

@DEV-DUFORD
DEV-DUFORD requested a review from IMbackK June 15, 2026 10:36
@github-actions github-actions Bot added the CUDA Related to the CUDA backend label Jun 15, 2026
@slavap

slavap commented Jun 16, 2026

Copy link
Copy Markdown

@IMbackK
-> im not sure its worth the effort for an architecture this old.
it is old, but mi50 is very popular, and many people are still using it, because it's a great solution for home AI server.

@DEV-DUFORD

Copy link
Copy Markdown
Contributor Author

@IMbackK I actually gave into curiosity lol, messed around some today and did some fine-tuning, specifically around get_mmq_y, and got some real uplift across quants when I set that to 64 for sparse models in particular for this arch. Would you prefer I update this PR with that change and some accompanying benchmarks or keep that for a follow up PR once this one is approved (as to not put too much into a single PR)?

@IMbackK

IMbackK commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

@IMbackK I actually gave into curiosity lol, messed around some today and did some fine-tuning, specifically around get_mmq_y, and got some real uplift across quants when I set that to 64 for sparse models in particular for this arch. Would you prefer I update this PR with that change and some accompanying benchmarks or keep that for a follow up PR once this one is approved (as to not put too much into a single PR)?

seperate pr, reverting this one if need be.

@DEV-DUFORD

Copy link
Copy Markdown
Contributor Author

Is there anything thing else I need to do for this PR to be merged? 👀

@JohannesGaessler Not to bother you (also 100% let me know if I shouldn't ping, I don't mean to be bothersome in the slightest), this is approved, could we get this merged in so I can open up my next optimization PR?

@phil2sat

Copy link
Copy Markdown

Tested against Rocm 6.2, 7.2, 7.14 works fine give a nice speedup wanna have
Amd Instinct MI25 gfx900, please merge...

@JohannesGaessler

Copy link
Copy Markdown
Contributor

My current personal situation is this: I went on a break from llama.cpp maintenance for a few weeks because I felt I was too stressed out. Prior to the break I opened a PR for a general refactor of the MMQ configuration: #24127 . I'm currently working through my backlog but would like to have that PR merged before more changes are stacked on top of the MMQ kernel.

@IMbackK

IMbackK commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

@JohannesGaessler this just changes ggml_cuda_should_use_mmq so 2127 is not affected, any subsiquent gfx900 mmq tuneing should be done after that pr, but i dont see any reason not merge this.

@IMbackK

IMbackK commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

@IMbackK -> im not sure its worth the effort for an architecture this old. it is old, but mi50 is very popular, and many people are still using it, because it's a great solution for home AI server.

this is for vega64/56 and mi25 not mi50. These architectures are pretty unpopular in the ai space as they are pretty slow at this point all gfx900 has going for it is packed fp16 instructions. They lack the dprods and high global memory bandwith of mi50 that makes it popular.

@JohannesGaessler
JohannesGaessler merged commit d9df110 into ggml-org:master Jun 30, 2026
22 checks passed
turbo-tan pushed a commit to turbo-tan/llama.cpp-tq3 that referenced this pull request Jul 1, 2026
…org#24588)

* HIP: keep MMQ for gfx900 MoE and Q8_0, use hipBLAS for dense K-quants

Assisted-by: GitHub Copilot CLI

* HIP: tighten conditional block to be explicitly for gfx900

* HIP: Further simplified gfx900 conditional block

* removed unnecessary comment
DFveloper pushed a commit to DFveloper/aikar-engine that referenced this pull request Jul 3, 2026
…org#24588)

* HIP: keep MMQ for gfx900 MoE and Q8_0, use hipBLAS for dense K-quants

Assisted-by: GitHub Copilot CLI

* HIP: tighten conditional block to be explicitly for gfx900

* HIP: Further simplified gfx900 conditional block

* removed unnecessary comment
adrianhoehne pushed a commit to adrianhoehne/llama.cpp that referenced this pull request Jul 5, 2026
…org#24588)

* HIP: keep MMQ for gfx900 MoE and Q8_0, use hipBLAS for dense K-quants

Assisted-by: GitHub Copilot CLI

* HIP: tighten conditional block to be explicitly for gfx900

* HIP: Further simplified gfx900 conditional block

* removed unnecessary comment
CowboyTim pushed a commit to aardbeiplantje/llama.cpp that referenced this pull request Jul 21, 2026
…org#24588)

* HIP: keep MMQ for gfx900 MoE and Q8_0, use hipBLAS for dense K-quants

Assisted-by: GitHub Copilot CLI

* HIP: tighten conditional block to be explicitly for gfx900

* HIP: Further simplified gfx900 conditional block

* removed unnecessary comment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CUDA Related to the CUDA backend ggml changes relating to the ggml tensor library for machine learning Nvidia GPU Issues specific to Nvidia GPUs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants