From 41b9cb9d702487160427c5e9854e617f61b1da46 Mon Sep 17 00:00:00 2001 From: "Sabnis, Omkar" Date: Fri, 30 Oct 2026 07:32:02 -0700 Subject: [PATCH] ggml-openvino: accept flash attention on layers without RoPE On layers without RoPE (SmolLM3: every 4th layer), Q reaches FLASH_ATTN_EXT through PERMUTE -> VIEW -> RESHAPE. The support check rejected this pattern, causing these layers to fall back to CPU and the split graph to fail with -fa on/auto. --- ggml/src/ggml-openvino/ggml-openvino.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ggml/src/ggml-openvino/ggml-openvino.cpp b/ggml/src/ggml-openvino/ggml-openvino.cpp index 097c65fca7eb..62085e125aee 100644 --- a/ggml/src/ggml-openvino/ggml-openvino.cpp +++ b/ggml/src/ggml-openvino/ggml-openvino.cpp @@ -1330,6 +1330,7 @@ static bool is_supported_flash_attn_pattern(const ggml_tensor * op) { // PERMUTE -> VIEW -> base (view_src==nullptr) (llama KV-cache path) // PERMUTE -> RESHAPE -> base (view_src==nullptr) (whisper Q) // VIEW -> base (view_src==nullptr) (whisper K/V from kv_pad) + // PERMUTE -> VIEW -> RESHAPE -> base (Q of a layer without RoPE, e.g. SmolLM3) for (int i = 0; i < 3; i++) { const ggml_tensor * src = op->src[i]; if (src->op == GGML_OP_PERMUTE) { @@ -1339,7 +1340,11 @@ static bool is_supported_flash_attn_pattern(const ggml_tensor * op) { if (src->src[0]->op != GGML_OP_VIEW && src->src[0]->op != GGML_OP_RESHAPE) { return false; } - if (src->src[0]->src[0] == nullptr || src->src[0]->src[0]->view_src != nullptr) { + const ggml_tensor * base = src->src[0]->src[0]; + if (base != nullptr && src->src[0]->op == GGML_OP_VIEW && base->op == GGML_OP_RESHAPE) { + base = base->src[0]; + } + if (base == nullptr || base->view_src != nullptr) { return false; } } else if (src->op == GGML_OP_VIEW) {