mirror of
https://github.com/ggml-org/llama.cpp.git
synced 2026-09-19 17:24:57 +02:00
llama: fix the qwen4exp PLE history seq_rm(-1) iterator invalidation and the fatal-warning build
ple_hist_rm recursed over ple_hist with a range-based for and the recursive call
erases the entry it is iterating when the whole sequence is removed (p0 <= 0,
p1 < 0), so the loop then increments an invalidated iterator. It is unreachable
today only because llama_memory_recurrent::seq_rm rejects seq_id < 0 before
llama_memory_hybrid_idx::seq_rm reaches the history, which is a guard in another
class. Advance past the entry before recursing.
Two smaller things in the same area:
- the n_toks sanity bound in ple_hist_state_read was the literal 64, which is
the value of LLAMA_MAX_PLE_HEADS, not of the quantity being checked. The
window is at most ple_ngram_size - 1 tokens, so the bound is
LLAMA_MAX_PLE_NGRAM - 1, eight times tighter.
- build_conv_state_at left mem_size unused, so -DLLAMA_FATAL_WARNINGS=ON does
not compile. Predates this series; drop the line.
(cherry picked from commit 6eba44a89d5f328eb4859b844e1d28fb564cbe3e)
This commit is contained in:
@@ -249,8 +249,12 @@ static void ple_hist_truncate(llama_memory_hybrid_idx::ple_history & h, llama_po
|
||||
|
||||
void llama_memory_hybrid_idx::ple_hist_rm(llama_seq_id seq_id, llama_pos p0, llama_pos p1) {
|
||||
if (seq_id < 0) {
|
||||
for (auto & it : ple_hist) {
|
||||
ple_hist_rm(it.first, p0, p1);
|
||||
// the recursive call erases seq_id's entry when the whole sequence is removed, so
|
||||
// advance past it first: erase invalidates only the iterator to the erased element
|
||||
for (auto it = ple_hist.begin(); it != ple_hist.end(); ) {
|
||||
const llama_seq_id id = it->first;
|
||||
++it;
|
||||
ple_hist_rm(id, p0, p1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -433,9 +437,9 @@ void llama_memory_hybrid_idx::ple_hist_state_read(llama_io_read_i & io, llama_se
|
||||
io.read(&next_pos, sizeof(next_pos));
|
||||
io.read(&n_toks, sizeof(n_toks));
|
||||
|
||||
// the window is never longer than ple_ngram_size - 1, so a larger count is a corrupt
|
||||
// blob and would size an allocation from the file
|
||||
if (n_toks > 64) {
|
||||
// the window is never longer than ple_ngram_size - 1; anything else is a corrupt or
|
||||
// mismatched blob, and reading it would size an allocation from the file
|
||||
if (n_toks > LLAMA_MAX_PLE_NGRAM - 1) {
|
||||
throw std::runtime_error("qwen4exp PLE history: implausible token count in state blob");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user