From 23221d33fa7bdc3ab482249a8f51960524934c74 Mon Sep 17 00:00:00 2001 From: bri-prism <288398250+bri-prism@users.noreply.github.com> Date: Fri, 6 Nov 2026 07:45:09 -0800 Subject: [PATCH] metal : use more command buffers on iOS iOS can stop a GPU command buffer that runs for more than a few seconds. With n_cb = 1, about 90% of each graph goes into a single command buffer, so a long prompt batch on a slow device can hit that limit. The buffer is then discarded with kIOGPUCommandBufferCallbackErrorInnocentVictim and llama_decode returns -3. Default to 8 command buffers on iOS. macOS is unchanged. --- ggml/src/ggml-metal/ggml-metal.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/ggml/src/ggml-metal/ggml-metal.cpp b/ggml/src/ggml-metal/ggml-metal.cpp index eaaaf524e026..d31c0eaefe4b 100644 --- a/ggml/src/ggml-metal/ggml-metal.cpp +++ b/ggml/src/ggml-metal/ggml-metal.cpp @@ -9,6 +9,8 @@ #include "ggml-metal-ops.h" #include "ggml-metal-tuning.h" +#include + #include #include @@ -586,6 +588,14 @@ static void ggml_backend_metal_graph_optimize(ggml_backend_t backend, ggml_cgrap ggml_metal_graph_optimize(ctx, cgraph); } +// iOS can stop a GPU command buffer that runs for more than a few seconds. +// Use more, shorter command buffers there so large prompt batches stay under that limit. +#if TARGET_OS_IPHONE +#define GGML_METAL_DEFAULT_N_CB 8 +#else +#define GGML_METAL_DEFAULT_N_CB 1 +#endif + static void ggml_backend_metal_set_n_cb(ggml_backend_t backend, int n_cb) { GGML_ASSERT(ggml_backend_is_metal(backend)); @@ -637,7 +647,7 @@ ggml_backend_t ggml_backend_metal_init(void) { /* .context = */ ctx, }; - ggml_backend_metal_set_n_cb(backend, 1); + ggml_backend_metal_set_n_cb(backend, GGML_METAL_DEFAULT_N_CB); return backend; } @@ -732,7 +742,7 @@ static ggml_backend_t ggml_backend_metal_device_init_backend(ggml_backend_dev_t /* .context = */ ctx, }; - ggml_backend_metal_set_n_cb(backend, 1); + ggml_backend_metal_set_n_cb(backend, GGML_METAL_DEFAULT_N_CB); return backend;