constrained decoding — mask invalid tokens before sampling
LLM
next-token
logits
raw logits (vocab)
"(" : 2.1
"0" : 1.8
"1" : 1.6
"2" : 1.4
"a" : 0.9
"b" : 0.7
"-" : -0.1
" " : -0.3
...
100k tokens
FSM state
at pos 0:
\d{3}-\d{3}-\d{4}
valid: {0-9}
logit processor
logit[t] = -inf
if t not in valid
keeps 10 of 100,000
masked logits
"(" : -inf
"0" : 1.8
"1" : 1.6
"2" : 1.4
"a" : -inf
"b" : -inf
"-" : -inf
" " : -inf
...
sample → "5"
repeat at every step; FSM advances with each accepted token
invalid continuations are unreachable — 100% valid output by construction