# Algoritmos de tokenização

O Transformers suporta três algoritmos de tokenização subpalavra: Byte pair encoding (BPE), Unigram e WordPiece. Eles dividem o texto em unidades entre palavras e caracteres, mantendo o vocabulário compacto e, ao mesmo tempo, capturando fragmentos significativos. Palavras comuns permanecem intactas como tokens únicos, enquanto palavras raras ou desconhecidas são decompostas em subpalavras.

Por exemplo, `annoyingly` pode ser dividido em `["annoying", "ly"]` ou `["annoy", "ing", "ly"]`, dependendo do vocabulário. A divisão em subpalavras permite que o modelo represente palavras não vistas a partir de subpalavras conhecidas.

> [!TIP]
> A tokenização de subpalavras é especialmente útil para idiomas como o turco, no qual é possível formar palavras longas e complexas ao encadear subpalavras.

## Codificação de pares de bytes (BPE)

[Byte pair encoding](https://huggingface.co/papers/1508.07909) (BPE) é o algoritmo de tokenização mais popular em Transformers, utilizado por modelos como [Llama](./model_doc/llama), [Gemma](./model_doc/gemma), [Qwen2](./model_doc/qwen2) e outros.

1. Um pré-tokenizador divide o texto em espaços em branco ou outras regras, produzindo um conjunto de palavras únicas e suas frequências.

```text
("hug", 10), ("pug", 5), ("pun", 12), ("bun", 4), ("hugs", 5)
```

2. O algoritmo BPE cria um vocabulário base, `["b", "g", "h", "n", "p", "s", "u"]`, a partir de todos os caracteres.

```text
("h" "u" "g", 10), ("p" "u" "g", 5), ("p" "u" "n", 12), ("b" "u" "n", 4), ("h" "u" "g" "s", 5)
```

3. O BPE começa com caracteres individuais e, iterativamente, mescla o par adjacente mais frequente. `"u"` e `"g"` aparecem juntos com mais frequência em `"hug"`, `"pug"` e `"hugs"`, portanto, o BPE os mescla em `"ug"` e adiciona esse token ao vocabulário.

```text
("h" "ug", 10), ("p" "ug", 5), ("p" "u" "n", 12), ("b" "u" "n", 4), ("h" "ug" "s", 5)
```

4. O próximo par mais comum é `"u"` e `"n"`, que aparecem em `"pun"` e `"bun"`, então eles se fundem em `"un"`.

```text
("h" "ug", 10), ("p" "ug", 5), ("p" "un", 12), ("b" "un", 4), ("h" "ug" "s", 5)
```

5. O vocabulário agora é `["b", "g", "h", "n", "p", "s", "u", "ug", "un"]`. O BPE continua aprendendo regras de mesclagem até atingir o tamanho alvo do vocabulário, que é igual ao tamanho do vocabulário base mais o número de mesclagens. O [GPT](model_doc/openai-gpt) usa BPE com um tamanho de vocabulário de 40.478 (478 tokens base + 40.000 mesclagens).

Qualquer caractere que não esteja no vocabulário base é mapeado para um token desconhecido, como `"<unk>"`. Na prática, o vocabulário base cobre todos os caracteres observados durante o treinamento, de modo que tokens desconhecidos são raros.

### BPE em nível de bytes

Incluir todos os caracteres Unicode tornaria o vocabulário base enorme. O BPE em nível de bytes usa 256 valores de bytes como vocabulário base, garantindo que todas as palavras possam ser tokenizadas sem o token `"<unk>"`. O [GPT-2](./model_doc/gpt2) usa BPE em nível de bytes com um tamanho de vocabulário de 50.257 (256 tokens de bytes + 50.000 mesclagens + token especial de fim de texto).

## Unigram

[Unigram](https://huggingface.co/papers/1804.10959) é o segundo algoritmo de tokenização mais popular em Transformers, utilizado por modelos como [T5](./model_doc/t5), [BigBird](./model_doc/big_bird), [Pegasus](./model_doc/pegasus), entre outros.

1. Unigram começa com um grande conjunto de subpalavras candidatas, e cada candidata recebe uma pontuação de probabilidade com base na frequência com que aparece.

```text
("hug", 10), ("pug", 5), ("pun", 12), ("bun", 4), ("hugs", 5)
["b", "g", "h", "n", "p", "s", "u", "hu", "ug", "un", "pu", "bu", "gs", "hug", "pug", "pun", "bun", "ugs", "hugs"]
```

2. Unigram avalia o quão bem o vocabulário atual tokeniza os dados de treinamento em cada etapa.
3. Para cada token, o Unigram mede o quanto a remoção do token aumentaria a perda geral. Por exemplo, remover `"pu"` quase não afeta a perda, pois `"pug"` e `"pun"` ainda podem ser tokenizados como `["p", "ug"]` e `["p", "un"]`.

    Mas remover `"ug"` aumentaria significativamente a perda, pois `"hug"`, `"pug"` e `"hugs"` dependem dele.

4. Unigram remove os tokens com o menor aumento de perda, geralmente os 10-20% inferiores. Os caracteres básicos sempre permanecem, de modo que qualquer palavra possa ser tokenizada. Tokens como `"bu"`, `"pu"`, `"gs"`, `"pug"` e `"bun"` são removidos porque contribuíram menos para a verossimilhança geral.

```text
["b", "g", "h", "n", "p", "s", "u", "hu", "ug", "un", "hug", "pun", "ugs", "hugs"]
```

5. As etapas 2 a 4 se repetem até que o vocabulário atinja o tamanho alvo.

Durante a inferência, o Unigram pode tokenizar uma palavra de várias maneiras. `"hugs"` pode se tornar `["hug", "s"]`, `["h", "ug", "s"]` ou `["h", "u", "g", "s"]`. O Unigram seleciona a tokenização com a maior probabilidade. Diferentemente do BPE, que é determinístico e baseado em regras de mesclagem, o Unigram é probabilístico e pode amostrar tokenizações diferentes durante o treinamento.

## SentencePiece

[SentencePiece](https://huggingface.co/papers/1808.06226) é uma biblioteca de tokenização que aplica BPE ou Unigram diretamente em texto bruto. O BPE e o Unigram padrão assumem que espaços em branco separam as palavras, o que não funciona para idiomas como o chinês e o japonês, que não usam espaços.

1. SentencePiece trata o texto de entrada como um fluxo bruto de bytes ou caracteres e inclui o caractere de espaço, representado como `"▁"`, no vocabulário.

```text
("▁hug", 10), ("▁pug", 5), ("▁pun", 12), ("▁bun", 4), ("▁hugs", 5)
```

2. Em seguida, o SentencePiece aplica BPE ou Unigram ao texto.

Na decodificação, o SentencePiece concatena todos os tokens e substitui `"▁"` por um espaço.

## WordPiece

[WordPiece](https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/37842.pdf) é o algoritmo de tokenização para modelos da família BERT, como [DistilBERT](./model_doc/distilbert) e [Electra](./model_doc/electra).

É semelhante ao [BPE](#byte-pair-encoding-bpe) e mescla pares de baixo para cima de forma iterativa, mas difere na forma como seleciona os pares.

```text
("h" "u" "g", 10), ("p" "u" "g", 5), ("p" "u" "n", 12), ("b" "u" "n", 4), ("h" "u" "g" "s", 5)
```

WordPiece mescla pares que maximizam a verossimilhança dos dados de treinamento.

```text
score("u", "g") = frequency("ug") / (frequency("u") × frequency("g"))
```

| par | frequência | score |
|---|---|---|
| `"u"` + `"g"` | 20 | 20 / (36 × 20) = 0.028 |
| `"u"` + `"n"` | 16 | 16 / (36 × 16) = 0.028 |
| `"h"` + `"u"` | 15 | 15 / (15 × 36) = 0.028 |
| `"g"` + `"s"` | 5 | 5 / (20 × 5) = 0.050 |

A pontuação favorece a fusão de `"g"` e `"s"` quando o token combinado aparece com mais frequência do que o esperado a partir das frequências dos tokens individuais. O BPE simplesmente funde o par que aparece com mais frequência. O WordPiece mede o quão *informativa* é cada fusão. Dois tokens que aparecem juntos muito mais do que o previsto pelo acaso são fundidos primeiro.

## Tokenização em nível de palavra

A tokenização em nível de palavra divide o texto em tokens com base em espaços, pontuação ou regras específicas do idioma.

```text
["Do", "n't", "you", "love", "🤗", "Transformers", "?", "We", "sure", "do", "."]
```

O tamanho do vocabulário se torna extremamente grande porque cada palavra única requer seu próprio token, incluindo todas as variações (`"love"`, `"loving"`, `"loved"`, `"lovingly"`). A matriz de incorporação resultante é enorme, aumentando a memória e o processamento. Palavras que não estão no vocabulário são mapeadas para um token `"<unk>"`, de modo que o modelo não consegue lidar com palavras novas.

## Tokenização em nível de caractere

A tokenização em nível de caracteres divide o texto em caracteres individuais.

```text
["D", "o", "n", "'", "t", "y", "o", "u", "l", "o", "v", "e"]
```

O vocabulário é pequeno e cada palavra pode ser representada, então não há problema com `"<unk>"`. Mas as sequências ficam muito mais longas. Um caractere como `"l"` carrega muito menos significado do que `"love"`, então o desempenho sofre.

## Recursos

- O [Capítulo 6](https://huggingface.co/learn/llm-course/chapter6/1) do curso de LLM ensina como treinar um tokenizer do zero e explica as diferenças entre os algoritmos BPE, Unigram e WordPiece.

