Constrained Decoding (Logit Masking)
How do you force an LLM to emit only valid JSON, a legal move, or a token your grammar allows? You mask the logits: set every disallowed token to −∞ before picking, so the model can only choose from the permitted set. It’s the backbone of structured-output and grammar-constrained decoding. Solve it in Python or TypeScript, with hidden tests.
The problem
Given the model’s logits (one score per token id) and a list of allowed token ids (the tokens a grammar or schema permits at this step), pick the next token by masking: only the allowed tokens are eligible, and you choose the one with the highest logit. Break ties by the smaller token id. Implement constrained_argmax(logits, allowed): return the chosen token id.
logits = [1.0, 5.0, 2.0, 4.0], allowed = [0, 2, 3]3logits = [9, 1, 1], allowed = [2, 1]1- Only tokens in
allowedmay be chosen — this is equivalent to setting every other logit to −∞ before taking the argmax. - Among allowed tokens, choose the one with the maximum logit; on a tie, choose the smallest token id.
allowedis non-empty and its ids are valid indices intologits.
Your turn — write it
Edit the stub, hit Run (or ⌘/Ctrl + Enter), and watch the hidden tests. Stuck? the hints are right above and Reveal solution is one click away.
Implement constrained_argmax(logits, allowed): scan the allowed ids in increasing order, tracking the best one; update only on a strictly larger logit so ties keep the smaller id. Return the best id.
- You only ever consider tokens in
allowed— the rest are effectively masked to −∞. - Iterate the allowed ids in ascending order and keep the one with the highest logit so far.
- Update the best only when you find a strictly larger logit; that way an equal logit does not displace the smaller id already held.
- Return the surviving best id — the token constrained decoding would emit.
Explore the topic
See this challenge alongside everything else on the same subject — handbooks, system designs, algorithms and tools, in one place.