mirror of
https://github.com/carlospolop/hacktricks
synced 2024-12-24 20:13:37 +00:00
205 lines
9 KiB
Markdown
205 lines
9 KiB
Markdown
|
# 3. Token Embeddings
|
||
|
|
||
|
## Token Embeddings
|
||
|
|
||
|
Após a tokenização dos dados textuais, o próximo passo crítico na preparação de 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 token embeddings, sua inicialização, uso e o papel dos embeddings posicionais em melhorar a compreensão do modelo sobre sequências de tokens.
|
||
|
|
||
|
{% hint style="success" %}
|
||
|
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.
|
||
|
|
||
|
**Exemplo:**
|
||
|
|
||
|
* **Tamanho do Vocabulário:** 6 tokens \[1, 2, 3, 4, 5, 6]
|
||
|
* **Dimensões do Embedding:** 3 (x, y, z)
|
||
|
|
||
|
### **Inicializando Token Embeddings**
|
||
|
|
||
|
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]`.
|
||
|
|
||
|
**Acessando o Embedding de um Token:**
|
||
|
```python
|
||
|
# Retrieve the embedding for the token at index 3
|
||
|
token_index = torch.tensor([3])
|
||
|
print(embedding_layer(token_index))
|
||
|
```
|
||
|
**Saída:**
|
||
|
```lua
|
||
|
tensor([[-0.4015, 0.9666, -1.1481]], grad_fn=<EmbeddingBackward0>)
|
||
|
```
|
||
|
**Interpretação:**
|
||
|
|
||
|
* 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.
|
||
|
|
||
|
### **Por que as Embeddings Posicionais são Necessárias:**
|
||
|
|
||
|
* **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.
|
||
|
* **Usado Por:** Modelos GPT da OpenAI.
|
||
|
2. **Embeddings Posicionais Relativos:**
|
||
|
* Codifica a distância relativa entre tokens em vez de suas posições absolutas.
|
||
|
* **Exemplo:** Indica quão distantes dois tokens estão, independentemente de suas posições absolutas na sequência.
|
||
|
* **Usado Por:** Modelos como Transformer-XL e algumas variantes do BERT.
|
||
|
|
||
|
### **Como as Embeddings Posicionais são Integradas:**
|
||
|
|
||
|
* **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:
|
||
|
```css
|
||
|
Combined Embedding = Token Embedding + Positional Embedding
|
||
|
= [0.5 + 0.1, -0.2 + 0.3, 0.1 + (-0.1)]
|
||
|
= [0.6, 0.1, 0.0]
|
||
|
```
|
||
|
**Benefícios dos Embeddings Posicionais:**
|
||
|
|
||
|
* **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)
|
||
|
"""
|
||
|
|
||
|
vocab_size = 50257
|
||
|
output_dim = 256
|
||
|
token_embedding_layer = torch.nn.Embedding(vocab_size, output_dim)
|
||
|
|
||
|
## Generate the dataloader like before
|
||
|
max_length = 4
|
||
|
dataloader = create_dataloader_v1(
|
||
|
raw_text, batch_size=8, max_length=max_length,
|
||
|
stride=max_length, shuffle=False
|
||
|
)
|
||
|
data_iter = iter(dataloader)
|
||
|
inputs, targets = next(data_iter)
|
||
|
|
||
|
# Apply embeddings
|
||
|
token_embeddings = token_embedding_layer(inputs)
|
||
|
print(token_embeddings.shape)
|
||
|
torch.Size([8, 4, 256]) # 8 x 4 x 256
|
||
|
|
||
|
# Generate absolute embeddings
|
||
|
context_length = max_length
|
||
|
pos_embedding_layer = torch.nn.Embedding(context_length, output_dim)
|
||
|
|
||
|
pos_embeddings = pos_embedding_layer(torch.arange(max_length))
|
||
|
|
||
|
input_embeddings = token_embeddings + pos_embeddings
|
||
|
print(input_embeddings.shape) # torch.Size([8, 4, 256])
|
||
|
```
|
||
|
## 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)
|