You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Eval bug: DFlash drafter fails to bind (vector::_M_range_check) when target GGUF encodes attention.sliding_window_pattern as an array — Muse-Glimmer-30B official GGUF #26894
version: b10349 (62bf73d, includes the #26841 merge)
Built from source (CUDA, CMAKE_CUDA_ARCHITECTURES=86;120) in a local Docker image.
Hardware: RTX 3090 + RTX 5060 Ti.
Binding the DFlash drafter (--spec-type draft-dflash) crashes at load time when the target GGUF encodes muse-glimmer.attention.sliding_window_pattern as an array, which is how the model creator's own official GGUF (meta-models/Muse-Glimmer-30B-GGUF) encodes it:
vector::_M_range_check: __n (which is 1) >= this->size() (which is 1)
The exact same drafter file binds and runs fine when the target is the unsloth conversion of the same model, whose muse-glimmer.attention.sliding_window_pattern is encoded as a scalar (UINT32 = 4).
Both target GGUFs load and generate fine without the drafter — src/models/muse-glimmer.cpp accepts both encodings (scalar period → set_swa_pattern(), array → per-layer is_swa_impl). The crash only happens on the DFlash bind path, which inherits the target's config and apparently only handles the scalar form. Note the irony: the model creator's official GGUF is the one that cannot bind the official drafter shipped in the same repo, while a third-party conversion can.
Validated workaround: copying the target GGUF with gguf-py copy_with_new_metadata, rewriting muse-glimmer.attention.sliding_window_pattern to scalar UINT32 = 4. With that single metadata change the drafter binds and runs (~137 t/s on the RTX 3090).
Suggested fix: when the DFlash path inherits the target's config, accept both encodings of <arch>.attention.sliding_window_pattern, mirroring what src/models/muse-glimmer.cpp already does at target load. Possibly related: the scalar overload llama_model_loader::get_key_or_arr(enum llm_kv, uint32_t &, bool) in src/llama-model-loader.cpp returns false (non-required) or throws when the key is an array, so any call site expecting a scalar silently takes the wrong branch on array-encoded GGUFs.
First Bad Commit
Not bisected — observed on b10349 (62bf73d). Possibly present since the DFlash path landed.
Relevant log output
vector::_M_range_check: __n (which is 1) >= this->size() (which is 1)
Hi @bordessoules, I can't reproduce on the current master or 62bf73d. Could you please share a stack trace or full reproducible instructions? I have tested with the following command, where the files are a local download of this repo.
First of all: thank you @pcuenca for taking the time to test, and @CISC — your hunch in the #26900 thread that this issue "may not actually be related" was correct. My original diagnosis was wrong, and I apologize for the noise it caused. I re-investigated from scratch and I believe I found the actual root cause. It has nothing to do with GGUF metadata, on either the target or the drafter side — but there does seem to be a small, reproducible bug underneath, still present on current master. Details below; please tell me if I got anything wrong.
What I believe the root cause is
src/llama-model.cpp, default-split layer assignment (line 1352 on current master):
// default split, by free memory
splits[i] = free; // from ggml_backend_dev_memory()
...
splits[i] /= split_sum; // free == 0 => 0/0 = NaNconstint layer_gpu = std::upper_bound(splits.begin(), splits.begin() + n_devices(),
float(il - i_gpu_start)/act_gpu_layers) - splits.begin();
auto * dev = devices.at(layer_gpu).dev;
If every visible device reports 0 bytes of free memory, split_sum == 0 and the normalization turns splits into NaNs. std::upper_bound over NaNs finds no element (x < NaN is false), returns end(), so layer_gpu == n_devices() — and devices.at(layer_gpu) throws exactly the error from my report:
llama_model_load: error loading model: vector::_M_range_check: __n (which is 1) >= this->size() (which is 1)
(1 >= 1 because I run with a single visible device via CUDA_VISIBLE_DEVICES.)
Reproduction
LD_PRELOAD shim that forces ggml_backend_dev_memory to report free = 0 for CUDA devices (real total preserved):
This reproduces the exact message, word for word, in every combination I tried: b10349 (the build from my original report) and b10380; the Muse Glimmer target with the DFlash drafter, and an unrelated dense model with no speculative decoding at all. So it is not specific to Muse Glimmer or to DFlash.
It also reproduces naturally, without the shim: saturating the GPU with a separate process (plain cuMemAlloc loop until nothing is allocatable; cuMemGetInfo monitored at 0 free bytes throughout) and then running my original command produces the identical failure sequence from my report, line for line — the ~20 GB target still loads (slowly, apparently falling back to host memory), and then the draft model load crashes:
llama_model_load: error loading model: vector::_M_range_check: __n (which is 1) >= this->size() (which is 1)
common_speculative_init_result: failed to load draft model, '.../dflash-kquant.gguf'
That is exactly what I saw on the night of the original report, which explains why the crash hit the draft-model load specifically.
Why my original report blamed the metadata
I went back to my logs from that night: the crash happened while loading the draft model, immediately after the ~20 GB target had loaded, at the end of a long benchmarking session with heavy VRAM churn — so the GPU was evidently being held by something else at that moment, matching the natural reproduction above. My metadata "fix" then appeared to work simply because I tested it later, with free VRAM — a timing coincidence that I mistook for causation, and the array-vs-scalar difference between the two conversions made it look convincing.
To make sure the file itself is innocent, I re-downloaded muse-glimmer-30B-kquant-dynamic.gguf (sha256 matches the Hub LFS oid) and re-ran it on both builds with the exact original command: it loads, binds the DFlash drafter and generates correctly, 10/10 repeated spawns. meta-models/Muse-Glimmer-30B-GGUF is fine as published.
Possible fix
Perhaps guard the degenerate case before normalizing, e.g.:
if (split_sum == 0.0f) {
// no device reported free memory — fall back to an even split// (or fail with a clear out-of-memory message)for (size_t i = 0; i < n_devices(); ++i) { splits[i] = float(i + 1) / n_devices(); }
}
or clamp layer_gpu to n_devices() - 1 — whichever you prefer. The main value would be that users in this situation get a clear "insufficient device memory" message instead of a cryptic out_of_range, which is what sent me down the wrong path here.
I'm happy to open a PR for this if useful, and to update this issue's title to reflect the actual bug — something like "model load crashes with vector::_M_range_check when a device reports 0 free memory (NaN in default-split layer assignment)". Or if you prefer to just close this and track it elsewhere, that's fine too. Thanks again for your time.
Independent confirmation of the root cause described above, with a reproduction that needs no LD_PRELOAD shim and no GPU-saturating helper process.
On a single RTX 4090 (24 GB, sm_89, WSL2) the failure is a pure function of the target model's context size: a large enough -c leaves the device with too little free memory by the time the draft model is loaded.
vector::_M_range_check: __n (which is 1) >= this->size() (which is 1)
The boundary sits exactly where the headroom runs out: 100000 with--mmproj peaks at 24098 MiB of 24564, i.e. ~466 MiB free, and the draft model is 1.14 GB.
Ruled out, so it is not the model or the format:
Fails at 130000 without--mmproj, and succeeds at 100000 with it — not the mmproj / M-RoPE path.
The draft GGUF loads fine standalone on the same binary (it then only fails at dflash requires ctx_other to be set, as expected).
This matches the NaN-in-default-split explanation exactly, and it is the shape a user actually hits in practice: not a saturated GPU from an unrelated process, but simply asking for a context size that does not leave room for the drafter.
The practical cost of the current message is that it reads like a model or format incompatibility rather than an out-of-memory condition. I spent a full session concluding DFlash2 was broken for my model before finding this issue — a clear "insufficient free device memory to load the draft model" would have saved all of it. Happy to test a patch.
Build: 2f3923b, i.e. the branch merged as #27342 / b10f9ca5. CUDA 12.8, CMAKE_CUDA_ARCHITECTURES=89. Target unsloth/Qwen3.8-27B-GGUF (UD-Q4_K_XL), draft z-lab/Qwen3.8-27B-DFlash2-GGUF (Q4_K_M).
Measurements and write-up produced in a Claude Code session; the hardware and the numbers are my own.
Activity
CISC commentedon Aug 11, 2026
Please test linked PR.
pcuenca commentedon Aug 12, 2026
Hi @bordessoules, I can't reproduce on the current
masteror 62bf73d. Could you please share a stack trace or full reproducible instructions? I have tested with the following command, where the files are a local download of this repo.bordessoules commentedon Aug 13, 2026
First of all: thank you @pcuenca for taking the time to test, and @CISC — your hunch in the #26900 thread that this issue "may not actually be related" was correct. My original diagnosis was wrong, and I apologize for the noise it caused. I re-investigated from scratch and I believe I found the actual root cause. It has nothing to do with GGUF metadata, on either the target or the drafter side — but there does seem to be a small, reproducible bug underneath, still present on current
master. Details below; please tell me if I got anything wrong.What I believe the root cause is
src/llama-model.cpp, default-split layer assignment (line 1352 on current master):If every visible device reports 0 bytes of free memory,
split_sum == 0and the normalization turnssplitsinto NaNs.std::upper_boundover NaNs finds no element (x < NaNis false), returnsend(), solayer_gpu == n_devices()— anddevices.at(layer_gpu)throws exactly the error from my report:(
1 >= 1because I run with a single visible device viaCUDA_VISIBLE_DEVICES.)Reproduction
LD_PRELOADshim that forcesggml_backend_dev_memoryto reportfree = 0for CUDA devices (realtotalpreserved):This reproduces the exact message, word for word, in every combination I tried: b10349 (the build from my original report) and b10380; the Muse Glimmer target with the DFlash drafter, and an unrelated dense model with no speculative decoding at all. So it is not specific to Muse Glimmer or to DFlash.
It also reproduces naturally, without the shim: saturating the GPU with a separate process (plain
cuMemAllocloop until nothing is allocatable;cuMemGetInfomonitored at 0 free bytes throughout) and then running my original command produces the identical failure sequence from my report, line for line — the ~20 GB target still loads (slowly, apparently falling back to host memory), and then the draft model load crashes:That is exactly what I saw on the night of the original report, which explains why the crash hit the draft-model load specifically.
Why my original report blamed the metadata
I went back to my logs from that night: the crash happened while loading the draft model, immediately after the ~20 GB target had loaded, at the end of a long benchmarking session with heavy VRAM churn — so the GPU was evidently being held by something else at that moment, matching the natural reproduction above. My metadata "fix" then appeared to work simply because I tested it later, with free VRAM — a timing coincidence that I mistook for causation, and the array-vs-scalar difference between the two conversions made it look convincing.
To make sure the file itself is innocent, I re-downloaded
muse-glimmer-30B-kquant-dynamic.gguf(sha256 matches the Hub LFS oid) and re-ran it on both builds with the exact original command: it loads, binds the DFlash drafter and generates correctly, 10/10 repeated spawns.meta-models/Muse-Glimmer-30B-GGUFis fine as published.Possible fix
Perhaps guard the degenerate case before normalizing, e.g.:
or clamp
layer_gputon_devices() - 1— whichever you prefer. The main value would be that users in this situation get a clear "insufficient device memory" message instead of a crypticout_of_range, which is what sent me down the wrong path here.I'm happy to open a PR for this if useful, and to update this issue's title to reflect the actual bug — something like "model load crashes with vector::_M_range_check when a device reports 0 free memory (NaN in default-split layer assignment)". Or if you prefer to just close this and track it elsewhere, that's fine too. Thanks again for your time.
docs(examples): add llama.cpp example for Muse-Glimmer-30B (K-Quant-D…
rrhausen commentedon Aug 29, 2026
Independent confirmation of the root cause described above, with a reproduction that needs no
LD_PRELOADshim and no GPU-saturating helper process.On a single RTX 4090 (24 GB, sm_89, WSL2) the failure is a pure function of the target model's context size: a large enough
-cleaves the device with too little free memory by the time the draft model is loaded.-cvector::_M_range_check: __n (which is 1) >= this->size() (which is 1)The boundary sits exactly where the headroom runs out: 100000 with
--mmprojpeaks at 24098 MiB of 24564, i.e. ~466 MiB free, and the draft model is 1.14 GB.Ruled out, so it is not the model or the format:
--mmproj, and succeeds at 100000 with it — not the mmproj / M-RoPE path.dflash requires ctx_other to be set, as expected).This matches the NaN-in-default-split explanation exactly, and it is the shape a user actually hits in practice: not a saturated GPU from an unrelated process, but simply asking for a context size that does not leave room for the drafter.
The practical cost of the current message is that it reads like a model or format incompatibility rather than an out-of-memory condition. I spent a full session concluding DFlash2 was broken for my model before finding this issue — a clear "insufficient free device memory to load the draft model" would have saved all of it. Happy to test a patch.
Build:
2f3923b, i.e. the branch merged as #27342 /b10f9ca5. CUDA 12.8,CMAKE_CUDA_ARCHITECTURES=89. Targetunsloth/Qwen3.8-27B-GGUF(UD-Q4_K_XL), draftz-lab/Qwen3.8-27B-DFlash2-GGUF(Q4_K_M).Measurements and write-up produced in a Claude Code session; the hardware and the numbers are my own.
github-actions commentedon Oct 13, 2026
This issue was closed because it has been inactive for 14 days since being marked as stale.