# 1. Tokenização {{#include ../../banners/hacktricks-training.md}} ## Tokenização **Tokenização** é o processo de dividir dados, como texto, em partes menores e gerenciáveis chamadas _tokens_. Cada token recebe um identificador numérico único (ID). Este é um passo fundamental na preparação do texto para processamento por modelos de aprendizado de máquina, especialmente em processamento de linguagem natural (NLP). > [!TIP] > O objetivo desta fase inicial é muito simples: **Dividir a entrada em tokens (ids) de uma maneira que faça sentido**. ### **Como a Tokenização Funciona** 1. **Dividindo o Texto:** - **Tokenizador Básico:** Um tokenizador simples pode dividir o texto em palavras individuais e sinais de pontuação, removendo espaços. - _Exemplo:_\ Texto: `"Olá, mundo!"`\ Tokens: `["Olá", ",", "mundo", "!"]` 2. **Criando um Vocabulário:** - Para converter tokens em IDs numéricos, um **vocabulário** é criado. Este vocabulário lista todos os tokens únicos (palavras e símbolos) e atribui a cada um um ID específico. - **Tokens Especiais:** Estes são símbolos especiais adicionados ao vocabulário para lidar com vários cenários: - `[BOS]` (Início da Sequência): Indica o início de um texto. - `[EOS]` (Fim da Sequência): Indica o fim de um texto. - `[PAD]` (Preenchimento): Usado para fazer todas as sequências em um lote terem o mesmo comprimento. - `[UNK]` (Desconhecido): Representa tokens que não estão no vocabulário. - _Exemplo:_\ Se `"Olá"` é atribuído ao ID `64`, `","` é `455`, `"mundo"` é `78`, e `"!"` é `467`, então:\ `"Olá, mundo!"` → `[64, 455, 78, 467]` - **Tratando Palavras Desconhecidas:**\ Se uma palavra como `"Tchau"` não está no vocabulário, ela é substituída por `[UNK]`.\ `"Tchau, mundo!"` → `["[UNK]", ",", "mundo", "!"]` → `[987, 455, 78, 467]`\ _(Assumindo que `[UNK]` tem ID `987`)_ ### **Métodos Avançados de Tokenização** Enquanto o tokenizador básico funciona bem para textos simples, ele tem limitações, especialmente com vocabulários grandes e ao lidar com palavras novas ou raras. Métodos avançados de tokenização abordam essas questões dividindo o texto em subunidades menores ou otimizando o processo de tokenização. 1. **Codificação de Par de Bytes (BPE):** - **Propósito:** Reduz o tamanho do vocabulário e lida com palavras raras ou desconhecidas, dividindo-as em pares de bytes que ocorrem com frequência. - **Como Funciona:** - Começa com caracteres individuais como tokens. - Mescla iterativamente os pares de tokens mais frequentes em um único token. - Continua até que não haja mais pares frequentes que possam ser mesclados. - **Benefícios:** - Elimina a necessidade de um token `[UNK]`, uma vez que todas as palavras podem ser representadas combinando tokens de subpalavras existentes. - Vocabulário mais eficiente e flexível. - _Exemplo:_\ `"jogando"` pode ser tokenizado como `["jogar", "ndo"]` se `"jogar"` e `"ndo"` forem subpalavras frequentes. 2. **WordPiece:** - **Usado Por:** Modelos como BERT. - **Propósito:** Semelhante ao BPE, divide palavras em unidades de subpalavras para lidar com palavras desconhecidas e reduzir o tamanho do vocabulário. - **Como Funciona:** - Começa com um vocabulário base de caracteres individuais. - Adiciona iterativamente a subpalavra mais frequente que maximiza a probabilidade dos dados de treinamento. - Usa um modelo probabilístico para decidir quais subpalavras mesclar. - **Benefícios:** - Equilibra entre ter um tamanho de vocabulário gerenciável e representar palavras de forma eficaz. - Lida eficientemente com palavras raras e compostas. - _Exemplo:_\ `"infelicidade"` pode ser tokenizado como `["in", "felicidade"]` ou `["in", "feliz", "dade"]` dependendo do vocabulário. 3. **Modelo de Linguagem Unigram:** - **Usado Por:** Modelos como SentencePiece. - **Propósito:** Usa um modelo probabilístico para determinar o conjunto mais provável de tokens de subpalavras. - **Como Funciona:** - Começa com um grande conjunto de tokens potenciais. - Remove iterativamente tokens que menos melhoram a probabilidade do modelo em relação aos dados de treinamento. - Finaliza um vocabulário onde cada palavra é representada pelas unidades de subpalavras mais prováveis. - **Benefícios:** - Flexível e pode modelar a linguagem de forma mais natural. - Muitas vezes resulta em tokenizações mais eficientes e compactas. - _Exemplo:_\ `"internacionalização"` pode ser tokenizado em subpalavras menores e significativas como `["internacional", "ização"]`. ## Exemplo de Código Vamos entender isso melhor a partir de um exemplo de código de [https://github.com/rasbt/LLMs-from-scratch/blob/main/ch02/01_main-chapter-code/ch02.ipynb](https://github.com/rasbt/LLMs-from-scratch/blob/main/ch02/01_main-chapter-code/ch02.ipynb): ```python # Download a text to pre-train the model import urllib.request url = ("https://raw.githubusercontent.com/rasbt/LLMs-from-scratch/main/ch02/01_main-chapter-code/the-verdict.txt") file_path = "the-verdict.txt" urllib.request.urlretrieve(url, file_path) with open("the-verdict.txt", "r", encoding="utf-8") as f: raw_text = f.read() # Tokenize the code using GPT2 tokenizer version import tiktoken token_ids = tiktoken.get_encoding("gpt2").encode(txt, allowed_special={"[EOS]"}) # Allow the user of the tag "[EOS]" # Print first 50 tokens print(token_ids[:50]) #[40, 367, 2885, 1464, 1807, 3619, 402, 271, 10899, 2138, 257, 7026, 15632, 438, 2016, 257, 922, 5891, 1576, 438, 568, 340, 373, 645, 1049, 5975, 284, 502, 284, 3285, 326, 11, 287, 262, 6001, 286, 465, 13476, 11, 339, 550, 5710, 465, 12036, 11, 6405, 257, 5527, 27075, 11] ``` ## Referências - [https://www.manning.com/books/build-a-large-language-model-from-scratch](https://www.manning.com/books/build-a-large-language-model-from-scratch) {{#include ../../banners/hacktricks-training.md}}