Phase 05 - Lesson 19

Tokenização de subpalavras — BPE, WordPiece, Unigram, SentencePiece

This lesson includes a graded coding exercise that runs in your browser, unlocked with lifetime access.

Tokenizadores de palavras engasgam com palavras desconhecidas. Tokenizadores de caracteres explodem o comprimento da sequência. Tokenizadores de subpalavras dividem a diferença. Todo LLM moderno é entregue com um deles.

Tipo: Aprender Linguagens: Python Pré-requisitos: Fase 5 · 01 (Processamento de Texto), Fase 5 · 04 (GloVe / FastText / Subpalavra) Tempo: ~60 minutos

O Problema

Seu vocabulário tem 50.000 palavras. Um usuário digita "untokenizable". Seu tokenizador retorna [UNK]. O modelo agora não tem nenhum sinal sobre a palavra. Pior: o documento no percentil 90 do seu corpus tem 40 palavras raras, o que significa 40 bits de informação descartada por documento.

A tokenização de subpalavras resolve isso. Palavras comuns permanecem como tokens únicos. Palavras raras se decompõem em pedaços significativos: untokenizableun, token, izable. Os dados de treinamento cobrem tudo porque qualquer cadeia de caracteres é, em última instância, uma sequência de bytes.

Todo LLM de fronteira em 2026 é entregue com um de três algoritmos (BPE, Unigram, WordPiece), envolvido em uma de três bibliotecas (tiktoken, SentencePiece, HF Tokenizers). Você não consegue entregar um modelo de linguagem sem escolher um.

O Conceito

BPE vs Unigram vs WordPiece, caractere por caractere

BPE (Byte-Pair Encoding). Comece com um vocabulário em nível de caractere. Conte cada par adjacente. Mescle o par mais frequente em um novo token. Repita até atingir o tamanho de vocabulário alvo. Algoritmo dominante: GPT-2/3/4, Llama, Gemma, Qwen2, Mistral.

BPE em nível de byte. O mesmo algoritmo, mas sobre bytes brutos (256 tokens base) em vez de caracteres Unicode. Garante zero tokens [UNK] — qualquer sequência de bytes é codificável. O GPT-2 usa 50.257 tokens (256 bytes + 50.000 merges + 1 especial).

Unigram. Comece com um vocabulário enorme. Atribua a cada token uma probabilidade unigram. Pode tokens, iterativamente, cuja remoção menos aumenta a log-verossimilhança do corpus. Probabilístico na inferência: pode amostrar tokenizações (útil para aumento de dados via regularização de subpalavras). Usado por T5, mBART, ALBERT, XLNet, Gemma.

WordPiece. Mescle pares que maximizam a verossimilhança do corpus de treinamento em vez da frequência bruta. Usado por BERT, DistilBERT, ELECTRA.

SentencePiece vs tiktoken. SentencePiece é a biblioteca que treina vocabulários (BPE ou Unigram) diretamente sobre texto Unicode bruto, codificando espaços em branco como . tiktoken é o codificador rápido da OpenAI contra vocabulários pré-construídos; ele não treina.

Regra geral:

  • Treinar um novo vocabulário: SentencePiece (multilíngue, sem pré-tokenização) ou HF Tokenizers.
  • Inferência rápida contra o vocabulário do GPT: tiktoken (cl100k_base, o200k_base).
  • Ambos: HF Tokenizers — uma biblioteca, treinamento + serviço.

Construa

Passo 1: BPE do zero

Veja code/main.py. O laço:

def train_bpe(corpus, num_merges):
    vocab = {tuple(word) + ("</w>",): count for word, count in corpus.items()}
    merges = []
    for _ in range(num_merges):
        pairs = Counter()
        for symbols, freq in vocab.items():
            for a, b in zip(symbols, symbols[1:]):
                pairs[(a, b)] += freq
        if not pairs:
            break
        best = pairs.most_common(1)[0][0]
        merges.append(best)
        vocab = apply_merge(vocab, best)
    return merges

Três fatos que o algoritmo codifica. </w> marca o fim da palavra para que "low" (sufixo) e "lower" (prefixo) permaneçam distintos. A ponderação por frequência faz com que pares de alta frequência vençam cedo. A lista de merges é ordenada — a inferência aplica os merges na ordem do treinamento.

Passo 2: codificar com os merges aprendidos

def encode_bpe(word, merges):
    symbols = list(word) + ["</w>"]
    for a, b in merges:
        i = 0
        while i < len(symbols) - 1:
            if symbols[i] == a and symbols[i + 1] == b:
                symbols = symbols[:i] + [a + b] + symbols[i + 2:]
            else:
                i += 1
    return symbols

Ingênuo, O(n·|merges|). Implementações de produção (tiktoken, HF Tokenizers) usam busca por rank de merge com filas de prioridade e rodam em tempo quase linear.

Passo 3: SentencePiece na prática

import sentencepiece as spm

spm.SentencePieceTrainer.train(
    input="corpus.txt",
    model_prefix="my_tokenizer",
    vocab_size=8000,
    model_type="bpe",          # or "unigram"
    character_coverage=0.9995, # lower for CJK (e.g. 0.9995 for English, 0.995 for Japanese)
    normalization_rule_name="nmt_nfkc",
)

sp = spm.SentencePieceProcessor(model_file="my_tokenizer.model")
print(sp.encode("untokenizable", out_type=str))
# ['▁un', 'token', 'izable']

Observe: nenhuma pré-tokenização necessária, espaço codificado como , character_coverage controla quão agressivamente caracteres raros são preservados em vez de mapeados para <unk>.

Passo 4: tiktoken para vocabulários compatíveis com a OpenAI

import tiktoken
enc = tiktoken.get_encoding("o200k_base")
print(enc.encode("untokenizable"))        # [127340, 101028]
print(len(enc.encode("Hello, world!")))   # 4

Apenas codificação. Rápido (backend em Rust). Correspondência exata com a tokenização do GPT-4/5 para contagem de bytes, estimativa de custo e orçamento de janela de contexto.

Armadilhas que ainda chegam à produção em 2026

  • Deriva do tokenizador (tokenizer drift). Treinar com o vocabulário A, implantar contra o vocabulário B. Os IDs de token diferem; o modelo produz lixo. Verifique o hash de tokenizer.json na CI.
  • Ambiguidade de espaço em branco. "hello" vs " hello" no BPE produzem tokens diferentes. Sempre especifique add_special_tokens e add_prefix_space explicitamente.
  • Subtreinamento multilíngue. Corpora dominados pelo inglês produzem vocabulários que dividem scripts não latinos em 5 a 10 vezes mais tokens. O mesmo prompt custa de 5 a 10 vezes mais em japonês/árabe no GPT-3.5. O o200k_base corrigiu isso parcialmente.
  • Divisões de emoji. Um único emoji pode ocupar 5 tokens. Verifique o tratamento de emojis ao orçar o contexto.

Use

A pilha de 2026:

Situação Escolha
Treinar um modelo monolíngue do zero HF Tokenizers (BPE)
Treinar um modelo multilíngue SentencePiece (Unigram, character_coverage=0.9995)
Servir uma API compatível com a OpenAI tiktoken (o200k_base para GPT-4+)
Vocabulário específico de domínio (código, matemática, proteína) Treine um BPE customizado no corpus de domínio, mescle com o vocabulário base
Inferência na borda (edge), modelo pequeno Unigram (vocabulários menores funcionam melhor)

O tamanho do vocabulário é uma decisão de escalonamento, não uma constante. Heurística aproximada: 32k para <1B de parâmetros, 50-100k para 1-10B, 200k+ para multilíngue/fronteira.

Entregue

Salve como outputs/skill-tokenizer-picker.md:

---
name: tokenizer-picker
description: Pick tokenizer algorithm, vocab size, library for a given corpus and deployment target.
version: 1.0.0
phase: 5
lesson: 19
tags: [nlp, tokenization]
---

Given a corpus (size, languages, domain) and deployment target (training from scratch / fine-tuning / API-compatible inference), output:

1. Algorithm. BPE, Unigram, or WordPiece. One-sentence reason.
2. Library. SentencePiece, HF Tokenizers, or tiktoken. Reason.
3. Vocab size. Rounded to nearest 1k. Reason tied to model size and language coverage.
4. Coverage settings. `character_coverage`, `byte_fallback`, special-token list.
5. Validation plan. Average tokens-per-word on held-out set, OOV rate, compression ratio, round-trip decode equality.

Refuse to train a character-coverage <0.995 tokenizer on corpora with rare-script content. Refuse to ship a vocab without a frozen `tokenizer.json` hash check in CI. Flag any monolingual tokenizer under 16k vocab as likely under-spec.

Exercícios

  1. Fácil. Treine um BPE de 500 merges no pequeno corpus de code/main.py. Codifique três palavras separadas (held-out). Quantas produziram exatamente 1 token vs >1 token?
  2. Médio. Compare as contagens de tokens em 100 frases da Wikipédia em inglês entre cl100k_base, o200k_base e um BPE de SentencePiece que você treine com vocab=32k. Reporte a razão de compressão de cada um.
  3. Difícil. Treine o mesmo corpus com BPE, Unigram e WordPiece. Meça a acurácia em tarefa posterior usando cada um em um pequeno classificador de sentimento. A escolha move o ponteiro em mais de 1 ponto de F1?

Termos-chave

Termo O que as pessoas dizem O que realmente significa
BPE Byte-Pair Encoding Mesclagem gulosa dos pares de caracteres mais frequentes até atingir o tamanho de vocabulário alvo.
BPE em nível de byte Nunca há tokens desconhecidos BPE sobre os 256 bytes brutos; GPT-2 / Llama usam isso.
Unigram Tokenizador probabilístico Poda a partir de um grande conjunto de candidatos usando log-verossimilhança; usado por T5, Gemma.
SentencePiece O do espaço em branco Biblioteca que treina BPE/Unigram sobre texto bruto; espaço codificado como .
tiktoken O rápido Codificador BPE da OpenAI baseado em Rust para vocabulários pré-construídos. Sem treinamento.
Lista de merges Os números mágicos Lista ordenada de merges (a, b) → ab; a inferência aplica em ordem.
Cobertura de caracteres Quão raro é raro demais? Fração dos caracteres no corpus de treinamento que o tokenizador deve cobrir; ~0,9995 típico.

Leitura Adicional

0 lifetime access. Curriculum based on AI Engineering from Scratch by Rohit Ghumare (MIT, used under attribution).