BpeTokenizer: mask_token_id sobrecarrega <unk> em span-MLM #25
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
TL;DR
A Phase EPSILON adicionou tokenização BPE 32K pros baselines SOTA (
scripts/bpe_corpus.py). O sentencepiece BPE não tem um piece dedicado pra<mask>. Quando o sweep usa mixed-objective com span-MLM (20%), oapply_objective_to_batchprecisa de ummask_token_id. Hoje o código usaunk_id()(= 1) como fallback — ou seja, e compartilham o mesmo id. Isso confunde dois eventos linguisticamente distintos (token mascarado deliberadamente vs token fora-do-vocab) em uma única classe.Por que isso importa
Em span-MLM o modelo é treinado a:
<mask>Com os dois compartilhando id=1, o modelo aprende sinais ambíguos: às vezes id=1 significa "tem alguma palavra aqui, prevê qual", às vezes "isso é uma palavra que não existe no vocab". Esperado: aprendizado de span-MLM enfraquecido em BPE.
Em escala nano + 256K tokens × 20% span-MLM = ~50K tokens de treino com a confusão — pouco, mas é um vies estrutural conhecido.
Onde mexer
Duas opções:
Opção A — retreinar BPE tokenizer com
<mask>dedicadoscripts/train_bpe_tokenizer.pyadiciona um user-defined symbol<mask>à sentencepiece config. Vocab vira 32_001 ou reserva-se um id já existente. Tokens de mask deixam de colidir com .Custo: 1 retreino do tokenizer (~60s), reprocessamento de qualquer parquet pre-tokenizado.
Opção B — usar último id como mask (sem retreinar)
BpeTokenizer.mask_id = vocab_size - 1. Mas esse id é uma piece BPE real, então mascarar com ele introduz outro vies (modelo tem que aprender a tratar o piece final como mask).Pior que A.
Opção C — desligar span-MLM em sweeps BPE
--objective-mix "0.7,0.3,0"em vez de "0.5,0.3,0.2" só pros sweeps BPE. Evita o problema mas reduz a comparabilidade do regime.Recomendação
Opção A — retreinar BPE 32K com
<mask>dedicado. ~60 segundos de compute, fix definitivo. O EPSILON sweep atual (em andamento) é OK com a sobrecarga<unk>, mas qualquer sweep BPE futuro com span-MLM deveria usar a versão correta.Critério de aceite
<mask>dedicado, salvo emdata/processed/bpe_32k_v2.model.BpeTokenizerexpõe atributo.mask_idapontando pro novo piece._run_oneemrun_ablation_word.pylê tokenizer.mask_id sem fallback pro<unk>.Não-bloqueante (por enquanto)
O EPSILON sweep que está rodando vai produzir números úteis com
<unk>como mask. Não invalida a comparação BPC porque ambos os baselines BPE (vanilla / deepseek / llama) usam a mesma sobrecarga. O viés é constante entre eles, então paired-t intra-BPE permanece justo. Só afeta a comparação absoluta BPE vs word-level (que tem um<mask>real).Referências
scripts/bpe_corpus.py— BpeTokenizerscripts/train_bpe_tokenizer.py— training scriptscripts/run_ablation_word.pylinha ~230 — fallback de mask_token_idmasha/training/mixed_objective.py— apply_objective_to_batch