Phase 07 - Lesson 06
BERT — Modelagem de Linguagem Mascarada
This lesson includes a graded coding exercise that runs in your browser, unlocked with lifetime access.
O GPT prevê a próxima palavra. O BERT prevê uma palavra ausente. Uma frase de diferença — e meia década de tudo moldado por embeddings.
Tipo: Build Idiomas: Python Pré-requisitos: Fase 7 · 05 (Full Transformer), Fase 5 · 02 (Text Representation) Tempo: ~45 minutos
O Problema
Em 2018, toda tarefa de PLN (Processamento de Linguagem Natural) — análise de sentimento, NER, QA, implicação lógica (entailment) — treinava seu próprio modelo do zero em seus próprios dados rotulados. Não havia um checkpoint pré-treinado de "compreensão de inglês" que você pudesse ajustar (fine-tune). O ELMo (2018) mostrou que era possível pré-treinar embeddings contextuais com uma LSTM bidirecional; isso ajudou, mas não generalizou.
O BERT (Devlin et al., 2018) propôs: e se pegássemos um encoder de transformer, o treinássemos em todas as frases da internet e o forçássemos a prever palavras ausentes a partir do contexto de ambos os lados? Depois, você faz o ajuste fino (fine-tune) de um cabeçalho (head) na sua tarefa downstream. A eficiência de parâmetros foi uma revelação.
O resultado: em 18 meses, o BERT e suas variantes (RoBERTa, ALBERT, ELECTRA) dominaram todos os rankings de PLN existentes. Em 2020, todo mecanismo de busca, pipeline de moderação de conteúdo e sistema de busca semântica na Terra tinha um BERT por dentro.
Em 2026, os modelos baseados apenas em encoder (encoder-only) ainda são a ferramenta certa para classificação, recuperação (retrieval) e extração estruturada — eles rodam de 5 a 10 vezes mais rápido por token do que os decoders, e seus embeddings são a espinha dorsal de toda pilha de recuperação moderna. O ModernBERT (dezembro de 2024) expandiu a arquitetura para um contexto de 8K com Flash Attention + RoPE + GeGLU.
O Conceito
O sinal de treinamento
Considere a frase: the quick brown fox jumps over the lazy dog.
Mascarar 15% dos tokens aleatoriamente:
input: the [MASK] brown fox jumps [MASK] the lazy dog
target: the quick brown fox jumps over the lazy dog
Treine o modelo para prever os tokens originais nas posições mascaradas. Como o encoder é bidirecional, prever [MASK] na posição 1 pode usar brown fox jumps nas posições 2 em diante. Isso é algo que o GPT não consegue fazer.
As regras de máscara do BERT
Dos 15% dos tokens selecionados para previsão:
- 80% são substituídos por
[MASK]. - 10% são substituídos por um token aleatório.
- 10% são deixados inalterados.
Por que não usar sempre [MASK]? Porque [MASK] nunca aparece no momento da inferência. Treinar o modelo esperando [MASK] em 100% das posições mascaradas criaria um desvio de distribuição (distribution shift) entre o pré-treinamento e o ajuste fino (fine-tuning). Os 10% aleatórios + 10% inalterados mantêm o modelo honesto.
Next Sentence Prediction (NSP) — e por que foi descartada
O BERT original também era treinado em NSP (Previsão de Próxima Frase): dadas duas frases A e B, prever se B vem depois de A. O RoBERTa (2019) realizou um estudo de ablação e mostrou que a NSP prejudicava em vez de ajudar. Os encoders modernos a ignoram.
O que mudou em 2026: ModernBERT
O artigo do ModernBERT de 2024 reconstruiu o bloco com primitivas de 2026:
| Componente | BERT Original (2018) | ModernBERT (2024) |
|---|---|---|
| Posicional | Absoluto aprendido | RoPE |
| Ativação | GELU | GeGLU |
| Normalização | LayerNorm | RMSNorm pré-norm |
| Atenção | Totalmente densa (Full dense) | Alternada local (128) + global |
| Comprimento de contexto | 512 | 8192 |
| Tokenizador | WordPiece | BPE |
E, ao contrário da pilha de 2018, ele é nativo de Flash Attention. A inferência é de 2 a 3 vezes mais rápida em comprimentos de sequência de 8K em comparação com o DeBERTa-v3, apresentando melhores pontuações no GLUE.
Casos de uso que ainda escolhem um encoder em 2026
| Tarefa | Por que o encoder supera o decoder |
|---|---|
| Embeddings de recuperação / busca semântica | Contexto bidirecional = melhor qualidade de embedding por token |
| Classificação (sentimento, intenção, toxicidade) | Apenas um passo à frente (forward pass); sem custo de geração |
| NER / rotulação de tokens | Saída por posição, nativamente bidirecional |
| Implicação lógica de zero-shot (NLI) | Cabeçalho de classificação sobre o encoder |
| Reranker para RAG | Pontuação via Cross-encoder, 10x mais rápido que rerankers baseados em LLM |
Construa-o
Passo 1: lógica de mascaramento
Consulte code/main.py. A função create_mlm_batch recebe uma lista de IDs de tokens, o tamanho do vocabulário e uma probabilidade de máscara. Retorna os IDs de entrada (com as máscaras aplicadas) e os rótulos (apenas nas posições mascaradas, com -100 nas demais — convenção de índice ignorado do PyTorch).
def create_mlm_batch(tokens, vocab_size, mask_prob=0.15, rng=None):
input_ids = list(tokens)
labels = [-100] * len(tokens)
for i, t in enumerate(tokens):
if rng.random() < mask_prob:
labels[i] = t
r = rng.random()
if r < 0.8:
input_ids[i] = MASK_ID
elif r < 0.9:
input_ids[i] = rng.randrange(vocab_size)
# else: keep original
return input_ids, labels
Passo 2: executar a previsão de MLM em um corpus minúsculo
Treine um encoder de 2 camadas + cabeçalho de MLM em um vocabulário de 20 palavras e 200 frases. Sem gradiente — fazemos verificações de sanidade no passo à frente (forward pass). O treinamento completo necessita do PyTorch.
Passo 3: comparar tipos de máscara
Mostre como a regra de três vias mantém o modelo utilizável sem [MASK]. Faça previsões em uma frase não mascarada e em uma frase mascarada. Ambas devem produzir distribuições de tokens razoáveis porque o modelo viu ambos os padrões no treinamento.
Passo 4: fazer o ajuste fino do cabeçalho
Substitua o cabeçalho de MLM por um cabeçalho de classificação em um conjunto de dados de sentimento fictício. Apenas o cabeçalho é treinado; o encoder é congelado. Esse é o padrão seguido por toda aplicação BERT.
Use-o
from transformers import AutoModel, AutoTokenizer
tok = AutoTokenizer.from_pretrained("answerdotai/ModernBERT-base")
model = AutoModel.from_pretrained("answerdotai/ModernBERT-base")
text = "Attention is all you need."
inputs = tok(text, return_tensors="pt")
out = model(**inputs).last_hidden_state # (1, N, 768)
Modelos de embedding são BERTs ajustados. Modelos da biblioteca sentence-transformers, como o all-MiniLM-L6-v2, são BERTs treinados com perda contrastiva (contrastive loss). O encoder é o mesmo. A função de perda foi alterada.
Rerankers cross-encoder também são BERTs ajustados. Classificação de pares em [CLS] query [SEP] doc [SEP]. A atenção bidirecional entre a query (consulta) e o doc (documento) é exatamente o que confere aos cross-encoders sua vantagem de qualidade sobre os biencoders.
Quando não escolher o BERT em 2026. Qualquer tarefa generativa. O encoder não possui uma forma lógica de produzir tokens de maneira autorregressiva. Além disso: qualquer caso com menos de 1B de parâmetros onde um decoder pequeno consiga igualar a qualidade com maior flexibilidade (Phi-3-Mini, Qwen2-1.5B).
Envie-o
Consulte outputs/skill-bert-finetuner.md. A habilidade (skill) define o escopo de um ajuste fino de BERT (escolha do backbone, especificação do cabeçalho, dados, avaliação, critério de parada) para uma nova tarefa de classificação ou extração.
Exercícios
- Fácil. Execute
code/main.pye exiba a distribuição de máscaras em 10.000 tokens. Confirme se cerca de 15% são selecionados e se, desses, aproximadamente 80% tornam-se[MASK]. - Médio. Implemente o mascaramento de palavra inteira (whole-word masking): se uma palavra for tokenizada em subwords, mascare todos os subwords juntos ou nenhum deles. Meça se isso melhora a precisão do MLM em um corpus de 500 frases.
- Difícil. Treine um BERT minúsculo (2 camadas, d=64) em 10.000 frases de um conjunto de dados público. Faça o ajuste fino do token
[CLS]para análise de sentimento no SST-2. Compare com um modelo baseline contendo apenas o decoder com parâmetros equivalentes — qual deles vence?
Termos-Chave
| Termo | O que dizem | O que realmente significa |
|---|---|---|
| MLM | "Modelagem de linguagem mascarada" | Sinal de treinamento: substituir aleatoriamente 15% dos tokens por [MASK] e prever os originais. |
| Bidirecional | "Olha para ambos os lados" | A atenção do encoder não possui máscara causal — cada posição enxerga todas as outras. |
[CLS] |
"O token de pooling (pooler token)" | Um token especial adicionado ao início de cada sequência; seu embedding final é usado como a representação a nível de frase. |
[SEP] |
"Separador de segmentos" | Separa sequências emparelhadas (ex: query/doc, frase A/B). |
| NSP | "Previsão de próxima frase" | A segunda tarefa de pré-treinamento do BERT; demonstrou-se inútil no RoBERTa e foi descartada após 2019. |
| Ajuste fino (Fine-tuning) | "Adaptar a uma tarefa" | Manter o encoder majoritariamente congelado; treinar um pequeno cabeçalho no topo para a tarefa downstream. |
| Cross-encoder | "Um reranker" | Um BERT que recebe tanto a query quanto o doc como entrada e retorna uma pontuação de relevância. |
| ModernBERT | "Atualização de 2024" | Encoder reconstruído com RoPE, RMSNorm, GeGLU, atenção local/global alternada e contexto de 8K. |
Leituras Adicionais
- Devlin et al. (2018). BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding — artigo original.
- Liu et al. (2019). RoBERTa: A Robustly Optimized BERT Pretraining Approach — como treinar o BERT corretamente; elimina a NSP.
- Clark et al. (2020). ELECTRA: Pre-training Text Encoders as Discriminators Rather Than Generators — a detecção de tokens substituídos supera o MLM em custos computacionais equivalentes.
- Warner et al. (2024). Smarter, Better, Faster, Longer: A Modern Bidirectional Encoder — artigo do ModernBERT.
- HuggingFace
modeling_bert.py— referência canônica de encoder.