Phase 10 - Lesson 01

Tokenizers: BPE, WordPiece, SentencePiece

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

Seu LLM não lê inglês. Ele lê inteiros. O tokenizer decide se esses inteiros carregam significado ou se o desperdiçam.

Tipo: Build Linguagens: Python Pré-requisitos: Phase 05 (NLP Foundations) Tempo: ~90 minutos

Objetivos de Aprendizado

  • Implementar os algoritmos de tokenização BPE, WordPiece e Unigram do zero e comparar suas estratégias de fusão
  • Explicar como o tamanho do vocabulário afeta a eficiência do modelo: muito pequeno cria sequências longas, muito grande desperdiça parâmetros de incorporação (embedding)
  • Analisar artefatos de tokenização em diferentes idiomas e código, identificando onde tokenizers específicos falham
  • Usar as bibliotecas tiktoken e sentencepiece para tokenizar texto e inspecionar os IDs de token resultantes

O Problema

Seu LLM não lê inglês. Ele não lê nenhum idioma. Ele lê números.

A diferença entre "Hello, world!" e [15496, 11, 995, 0] é o tokenizer. Cada palavra, cada espaço, cada sinal de pontuação deve ser convertido em um número inteiro antes que um modelo possa processá-lo. Essa conversão não é neutra. Ela introduz suposições no modelo que não podem ser desfeitas posteriormente.

Se você errar nisso, seu modelo desperdiçará capacidade codificando palavras comuns com múltiplos tokens. "unfortunately" se torna quatro tokens em vez de um. Sua janela de contexto de 128K acaba de encolher em 75% para textos repletos de palavras polissílabas. Se você acertar, a mesma janela de contexto conterá o dobro de significado. A diferença entre "este modelo lida bem com código" e "este modelo engasga com Python" geralmente se resume a como o tokenizer foi treinado.

Cada chamada de API que você faz para o GPT-4 ou Claude é cobrada por token. Cada token que seu modelo gera custa computação. Quanto menos tokens forem necessários para representar uma saída, mais rápida será a inferência de ponta a ponta. A tokenização não é pré-processamento. Ela é arquitetura.

O Conceito

Três Abordagens Que Falharam (e Uma Que Venceu)

Existem três maneiras óbvias de converter texto em números. Duas delas não funcionam em escala.

Tokenização em nível de palavra divide o texto em espaços e pontuações. "The cat sat" torna-se ["The", "cat", "sat"]. Simples. Mas e quanto a "tokenization"? Ou "GPT-4o"? Ou uma palavra composta em alemão como "Geschwindigkeitsbegrenzung"? O nível de palavra requer um vocabulário massivo para cobrir cada palavra em cada idioma. Esqueça uma palavra e você obterá o temido token [UNK] — a forma de o modelo dizer "não tenho ideia do que é isso". Somente o inglês tem mais de um milhão de formas de palavras. Adicione código, URLs, notação científica e outros 100 idiomas, e você precisará de um vocabulário infinito.

Tokenização em nível de caractere vai na direção oposta. "hello" torna-se ["h", "e", "l", "l", "o"]. O vocabulário é minúsculo (algumas centenas de caracteres). Nunca há tokens desconhecidos. Mas as sequências tornam-se extremamente longas. Uma frase que teria 10 tokens em nível de palavra torna-se 50 tokens em nível de caractere. O modelo precisa aprender que "t", "h", "e" juntos significam "the" — consumindo capacidade de atenção com algo que um ser humano aprende aos três anos de idade.

Tokenização de subpalavra encontra o ponto ideal. Palavras comuns permanecem inteiras: "the" é um único token. Palavras raras são decompostas em partes significativas: "unhappiness" torna-se ["un", "happi", "ness"]. O vocabulário permanece gerenciável (de 30K a 128K tokens). As sequências permanecem curtas. Os tokens desconhecidos praticamente desaparecem porque qualquer palavra pode ser construída a partir de subpalavras.

Todo LLM moderno usa tokenização de subpalavra. GPT-2, GPT-4, BERT, Llama 3, Claude — todos eles. A questão é qual algoritmo utilizar.

graph TD
    A["Texto: 'unhappiness'"] --> B{"Estratégia de Tokenização"}
    B -->|Nível de palavra| C["['unhappiness']\n1 token se estiver no vocabulário\n[UNK] se não"]
    B -->|Nível de caractere| D["['u','n','h','a','p','p','i','n','e','s','s']\n11 tokens"]
    B -->|BPE de subpalavra| E["['un','happi','ness']\n3 tokens"]

    style C fill:#ff6b6b,color:#fff
    style D fill:#ffa500,color:#fff
    style E fill:#51cf66,color:#fff

BPE: Byte Pair Encoding

BPE é um algoritmo de compressão ganancioso (greedy) reaproveitado para tokenização. A ideia é simples o suficiente para caber em um cartão de anotações.

Comece com caracteres individuais. Conte cada par adjacente no corpus de treinamento. Mescle o par mais frequente em um novo token. Repita até atingir o tamanho de vocabulário desejado.

Aqui está o BPE rodando em um corpus minúsculo com as palavras "lower", "lowest" e "newest":

Corpus (with word frequencies):
  "lower"  x5
  "lowest" x2
  "newest" x6

Step 0 -- Start with characters:
  l o w e r       (x5)
  l o w e s t     (x2)
  n e w e s t     (x6)

Step 1 -- Count adjacent pairs:
  (e,s): 8    (s,t): 8    (l,o): 7    (o,w): 7
  (w,e): 13   (e,r): 5    (n,e): 6    ...

Step 2 -- Merge most frequent pair (w,e) -> "we":
  l o we r        (x5)
  l o we s t      (x2)
  n e we s t      (x6)

Step 3 -- Recount and merge (e,s) -> "es":
  l o we r        (x5)
  l o we s t      (x2)    <- 'es' only forms from 'e'+'s', not 'we'+'s'
  n e we s t      (x6)    <- wait, the 'e' before 'we' and 's' after 'we'

Actually tracking this precisely:
  After "we" merge, remaining pairs:
  (l,o): 7   (o,we): 7   (we,r): 5   (we,s): 8
  (s,t): 8   (n,e): 6    (e,we): 6

Step 3 -- Merge (we,s) -> "wes" or (s,t) -> "st" (tied at 8, pick first):
  Merge (we,s) -> "wes":
  l o we r        (x5)
  l o wes t       (x2)
  n e wes t       (x6)

Step 4 -- Merge (wes,t) -> "west":
  l o we r        (x5)
  l o west        (x2)
  n e west        (x6)

...continue until target vocab size reached.

A tabela de fusão (merge table) é o tokenizer. Para codificar um novo texto, aplique as fusões na ordem em que foram aprendidas. O corpus de treinamento determina quais fusões existem, e essa escolha molda permanentemente o que o modelo vê.

graph LR
    subgraph Training["Loop de Treinamento BPE"]
        direction TB
        T1["Início: vocabulário de caracteres"] --> T2["Contar todos os pares adjacentes"]
        T2 --> T3["Mesclar o par mais frequente"]
        T3 --> T4["Adicionar token mesclado ao vocabulário"]
        T4 --> T5{"Atingiu o tamanho\nde vocabulário alvo?"}
        T5 -->|Não| T2
        T5 -->|Sim| T6["Concluído: salvar tabela de fusão"]
    end

Byte-Level BPE (GPT-2, GPT-3, GPT-4)

O BPE padrão opera em caracteres Unicode. O BPE em nível de byte (Byte-level BPE) opera em bytes brutos (0-255). Isso fornece um vocabulário básico de exatamente 256, lida com qualquer idioma ou codificação e nunca produz um token desconhecido.

O GPT-2 introduziu essa abordagem. O vocabulário básico cobre todos os bytes possíveis. As fusões do BPE são construídas sobre isso. A biblioteca tiktoken da OpenAI implementa o BPE em nível de byte com os seguintes tamanhos de vocabulário:

  • GPT-2: 50.257 tokens
  • GPT-3.5/GPT-4: ~100.256 tokens (codificação cl100k_base)
  • GPT-4o: 200.019 tokens (codificação o200k_base)

WordPiece (BERT)

O WordPiece parece semelhante ao BPE, mas escolhe as fusões de maneira diferente. Em vez da frequência bruta, ele maximiza a probabilidade dos dados de treinamento:

BPE merge criterion:      count(A, B)
WordPiece merge criterion: count(AB) / (count(A) * count(B))

O BPE pergunta: "Qual par aparece com mais frequência?" O WordPiece pergunta: "Qual par aparece junto com mais frequência do que o esperado por acaso?" Essa diferença sutil produz vocabulários diferentes. O WordPiece favorece fusões onde a coocorrência é surpreendente, não apenas frequente.

O WordPiece também usa um prefixo "##" para subpalavras de continuação:

"unhappiness" -> ["un", "##happi", "##ness"]
"embedding"   -> ["em", "##bed", "##ding"]

O prefixo "##" informa que esta parte continua um token anterior. O BERT usa WordPiece com um vocabulário de 30.522 tokens. Toda variante do BERT — DistilBERT, o tokenizer do RoBERTa é na verdade BPE, mas o próprio BERT é WordPiece.

SentencePiece (Llama, T5)

O SentencePiece trata a entrada como uma sequência bruta de caracteres Unicode, incluindo espaços em branco. Sem etapa de pré-tokenização. Sem regras específicas de idioma sobre limites de palavras. Isso o torna genuinamente agnóstico em relação ao idioma — funciona em chinês, japonês, tailandês e outros idiomas onde os espaços não separam as palavras.

O SentencePiece suporta dois algoritmos:

  • Modo BPE: a mesma lógica de fusão do BPE padrão, aplicada a sequências de caracteres brutos
  • Modo Unigram: começa com um vocabulário grande e remove iterativamente os tokens que menos afetam a probabilidade geral. O inverso do BPE — poda em vez de fusão.

O Llama 2 usa SentencePiece BPE com um vocabulário de 32.000 tokens. O T5 usa SentencePiece Unigram com 32.000 tokens. Nota: O Llama 3 mudou para um tokenizer BPE em nível de byte baseado em tiktoken com 128.256 tokens.

Vocabulary Size Tradeoffs

Esta é uma decisão real de engenharia com consequências mensuráveis.

graph LR
    subgraph Small["Vocabulário Pequeno (32K)\nex: BERT, T5"]
        S1["Mais tokens por texto"]
        S2["Sequências mais longas"]
        S3["Matriz de incorporação menor"]
        S4["Melhor tratamento de palavras raras"]
    end
    subgraph Large["Vocabulário Grande (128K+)\nex: Llama 3, GPT-4o"]
        L1["Menos tokens por texto"]
        L2["Sequências mais curtas"]
        L3["Matriz de incorporação maior"]
        L4["Inferência mais rápida"]
    end

Números concretos. Para um vocabulário de 128K com embeddings de 4.096 dimensões, a matriz de incorporação (embedding) sozinha tem 128.000 x 4.096 = 524 milhões de parâmetros. Para um vocabulário de 32K, são 131 milhões de parâmetros. Isso representa uma diferença de 400M de parâmetros apenas pela escolha do tokenizer.

Mas vocabulários maiores comprimem o texto de forma mais agressiva. O mesmo parágrafo em inglês que leva 100 tokens com um vocabulário de 32K pode levar 70 tokens com um vocabulário de 128K. Isso significa 30% menos passagens diretas (forward passes) durante a geração. Para um modelo que atende a milhões de requisições, isso representa uma redução direta no custo de computação.

A tendência é clara: os tamanhos dos vocabulários estão crescendo. O GPT-2 usava 50.257. O GPT-4 usa ~100K. O Llama 3 usa 128K. O GPT-4o usa 200K.

Modelo Tamanho do Vocabulário Tipo de Tokenizer Média de Tokens por Palavra em Inglês
BERT 30.522 WordPiece ~1,4
GPT-2 50.257 BPE em nível de byte ~1,3
Llama 2 32.000 SentencePiece BPE ~1,4
GPT-4 ~100.256 BPE em nível de byte ~1,2
Llama 3 128.256 BPE em nível de byte (tiktoken) ~1,1
GPT-4o 200.019 BPE em nível de byte ~1,0

O Imposto Multilíngue

Tokenizers treinados principalmente em inglês são brutais com outros idiomas. Textos em coreano no tokenizer do GPT-2 têm média de 2 a 3 tokens por palavra. Em chinês pode ser pior. Isso significa que um usuário coreano tem efetivamente uma janela de contexto que é metade do tamanho da de um usuário de língua inglesa — pagando o mesmo preço por menos densidade de informação.

É por isso que o Llama 3 quadruplicou seu vocabulário de 32K para 128K. Mais tokens dedicados a escritas não inglesas significam uma compressão mais justa entre os idiomas.

Build It

Passo 1: Tokenizer em Nível de Caractere

Comece pela base. Um tokenizer em nível de caractere mapeia cada caractere para seu ponto de código Unicode (code point). Nenhum treinamento é necessário. Nenhum token desconhecido. Apenas um mapeamento direto.

class CharTokenizer:
    def encode(self, text):
        return [ord(c) for c in text]

    def decode(self, tokens):
        return "".join(chr(t) for t in tokens)

"hello" torna-se [104, 101, 108, 108, 111]. Cada caractere é seu próprio token. Esta é a linha de base sobre a qual melhoramos.

Passo 2: Tokenizer BPE do Zero

A implementação real. Treinamos em bytes brutos (como o GPT-2), contamos pares, mesclamos o mais frequente e registramos cada fusão em ordem. A tabela de fusão (merge table) é o tokenizer.

from collections import Counter

class BPETokenizer:
    def __init__(self):
        self.merges = {}
        self.vocab = {}

    def _get_pairs(self, tokens):
        pairs = Counter()
        for i in range(len(tokens) - 1):
            pairs[(tokens[i], tokens[i + 1])] += 1
        return pairs

    def _merge_pair(self, tokens, pair, new_token):
        merged = []
        i = 0
        while i < len(tokens):
            if i < len(tokens) - 1 and tokens[i] == pair[0] and tokens[i + 1] == pair[1]:
                merged.append(new_token)
                i += 2
            else:
                merged.append(tokens[i])
                i += 1
        return merged

    def train(self, text, num_merges):
        tokens = list(text.encode("utf-8"))
        self.vocab = {i: bytes([i]) for i in range(256)}

        for i in range(num_merges):
            pairs = self._get_pairs(tokens)
            if not pairs:
                break
            best_pair = max(pairs, key=pairs.get)
            new_token = 256 + i
            tokens = self._merge_pair(tokens, best_pair, new_token)
            self.merges[best_pair] = new_token
            self.vocab[new_token] = self.vocab[best_pair[0]] + self.vocab[best_pair[1]]

        return self

    def encode(self, text):
        tokens = list(text.encode("utf-8"))
        for pair, new_token in self.merges.items():
            tokens = self._merge_pair(tokens, pair, new_token)
        return tokens

    def decode(self, tokens):
        byte_sequence = b"".join(self.vocab[t] for t in tokens)
        return byte_sequence.decode("utf-8", errors="replace")

O loop de treinamento é o núcleo do BPE: contar pares, mesclar o vencedor, repetir. Cada mesclagem reduz a contagem total de tokens. Após num_merges rodadas, o vocabulário cresce de 256 (bytes básicos) para 256 + num_merges.

A codificação aplica as mesclagens na ordem exata em que foram aprendidas. Isso é importante. Se a fusão 1 criou "th" e a fusão 5 criou "the", a codificação deve aplicar primeiro a fusão 1 para que "the" possa se formar a partir de "th" + "e" na fusão 5.

A decodificação é o inverso: procurar cada ID de token no vocabulário, concatenar os bytes e decodificar para UTF-8.

Passo 3: Teste de Ida e Volta (Roundtrip) de Codificação e Decodificação

corpus = (
    "The cat sat on the mat. The cat ate the rat. "
    "The dog sat on the log. The dog ate the frog. "
    "Natural language processing is the study of how computers "
    "understand and generate human language. "
    "Tokenization is the first step in any NLP pipeline."
)

tokenizer = BPETokenizer()
tokenizer.train(corpus, num_merges=40)

test_sentences = [
    "The cat sat on the mat.",
    "Natural language processing",
    "tokenization pipeline",
    "unhappiness",
]

for sentence in test_sentences:
    encoded = tokenizer.encode(sentence)
    decoded = tokenizer.decode(encoded)
    raw_bytes = len(sentence.encode("utf-8"))
    ratio = len(encoded) / raw_bytes
    print(f"'{sentence}'")
    print(f"  Tokens: {len(encoded)} (from {raw_bytes} bytes) -- ratio: {ratio:.2f}")
    print(f"  Roundtrip: {'PASS' if decoded == sentence else 'FAIL'}")

A taxa de compressão (compression ratio) informa quão eficaz é o tokenizer. Uma taxa de 0,50 significa que o tokenizer comprimiu o texto para metade dos tokens em comparação com os bytes brutos. Quanto menor, melhor. No corpus de treinamento, a taxa será boa. Em textos fora de distribuição (out-of-distribution), como "unhappiness" (que não aparece no corpus), a taxa será pior — o tokenizer recorre à codificação em nível de caractere para padrões não vistos.

Passo 4: Comparar com tiktoken

import tiktoken

enc = tiktoken.get_encoding("cl100k_base")

texts = [
    "The cat sat on the mat.",
    "unhappiness",
    "Hello, world!",
    "def fibonacci(n): return n if n < 2 else fibonacci(n-1) + fibonacci(n-2)",
    "Geschwindigkeitsbegrenzung",
]

for text in texts:
    our_tokens = tokenizer.encode(text)
    tiktoken_tokens = enc.encode(text)
    tiktoken_pieces = [enc.decode([t]) for t in tiktoken_tokens]
    print(f"'{text}'")
    print(f"  Our BPE:   {len(our_tokens)} tokens")
    print(f"  tiktoken:  {len(tiktoken_tokens)} tokens -> {tiktoken_pieces}")

O tiktoken usa exatamente o mesmo algoritmo, mas treinado em centenas de gigabytes de texto com 100.000 mesclagens. O algoritmo é idêntico. A diferença está nos dados de treinamento e no número de fusões. Seu tokenizer treinado em um parágrafo com 40 fusões não pode competir com as 100K fusões do tiktoken em um corpus massivo. Mas o mecanismo é o mesmo.

Passo 5: Análise de Vocabulário

def analyze_vocabulary(tokenizer, test_texts):
    total_tokens = 0
    total_chars = 0
    token_usage = Counter()

    for text in test_texts:
        encoded = tokenizer.encode(text)
        total_tokens += len(encoded)
        total_chars += len(text)
        for t in encoded:
            token_usage[t] += 1

    print(f"Vocabulary size: {len(tokenizer.vocab)}")
    print(f"Total tokens across all texts: {total_tokens}")
    print(f"Total characters: {total_chars}")
    print(f"Avg tokens per character: {total_tokens / total_chars:.2f}")

    print(f"\nMost used tokens:")
    for token_id, count in token_usage.most_common(10):
        token_bytes = tokenizer.vocab[token_id]
        display = token_bytes.decode("utf-8", errors="replace")
        print(f"  Token {token_id:4d}: '{display}' (used {count} times)")

    unused = [t for t in tokenizer.vocab if t not in token_usage]
    print(f"\nUnused tokens: {len(unused)} out of {len(tokenizer.vocab)}")

Isso revela a distribuição de Zipf em seu vocabulário. Alguns tokens dominam (espaços, "the", "e"). A maioria dos tokens é raramente usada. Tokenizers de produção otimizam para essa distribuição — padrões comuns recebem IDs de token curtos, padrões raros recebem representações mais longas.

Use It

Seu BPE feito do zero funciona. Agora veja como são as ferramentas de produção.

tiktoken (OpenAI)

import tiktoken

enc = tiktoken.get_encoding("cl100k_base")

text = "Tokenizers convert text to integers"
tokens = enc.encode(text)
print(f"Tokens: {tokens}")
print(f"Pieces: {[enc.decode([t]) for t in tokens]}")
print(f"Roundtrip: {enc.decode(tokens)}")

O tiktoken é escrito em Rust com bindings para Python. Ele codifica milhões de tokens por segundo. Mesmo algoritmo BPE, com implementação de nível industrial.

Hugging Face tokenizers

from tokenizers import Tokenizer
from tokenizers.models import BPE
from tokenizers.trainers import BpeTrainer
from tokenizers.pre_tokenizers import ByteLevel

tokenizer = Tokenizer(BPE())
tokenizer.pre_tokenizer = ByteLevel()

trainer = BpeTrainer(vocab_size=1000, special_tokens=["<pad>", "<eos>", "<unk>"])
tokenizer.train(["corpus.txt"], trainer)

output = tokenizer.encode("The cat sat on the mat.")
print(f"Tokens: {output.tokens}")
print(f"IDs: {output.ids}")

A biblioteca tokenizers do Hugging Face também é baseada em Rust por baixo dos panos. Ela treina o BPE em corpora de escala de gigabytes em segundos. É o que você usa ao treinar seu próprio modelo.

Loading Llama's Tokenizer

from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3.1-8B")

text = "Tokenizers are the unsung heroes of LLMs"
tokens = tokenizer.encode(text)
print(f"Token IDs: {tokens}")
print(f"Tokens: {tokenizer.convert_ids_to_tokens(tokens)}")
print(f"Vocab size: {tokenizer.vocab_size}")

multilingual = ["Hello world", "Hola mundo", "Bonjour le monde"]
for text in multilingual:
    ids = tokenizer.encode(text)
    print(f"'{text}' -> {len(ids)} tokens")

O vocabulário de 128K do Llama 3 comprime textos que não estão em inglês significativamente melhor do que o vocabulário de 50K do GPT-2. Você mesmo pode verificar isso — codifique a mesma frase em vários idiomas e conte os tokens.

Ship It

Esta lição produz outputs/prompt-tokenizer-analyzer.md — um prompt reutilizável que analisa a eficiência da tokenização para qualquer combinação de texto e modelo. Alimente-o com uma amostra de texto e ele lhe dirá qual tokenizer de modelo lida melhor com ela.

Exercícios

  1. Modifique o tokenizer BPE para imprimir o vocabulário em cada etapa de fusão. Observe como "t" + "h" se torna "th", então "th" + "e" se torna "the". Acompanhe como palavras comuns em inglês são montadas peça por peça.

  2. Adicione tokens especiais (<pad>, <eos>, <unk>) ao tokenizer BPE. Atribua a eles os IDs 0, 1, 2 e mude todos os outros tokens de acordo. Implemente uma etapa de pré-tokenização que divide em espaços em branco antes de executar o BPE.

  3. Implemente o critério de fusão do WordPiece (razão de verossimilhança em vez de frequência). Treine tanto o BPE quanto o WordPiece no mesmo corpus com o mesmo número de fusões. Compare os vocabulários resultantes — qual deles produz subpalavras linguisticamente mais significativas?

  4. Construa um benchmark de eficiência de tokenizer multilíngue. Pegue 10 frases em inglês, espanhol, chinês, coreano e árabe. Tokenize cada uma com tiktoken (cl100k_base) e meça a média de tokens por caractere. Quantifique o "imposto multilíngue" para cada idioma.

  5. Treine seu tokenizer BPE em um corpus maior (baixe um artigo da Wikipédia). Ajuste o número de fusões para obter uma taxa de compressão dentro de 10% do tiktoken no mesmo texto. Isso forçará você a entender a relação entre o tamanho do corpus, a contagem de fusões e a qualidade da compressão.

Termos-chave

Termo O que as pessoas dizem O que realmente significa
Token "Uma palavra" Uma unidade no vocabulário do modelo — pode ser um caractere, subpalavra, palavra ou bloco de várias palavras
BPE "Alguma coisa de compressão" Byte Pair Encoding — mescla iterativamente o par adjacente mais frequente de tokens até atingir o tamanho do vocabulário alvo
WordPiece "O tokenizer do BERT" Semelhante ao BPE, mas as fusões maximizam a razão de verossimilhança count(AB)/(count(A)*count(B)) em vez da frequência bruta
SentencePiece "Uma biblioteca de tokenizer" Um tokenizer agnóstico em relação ao idioma que opera em Unicode bruto sem pré-tokenização, suportando os algoritmos BPE e Unigram
Tamanho do vocabulário "Quantas palavras ele conhece" O número total de tokens exclusivos: o GPT-2 possui 50.257, o BERT possui 30.522, o Llama 3 possui 128.256
Fertilidade "Não é um termo de tokenizer" Número médio de tokens por palavra — mede a eficiência do tokenizer entre idiomas (1,0 é perfeito, 3,0 significa que o modelo trabalha três vezes mais)
BPE em nível de byte "O tokenizer do GPT" BPE operando em bytes brutos (0-255) em vez de caracteres Unicode, garantindo que não haja tokens desconhecidos para qualquer entrada
Tabela de fusão "O arquivo do tokenizer" Lista ordenada de fusões de pares aprendidas durante o treinamento — isso É o tokenizer, e a ordem importa
Pré-tokenização "Divisão em espaços" Regras aplicadas antes da tokenização de subpalavras: divisão por espaços em branco, separação de dígitos, tratamento de pontuação
Taxa de compressão "Quão eficiente é o tokenizer" Tokens produzidos divididos pelos bytes de entrada — menor significa melhor compressão e inferência mais rápida

Leitura Adicional

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