fix(qwen35): warn when a prompt outgrows --fa-window - #653
Open
davide221 wants to merge 1 commit into
Open
Conversation
A finite --fa-window caps the full-attention layers to a sliding window, so any content earlier than the window is invisible to them. Nothing reports this. The model still answers, it simply cannot see the head of a long prompt, so the failure looks like a model quality problem rather than a configuration one. Found while benchmarking long context on a Radeon AI PRO R9700 with Qwen3.8-27B: with --fa-window 2048, a label planted at the top of the prompt was recalled at 1,556 tokens and missed at every longer length, with no diagnostic anywhere. Dropping the flag restored recall at all lengths up to 81K, and cost nothing measurable (44.4 vs 45.7 tok/s at a 27K prompt), so the silent tradeoff was not even buying speed on this hardware. Warn once, the first time a prompt actually outgrows the window, naming both numbers so the cause is unambiguous. Verified on the same box: the warning fires exactly once, on the 6,208-token request that does lose the label, and does not fire for the 1,556-token request that retrieves it.
Contributor
There was a problem hiding this comment.
1 issue found across 1 file
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="server/src/qwen35/qwen35_backend.cpp">
<violation number="1" location="server/src/qwen35/qwen35_backend.cpp:1634">
P3: The warning only checks the prefill-time length (tokens + kv_offset) and emits once, so it never fires when the prompt fits inside the window at prefill but a long generation then pushes the context past it. The decode-time sliding window at layer_split_forward.cpp:335 covers only [kv_start - fa_window, kv_start], so as generation grows kv_start the prompt head is dropped mid-generation with no warning, exactly the silent-retrieval problem the PR targets. Consider also warning from the decode path the first time kv_start exceeds fa_window with a finite window.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| // configuration one. Say so once, the first time a prompt actually | ||
| // outgrows the window. | ||
| if (cfg_.fa_window > 0 && | ||
| (int)tokens.size() + kv_offset > cfg_.fa_window) { |
Contributor
There was a problem hiding this comment.
P3: The warning only checks the prefill-time length (tokens + kv_offset) and emits once, so it never fires when the prompt fits inside the window at prefill but a long generation then pushes the context past it. The decode-time sliding window at layer_split_forward.cpp:335 covers only [kv_start - fa_window, kv_start], so as generation grows kv_start the prompt head is dropped mid-generation with no warning, exactly the silent-retrieval problem the PR targets. Consider also warning from the decode path the first time kv_start exceeds fa_window with a finite window.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At server/src/qwen35/qwen35_backend.cpp, line 1634:
<comment>The warning only checks the prefill-time length (tokens + kv_offset) and emits once, so it never fires when the prompt fits inside the window at prefill but a long generation then pushes the context past it. The decode-time sliding window at layer_split_forward.cpp:335 covers only [kv_start - fa_window, kv_start], so as generation grows kv_start the prompt head is dropped mid-generation with no warning, exactly the silent-retrieval problem the PR targets. Consider also warning from the decode path the first time kv_start exceeds fa_window with a finite window.</comment>
<file context>
@@ -1624,6 +1624,24 @@ int Qwen35Backend::do_prefill(const std::vector<int32_t> & tokens,
+ // configuration one. Say so once, the first time a prompt actually
+ // outgrows the window.
+ if (cfg_.fa_window > 0 &&
+ (int)tokens.size() + kv_offset > cfg_.fa_window) {
+ static std::atomic<bool> s_fa_window_warned{false};
+ if (!s_fa_window_warned.exchange(true)) {
</file context>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug
A finite
--fa-windowcaps the full-attention layers to a sliding window, so content earlier than the window is invisible to them. Nothing reports this. The model still answers, it just cannot see the head of a long prompt, so it reads as a model quality problem rather than a configuration one.Found while benchmarking long context on a Radeon AI PRO R9700 with Qwen3.8-27B. A label was planted at the very top of the prompt and the model asked to repeat it:
--fa-window 2048No warning was emitted in any of the failing cases.
Worth noting: on this hardware the flag was not even buying speed. At a 27K prompt it measured 44.4 tok/s with the window against 45.7 without, and full attention recalled the label at every length tested up to 81K.
The fix
Warn once, the first time a prompt actually outgrows the window, naming both numbers so the cause is unambiguous. No behaviour change otherwise.
Validation
On the same box with
--fa-window 2048: the warning fires exactly once, on the 6,208-token request that does lose the label, and does not fire for the 1,556-token request that retrieves it.