Fix stateful KV tail at the NGEN limit#567
Conversation
|
Thanks for this β the stateful-KV-tail bug is real (the last token dropped from persistence and re-forwarded on MORE), and shipping a dependency-free regression test is exactly right. But the test itself is failing in CI on both Linux and Windows, so I can't merge yet: It's the one-shot case ( Once the test is green I'll merge it β the fix direction is correct and the coverage is good; it's just that the gate has to pass before it lands on |
|
This is a real bug and Why it's now CONFLICTING: #581 gave static int spec_decode(Model *m, int *all, int kv, int n_new, int eos, float *logit,
void (*emit)(int,void*), void *ud, int *kv_out, float **logit_out);Your one-line change to line ~4721 is untouched by that (I didn't move the And here's why your fix matters more after the rebase, not less: #581 added a fifth int prod = spec_decode(m, sc->hist, sc->len, r->maximum - r->emitted, eos, lg,
mux_spec_emit, &ud, &sc->len, NULL); // kv_out = &sc->len (non-NULL)At an NGEN cap this hits the same So the rebase is worth it: (1) trailing +1. Correct root-cause fix; the merge order just means it needs a touch-up against the new signature. |
|
Thanks, Zachary β this is really helpful, especially the context around the new single-slot mux caller. I also found the cause of the earlier Linux/Windows CI failure. It is in my test helper, not the stateful fix: choose() allocates the logits with falloc() (which uses malloc) but initializes only the selected slot. The remaining entries contain uninitialized values, so another token can accidentally win on some platforms. I will initialize the full logits buffer before setting the chosen token. I will rebase onto the current dev branch, add the trailing NULL logit_out argument to every spec_decode call in the test, and rerun make -C c test-c and make -C c check before pushing the update. The mux path is useful confirmation that this fix now protects more than the original :more case. I can also add a focused mux regression, or adjust the existing coverage, if you think that would be useful β just let me know what you would prefer. |
Summary
When generation stopped exactly at the NGEN limit,
spec_decodeemitted the final token but returned before forwarding it into the stateful KV cache. As a result,:moreresumed from the preceding token and.coli_kvomitted the visible tail of the answer.Let stateful callers take the existing zero-draft forward path for the capped token before
kv_outadvances. One-shot generation keeps its existing saved terminal forward.Add a dependency-free zero-layer regression covering NGEN 0/1, continued generation and
:more, persisted history, accepted speculative tokens, EOS, and normal non-limit termination.Validation
No CUDA paths or performance claims are involved.
make -C c checkmake -C c cuda-test(if applicable)Compatibility