Make _added_tokens_decoder the single source of truth for added-token state - #47440
Make _added_tokens_decoder the single source of truth for added-token state#47440ishan-1010 wants to merge 1 commit into
Conversation
|
cc @itazap |
12fdfb5 to
c2c0177
Compare
|
[For maintainers] Suggested jobs to run (before merge) run-slow: bartpho, cpmant, plbart, tapas, wav2vec2 |
CI recapDashboard: View test results in Grafana |
|
For whoever picks this up: the red shard is unrelated to this diff. I cannot re-run the job from my side. Happy to rebase to force a fresh run if that is easier than a re-run. |
|
I'm not sure if the sync function is what we're looking for here, there should be a direct way to fix the used _added_tokens_decoder / _added_tokens_encoder in the models that touch them |
|
The catch is that the properties read a cached sorted view now (L479 and L487), so anything that mutates If the cache goes as well then direct fixes are enough, and then it's only the two that are actually broken. cpmant L151 pops That loses the per-access re-sort, which wasn't the point here anyway. I'll push it that way unless you'd rather keep the cache and inline the invalidation. |
What this fixes
Fixes #47439. Two bugs and the structure that produced them.
Added tokens live in
_added_tokens_decoder(source of truth) plus a hand-maintained_added_tokens_encodercache, and the public properties rebuild sorted views on every access. Five model tokenizers mutate the decoder directly; cpmant and wav2vec2 forget the encoder, soconvert_tokens_to_idsreturns ids that no longer exist:</_>/</n>markers keep their old added ids in the cache; before Fix convert_tokens_to_ids performance regression for slow tokenizers (#46315) #46323 they fell through to unk. Restored that behavior.set_target_lang, a removed added token still encodes to its old id, which now decodes to an unrelated vocabulary token from the new language.The change
_sync_added_tokens()on the python backend: rebuilds the encoder cache from the decoder and drops the cached sorted view. Direct decoder mutations call it.added_tokens_encoder/added_tokens_decoderproperties serve a cached sorted view instead of re-sorting per access. They still return a new dict per call, so existing code that mutates a returned dict (cpmant did) keeps working.__init__, theadded_tokens_decodersetter,_add_tokensin both the python and sentencepiece backends.The fast (tokenizers) backend is untouched; it has its own added-token handling.
Numbers
Correctness is the point; the cached view is a side benefit: 500 property accesses with 4000 added tokens go from 420 ms to 159 ms (M1, CPU).
Tests
Three regression tests: cpmant marker consistency, wav2vec2 stale-entry after
set_target_lang, and a base test that the views follow every mutation path (add_tokens, the setter, and mutation of a returned dict staying harmless).Notes
Not a duplicate: no open PR touches these paths. AI-assisted; I reviewed every line, wrote the repros, and ran the tests and benchmark above.