Após a tokenização dos dados textuais, o próximo passo crítico na preparação dos dados para treinar grandes modelos de linguagem (LLMs) como o GPT é criar **token embeddings**. Token embeddings transformam tokens discretos (como palavras ou subpalavras) em vetores numéricos contínuos que o modelo pode processar e aprender. Esta explicação detalha os token embeddings, sua inicialização, uso e o papel dos embeddings posicionais em melhorar a compreensão do modelo sobre sequências de tokens.
O objetivo desta terceira fase é muito simples: **Atribuir a cada um dos tokens anteriores no vocabulário um vetor das dimensões desejadas para treinar o modelo.** Cada palavra no vocabulário será um ponto em um espaço de X dimensões.\
Note que inicialmente a posição de cada palavra no espaço é apenas inicializada "aleatoriamente" e essas posições são parâmetros treináveis (serão melhorados durante o treinamento).
Além disso, durante o token embedding **outra camada de embeddings é criada** que representa (neste caso) a **posição absoluta da palavra na frase de treinamento**. Dessa forma, uma palavra em diferentes posições na frase terá uma representação (significado) diferente.
{% endhint %}
### **O Que São Token Embeddings?**
**Token Embeddings** são representações numéricas de tokens em um espaço vetorial contínuo. Cada token no vocabulário está associado a um vetor único de dimensões fixas. Esses vetores capturam informações semânticas e sintáticas sobre os tokens, permitindo que o modelo entenda relacionamentos e padrões nos dados.
* **Tamanho do Vocabulário:** O número total de tokens únicos (por exemplo, palavras, subpalavras) no vocabulário do modelo.
* **Dimensões do Embedding:** O número de valores numéricos (dimensões) no vetor de cada token. Dimensões mais altas podem capturar informações mais sutis, mas requerem mais recursos computacionais.
No início do treinamento, os token embeddings são tipicamente inicializados com pequenos valores aleatórios. Esses valores iniciais são ajustados (afinados) durante o treinamento para representar melhor os significados dos tokens com base nos dados de treinamento.
**Exemplo PyTorch:**
```python
import torch
# Set a random seed for reproducibility
torch.manual_seed(123)
# Create an embedding layer with 6 tokens and 3 dimensions
embedding_layer = torch.nn.Embedding(6, 3)
# Display the initial weights (embeddings)
print(embedding_layer.weight)
```
**Saída:**
```lua
luaCopy codeParameter containing:
tensor([[ 0.3374, -0.1778, -0.1690],
[ 0.9178, 1.5810, 1.3010],
[ 1.2753, -0.2010, -0.1606],
[-0.4015, 0.9666, -1.1481],
[-1.1589, 0.3255, -0.6315],
[-2.8400, -0.7849, -1.4096]], requires_grad=True)
```
**Explicação:**
* Cada linha corresponde a um token no vocabulário.
* Cada coluna representa uma dimensão no vetor de embedding.
* Por exemplo, o token no índice `3` tem um vetor de embedding `[-0.4015, 0.9666, -1.1481]`.
* O token no índice `3` é representado pelo vetor `[-0.4015, 0.9666, -1.1481]`.
* Esses valores são parâmetros treináveis que o modelo ajustará durante o treinamento para representar melhor o contexto e o significado do token.
### **Como os Embeddings de Token Funcionam Durante o Treinamento**
Durante o treinamento, cada token nos dados de entrada é convertido em seu vetor de embedding correspondente. Esses vetores são então usados em vários cálculos dentro do modelo, como mecanismos de atenção e camadas de rede neural.
**Cenário de Exemplo:**
* **Tamanho do Lote:** 8 (número de amostras processadas simultaneamente)
* **Comprimento Máximo da Sequência:** 4 (número de tokens por amostra)
* **Dimensões do Embedding:** 256
**Estrutura de Dados:**
* Cada lote é representado como um tensor 3D com forma `(batch_size, max_length, embedding_dim)`.
* Para nosso exemplo, a forma seria `(8, 4, 256)`.
**Visualização:**
```css
cssCopy codeBatch
┌─────────────┐
│ Sample 1 │
│ ┌─────┐ │
│ │Token│ → [x₁₁, x₁₂, ..., x₁₂₅₆]
│ │ 1 │ │
│ │... │ │
│ │Token│ │
│ │ 4 │ │
│ └─────┘ │
│ Sample 2 │
│ ┌─────┐ │
│ │Token│ → [x₂₁, x₂₂, ..., x₂₂₅₆]
│ │ 1 │ │
│ │... │ │
│ │Token│ │
│ │ 4 │ │
│ └─────┘ │
│ ... │
│ Sample 8 │
│ ┌─────┐ │
│ │Token│ → [x₈₁, x₈₂, ..., x₈₂₅₆]
│ │ 1 │ │
│ │... │ │
│ │Token│ │
│ │ 4 │ │
│ └─────┘ │
└─────────────┘
```
**Explicação:**
* Cada token na sequência é representado por um vetor de 256 dimensões.
* O modelo processa essas embeddings para aprender padrões de linguagem e gerar previsões.
## **Embeddings Posicionais: Adicionando Contexto às Embeddings de Token**
Enquanto as embeddings de token capturam o significado de tokens individuais, elas não codificam inherentemente a posição dos tokens dentro de uma sequência. Compreender a ordem dos tokens é crucial para a compreensão da linguagem. É aqui que as **embeddings posicionais** entram em cena.
* **A Ordem dos Tokens Importa:** Em frases, o significado muitas vezes depende da ordem das palavras. Por exemplo, "O gato sentou no tapete" vs. "O tapete sentou no gato."
* **Limitação da Embedding:** Sem informações posicionais, o modelo trata os tokens como um "saco de palavras", ignorando sua sequência.
### **Tipos de Embeddings Posicionais:**
1.**Embeddings Posicionais Absolutos:**
* Atribui um vetor de posição único a cada posição na sequência.
* **Exemplo:** O primeiro token em qualquer sequência tem a mesma embedding posicional, o segundo token tem outra, e assim por diante.
* **Mesmas Dimensões:** As embeddings posicionais têm a mesma dimensionalidade que as embeddings de token.
* **Adição:** Elas são adicionadas às embeddings de token, combinando a identidade do token com informações posicionais sem aumentar a dimensionalidade geral.
**Exemplo de Adição de Embeddings Posicionais:**
Suponha que um vetor de embedding de token seja `[0.5, -0.2, 0.1]` e seu vetor de embedding posicional seja `[0.1, 0.3, -0.1]`. A embedding combinada usada pelo modelo seria:
* **Consciência Contextual:** O modelo pode diferenciar entre tokens com base em suas posições.
* **Compreensão de Sequência:** Permite que o modelo entenda gramática, sintaxe e significados dependentes do contexto.
## Exemplo de Código
Seguindo com o 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
# Use previous code...
# Create dimensional emdeddings
"""
BPE uses a vocabulary of 50257 words
Let's supose we want to use 256 dimensions (instead of the millions used by LLMs)