Commit e853ec9a8 for llama.cpp
commit e853ec9a8c72e91e8fb0eaa68e1dfe02f3c396f0
Author: Aman Gupta <amangupta052@gmail.com>
Date: Wed Nov 4 17:23:25 2026 +0800
llama : follow ctx_other devices and flash attention in Gemma4 assistant (#31635)
* llama : follow ctx_other devices and flash attention in Gemma4 assistant
* llama : include <algorithm> for std::any_of
diff --git a/src/llama-context.cpp b/src/llama-context.cpp
index eb9756996..85c32c995 100644
--- a/src/llama-context.cpp
+++ b/src/llama-context.cpp
@@ -14,6 +14,7 @@
#include "llama-sampler.h"
#include "llama.h"
+#include <algorithm>
#include <cinttypes>
#include <cmath>
#include <cstring>
@@ -332,6 +333,18 @@ llama_context::llama_context(
cparams.flash_attn = params.flash_attn_type != LLAMA_FLASH_ATTN_TYPE_DISABLED;
cparams.auto_fa = params.flash_attn_type == LLAMA_FLASH_ATTN_TYPE_AUTO;
+ // the KV cache is shared with ctx_other, so follow its flash attention setting instead of resolving it here:
+ // the probe disables it when the layers and the shared KV are on different devices, which breaks a quantized V cache
+ if (model.arch == LLM_ARCH_GEMMA4_ASSISTANT) {
+ const bool flash_attn_other = cparams.ctx_other->get_cparams().flash_attn;
+ if (!cparams.auto_fa && cparams.flash_attn != flash_attn_other) {
+ LLAMA_LOG_WARN("%s: flash_attn = %d does not match the context the KV cache is shared with, using %d\n",
+ __func__, cparams.flash_attn, flash_attn_other);
+ }
+ cparams.flash_attn = flash_attn_other;
+ cparams.auto_fa = false;
+ }
+
cparams.fused_gdn_ar = true;
cparams.fused_gdn_ch = true;
cparams.auto_fgdn = false;
@@ -459,6 +472,22 @@ llama_context::llama_context(
backends.emplace_back(backend);
}
+ // tensors of ctx_other (e.g. a shared KV cache) can be on devices that this model does not use
+ if (cparams.ctx_other) {
+ for (const auto & dev_other : llama_get_model(cparams.ctx_other)->devices) {
+ const bool found = std::any_of(model.devices.begin(), model.devices.end(),
+ [&](const llama_device & dev) { return dev.dev == dev_other.dev; });
+ if (found) {
+ continue;
+ }
+ ggml_backend_t backend = ggml_backend_dev_init(dev_other.dev, nullptr);
+ if (backend == nullptr) {
+ throw std::runtime_error(format("failed to initialize %s backend", ggml_backend_dev_name(dev_other.dev)));
+ }
+ backends.emplace_back(backend);
+ }
+ }
+
// add ACCEL backends (such as BLAS)
for (size_t i = 0; i < ggml_backend_dev_count(); ++i) {
ggml_backend_dev_t dev = ggml_backend_dev_get(i);