A rig de avaliação Tier 1: roadmap #21

Open
opened 2026-05-14 02:13:44 -03:00 by navigator · 0 comments
Owner

TL;DR

A próxima onda de trabalho não é mais experimento — é construir a infraestrutura que torna experimentos futuros confiáveis. Cinco peças formam a rig Tier 1: (1) métrica BPC além de PPL, (2) mascaramento por POS, (3) tarefas downstream, (4) hyperparameter sweep com tranca de config, (5) bootstrap CI para amostras pequenas. Quando essa rig estiver pronta, qualquer ablation futuro produz evidência defensável.

Background

Decidimos no doc 09 parar de iterar e investir em fundação. Este documento lista o quê, concretamente. A escolha de chamar de Tier 1 indica que existem Tier 2 e Tier 3 mais adiante (multi-tarefa em larga escala, eval humano, prova de generalização cross-domain), mas a Tier 1 é o piso ético: sem ela, nenhum resultado é defensável.

Peça 1 — BPC (Bits Per Character)

Problema: PPL depende do vocabulário. Comparar PPL de um modelo BPE 32K com um modelo word-level 200K é incorreto: o segundo modelo tem que escolher entre mais opções por passo, então PPL infla artificialmente. Os números 1521 (BPE) e 1521 (word) não significam a mesma coisa.

Solução: reportar BPC (Bits Per Character) — quantos bits o modelo gasta, em média, pra prever cada caractere do held-out. Independente do vocabulário, comparável entre tokenizações diferentes.

Fórmula: BPC = cross_entropy_loss × num_tokens / (num_chars × log(2)).

Implementação: adicionar campo bpc ao output do held-out eval. Trivial dado que já temos loss e contagem de tokens/chars.

Peça 2 — Mascaramento por POS

Problema: PPL agregado mistura tudo — substantivos, verbos, preposições, pontuação. Onde MASHA está ganhando ou perdendo? Não sabemos.

Solução: avaliar PPL condicional por classe gramatical. "Qual o PPL médio nas posições rotuladas como NOUN pelo Stanza?" Se MASHA tem prior morfêmico que beneficia substantivos derivados, isso deve aparecer em PPL[NOUN] menor que o Baseline mesmo se o PPL agregado estiver empatado.

Implementação: reusar parquet de deps que já anota POS por palavra. Calcular PPL em subsets {NOUN, VERB, ADJ, PROPN, ADV, OUTROS}. Reportar 6 números em vez de 1.

Peça 3 — Tarefas downstream

Problema: PPL é proxy. Um modelo pode ter PPL baixo e gerar texto incoerente; outro pode ter PPL alto e gerar texto utilizável.

Solução: 3 tarefas downstream mínimas:

  • Geração coerente: dadas 50 prompts, gerar 100 tokens, medir parse_rate via Stanza (% de sentenças com árvore válida) e tree_depth. Scripts existentes em masha_grad/text_quality.py.
  • Concordância sujeito-verbo: dadas 200 frases mascaradas no verbo, ver se o modelo prefere o verbo concordante. Tem sv_agreement em text_quality.py.
  • Similaridade semântica: usar ASSIN-2 ou STSb-pt-br pra similaridade entre pares de frases. Coseno entre embeddings das últimas camadas.

Implementação: novo módulo masha_grad/benchmarks/tier1.py que carrega os 3 datasets e roda batch de comparações MASHA vs Baseline.

Peça 4 — Hyperparameter sweep + tranca

Problema: o base_lr=0.0003 veio de instinto, não de busca. Se MASHA gosta de lr=0.0005 e Baseline gosta de lr=0.0002, comparar os dois no mesmo lr favorece um e prejudica o outro.

Solução: sweep formal só no Baseline primeiro (10 LRs em escala log, 1 seed cada, 2K steps, escolher melhor). Trancar lr_baseline_best. Depois rodar mesmo sweep no MASHA, escolher lr_masha_best. Comparações finais usam cada um no seu LR ótimo. Reportar curva LR-vs-Loss pros dois.

A curva LR-vs-Loss é importante por si só: mostra se o modelo está numa região "robusta a LR" ou se a escolha é frágil. Resultados frágeis a hiperparâmetros são suspeitos.

Peça 5 — Bootstrap CI

Problema: paired t-test com N=3 é fraco. Não rejeita H0 mesmo quando o efeito é real — falta poder estatístico. Pior, t-test assume distribuição normal das diferenças, o que pode não valer.

Solução: bootstrap por reamostragem. Para cada teste, gerar 10.000 amostras simuladas reamostrando seeds com reposição. Calcular intervalo de confiança 95% das diferenças. Reportar [Δ_low, Δ_high] em vez de só μ, t.

Implementação: já existe bootstrap_ci em masha_grad/benchmark.py. Só plugar no fluxo de report dos ablations.

Critério de "Tier 1 pronto"

A rig é considerada completa quando, ao rodar python -m masha_grad.benchmarks.tier1 --kinds baseline,masha_ab,masha_abc --seeds 41,42,43,44,45, o output traz:

  • PPL agregado + BPC para os 3 kinds em cada seed.
  • PPL[NOUN], PPL[VERB], PPL[ADJ], PPL[PROPN], PPL[ADV], PPL[OUTROS] por kind/seed.
  • parse_rate, tree_depth, sv_agreement, sim_assin2 por kind/seed.
  • Per-seed table + aggregated table com μ, σ, paired_t, bootstrap_95CI.
  • Hyperparameter usado, com link pro sweep que produziu ele.

Quando isso estiver pronto, qualquer experimento futuro (long-training, mais seeds, sweep de bias_strength) usa essa rig como instrumento. Os resultados ficam comparáveis ao longo do tempo, e o overhead por novo experimento cai pra "rodar e ler relatório".

Por que isso importa

A diferença entre "papers que envelhecem bem" e "papers que envelhecem mal" geralmente é qualidade da rig de avaliação, não a engenhosidade da arquitetura. MASHA tem boa arquitetura. Precisa de boa rig.

E pragmaticamente: depois da Tier 1, dá pra publicar — mesmo que o resultado final seja "MASHA não bate Baseline em escala Nano". Isso é resultado negativo defensável, que ajuda outras pessoas a não repetirem a tentativa. Sem a rig, é só ruído.

Termos usados

  • BPC (Bits Per Character): medida de compressão por caractere. Tokenizer-agnóstica.
  • Mascaramento (em avaliação): avaliar a perda só em posições específicas (não no agregado). Permite stratify por POS, por dependency relation etc.
  • Tarefa downstream: aplicação fora do treino de LM. Geralmente revela diferenças que loss não captura.
  • Hyperparameter sweep: busca sistemática de configurações ótimas. Necessário pra comparações justas.
  • Tranca de config (config lock): depois do sweep, congelar a config; experimentos futuros usam a versão trancada e mudam só a variável de interesse.
  • Bootstrap CI: reamostragem com reposição para gerar intervalo de confiança. Não pressupõe distribuição normal. Custa CPU mas é grátis em tempo de wall-clock.
  • ASSIN-2 / STSb-pt-br: datasets brasileiros de similaridade textual semântica.
  • Stanza parse_rate / tree_depth / sv_agreement: métricas implementadas em masha_grad/text_quality.py que medem qualidade de geração via parser linguístico.
  • Tier 1 / Tier 2 / Tier 3: convenção interna pra graus de rigor da avaliação. Tier 1 = mínimo defensável; Tier 2 = avaliação multi-domínio; Tier 3 = eval humano + cross-language.
## TL;DR A próxima onda de trabalho não é mais experimento — é **construir a infraestrutura que torna experimentos futuros confiáveis**. Cinco peças formam a rig Tier 1: (1) métrica BPC além de PPL, (2) mascaramento por POS, (3) tarefas downstream, (4) hyperparameter sweep com tranca de config, (5) bootstrap CI para amostras pequenas. Quando essa rig estiver pronta, qualquer ablation futuro produz evidência defensável. ## Background Decidimos no doc `09` parar de iterar e investir em fundação. Este documento lista o quê, concretamente. A escolha de chamar de **Tier 1** indica que existem Tier 2 e Tier 3 mais adiante (multi-tarefa em larga escala, eval humano, prova de generalização cross-domain), mas a Tier 1 é o piso ético: sem ela, nenhum resultado é defensável. ## Peça 1 — BPC (Bits Per Character) **Problema**: PPL depende do vocabulário. Comparar PPL de um modelo BPE 32K com um modelo word-level 200K **é incorreto**: o segundo modelo tem que escolher entre mais opções por passo, então PPL infla artificialmente. Os números 1521 (BPE) e 1521 (word) não significam a mesma coisa. **Solução**: reportar **BPC** (Bits Per Character) — quantos bits o modelo gasta, em média, pra prever cada caractere do held-out. Independente do vocabulário, comparável entre tokenizações diferentes. Fórmula: `BPC = cross_entropy_loss × num_tokens / (num_chars × log(2))`. Implementação: adicionar campo `bpc` ao output do held-out eval. Trivial dado que já temos loss e contagem de tokens/chars. ## Peça 2 — Mascaramento por POS **Problema**: PPL agregado mistura tudo — substantivos, verbos, preposições, pontuação. Onde MASHA está ganhando ou perdendo? Não sabemos. **Solução**: avaliar PPL condicional por classe gramatical. "Qual o PPL médio nas posições rotuladas como `NOUN` pelo Stanza?" Se MASHA tem prior morfêmico que beneficia substantivos derivados, isso deve aparecer em PPL[NOUN] menor que o Baseline mesmo se o PPL agregado estiver empatado. Implementação: reusar parquet de deps que já anota POS por palavra. Calcular PPL em subsets {NOUN, VERB, ADJ, PROPN, ADV, OUTROS}. Reportar 6 números em vez de 1. ## Peça 3 — Tarefas downstream **Problema**: PPL é proxy. Um modelo pode ter PPL baixo e gerar texto incoerente; outro pode ter PPL alto e gerar texto utilizável. **Solução**: 3 tarefas downstream mínimas: - **Geração coerente**: dadas 50 prompts, gerar 100 tokens, medir parse_rate via Stanza (% de sentenças com árvore válida) e tree_depth. Scripts existentes em `masha_grad/text_quality.py`. - **Concordância sujeito-verbo**: dadas 200 frases mascaradas no verbo, ver se o modelo prefere o verbo concordante. Tem `sv_agreement` em `text_quality.py`. - **Similaridade semântica**: usar ASSIN-2 ou STSb-pt-br pra similaridade entre pares de frases. Coseno entre embeddings das últimas camadas. Implementação: novo módulo `masha_grad/benchmarks/tier1.py` que carrega os 3 datasets e roda batch de comparações MASHA vs Baseline. ## Peça 4 — Hyperparameter sweep + tranca **Problema**: o `base_lr=0.0003` veio de instinto, não de busca. Se MASHA gosta de `lr=0.0005` e Baseline gosta de `lr=0.0002`, comparar os dois no mesmo `lr` favorece um e prejudica o outro. **Solução**: sweep formal **só no Baseline** primeiro (10 LRs em escala log, 1 seed cada, 2K steps, escolher melhor). Trancar `lr_baseline_best`. Depois rodar **mesmo sweep no MASHA**, escolher `lr_masha_best`. Comparações finais usam cada um no seu LR ótimo. Reportar curva LR-vs-Loss pros dois. A curva LR-vs-Loss é importante por si só: mostra se o modelo está numa região "robusta a LR" ou se a escolha é frágil. Resultados frágeis a hiperparâmetros são suspeitos. ## Peça 5 — Bootstrap CI **Problema**: paired t-test com N=3 é fraco. Não rejeita H0 mesmo quando o efeito é real — falta poder estatístico. Pior, t-test assume distribuição normal das diferenças, o que pode não valer. **Solução**: bootstrap por reamostragem. Para cada teste, gerar 10.000 amostras simuladas reamostrando seeds com reposição. Calcular intervalo de confiança 95% das diferenças. Reportar `[Δ_low, Δ_high]` em vez de só `μ, t`. Implementação: já existe `bootstrap_ci` em `masha_grad/benchmark.py`. Só plugar no fluxo de report dos ablations. ## Critério de "Tier 1 pronto" A rig é considerada completa quando, ao rodar `python -m masha_grad.benchmarks.tier1 --kinds baseline,masha_ab,masha_abc --seeds 41,42,43,44,45`, o output traz: - PPL agregado + BPC para os 3 kinds em cada seed. - PPL[NOUN], PPL[VERB], PPL[ADJ], PPL[PROPN], PPL[ADV], PPL[OUTROS] por kind/seed. - parse_rate, tree_depth, sv_agreement, sim_assin2 por kind/seed. - Per-seed table + aggregated table com μ, σ, paired_t, bootstrap_95CI. - Hyperparameter usado, com link pro sweep que produziu ele. Quando isso estiver pronto, qualquer experimento futuro (long-training, mais seeds, sweep de bias_strength) usa essa rig como instrumento. Os resultados ficam comparáveis ao longo do tempo, e o overhead por novo experimento cai pra "rodar e ler relatório". ## Por que isso importa A diferença entre "papers que envelhecem bem" e "papers que envelhecem mal" geralmente é qualidade da rig de avaliação, não a engenhosidade da arquitetura. MASHA tem boa arquitetura. Precisa de boa rig. E pragmaticamente: depois da Tier 1, dá pra publicar — mesmo que o resultado final seja "MASHA não bate Baseline em escala Nano". Isso é resultado **negativo defensável**, que ajuda outras pessoas a não repetirem a tentativa. Sem a rig, é só ruído. ## Termos usados - **BPC (Bits Per Character)**: medida de compressão por caractere. Tokenizer-agnóstica. - **Mascaramento (em avaliação)**: avaliar a perda só em posições específicas (não no agregado). Permite stratify por POS, por dependency relation etc. - **Tarefa downstream**: aplicação fora do treino de LM. Geralmente revela diferenças que loss não captura. - **Hyperparameter sweep**: busca sistemática de configurações ótimas. Necessário pra comparações justas. - **Tranca de config (config lock)**: depois do sweep, congelar a config; experimentos futuros usam a versão trancada e mudam só a variável de interesse. - **Bootstrap CI**: reamostragem com reposição para gerar intervalo de confiança. Não pressupõe distribuição normal. Custa CPU mas é grátis em tempo de wall-clock. - **ASSIN-2 / STSb-pt-br**: datasets brasileiros de similaridade textual semântica. - **Stanza parse_rate / tree_depth / sv_agreement**: métricas implementadas em `masha_grad/text_quality.py` que medem qualidade de geração via parser linguístico. - **Tier 1 / Tier 2 / Tier 3**: convenção interna pra graus de rigor da avaliação. Tier 1 = mínimo defensável; Tier 2 = avaliação multi-domínio; Tier 3 = eval humano + cross-language.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
pop/MASHA#21
No description provided.