Commit Graph

1231 Commits

Author SHA1 Message Date
SamuelOliveirads 0d75eee35a remove duplicated code and unnecesary refactor 2026-06-14 16:02:02 -03:00
SamuelOliveirads 3a1d46c4d1 Merge remote-tracking branch 'origin/main' into feat/dflash-implementation
# Conflicts:
#	common/common.cpp
#	common/speculative.cpp
#	convert_hf_to_gguf.py
#	examples/server/server-context.cpp
#	examples/server/server-context.h
#	src/llama-arch.cpp
#	src/llama-arch.h
#	src/llama-model.cpp
#	src/llama.cpp
2026-06-13 17:27:52 -03:00
Samuel Oliveira Alves 8a38025174
Refactor: Move spec outside server (#1949)
* Refactor speculative decoding: move logic outside of server

* remove duplicated tokens in mtp kv cache

* narrow to only discard draft cells in MTP

* revert mtp_speculative_gen_draft
2026-06-12 18:12:39 +02:00
Simon Lundell b1eb8bb0a1
server: gate llama_decode_stop() to the active decode (fix queued-cancel cascade) (#1941)
With --parallel 1, a client disconnect/timeout on a *queued* request aborts the
*active* decode of a different client (llama_decode: failed to decode, ret = -3 /
"Decode process is cancelled by user"), releasing the slot with the request
unfinished. To the active client the stream silently stalls and never returns,
while the server reports healthy — easy to misdiagnose as a network/proxy wedge.

Root cause: llama_decode_stop() signals a process-global stop flag that the
active decode loop polls. examples/server/server.cpp calls it *ungated* from the
request reader's connection-closed paths, so any reader closing (including a
queued, not-yet-running task's) trips the global flag against whatever decode is
currently active. Adjacent to #1576/#1673 ("clear sticky stop flag" +
hybrid/recurrent ret=-3), which did not gate these call sites against non-active
readers, so the queued-cancel-kills-active cascade still fires on current main.

Fix (minimal gate): add server_response_reader::any_task_on_slot() and gate the
three llama_decode_stop() sites on it, so the global stop is signalled only when
one of THIS reader's tasks is on a slot (the active decode). A queued task's
disconnect then only drops that queued task. Verified in production under heavy
concurrent, frequently-cancelled load (hundreds of queued-task cancels, zero
active-decode kills). Stdlib-only reproducer in the PR description.

Caveat: any_task_on_slot() reads the slots vector from the reader thread — the
same race class as the existing process-global flag; can be tightened to a
per-context/per-task cancellation if preferred.
2026-06-12 08:25:44 +02:00
Kawrakow e6f8112f3b
Adjust CUDA FA kernel parameters for head size 512 on Turing (#1942) 2026-06-10 07:49:21 +02:00
firecoperana 2a1148384c
server: fix double submits of infill (#1944)
Co-authored-by: firecoperana <firecoperana>
2026-06-10 07:48:15 +02:00
Farmadupe 6b9de3dbaa
Fix mrope application across chunk boundaries (Fixes #993 and #1902 -- part 2) (#1918)
* (qwen3vl) Correct calculation for injection point of deepstack image embeddings

INjection point for deepstack embeddings used Hyperparameter n_embd_inp(), which caused the hidden state to be double accounted for, causing an OOB array access. The correct accessor is n_embd()

* Fix m-rope when pipeline parallelism is enabled
2026-06-05 17:10:02 +02:00
Farmadupe 1520eda980
prompt cache: Fix assertion that prompt cache does ot rewind to middle of image (#1913) 2026-06-04 17:53:06 +02:00
Samuel Oliveira Alves 007d640098
Standardize speculative decoding arguments on the server (#1908)
* refactor spec args

* add shell-safe quoting of string-valued stage keys in speculative decoding
2026-06-04 15:44:57 +02:00
firecoperana 6c0180d702
server: enable mcp proxy (#1904)
* update http lib

* Add cors proxy

---------

Co-authored-by: firecoperana <firecoperana>
2026-06-04 15:43:07 +02:00
firecoperana 074fc7dafd
webui: update llamacpp webui (#1903)
update config

ui: fix audio and video modality detection (#23756)

When model props are fetched asynchronously from the server,
modelPropsVersion is incremented to trigger reactivity, but
only the vision effect was listening to it.

webui: update ignore files

ui: handle audio/vnd.wave as audio WAV file (#23754)

Firefox on Linux uses this MIME type

ui: exclude generated build dirs from prettier and eslint so lint errors stop being masked (#23910)

webui: add custom CSS injection via config (#23904)

* webui: add custom CSS injection via config

register a customCSS setting in the Developer section under Custom JSON,
syncable so it rides the existing ui-config pass through. inject the value
into a single style element in the head, reactive on the setting. lets an
operator theme a prebuilt binary through --ui-config without rebuilding,
and lets a user set it from the settings panel.

move the textContent write into a use: action on the head style node.
the action is the idiomatic way to touch a node, so the no-dom-manipulating
lint rule is satisfied without a disable. value stays text through
textContent, never parsed as HTML.

* Update tools/ui/src/lib/constants/settings-keys.ts

Co-authored-by: Aleksander Grygier <aleksander.grygier@gmail.com>

* ui: address review from @allozaur, rename custom config key to customJson with migration

rename the custom config key to customJson across the type, the chat
request builder, the settings save check and the custom tools reader,
keeping the custom API param name unchanged. add a non destructive
migration that copies the legacy custom key to customJson at startup.
only render the head style tag when custom CSS is set.

---------

Co-authored-by: Aleksander Grygier <aleksander.grygier@gmail.com>

server: real-time reasoning interruption via control endpoint (#23971)

Builds on the manual reasoning budget trigger from #23949. Adds a
CONTROL task that mirrors the CANCEL path on the live slot and calls
common_sampler_reasoning_budget_force to end thinking mid-generation.
POST /v1/chat/completions/control with { id_slot, action }, opt-in
reasoning_control arms the budget sampler on demand. Router and single
model. Minimal WebUI button as a skeleton for further UI work.

* ui: track reasoning phase via explicit streaming state

Add isReasoning to the chat store, mirroring the isLoading pattern:
per conversation map, private setter, public accessor and reactive
export. Set from the stream callbacks, true on reasoning chunks, false
on the first content chunk, reset on stream end and resynced on
conversation switch. The skip button now keys off isReasoning so it
shows only during the thinking phase, not the whole generation.

* ui: extract control endpoint and action into constants

Move the chat completion routes, the slots route and the reasoning
control action out of chat.service into api-endpoints and a dedicated
control-actions module. No behavior change, drops the magic strings so
the control protocol has a single source of truth.

* server: target reasoning control by completion id

Address @ngxson review on the control endpoint.

Switch from id_slot to the chat completion id to avoid a TOCTOU: the
slot can be reassigned between the lookup and the control request, so
matching the live completion (oaicompat_cmpl_id) is safe and a finished
one simply matches nothing. Rename the action to reasoning_end, guard
it on the reasoning_control flag of the target slot, and reduce the
response to {success} with an optional message.

* ui: target reasoning control by completion id

Keep the streamed completion id on the message and post it back to the
control endpoint instead of probing /slots. Drops the slot discovery
and the TOCTOU that came with it. Action renamed to reasoning_end,
response read as {success}.

* server: address review from @ngxson

Move the control fields into task_params and drop the redundant
comments on the control path.

* server: document the reasoning control endpoint

* Update tools/ui/src/lib/types/database.d.ts

Co-authored-by: Aleksander Grygier <aleksander.grygier@gmail.com>

* ui: rename cmplId to completionId

Per @allozaur review, clearer name for the streamed completion id.

* ui: wire completion id capture through the agentic flow

The webui streams through the agentic flow, which relayed onModel but
not onCompletionId, so the completion id never reached the message and
the control request was never sent. Relay it through the flow and its
callbacks type, declare id on the chunk type, and log an explicit error
when the button fires without a usable id.

* ui: target reasoning control model from the message

The model is a property of the completion, so read it from the streaming
message like the id, not from the model dropdown which is unrelated UI
state. Makes the request self-consistent by construction instead of just
unlikely to drift.

---------

Co-authored-by: Aleksander Grygier <aleksander.grygier@gmail.com>

ui: Add Thinking mode toggle with reasoning effort levels + improvements for Chat Form Add Action UI (#23434)

Co-authored-by: Aleksander Grygier <aleksander.grygier@gmail.com>

* fix: Model tags

ui: simplify network error handling (#23431)

Previously error to string conversion was split in two different files,
with one converting errors into strings, and another function analyzing
those strings to generate yet another string.

Now the the error handling for network fetches has been centralised and
uses directly HTTP error codes whereas possible to generate the
human-readable error strings.

It also fixes an issue where all JSON errors reported from the backend,
such as "Invalid API key", would get turned incorrectly in to
"Failed to connect to server" due to poor matching logic in the
now-gone getErrorMessage function.

update html

ui: Mermaid Diagrams in chat + interactive preview (#24032)

webui: fix tool selector toggle/counter, key tools by stable identity (#24065)

* webui: fix tool selector toggle/counter, key tools by stable identity

Key the disabled set, counts and toggles by a stable per-tool key
instead of bare function name, deduped from one canonical list. Per-tool
checkboxes become presentational (single row handler, no nested button),
category checkboxes drop the tristate (n/total carries partial). One
getEnabledToolsForLLM keeps normalized MCP schemas and dedupes by name.

* ui: use SvelteSet and SvelteMap for local tool collections to satisfy svelte/prefer-svelte-reactivity

Co-authored-by: firecoperana <firecoperana>
2026-06-04 15:41:23 +02:00
Farmadupe e08ad51f15
Insert image pad markers for kimi K2.5 and K2.6 (#1912) 2026-06-04 09:27:28 +02:00
SamuelOliveirads 1250f522ed add qwen, gemma and kimi dflash support 2026-06-01 17:14:25 -03:00
SamuelOliveirads 1369e68471 fix graph mask, swa layers and tokens positions 2026-05-31 11:12:03 -03:00
SamuelOliveirads 532499836e improve DFlash caching and profiling capabilities 2026-05-30 21:36:10 -03:00
Samuel Oliveira Alves 3f40e73c36
expand np guardrail for all mtp types (#1901) 2026-05-30 16:19:53 +03:00
SamuelOliveirads 9f5f70cf7e implement target position tracking and context management 2026-05-29 23:11:38 -03:00
SamuelOliveirads 82cff238fe Initial dflash implementation 2026-05-28 18:57:58 -03:00
Samuel Oliveira Alves 9f7ba245ab
Update autofix and presets (#1867)
* Add configuration files for format, presets and examples

* add clang in pre-commit config

* remove clang configurations

* Refactor .gitignore for consistency in formatting
2026-05-24 07:30:44 +03:00
dungquixote42 642c038ccd
Extend expiring logit bias to other sampling parameters (#1770)
* initial commit

* fix underflow bug, add debug prints, update macro/variable names

* fix phrases-sharing-1-flag bug, replace macros with struct member function

* cleanup

* fix file parsing

* string_split_open_close() -> string_extract(), improve escape handling

* support multiple nested entries

* make persistent entries global, simplify file parsing

* cosmetic changes

* add support for jumping to exitword

* update variable names

* fix bad search bug

* better debug prints, reorg

* replace lambda with string_is_found(), add string_unescape() for debug

* add support for inline comments

* add missing debug print macro

* fix type promotion bug

* actually fix type promotion bug
2026-05-23 19:19:12 +03:00
Samuel Oliveira Alves d51036a0c4
fix: reset KV cache and prompt state in server_slot and server_context (#1860) 2026-05-22 08:14:47 +03:00
Samuel Oliveira Alves 11a1fea9e2
Move embedding management to speculative (#1825)
* refactor speculative decoding with companion context and draft result structures

* feat: add common speculative feature handling in server context

* refactor: move embedings outside server

* feat: harden draft input hidden state in llama context

* remove unused functions

* refactor: streamline speculative feature handling and remove unused code

* remove redundant code

* remove more unused variables

* refactor: implement speculative feature handling
2026-05-20 17:42:48 +03:00
Samuel Oliveira Alves 77413bc900
Add Hadamard parameters to draft model loading (#1840) 2026-05-19 18:30:41 +03:00
firecoperana 104846ddee
spec : disacard last drafted token with low prob (#1820)
* spec : disacard last drafted token with low prob

* Apply suggestion from @ikawrakow

Co-authored-by: Kawrakow <iwankawrakow@gmail.com>

---------

Co-authored-by: firecoperana <firecoperana>
Co-authored-by: Kawrakow <iwankawrakow@gmail.com>
2026-05-19 08:35:35 +03:00
firecoperana f645ed1e2d
AutoParser: improve reasoning budget and handling of space/newline in tool calls (#1819)
common/chat, server: refactor, move all conversion functions to common, add tests (#20690)

jinja : remove unused header (#22310)

common : fix jinja warnings with clang 21 (#22313)

Signed-off-by: Adrien Gallouët <angt@huggingface.co>

chat: fix handling of space in reasoning markers (#22353)

* chat: fix handling of space in reasoning markers

common : re-arm reasoning budget after DONE on new <think> (#22323)

common : determine generation prompt using longest common prefix (#22657)

common/autoparser: fixes for newline handling / forced tool calls (#22654)

* chat/autoparser: the fixes

* Move optspace() to chat-peg-parser, comment out server tests invalidated due to content now allowed with forced tool calls.

* Trim whitespace on apply instead

common/chat : preserve media markers for typed-content templates (#22634)

common : revert reasoning budget +inf logit bias (#22740)

common : do not wrap raw strings in schema parser for tagged parsers (#22827)

common : enable streaming JSON argument values (#23173)

* common : remove atomic from json arguments

* common : remove parsing logic on JSON arguments

common : do not pass prompt tokens to reasoning budget sampler (#22488)

reasoning-budget: clone should do a deep-copy (#23095)

Co-authored-by: Piotr Wilkin (ilintar) <piotr.wilkin@syndatis.com>
2026-05-19 08:34:19 +03:00
gapeleon c35189d83c
fix(server): reset chat parser on slot reuse to prevent crash (#1763) (#1794)
If a slot is reused for a standard completion (`/v1/completions`) after
being used for a chat completion (`/v1/chat/completions`), the previous
chat's PEG parser would remain active in the slot's parameters. This
caused standard text completions to throw on the raw text.
2026-05-17 18:26:45 +03:00
Kawrakow 1f8c603d9c
Quantize: add extra output tensor for MTP (#1810)
* Quantize: add extra output tensor for MTP

* Consistently use --mtp-requantize-output-tensor
2026-05-17 13:59:56 +03:00
Samuel Oliveira Alves f4f4b3ff26
Allow dual speculative decoding (#1789)
* wip: test logic to use multiple specs

* feat: introduce composite speculative decoding stages

* handle MTP context and draft invalidation

* fix: allow gemma mtp for speculative stages

* fix: normalize spec stage keys

* refactor: remove enable_mtp flag and improve speculative stage handling

* fix: update cached text tokens handling for stage chains

* feat: implement sync for external MTP after non-MTP accept
2026-05-15 10:10:40 +03:00
Samuel Oliveira Alves 40b65d8f54
feat: add support for draft imatrix output file (#1803) 2026-05-15 08:10:58 +03:00
Kawrakow ba72890076
Faster imatrix (#1801)
* Faster imatrix on AVX2

* Slightly better
2026-05-15 07:15:16 +03:00
Samuel Oliveira Alves 35fbe08d6e
disable MTP for parallel slots (#1804) 2026-05-15 07:11:04 +03:00
Samuel Oliveira Alves 0fcffdb64d
feat: map Gemma 4 tensor and support with imatrix (#1796) 2026-05-14 09:01:24 +03:00
ubergarm ca52a825db
feat: add --threads-mtmd for independent multimodal thread count (#1797)
Add `-tm` / `--threads-mtmd` to control CPU thread count used during
multimodal image/audio processing (mmproj encoding), separate from the
main LLM thread count.

This allows running the LLM on GPU with minimal CPU threads (e.g. `-t 1`)
to reduce sync overhead, while using many threads (e.g. `-tm 16`) for
CPU-bound mmproj encoding with `--no-mmproj-offload`.

Fallback chain when `-tm` is not specified:
 1. `--threads-batch` (-tb) — multimodal encoding is a batch/prefill-like
    operation, so it makes sense to track with batch thread count
 2. `--threads` (-t) — final default

Works with both mtmd-cli and llama-server.

AI: ubergarm/Qwen3.6-27B-GGUF MTP IQ4_KS 15.113 GiB (4.752 BPW) + pi.dev
2026-05-13 17:44:43 +03:00
firecoperana cdc288bc97
server: reset cache tokens after pp stops (#1787)
Co-authored-by: firecoperana <firecoperana>
2026-05-13 09:05:32 +03:00
Samuel Oliveira Alves be8435793e
Pre-allocate buffers for hybrid model checkpoints (#1774)
* hybrid-spec: improve recurrent checkpoint handling in speculative decoding

* change per-step save to support scheduling and asynchronous tensor operations

* remove redudant backend tensor fallback

* improve recurrent tensor handling for split graph
2026-05-12 07:21:25 +03:00
Lingfeng Ren c2f498ab4c
MTP: use target slot position for drafting (#1781) 2026-05-12 07:21:03 +03:00
Lingfeng Ren 35845dd975
server : support MTP with multimodal prompts (#1758)
Synchronize MTP state after mtmd decode batches so multimodal prompt chunks do not desync the draft context.
2026-05-11 09:51:07 +03:00
Samuel Oliveira Alves c2b8bca807
Add MTP Support for Gemma 4 (#1744)
* gemma-mtp: build the arch to load the MTP model

* gemma-mtp: fix mtp kv state

* gemma-mtp: refactor some functions and create gguf

* gemma-mtp: make usable for embeddings models variant

* gemma-mtp: fix qwen mtp load in graph split

* gemma-mtp: refactor tensor creation and adjust output tensor handling

* Gemma 4 MTP: improve tensor handling, and adjust split mode logic
2026-05-10 07:44:20 +03:00
Alex 51331f4973
Fix two speculative-decoding crashes that prevent any usage (#1760)
This patch addresses two latent bugs in examples/speculative/speculative.cpp
that prevent llama-speculative.exe from running on greedy sampling
(temp=0) or producing rejection-sampling output (temp>0):

1. Line 191: `params.sparams.grammar = { COMMON_GRAMMAR_TYPE_NONE, "" };`
   invokes `common_grammar(type, grammar)` which asserts
   `type != NONE || !grammar.empty()`. Both conditions fail with the
   intended-to-be-empty grammar, so every speculative run hits a hard
   `GGML_ASSERT` in common/sampling.h:63 immediately after model load.

   Fix: default-construct via `common_grammar{}` to bypass the
   field-init constructor.

2. Lines 293-294: `GGML_ASSERT(dist_tgt.sorted)` and
   `GGML_ASSERT(dist_dft.sorted)` fire whenever the draft sampler does
   not set the .sorted flag (which is most modern sampler paths).
   Comment them out — the next ~10 lines re-sort both distributions
   by id explicitly, so the assertion is incorrect anyway.

   Fix: replace the asserts with an explanatory comment.

After both fixes, `llama-speculative.exe` runs to completion. The
acceptance-rate measurement at temp=0 still looks suspicious (0%
across same-family draft/target pairs), but that is a different
issue out of scope for this PR.

Tested on Qwen3-0.6B-IQ4_XS drafting Qwen3-1.7B-IQ4_XS, both base
models from `bartowski/Qwen_Qwen3-*-GGUF` on Windows + ik_llama.cpp
build at HEAD of windows-mingw-default-win10 (which is itself a
follow-up to PR #1755).
2026-05-09 08:36:38 +03:00
dungquixote42 b93721902b
Add Expiring Logit Bias (#1731)
* initial commit

* fix substr() out of range

* add tilde (~) as bias range indicator

* fix runtime error when the first entry is exitword
2026-05-06 09:25:38 +03:00
firecoperana 39b3a188e8
server: fix mtmd checkpoint restore and avoid checkpoint host copies (#1743)
Co-authored-by: firecoperana <firecoperana>
2026-05-06 08:42:21 +03:00
Heath Albritton bc549da0f7
server : catch sampler/grammar exceptions to avoid process abort (#1725) (#1726)
Wrap the two slot-level sample/accept call sites in
try/catch (std::exception). On exception: log, send_error to the
task, release the slot, continue serving. Matches the existing
try/catch around common_sampler_init in the same file.

Without this, llama_grammar_accept_token throwing
"Unexpected empty grammar stack after accepting piece: <pad> (0)"
(reproducible on Gemma 4 + json_schema + ctx_shift, see #1725)
unwinds out of update_slots -> queue start_loop -> main, hits
std::terminate, and aborts the whole server process.
2026-05-03 08:21:09 +03:00
firecoperana 9f1deefa71
server: revert checkpoint fix (#1716)
Co-authored-by: firecoperana <firecoperana>
2026-05-02 16:09:28 +03:00
KeinNiemand 9c7d8b07cc
perplexity : fix large-vocab logit offset overflow (#1717)
Co-authored-by: Codex <noreply@openai.com>
2026-05-02 16:08:49 +03:00
Kawrakow a8aecbf159
Disable k-shift for split mode graph (#1714) 2026-04-30 18:03:29 +02:00
Samuel Oliveira Alves 67e6346225
Support for Qwen 3.5 MTP (dense models only) (#1698)
* qwen-mtp: add dense mtp for one draft

* add support for smaller qwen mtp commit

* qwen-mtp: fix graph for qwen dense variants

* Squashed commit of the following:

commit a92a154b38c7fddc84460f8852c900f8d6ce907e
Author: SamuelOliveirads <samueloliveira32df@gmail.com>
Date:   Mon Apr 20 13:30:21 2026 -0300

    recurrent model: refactor api

commit dfac8f19f6edc0014b4116041b89c1e0dfb173c7
Author: SamuelOliveirads <samueloliveira32df@gmail.com>
Date:   Mon Apr 20 12:22:29 2026 -0300

    recurrent model: implement recurrent kernel checkpoint

commit 9c44b117f93e9060030907e1250106358c9ccf47
Author: SamuelOliveirads <samueloliveira32df@gmail.com>
Date:   Sat Apr 18 11:52:39 2026 -0300

    speculative: fix sampler for checkpoints

commit e7006393bca20adcd86e2d77021e0b41d7bd9db1
Author: SamuelOliveirads <samueloliveira32df@gmail.com>
Date:   Fri Apr 17 14:08:25 2026 -0300

    server: refactor checkpoint state logic

commit 57eabf04df5185cab19539185b8f4b85e578905b
Merge: dc4797b7 64234e3c
Author: SamuelOliveirads <samueloliveira32df@gmail.com>
Date:   Fri Apr 17 13:53:41 2026 -0300

    Merge branch 'main' into fix/hybrid-cache-speculative

commit dc4797b72363482bb35750bb5edc87068116dc0f
Author: SamuelOliveirads <samueloliveira32df@gmail.com>
Date:   Fri Apr 17 13:12:40 2026 -0300

    reset ngram mod state for rejected tokens

commit 8ff2d943a31b3d54440698db41e62ea121d661be
Author: SamuelOliveirads <samueloliveira32df@gmail.com>
Date:   Fri Apr 17 13:08:04 2026 -0300

    server: snapshot recurrent state in tensor

commit d93dfb5e6b78a822e7331b33feedbdc47eb5ec79
Author: SamuelOliveirads <samueloliveira32df@gmail.com>
Date:   Thu Apr 16 22:36:37 2026 -0300

    fix: save/restore sampler state during speculative checkpoint

    When speculative decoding rejects draft tokens and restores the
    recurrent state checkpoint, the sampler (RNG, grammar, prev tokens)
    must also be restored to maintain consistency. Without this, the
    sampler state reflects the rejected draft tokens, leading to
    potential divergence.

    Uses common_sampler_clone() to snapshot the sampler before the
    speculative batch decode, and restores it on rejection.

commit d670cf85cd59f23a339faf6fd773889063176801
Author: SamuelOliveirads <samueloliveira32df@gmail.com>
Date:   Thu Apr 16 21:53:52 2026 -0300

    server: spec checkpoints for recurrent models

* server: fix leak context between requests

* qwen3: allow mtp to run with split graph

* qwen3 mtp: selects rows before the ffn
2026-04-28 07:47:50 +02:00
Samuel Oliveira Alves ea94afe777
Speculative checkpoints for recurrent models (#1669)
* server: spec checkpoints for recurrent models

* fix: save/restore sampler state during speculative checkpoint

When speculative decoding rejects draft tokens and restores the
recurrent state checkpoint, the sampler (RNG, grammar, prev tokens)
must also be restored to maintain consistency. Without this, the
sampler state reflects the rejected draft tokens, leading to
potential divergence.

Uses common_sampler_clone() to snapshot the sampler before the
speculative batch decode, and restores it on rejection.

* server: snapshot recurrent state in tensor

* reset ngram mod state for rejected tokens

* server: refactor checkpoint state logic

* speculative: fix sampler for checkpoints

* recurrent model: implement recurrent kernel checkpoint

* recurrent model: refactor api

* spec: free rbudget before overwriting
2026-04-24 09:59:30 +02:00
Yap Sok Ann 1c13288164
Fix infinite tool calls loop with `--parallel-tool-calls` (#1679)
Previously, the end-of-turn token would be added to prompt cache by
`slot.cache_tokens.push_back(slot.sampled)`, without going through
`llama_decode()` first. As such, the token doesn't exist yet in the
actual KV cache. Then, in the next turn, processing of this EOT token
will be skipped since it is already in the prompt cache.

The expected sequence (with Qwen3.5 chat template):

    </tool_call><|im_end|>
    <|im_start|>user
    <tool_response>

The actual sequence that the model sees:

    </tool_call>
    <|im_start|>user
    <tool_response>

As the conversation goes on, the model starts losing the ability to
generate an EOT token after `</tool_call>`, since it hasn't seen this
pattern in the context. With `--parallel-tool-calls`, the grammar
allows `</tool_call>` to be followed by either another tool call or an
EOT token. So, this eventually leads to the model making infinite tool
calls.

We fix this by deferring all the processing of the EOT token to the
next turn.

Fixes #1661
2026-04-24 09:48:21 +02:00
markaalonzo 48819dadaf
server: fix ret=-3 on hybrid/recurrent prompt cache, and clear sticky stop flag (#1673)
Two related issues that manifest as 'llama_decode ret=-3' on hybrid
architectures (e.g. Qwen3.5/3.6 MoE, Qwen3-Next), matching the symptom
reported in #1576.

1) server_context::apply_checkpoint() was written around transformer KV
   semantics (pos_min / pos_max per-token window). For hybrid and pure
   recurrent models the per-token pos_min threshold does not apply: the
   recurrent state is a single snapshot, and the server-side checkpoint
   is a whole-prefix record. The old selector 'cur.pos_min < pos_min_thold'
   can succeed on a checkpoint whose pos_max is past the current n_past,
   and — more commonly — fall through to do_reset = true, which zeros
   slot.n_past / slot.n_past_prompt. Zeroing in-place while the recurrent
   state in the context is still populated makes the next decode batch
   disagree with the live state, returning ret=-3.

   This change gates the checkpoint path on
   llama_model_has_recurrent(llama_get_model(slot.ctx)):
   - selector uses pos_max <= slot.n_past && pos_max < pos_next
     (whole-prefix match, leaves at least one token to decode);
   - on miss, slot state is preserved rather than zeroed, letting
     update_slots() continue from the already-valid n_past_prompt;
   - the erase loop drops any checkpoint whose pos_max > pos_next,
     matching the rewind semantics for recurrent state.

   Transformer behavior is unchanged.

2) stop_internal_decode is a file-static global in src/llama.cpp, set by
   llama_decode_stop() (called on client disconnect) and polled inside
   the decode loop to bail out with ret=-3. The flag is only cleared on
   one conditional path in server_slot::release(), so a stop signal that
   arrives after the interrupted llama_decode() has already returned
   bleeds into the NEXT decode call and causes an immediate ret=-3 with
   no work performed. Clear it at the top of the public llama_decode()
   entry so the signal is scoped to the in-flight decode it was meant
   for.

Build-verified: llama-server with GGML_CUDA=ON, -DCMAKE_CUDA_ARCHITECTURES=86
(sm_86), IQK flash-attn + matmul enabled. No new APIs introduced —
llama_model_has_recurrent is already public and already used elsewhere in
server-context.cpp.

Closes #1576
2026-04-23 09:19:17 +02:00
Kawrakow e5355e9895
Quantization options (#1677) 2026-04-23 09:05:39 +02:00