Commit Graph
5149 Commits
Author SHA1 Message Date
Pranesh Gonegandlaandpraneshgo a11d16a8d5 CUDA: branchless Q4_K/Q5_K unpack to speed up mmvq, L2 prefetch on DGX Spark (llama/26705)
* Update Q4_K and Q5_K to use branchless computation, which stops the scale unpack being re-executed for every column in mmvq, improving perf at batch sizes > 1

* Gating the change off from DGX Spark due to no gain

* Adding prefetch gated to Spark, making branchless change in Q4_K and Q5_K general and modifying switch points based on latest perf data

* Guard the mmvq L2 prefetch against MUSA as well as HIP

* Define the mmvq L2 prefetch only under the Spark guard

* Update switch point for Q4_K to accommodate more models

* Remove stale comments

* Add block_size to ggml_cuda_type_traits and create a separate mmvq_should_prefetch function

* Rename block_size to bs for cleaner indentation

* Fix build error on non-Spark CUDA arch with appropriate conditional around new function added

---------

Co-authored-by: praneshgo <227579474+praneshgo@users.noreply.github.com>
2026-09-14 20:45:06 +03:00
Jeff BolzandAiChiTuDouPian 60e475f215 vulkan: support type-aligned GET_ROWS (llama/28253)
* vulkan: fall back to CPU for GET_ROWS with misaligned offsets

The Vulkan GET_ROWS shader asserts when a tensor's backing-buffer offset
plus view_offs is misaligned w.r.t. minStorageBufferOffsetAlignment
(see init_pushconst_tensor_offsets). Previously this caused a hard crash
on models using ggml_view + ggml_get_rows (e.g. Qwen3-TTS, Qwen3-VL).

Return false from supports_op() in the misaligned case so the scheduler
falls back to CPU, matching the existing pattern for PAD_REFLECT_1D and
other unsupported op/shape combinations.

Repro: llama-tts -m Qwen3-TTS-*.gguf -mm mmproj-*.gguf -ngl 99
Crash: GGML_ASSERT(dst->op != GGML_OP_GET_ROWS || (a_offset == 0 && ...)) failed

* vulkan: trim comment for GET_ROWS misalign fallback

* vulkan: fix file corruption in gated_linear_attn struct

* vulkan: properly handle misaligned offsets in GET_ROWS quantized path

- get_rows_quant.comp was missing get_aoffset()/get_boffset()/get_doffset()
  calls that are already present in get_rows.comp, causing GGML_ASSERT crashes
  when GET_ROWS operates on views with non-zero view_offs, as produced by
  KV cache slices in Qwen3-TTS and Qwen3-VL.
- Remove the defensive misalignment GGML_ASSERT in init_pushconst_tensor_offsets
  for the binary push-constants specialization, since both get_rows.comp and
  get_rows_quant.comp now correctly apply per-tensor base offsets.
- Remove the workaround CPU fallback in supports_op() for GET_ROWS, since the
  Vulkan backend now handles misaligned offsets natively (no more bailout).
- Add backend test coverage with view_src0=true (ggml_view_4d into a padded
  tensor) for F32, F16, Q4_0, Q4_K, Q8_0, and I32 types, exercising both the
  non-quantized (get_rows.comp) and quantized (get_rows_quant.comp) paths
  with non-zero view_offs that reproduce the original Qwen3-TTS crash.

* tests: trim redundant comments in test_get_rows vs0 region

* tests: trim redundant comments in test_get_rows vs0 region (follow-up)

* vulkan: bind tensor base for binary ops, pass full view_offs via push constants

For ops using vk_op_binary_push_constants (GET_ROWS, ADD, SUB, MUL, etc.),
bind the view_src base and pass the full view_offs divided by type_size via
push constant misalign_offsets. This avoids truncation when misalign_bytes is
not a multiple of quantized block size.

ggml_vk_tensor_subbuffer gains a use_view_offs parameter. When false, the
binding points to vk_tensor_offset (base) and size includes view_offs.
init_pushconst_tensor_offsets<binary> computes a/b/d_offset directly from
tensor->view_offs, which is always row-aligned and therefore exact.

Added non-zero view offset (offset_rows=3) backend tests for GET_ROWS across
all_types with be1={1,7}, v={false,true}, skipping gradient setup for view
tensors (GGML_OP_VIEW fails ggml_set_param).

All 223 GET_ROWS tests pass on Vulkan (NVIDIA RTX 5060 Ti).

* vulkan: bind aligned offset for binary ops, pass adjusted misalign via push constants

For ops using vk_op_binary_push_constants (GET_ROWS, ADD, SUB, etc.), bind
the buffer to an aligned position near the view offset (not the tensor base)
and pass the adjusted misalignment via push constants.

ggml_vk_get_adjusted_misalign finds the smallest misalign that is both a
multiple of minStorageBufferOffsetAlignment and type_size, ensuring
misalign/type_size is exact (no truncation for quantized block types).

ggml_vk_tensor_subbuffer gains use_view_offs parameter. When false, binds
to (target - adjusted_misalign) instead of the view_src base, keeping the
offset small enough for 16-bit/8-bit push constant fields.

Added non-zero view offset (offset_rows=3) backend tests for GET_ROWS across
all_types with be1={1,7}, v={false,true}, skipping gradient setup for view
tensors (GGML_OP_VIEW fails ggml_set_param).

All 223 GET_ROWS tests pass on Vulkan (NVIDIA RTX 5060 Ti).

* vulkan: bind aligned offset for binary ops, fix UMA offset mismatch

For ops using vk_op_binary_push_constants (GET_ROWS, ADD, SUB, etc.), bind
the buffer to an aligned position near the view offset (not the tensor base)
and pass the adjusted misalignment via push constants.

Added ggml_vk_tensor_physical_offset to unify physical offset lookup across
UMA and non-UMA devices. On UMA, resolves via ggml_vk_host_get(tensor->data);
otherwise uses vk_tensor_offset(t) + t->view_offs. Both get_misalign_bytes and
the new ggml_vk_get_adjusted_misalign helper build on top of this function,
so buffer bindings and push constant offsets are always consistent regardless
of device memory model.

ggml_vk_get_adjusted_misalign finds the smallest misalign that is both a
multiple of minStorageBufferOffsetAlignment and type_size, ensuring
misalign/type_size is exact (no truncation for quantized block types) while
remaining small enough for 16-bit/8-bit push constant fields
(adjusted_misalign < lcm(align, type_size)).

ggml_vk_tensor_subbuffer gains use_view_offs parameter. When false, binds
to (physical_offset - adjusted_misalign) on both UMA and discrete GPUs,
fixing a bug where the UMA host_get path previously skipped the adjusted
misalign binding and returned the target offset directly.

Added non-zero view offset (offset_rows=3) backend tests for GET_ROWS across
all_types with be1={1,7}, v={false,true}, skipping gradient setup for view
tensors (GGML_OP_VIEW fails ggml_set_param).

All 223 GET_ROWS tests pass on Vulkan (NVIDIA GeForce RTX 5060 Ti).

* finish misalignment fix

* supports_op changes for openvino/webgpu

---------

Co-authored-by: AiChiTuDouPian <15327701848@qq.com>
2026-09-14 20:45:06 +03:00
Siavash Norouzi c6135ac226 ggml-cuda: fix divergent barrier in f16 flash attention (llama/27870)
* ggml-cuda: fix divergent barrier in f16 flash attention

* ggml-cuda: avoid duplicate metadata pointer setup
2026-09-14 20:45:06 +03:00
Aman Gupta 1da558c5cd ggml: allow backend inputs to not create another split (llama/28387) 2026-09-14 20:45:06 +03:00
Jeff Bolz 8d3ed20053 vulkan: rms_norm fusion opportunities (llama/28024)
Support RMS_NORM + MUL + ADD (+ MUL) and RMS_NORM + VIEW + SET_ROWS.
Extend ROPE + VIEW + SET_ROWS to support IMROPE.

Worth around 4% in gemma4 on my system.
2026-09-14 20:45:06 +03:00
Anjielon 088b3b4ad0 vulkan: add TQ1_0 support (mm, mat-vec, mat-vec-id, dequant, get_rows) (llama/27765)
* vulkan: add TQ1_0 support (mm, mat-vec, dequant, get_rows)

* vulkan: pack TQ1_0 powers of 3 into a 32-bit constant

Replaces the constant array with a packed 32-bit value (7 bits per entry,
max 81 < 128) extracted with shift/mask, as suggested in review — avoids a
constant array that may not be kept in registers.

test-backend-ops on gfx1151: tq1_0 MUL_MAT 11/11, MUL_MAT_ID 6/6,
GET_ROWS 4/4, unchanged.

* vulkan: address review - shared TQ1_0 decode helpers, fix standalone dequant shader

Review feedback from jeffbolznv, all points:

- Move the packed-pow3 decode into shared helpers in types.glsl
  (tq1_0_byte_of / tq1_0_digit_of / tq1_0_trit) and use them from
  dequant_funcs.glsl, mul_mm_funcs.glsl, dequant_funcs_cm2.glsl and
  dequant_tq1_0.comp instead of repeating the logic. The cm2 path also
  drops its constant array for the packed-constant extraction.
- Translate all remaining comments to English.
- dequant_tq1_0.comp: use dequant_head.glsl. The shader previously declared
  its own single-field push constant while the pipeline is created with the
  5-field layout, so p.ne read the wrong field - confirmed broken, as
  suspected in review.
- Fix wg_denoms for the standalone dequant pipeline: one invocation decodes
  4 elements with local_size 256, so a workgroup covers 256*4 elements, not
  256*16. With the old value the dispatcher launched a quarter of the
  required workgroups.

Verified by temporarily forcing the dequant + f16 matmul path for TQ1_0
(hack not committed): test-backend-ops MUL_MAT passes through the rewritten
standalone shader, and the standard MUL_MAT / MUL_MAT_ID / GET_ROWS
tq1_0 cases still pass on Vulkan (AMD gfx1151).

* vulkan: address review — English comments, shared tq1_0_trit, trim TQ1_0 test cases

- mul_mat_vec_tq1_0.comp: drop leftover non-English comment and the local
  POW3_PACKED constant; all decode sites now call tq1_0_trit() from types.glsl
- types.glsl / dequant_funcs_cm2.glsl: ASCII-only, drop stale reviewer note
- test-backend-ops: remove the oversized MUL_MAT_ID case (432 MiB A tensor,
  ~172 GFLOP reference); move the two remaining ones next to the other
  backend-specific mul_mat_id one-offs and document why they are needed

* metal: decline TQ1_0 for GET_ROWS and mat-mul in supports_op

The new TQ1_0 cases in test-backend-ops exposed that the Metal backend
claimed support for GET_ROWS/MUL_MAT/MUL_MAT_ID with TQ1_0 sources while
having no such kernels (ggml_metal_library_compile_pipeline aborted on the
missing kernel_get_rows_tq1_0). Decline the type so the ops fall back to
the CPU, matching the existing NVFP4 handling on the same lines.

Assisted-by: Claude Fable 5

* vulkan: trim the TQ1_0 comments

Addresses @0cc4m's review: keep only what the code does not already say.

Removed the block-format recaps (the layout is right there in the struct) and
the step-by-step decode walkthrough. Kept the two facts a reader cannot infer:
the 8-bit truncation is part of the format, not an optimisation, and the powers
of 3 are packed into one uint so they do not end up in a constant array that
may miss the registers.

No functional change.

* vulkan: address review — trim comments, fold Metal check, drop unused _v

Per @0cc4m's review:

- dequant_funcs.glsl, dequant_funcs_cm2.glsl: drop the "see types.glsl"
  pointers — they apply to every quant and say nothing specific.
- dequant_tq1_0.comp: drop the wg_denoms note. It is a precondition, not
  information.
- mul_mm_funcs.glsl: same pointer removed.
- types.glsl: the comment on tq1_0_trit is down to the one fact the code
  cannot show — the 8-bit truncation is part of the format, matching the C
  reference, not an optimisation.
- dequant_funcs_cm2.glsl: removed dequantFuncTQ1_0_v and its define. You were
  right that it is optional: it wrapped four scalar decodes and vectorised
  nothing, and mul_mm_cm2.comp already guards the path with
  `#if defined(dequantFuncA_v)` (DATA_A_F32 omits it the same way).
- ggml-metal-device.m: folded TQ1_0 into the existing NVFP4 check instead of a
  separate block, and dropped both comments.
- test-backend-ops.cpp: the two mul_mat_id cases stay — they cover the
  block-stride loop and the per-expert base offset that k == 256 alone never
  reaches — but the comment is now one line instead of five.

Kept: the one-line labels on the three block regions in mul_mat_vec_tq1_0.comp
and on tq1_0_byte_of(). Those state the 5-trits-per-byte packing, which the
loop bounds do not show. Happy to remove them too if you prefer.

Re-verified on AMD gfx1151 (Vulkan), test-backend-ops, 2/2 backends passed:
MUL_MAT 9 TQ1_0 cases, MUL_MAT_ID 5, GET_ROWS 4 — all OK, no failures.
The coopmat2 path is unchanged apart from the removed _v define.
2026-09-14 20:45:06 +03:00
lhez ad344d1668 opencl: properly choose weights pack for q4_K, q5_K mul_mat (llama/28402) 2026-09-14 20:45:06 +03:00
Aman Gupta a0e75c849a cuda: fixes races in mmid and mmf (llama/28475) 2026-09-14 20:45:06 +03:00
Niklas Wenzel 1299eb6c15 metal : add remaining fa-vec tunings for M2 Max (llama/28458) 2026-09-14 20:45:06 +03:00
Niklas Wenzel 614c74ab60 metal : fix memory leak in early return (llama/28399) 2026-09-14 20:45:06 +03:00
Jingxin (Philip) Li 0006e3e2e2 sycl : fix test-backend-ops CI break && restore Kronecker product FWHT support (#28016) (llama/28254)
* Reapply "sycl : add Kronecker product FWHT support for sizes 384, 640, 768, 12…" (llama/28184)

This reverts commit c845263f8b7d60113e213a3bd2d5cc6472ccf204.

* tests : fix unused variable M in test-backend-ops

* tests: fix trailing space error and isolate kronecker tests for sycl backend only
2026-09-14 20:45:06 +03:00
Nick Farrell 07796107ef sycl: attribute device allocations by site (GGML_SYCL_MEMTRACE) (llama/27631)
define two new environment variables to better understand how much
memory is being allocated, and when. This has been invaluable in
inproving the --fit algorithm, and is likely to be useful when debugging
other memory-related issues.

`-lv 4` will be required to enable the following:

GGML_SYCL_MEMTRACE=1 will show per-site memory usage, updated whenever
it increases by more than 64MiB.
GGML_SYCL_MEMTRACE=2 will show every allocation and deallocation.

To change the default 64MiB threshold for reporting memory usage increases, use
GGML_SYCL_MEMTRACE_STEP.

A sample log line:
[SYCL-MEMTRACE] device memory query (dev): total 59493 MiB, free  4494, in use 54998; allocated     0 (buffers     0 + scratch     0), peak     0 MiB
2026-09-14 20:45:06 +03:00
Isaac ad218df420 metal : add remaining fa-vec tunings for M3 (llama/28396)
* addition of m3 in fa_vec_tuned_table

* adding q4_0,q4_1,q5_0,q5_1 in ggml-metal-tuning

* Fix formatting in ggml-metal-tuning.cpp
2026-09-14 20:45:06 +03:00
Hongqiang Wang 25c6ab5d99 opencl: extend the elementwise and data‐movement op coverage (#27633)
* opencl: add extended elementwise unary ops (sgn, step, elu, hardswish, hardsigmoid, floor, ceil, round, trunc)

Adds nine GGML_UNARY_OP_* elementwise ops that were falling back to CPU on the
OpenCL backend, following the same variant shape as the existing ABS op: f32,
f32_4 (vec4), f16, f16_4 (vec4), and stride-addressed f32_nc / f16_nc for
non-contiguous inputs. New kernels/unary_ext.cl (macro-generated), a shared
ggml_cl_unary_ext dispatch helper mirroring ggml_cl_abs, the supports_op cases,
and the compute-forward cases.

Values are computed in float (the f16 variants read/write half and convert), so
the conditional ops (step, elu) match the CPU reference; the vec4 forms use
select() for the branch.

Validated with test-backend-ops on Adreno 840 and 850 (E17): all nine ops pass
every case including the vec4 and non-contiguous variants (8/8 or 14/14).

* opencl: dispatch a contiguous f32 copy over the whole device

kernel_cpy_f32_f32 maps one workgroup to each (i01,i02,i03) row and strides the
row across that workgroup's lanes, and the host launches ne01*MIN(64,ne00) work
items. A tensor with few long rows therefore runs on a single workgroup. The
mamba2 and gated-delta-net recurrent state cache is one row of 524288 floats,
copied once per layer per graph, and lands on 64 work items.

When both sides are contiguous the copy is a linear move, so dispatch it over
the whole device: one work item per float4. Gated on ggml_is_contiguous for both
tensors and equal element counts, so copies already spread over many rows keep
the existing path. The kernel is created optionally, so a driver that rejects it
falls back rather than aborting.

vload4/vstore4 rather than a float4 cast: they require only the scalar type's
alignment, and these buffers carry an arbitrary 4-byte view offset.

CPY, DUP and CONT are 217/217 on Adreno 840 and 740 with the path enabled and
disabled. GGML_OPENCL_CPY_FLAT=0 forces the old kernel.

* opencl: support all easy-copy types in CONCAT

CONCAT was F32-only. Extend it to every "easy-copy" type -- any non-quantized
type with a block size of 1 and an element size of 1, 2, 4 or 8 bytes, i.e.
f16/bf16/i8/i16/i32/i64 as well as f32.

The kernels are keyed by element SIZE rather than by type, which is what CUDA
already does for the same op: one kernel per byte width (b1/b2/b4/b8) plus the
packed b4 fast path, instead of one per ggml type. supports_op gates on the
same property, so a new type of a supported width is picked up with no further
work.

Validated with test-backend-ops on Adreno 840 / A8X and X2-90 / X2E.
2026-09-14 20:45:06 +03:00
yzyyzyhhhandhappyyzy 7fb2dafcb8 opencl: add Adreno xmem SDPA path (llama/26331)
* opencl: add Adreno xmem SDPA path

Assisted-by: Codex

* Removed the Adreno-specific queue profiling override

* Clean up formatting

* 修复数值误差优化gqa/mask attn

Assisted-by: Codex

* add env GGML_OPENCL_XMEM_SDPA

Assisted-by: OpenAI Codex

---------

Co-authored-by: happyyzy <happyyzy@users.noreply.github.com>
2026-09-14 20:45:06 +03:00
Georgi Gerganov 70598eee9c scripts : fix sync (#0) 2026-09-14 20:45:06 +03:00
Adrien Gallouët f133970bbb ci : use devlab-dispatch for npu-amd-windows (#4060)
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2026-09-14 06:35:58 +02:00
Daniel Bevenius 1da4dc82fa ci : rename cublas to cuda in release.yml (#4057)
This commit renames the cublas jobs and release artifacts to just use
cuda instead of cublas.

The motivation for this is that I think that the cublas naming came for
a time when the ggml-cuda backend mostly or perhaps completely delegated
to cublas. But this is not the case any more and naming this cuda would
make sense now. This is also consistent with how llama.cpp names their
cuda binary build artifacts.
2026-09-11 16:13:24 +02:00
Adrien Gallouët 0261298154 ci : use devlab-dispatch for npu-amd-linux (#4056)
Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
2026-09-11 09:35:25 +02:00
Daniel Bevenius 927cfce34f metal : remove leftover ggml-metal.metal kernels file (#4051)
This commit removes the ggml-metal.metal file that used to contain all
the metal kernels. These have now been separated into separate kernels
in ggml/src/ggml-metal/kernels and it seems that this file was not
removed when synced with ggml.

This is currently preventing whisper.cpp to be released as the release
check fails.
v1.9.4 b5130
2026-09-10 20:00:34 +02:00
Daniel Bevenius dd80eb2afd scripts : use sed instead of grep for version parsing [no ci] (#4052)
This commit updates the version parsing in make-release-checks.sh to use
sed instead of grep. The motivation for this is that currently when
running this script on macos it errors:
```console
$ ./scripts/make-release-checks.sh --dry-run
grep: invalid option -- P
usage: grep [-abcdDEFGHhIiJLlMmnOopqRSsUVvwXxZz] [-A num] [-B num] [-C[num]]
	[-e pattern] [-f file] [--binary-files=value] [--color=when]
	[--context[=num]] [--directories=action] [--label] [--line-buffered]
	[--null] [pattern] [file ...]
```
2026-09-10 19:49:10 +02:00
Daniel Bevenius 1fa6dfa05f ci : update WoA CUDA 13.4 to use 13.4.1 GA (#4053)
Refs: https://github.com/ggml-org/llama.cpp/pull/28687
2026-09-10 19:22:25 +02:00
Daniel Bevenius a2b36eb677 whisper : bump version to 1.9.4 (#4050) b5127 2026-09-10 12:17:05 +02:00
Daniel Bevenius 6fb4cd675c ci : add Windows On ARM support to release job (#4048)
* ci : add Windows On ARM support to release job (wip)

This commit adds Windows On Arm (WoA) support to whisper.cpp and the
release process.

The underlying support was already in place as this had been synced
with ggml, but the missing part was producesing release artifacts which
is what this commit does.

* ci : add note about CUDA WoA is a preview edition [no ci]
2026-09-10 09:51:35 +02:00
Javier De Jesus c44b60b805 whisper : call encoder_begin_callback before language auto-detect (#3936)
The language auto-detect path in whisper_full_with_state ran the encoder
without firing encoder_begin_callback, unlike the main transcription loop.
Callers that gate, observe, or abort whisper's encode through the callback
had no control over the auto-detection pass. Guard the auto-detect encode
with the callback the same way the main loop does.
2026-09-08 13:35:34 +02:00
davidcabcabanddavid 6d0ed91499 whisper : re-seed decoder 0 between calls (#4025)
Decoder 0 is seeded once in whisper_init_state() and the per-call re-seeding
loop in whisper_full_with_state() starts at j = 1, so decoder 0 is skipped.
Its mt19937 therefore carries over from one call to the next for the whole
lifetime of the state.

It is only consulted in the temperature > 0 branch (whisper_sample_token),
which is reached through temperature fallback -- so the effect only shows on
audio that falls back, and looks like nondeterminism rather than a bug: the
output becomes a function of how many calls the state has already served, and
the same audio decoded twice can yield different text.

Reproduced on a whisper-server instance: three noisy 30 s clips decoded four
times each in the same process gave 3/4 distinct transcripts per clip before
this change and identical transcripts after it. Fresh processes decoding each
clip once hide the issue entirely, which is why it is easy to miss.

Re-seeding decoder 0 with mt19937(0) matches what the loop does for every
other decoder (mt19937(j)) and makes decoding reproducible across calls.

Co-authored-by: david <david@cabrini.ch>
2026-09-08 11:58:05 +02:00
Daniel Bevenius cec4dbe5d5 ci : update close-issue job to not close issues (#4045)
This commit updates the close-issue CI job to not automatically close
issues. It also adds a stale lable message that explains why the issue
was marked as stale.

The motivation for this is that we enabled this job recently and there
have been a few comments from users/reporters that they did not get any
notification or motivation for closing. Hopefully marking the issues as
stale will give a notification the the reporters and we can manually
look through stale issues.

Refs: https://github.com/ggml-org/whisper.cpp/issues/586#issuecomment-5579674875
2026-09-08 11:57:20 +02:00
Abir Deol 79f2d92112 tests : load backends before init when built with GGML_BACKEND_DL (#4031)
With GGML_BACKEND_DL=ON no backend is registered until something calls
ggml_backend_load_all(). Every example does; the tests never did, so
whisper_init_* and parakeet_init_* ran with devices = 0 and aborted on
GGML_ASSERT(device) in ggml_backend_dev_backend_reg.

Three tests aborted on such a build - test-whisper-zero-samples,
test-vad and test-parakeet - taking ctest -L gh to 2 of 4.
test-vad-full has the same fault and reaches it only once a real
base.en model is present.

No workflow caught this because none pairs the two: build-clang,
build-gcc and build-sanitize run ctest -L gh but never set
GGML_BACKEND_DL, while release.yml sets it and runs no tests.

ggml_backend_load_all() is already reachable through whisper.h and
parakeet.h via ggml-cpu.h, so no new include is needed.

Resolves: https://github.com/ggml-org/whisper.cpp/issues/4030
2026-09-08 07:14:42 +02:00
Álvaro Justen 61e6ccade0 server : return language in detect response (#4035)
Resolves: https://github.com/ggml-org/whisper.cpp/issues/3603
2026-09-08 07:12:52 +02:00
Georgi Gerganov 52a939a2a7 sync : ggml 2026-09-04 13:40:00 +03:00
Georgi Gerganov a937f4e8ef ggml : bump version to 0.23.0 (ggml/1618) 2026-09-04 13:39:43 +03:00
Niklas Wenzel 11d4eec830 metal : add remaining fa-vec tunings for M3 Max (llama/28373) 2026-09-04 13:39:43 +03:00
Daniel Bevenius 140e57a4e2 ggml : replace compile definitions with version.h.in (llama/28364)
This commit adds a cmake version configuration file to replace the
current compile definition solution for the version.

The motivation for this change is that I made a mistake and did not take
into consideration that the compile definition means that this will
become a compiler flag for all sources in the target. This means that
when a version update happens that will recompile all sources in the
target even if they have not changed.

Refs: https://github.com/ggml-org/llama.cpp/pull/28278
2026-09-04 13:39:43 +03:00
Georgi Gerganov e2389eb99c ggml : rename and make private ggml_op_alloc_size_may_expand() (ggml/0)
cont https://github.com/ggml-org/llama.cpp/pull/27960
2026-09-04 13:39:43 +03:00
Adrien Gallouët 1b37beadd7 ggml : don't crash when backend search path can't be read (llama/28271)
Use std::error_code overloads of fs::current_path() and
fs::directory_iterator in ggml_backend_load_best() so an
inaccessible search path (WebDAV mount, removed CWD) is
skipped instead of terminating the process with an uncaught
filesystem_error.

Signed-off-by: Adrien Gallouët <angt@huggingface.co>
2026-09-04 13:39:43 +03:00
Adrien Gallouët f32e6fa0c8 ggml : remove GGML_CUDA_PEER_MAX_BATCH_SIZE (llama/28177)
Signed-off-by: Adrien Gallouët <angt@huggingface.co>
2026-09-04 13:39:43 +03:00
Aaron Teo e1bbe40520 ggml-cpu(s390x) : fix q5_1 uninitialized v_acc (llama/28332)
Signed-off-by: Aaron Teo <aaron.teo1@ibm.com>
2026-09-04 13:39:42 +03:00
Frosty40 d1e0e6491f sycl: fuse rms_norm+mul+add and add+add residual chains (llama/27610)
Fuse RMS_NORM+MUL+ADD and ADD+ADD under GGML_SYCL_ENABLE_FUSION.

ADD+ADD uses the same binbcast indexing and type matrix as standalone
add() (f32, f16, f16/f32, i32, i16, bf16, including broadcast and
non-contiguous). Unsupported combinations fall back to two add() launches.
2026-09-04 13:39:42 +03:00
Ozymandias_EBON 36f170e5fe SYCL: Refactor GGML_SYCL_ENABLE_MKL_FA to global var (llama/26863) 2026-09-04 13:39:42 +03:00
Hongqiang Wang d784add75f opencl: quant lm_head / decode GEMV and medium-batch GEMM optimizations (speculative decoding/MTP) (llama/26477)
* opencl: quant lm_head / decode GEMV and medium-batch GEMM optimizations

* opencl: guard q4_K/q6_K tiled_ns convert-kernel registration for non-Adreno build

* opencl: gate q4_K MUL_MAT+GLU fusion dispatch to Adreno

* opencl: require the noshuffle weight layout in the q4_K GLU fusion gate

* opencl: do not take the vectorized f16 mrow GEMV path on an unaligned row stride

* opencl: pass the new get_scale_min_k4 stride argument at the row-major call sites

* opencl: enable the q4_K split-K decode GEMV only where it is measured to win

* opencl: record the X1-85 split-K datapoint (neutral, exclusion confirmed)

* opencl: restrict the tiled lm_head/embed GEMV default to X2E/A8X

* opencl: fix q4_K variant kernels to read the transposed scales layout

* opencl: keep the flat-GEMV large-m escape opt-in

* opencl: guard the o4 GEMV store against the rounded-up dispatch tail

* opencl: restore the tiled q4_K/q6_K layout on tensor read-back

* opencl: split-K for the q8_0 decode GEMV at small M

* opencl: keep the q6_K noshuffle correctness escape ahead of the opt-in gate
2026-09-04 13:39:42 +03:00
kbenkhaled 0a4a95c86e tune MMVQ to MMQ crossover for SM87 (llama/28285) 2026-09-04 13:39:42 +03:00
Georgi Gerganov 4dd48dde35 metal : add sparse FA (llama/28098)
* metal : support n_kv_max sparse mask hint in flash attention vec kernel

- add kernel_flash_attn_ext_vec_idx: compacts finite mask entries into
  a per-row index list (Hillis-Steele scan, one threadgroup per row)
- extend vec FA kernel with optional sparse index gathering (FC slot 5)
- add host-side gate: sparse path when n_kv_max > 0, mask present,
  supported head sizes / KV types, n_kv_max <= 4096
- new buffer region extra_idx for the index list
- pipeline getter extended with has_sparse param
- add test cases: head sizes, quant types, nb>1, nr23 variants,
  sinks, ALiBi, softcap, permute, v_view_of_k, no-mask fallback

Note: multi-row (nb*nr23[1] > 1) cases still failing - rid mapping
in the store phase needs revisiting for the sparse path.

Assisted-by: pi:llama.cpp/Qwen3.8-27B

* metal : fix sparse flash attention row addressing

- kernel_flash_attn_ext_vec_idx: mask param is half* but nb31 is a byte
  stride, so the per-row mask offset was scaled by 2x; cast to char*
  before applying the byte strides
- kernel_flash_attn_ext_vec: sparse pidx param is char* so the per-row
  element offset was under-scaled by sizeof(int); scale it by sizeof(int)
  to get the correct byte offset
- fixes the multi-row (nb*nr23[1] > 1) sparse flash attention failures

Assisted-by: pi:llama.cpp/DeepSeek-v4-0731

* cont : use sparse vec FA for prefill

* metal : single-pass flash attention sparse index compaction

The idx kernel previously read the mask row twice: once to count the finite
entries (for the prefix scan) and again to recover their positions. Since the
kernel is memory-bound, this doubled the mask traffic.

Keep the finite positions in a per-thread register array during the count
pass and write them out directly, avoiding the second mask read. A dense
mask with more than NLOCAL finite entries in a slice falls back to re-reading
the mask to write the remaining positions.

Assisted-by: pi:llama.cpp/DeepSeek-v4-0731

* tests : add perf cases for sparse flash attention prefill

Measure the sparse vec FA kernel across KV sizes, n_kv_max hints and batch
sizes. Run with:

    ./build/bin/test-backend-ops -b MTL0 -o FLASH_ATTN_EXT -p "n_kv_max=[1-9]" perf

Assisted-by: pi:llama.cpp/DeepSeek-v4-0731

* qwen4 : enable sparse attention

* cont : adjust nsg

* cont : sync test-backend-ops

* cont : disable Qwen4 for now

* cont : clean-up + tests
2026-09-04 13:39:42 +03:00
Georgi Gerganov d55d345e69 metal : fix glu dispatch with ne00 = 1 (llama/28306)
* metal : fix glu dispatch with ne00 = 1

* tests : disable ill-defined tests
2026-09-04 13:39:42 +03:00
25350b579e CUDA: Allow concurrent streams per split for multi-GPU (llama/28198)
* CUDA: Allow CUDA optimization per split for multi-GPU.

Previous guard caused multi-GPU to skip the graph optimization.  The
graph is already split per device and the optimization doesnt run
over the whole model but once per split, and thus should be allowed.
However, the CUDA event ggml_cuda_concurrent_event belongs to
whichever GPU was "current" when created. If the pass ran while
GPU 0 was current, it would stick and during event creation for the
second GPU it would land on GPU 0.

The fix: set the device explicitly ggml_cuda_set_device(cuda_ctx->device);
Default behaviour remains unchanged, only active for GGML_CUDA_GRAPH_OPT=1.
Explicit device setting pattern re-used from ggml_backend_cuda_graph_compute.

* Update ggml/src/ggml-cuda/ggml-cuda.cu

Co-authored-by: Aman Gupta <amangupta052@gmail.com>

---------

Co-authored-by: tannerbruhn <tannerbruhn@users.noreply.github.com>
Co-authored-by: Aman Gupta <amangupta052@gmail.com>
2026-09-04 13:39:41 +03:00
Nathan Wilson 47d348a278 vulkan: fix FA dequant path engagement (llama/28190)
Skip the nb[3] check when ne[3] == 1, the shader never reads it for a
single stream. Cache views carry the full-buffer stride there, so the old
check reduced to n_kv == kv_size and the path only engaged with the
cache full.
2026-09-04 13:39:41 +03:00
Neo Zhang f24a38605b sycl : enhance the api to support peer-to-peer copy (llama/27550) 2026-09-04 13:39:41 +03:00
EurekaticandRaulAbejonDelgado a704770e3b sycl: reduce redundant work in Q4_K multi-column MMVQ (llama/27062)
* sycl: Q4_K Weight unpack optimization and reuse between destination Columns

* sycl: Q4_K small N (N=2..4) + two output rows by subgroup reuse of activation between two rows.

* sycl: gate Q4_K two-row reuse for small N=2

* sycl: Fix on magic number now uses Q4_K_MMVQ_ROW_PAIR_MIN_NROWS=6272 for it, added tests for coverage around Q4_K_MMVQ_ROW_PAIR_MIN_NROWS with perf support to test Q4_K MUL_MAT, applied the same  reuse pattern to the activation as the weights.

Assisted-by: GPT-5.6 Sol

---------

Co-authored-by: RaulAbejonDelgado <raul.abejon.delgado@gmail.com>
2026-09-04 13:39:41 +03:00
Xuan-Son Nguyen e5605697ce finetune: fix no KV cache (llama/27199)
* training: fix no KV cache

* apply @ ggerganov
 suggestion
2026-09-04 13:39:41 +03:00
cqderek 37f0f443d7 ggml-hexagon: add F16 support for unary ops (llama/28228)
Extend the HTP backend's F16 unary op coverage to include ABS on top
of the existing NORM/RMS_NORM/L2_NORM/SCALE/CLAMP/SQR/SQRT set.

- Add hvx_abs_f16_{aa,au,ua,uu} + dispatcher in hvx-arith.h, mirroring
  the sqr_f16 kernel structure and using the existing hvx_vec_abs_f16()
  sign-bit-clear helper
- Add abs_f16() row-wise dispatch and DEFINE_UNARY_TASK_F16(unary_abs, ...)
  in unary-ops.c, wired into execute_op_unary()'s op_type/task_func
  switches
- Register HTP_OP_UNARY_ABS in htp_op_is_unary() (unary-ops.h) so that
  ggml_hexagon_precompute_unary_params() fills kernel_params (n_threads,
  VTCM layout) for ABS nodes -- required for the F16 path to function
- Narrow the F16 GGML_OP_UNARY gate in ggml_hexagon_supported_unary()
  (ggml-hexagon.cpp) to allow GGML_UNARY_OP_ABS specifically, instead of
  rejecting all GGML_OP_UNARY ops for F16
- Merge the separate execute_op_unary_f32()/execute_op_unary_f16()
  functions into a single execute_op_unary(), branching on an is_f16
  flag for the parts that actually differ by type (elem_size, the
  early F16 op-support check, and which task_func table to use) while
  keeping the F32-only tiled/RMS_NORM_MUL paths intact -- per review
  feedback to avoid duplicating the shared VTCM/DMA plumbing

Verified on-device (QRD8850, Hexagon v81) via test-backend-ops -o ABS:
8/8 passing (F16 + F32, HTP0, no CPU fallback). Regression-checked
SQR/CLAMP/SQRT (F16+F32) and NORM/RMS_NORM/L2_NORM/SCALE (F32; their F16
paths have no CPU reference kernel in test-backend-ops and cannot be
correctness-tested there independent of this change).
2026-09-04 13:39:41 +03:00
Isaac 1bdda1e366 metal : add fa-vec tunings for M3 (llama/28236) 2026-09-04 13:39:41 +03:00