fix(generate): reject top_k below 1 instead of masking every logit - #2309
fix(generate): reject top_k below 1 instead of masking every logit#2309Anai-Guo wants to merge 1 commit into
Conversation
️✅ There are no secrets present in this pull request anymore.If these secrets were true positive and are still valid, we highly recommend you to revoke them. 🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request. |
Signed-off-by: Tai An <antai12232931@outlook.com>
7bfdef0 to
ed0ca01
Compare
|
Sorry about the noise — an earlier push accidentally included two local |
What
sample()validatestop_pbut nottop_k. Atop_kbelow 1 selects nocandidates at all, and the failure is silent in greedy mode.
The bug
With
top_k=0,torch.topk(..., 0)returns empty tensors, the scatter writesnothing, and every logit stays at the fill value. The output stops depending on
the model:
Greedy decoding is the one that hurts: no warning, no exception, just token 0
emitted at every step. The two sampling-mode errors do stop the run, but they
surface inside
torch.multinomial/torch.topkand name neithertop_knorsample.top_karrives here straight from the caller —litgpt generate,litgpt chat,LLM.generate(), and the LitServe endpoints inlitgpt/deploy/serve.pyall forward it unchanged.The fix
Add the range check next to the one
top_palready has:litgpt/generate/speculative_decoding.pyhas the samesample()with the sametop_pguard and the same unguardedtop_k, so it gets the same check. Thesilent mode there is worse: with
apply_softmax=Falsethe mask fill value is0instead of-inf, so the draft distribution handed to the acceptance testcomes out all zeros.
Compatibility
No default in the tree is below 1 — they are
Noneor50— so no workingconfiguration changes. The values that now raise are exactly the ones that
could only produce garbage before.
top_p=0andtemperature=0keep their documented meaning (greedy); this onlycovers
top_k, whose domain starts at 1.Tests
tests/generate/test_main.pytest_sample_rejects_top_k_below_one—top_kin(0, -1)×temperaturein
(0.0, 1.0)all raiseValueErrortest_sample_top_k_one_is_greedy— the smallest accepted value still worksand pins sampling to the argmax
tests/test_generate_speculatively.pytest_sample_rejects_top_k_below_one— same guard on the speculative copyVerified locally on Windows / Python 3.12 / torch 2.x:
(
test_cliin both files fails identically before and after this change — itshells out to a
litgptentry point that is not installed in my environment.)ruff checkandruff format --checkclean at the pinnedv0.15.9from.pre-commit-config.yaml.🤖 Generated with Claude Code