Pedro's dev blog

Transformers: Revolucionando a Inteligência Artificial

Transformers.jpg
Published on
/12 mins read/---

✨ Transformers: Revolucionando a Inteligência Artificial ✨

Os Transformers são um tipo de arquitetura de rede neural introduzida no artigo seminal "Attention Is All You Need" por Vaswani et al. em 2017. Eles revolucionaram o campo do Processamento de Linguagem Natural (PLN) e se tornaram a base para muitos dos modelos de IA mais avançados que vemos hoje, como BERT, GPT-3, GPT-4, e muitos outros.

Sua principal inovação foi abandonar as arquiteturas recorrentes RNNs, LSTMs e convolucionais CNNs – que processavam dados sequencialmente – em favor de um mecanismo chamado Atenção (Attention), especialmente o Self-Attention (Auto-Atenção).

🤔 Por Que Transformers? O Problema com RNNs/LSTMs

Modelos anteriores, como RNNs e Notas/ML/LSTMs, processavam sequências palavra por palavra (ou token por token). Isso trazia desafios:

  1. Dependências de Longo Alcance: Era difícil para eles manter informações relevantes de palavras muito distantes na sequência. O "contexto" tendia a se diluir.
  2. Processamento Sequencial: Não podiam ser facilmente paralelizados, tornando o treinamento em grandes datasets muito lento. Cada passo dependia do anterior.
  3. Problema de Gradientes: Sofriam com problemas de desaparecimento ou explosão de gradientes durante o treinamento.

Os Transformers surgiram para resolver esses problemas, principalmente através do mecanismo de atenção.

🏛️ A Arquitetura Transformer: Uma Visão Geral

A arquitetura original do Transformer é composta por duas partes principais: um Codificador (Encoder) e um Decodificador (Decoder).

  • Encoder: Processa a sequência de entrada (por exemplo, uma frase em inglês) e a transforma em uma representação rica em contexto (um conjunto de vetores).
  • Decoder: Recebe a representação do Encoder e gera a sequência de saída (por exemplo, a tradução em português), um token de cada vez.
Diagrama de Atenção

Nota: Muitos modelos modernos usam apenas o Encoder (como o BERT, para tarefas de compreensão) ou apenas o Decoder (como o GPT, para tarefas de geração).

🧩 Componentes Chave

Vamos detalhar os blocos de construção essenciais:

1. Embedding & Positional Encoding

  • [[Notas/ML/Embedding]]: Assim como em outros modelos de PLN, as palavras (ou sub-palavras/tokens) são convertidas em vetores numéricos densos. Cada palavra única tem seu vetor.
  • Positional Encoding: Como o Transformer não processa palavras sequencialmente, ele não tem noção inerente da ordem das palavras. O Positional Encoding adiciona vetores aos embeddings que carregam informações sobre a posição de cada token na sequência. Isso é crucial! Geralmente, usam-se funções seno e cosseno de diferentes frequências, ou são embeddings aprendidos.

Por que isso importa? A frase "O cachorro mordeu o homem" tem significado diferente de "O homem mordeu o cachorro". A posição é fundamental!

2. Mecanismo de Atenção (Attention Mechanism) 🧠

Este é o coração do Transformer! Permite que o modelo pondere a importância de diferentes partes da sequência de entrada ao processar uma palavra específica.

Analogia: Pense em como você lê uma frase complexa. Ao encontrar um pronome como "ele", seu cérebro automaticamente "presta atenção" a possíveis substantivos anteriores aos quais "ele" pode se referir. A atenção faz algo semelhante.

a) Self-Attention (Auto-Atenção)

Permite que o modelo olhe para outras palavras na mesma sequência (seja a de entrada no Encoder, ou a de saída parcial no Decoder) para obter um melhor entendimento contextual de cada palavra.

Como funciona (Conceitualmente):

Para cada palavra (token), criamos três vetores:

  1. Query (Consulta): O que estou procurando? (Representa a palavra atual)
  2. Key (Chave): O que eu posso oferecer? (Representa as outras palavras como "marcadores")
  3. Value (Valor): O que eu realmente sou / qual informação eu carrego? (Representa a informação das outras palavras)

O modelo calcula um score de atenção comparando o Query da palavra atual com as Keys de todas as outras palavras (incluindo ela mesma). Esses scores são normalizados (geralmente via softmax) para que somem 1, indicando quanta "atenção" a palavra atual deve dar a cada outra palavra. Finalmente, esses scores ponderam os vetores Value de todas as palavras, e a soma ponderada se torna a nova representação da palavra atual, agora rica em contexto.

Uma imagem

(Diagrama simplificado ilustrando que 'it' provavelmente prestará mais atenção a 'animal' e 'tired' na frase "The animal didn't cross the street because it was too tired.")

b) Multi-Head Attention (Atenção Multi-Cabeça)

Em vez de calcular a atenção uma única vez, o Multi-Head Attention faz isso várias vezes em paralelo, com diferentes conjuntos de matrizes de projeção para Q, K e V. Cada um desses "cabeçalhos" (heads) pode aprender a focar em diferentes tipos de relações ou aspectos da informação (ex: um head foca em relações sintáticas, outro em semânticas, etc.). Os resultados de todos os heads são concatenados e projetados novamente para produzir a saída final da camada de atenção.

img

3. Add & Norm (Conexões Residuais e Normalização de Camada)

  • Conexões Residuais (Add): A saída de cada sub-camada (como Multi-Head Attention ou Feed-Forward) é adicionada à entrada original da sub-camada (x + SubLayer(x)). Isso ajuda a treinar redes muito profundas, facilitando o fluxo de gradientes (semelhante às ResNets em visão computacional).
  • Normalização de Camada (Norm): Aplicada após a adição residual. Normaliza as ativações dentro de uma única camada, ajudando a estabilizar o treinamento e acelerar a convergência.

4. Position-wise Feed-Forward Networks (Redes Feed-Forward por Posição)

Após a camada de atenção (e Add & Norm), cada posição na sequência passa por uma rede feed-forward idêntica, mas independente das outras posições. Geralmente consiste em duas camadas lineares com uma função de ativação ReLU (ou similar) no meio. Isso adiciona capacidade de processamento não-linear ao modelo.

⚙️ O Fluxo Completo

  • Encoder: Uma pilha de N camadas idênticas. Cada camada tem:
    1. Multi-Head Self-Attention
    2. Add & Norm
    3. Position-wise Feed-Forward Network
    4. Add & Norm
  • Decoder: Uma pilha de N camadas idênticas. Cada camada tem:
    1. Masked Multi-Head Self-Attention (mascarada para que uma posição não possa "ver" posições futuras na sequência de saída durante o treinamento/geração).
    2. Add & Norm
    3. Multi-Head Encoder-Decoder Attention (a Query vem da camada anterior do Decoder, mas Key e Value vêm da saída final do Encoder - permite ao Decoder focar em partes relevantes da entrada).
    4. Add & Norm
    5. Position-wise Feed-Forward Network
    6. Add & Norm
  • Camada Linear Final + Softmax: No topo do Decoder, transforma a representação vetorial final em probabilidades sobre o vocabulário para escolher a próxima palavra.
img

🧑‍💻 Implementação Prática no Google Colab: Tradução Inglês-Português

🚀 Exemplo Real: Tradução Automática (Inglês -> Português)

Vamos traduzir: "The black cat sat" -> "O gato preto sentou"

  1. Entrada Encoder: As palavras "The", "black", "cat", "sat" são convertidas em embeddings e recebem positional encodings.
  2. Processamento Encoder:
    • As camadas do Encoder processam essa sequência.
    • Na camada de Self-Attention, "cat" pode prestar atenção a "black" (modificador) e "sat" (verbo associado). "The" pode ter menos atenção relativa.
    • O resultado é um conjunto de vetores ricos em contexto (H_the, H_black, H_cat, H_sat) que representam a frase de entrada.
  3. Início Decoder: O Decoder começa com um token de início (ex: <start>). Ele recebe os vetores do Encoder (H_...).
  4. Geração da Primeira Palavra:
    • O Decoder usa Masked Self-Attention (trivial no primeiro passo).
    • Usa Encoder-Decoder Attention: O token <start> (como Query) "olha" para os vetores do Encoder (H_... como Keys e Values) para decidir qual informação da entrada é mais relevante para começar a tradução. Talvez H_the e H_cat sejam mais importantes.
    • Passa pela Feed-Forward.
    • A camada Linear + Softmax prevê a probabilidade de cada palavra no vocabulário português. A palavra com maior probabilidade é "O".
  5. Geração da Segunda Palavra:
    • A entrada para o Decoder agora é <start>, "O".
    • Masked Self-Attention: "O" presta atenção a <start>.
    • Encoder-Decoder Attention: "O" (como Query) olha novamente para os vetores do Encoder (H_...). Agora, talvez H_cat seja o mais relevante.
    • O modelo prevê "gato".
  6. Geração das Palavras Seguintes:
    • Entrada Decoder: <start>, "O", "gato".
    • Masked Self-Attention: "gato" presta atenção a "O" e <start>.
    • Encoder-Decoder Attention: "gato" (como Query) foca em H_.... Provavelmente H_black se torna relevante agora.
    • Prevê "preto".
    • ... e assim por diante, até prever "sentou" e um token de fim de sentença (ex: <end>).

✅ Vantagens dos Transformers

  • Paralelização: Cálculos de atenção e feed-forward podem ser massivamente paralelizados, acelerando o treinamento.
  • Dependências de Longo Alcance: O Self-Attention conecta diretamente todas as palavras, não importando a distância, facilitando a captura dessas dependências.
  • Desempenho State-of-the-Art: Tornaram-se o padrão ouro em quase todas as tarefas de PLN e estão se expandindo para outras áreas (visão, áudio, etc.).
  • Escalabilidade: Tendem a melhorar o desempenho com mais dados e parâmetros (modelos maiores).

Para solidificar o entendimento, vamos usar o ambiente Google Colab para executar um exemplo prático de tradução automática usando um modelo Transformer pré-treinado. Utilizaremos a biblioteca transformers da Hugging Face, que facilita o acesso a modelos de última geração.

Passo 1: Configuração do Ambiente no Colab

Abra um novo notebook no Google Colab. A primeira coisa a fazer é instalar a biblioteca transformers:

!pip install transformers

Passo 2: Carregando um Modelo Transformer Pré-treinado para Tradução

Vamos usar um modelo pré-treinado para tradução de inglês para português. A Hugging Face Hub oferece diversos modelos; um popular é o Helsinki-NLP/opus-mt-en-pt. Este modelo é baseado na arquitetura Transformer e já foi treinado em grandes volumes de dados bilíngues.

from transformers import pipeline
 
translator = pipeline('translation_en_to_pt', model='Helsinki-NLP/opus-mt-en-pt')
  • pipeline('translation_en_to_pt', model='Helsinki-NLP/opus-mt-en-pt'): Esta linha cria um pipeline de tradução. O pipeline da transformers abstrai muitos detalhes, permitindo usar modelos complexos com poucas linhas de código. Especificamos a tarefa (translation_en_to_pt) e o modelo pré-treinado (Helsinki-NLP/opus-mt-en-pt).

Passo 3: Traduzindo a Frase de Exemplo

Agora, vamos usar o translator para traduzir a frase "The black cat sat" para português, seguindo o exemplo que discutimos:

english_text = "The black cat sat"
portuguese_translation = translator(english_text)[0]['translation_text']
 
print(f"Texto em Inglês: '{english_text}'")
print(f"Tradução para Português: '{portuguese_translation}'")
  • translator(english_text): Passamos a frase em inglês para o translator. Internamente, o pipeline cuida de todas as etapas: tokenização da entrada, passagem pelo modelo Transformer (Encoder e Decoder), e decodificação da saída.
  • [0]['translation_text']: O resultado do translator é uma lista de dicionários. Acessamos o primeiro elemento ([0]) e pegamos o valor da chave 'translation_text', que contém a frase traduzida.
  • print(...): Imprimimos o texto original e a tradução para verificar o resultado.

Executando o Código no Colab

Execute as células de código no seu notebook Colab. Você deverá ver uma saída similar a esta:

Texto em Inglês: 'The black cat sat'
Tradução para Português: 'O gato preto sentou-se'

Análise do Resultado e Conexão com a Arquitetura Transformer

  • Resultado: O modelo traduziu corretamente "The black cat sat" para "O gato preto sentou-se" (ou similar, pequenas variações podem ocorrer dependendo da versão do modelo e da biblioteca). Isso demonstra a capacidade do Transformer em traduzir frases, capturando a ordem e o significado das palavras.

  • Encoder e Decoder em Ação (Nos Bastidores):

    • Encoder: Quando você passa "The black cat sat" para o translator, o pipeline internamente usa o Encoder do Transformer para processar essa frase. O Encoder realiza o embedding das palavras, adiciona positional encodings e aplica as camadas de Self-Attention para criar representações contextuais de cada palavra (H_the, H_black, H_cat, H_sat).
    • Decoder: O Decoder, então, entra em ação. Começando com um token de início (implicitamente gerenciado pelo pipeline), ele gera a tradução palavra por palavra. Em cada passo da geração (como descrito no exemplo teórico):
      • O Decoder usa Masked Self-Attention (para garantir que ele só "olhe" para as palavras já geradas).
      • O Decoder usa Encoder-Decoder Attention para "prestar atenção" nas representações contextuais do Encoder (H_the, H_black, H_cat, H_sat). É aqui que o Decoder decide quais partes da frase de entrada são mais relevantes para gerar a próxima palavra em português.
      • O Decoder passa por Feed-Forward Networks e finalmente usa uma camada Linear + Softmax para prever a próxima palavra em português ("O", "gato", "preto", "sentou-se", etc.).
  • Vantagens na Prática: Este exemplo rápido demonstra algumas vantagens dos Transformers:

    • Desempenho: A tradução é precisa e fluente, mesmo com um modelo pré-treinado e sem ajuste fino para essa frase específica.
    • Facilidade de Uso (com transformers): Com poucas linhas de código, podemos usar modelos complexos para tarefas de PLN, graças à abstração fornecida pela biblioteca Hugging Face.

Explorando Mais (Opcional)

  • Experimente outras frases: Modifique a variável english_text com outras frases em inglês e veja os resultados da tradução.
  • Explore outros modelos: A Hugging Face Hub (https://huggingface.co/models) possui milhares de modelos pré-treinados para diversas tarefas e idiomas. Você pode experimentar outros modelos de tradução ou para outras tarefas de PLN.
  • Aprofunde-se na biblioteca transformers: Consulte a documentação da Hugging Face Transformers para entender melhor como usar os pipelines, tokenizers e modelos diretamente, e para explorar opções de fine-tuning e treinamento de modelos.

Conclusão da Implementação

Este exemplo prático no Colab demonstra de forma simples o poder dos Transformers para tarefas de tradução automática. Ao usar um modelo pré-treinado, podemos rapidamente obter resultados impressionantes, mesmo com um conhecimento inicial da arquitetura Transformer. A biblioteca transformers da Hugging Face torna acessível o uso dessas tecnologias avançadas, permitindo que você explore e experimente com modelos de linguagem de última geração.

❌ Desvantagens

  • Custo Computacional: O Self-Attention tem complexidade quadrática em relação ao comprimento da sequência (O(n²)), tornando-o muito caro para sequências extremamente longas. (Existem variantes como Sparse Attention, Longformer, etc., para mitigar isso).
  • Necessidade de Dados: Geralmente requerem grandes quantidades de dados para treinar eficazmente.
  • Interpretabilidade: Embora os scores de atenção possam dar alguma intuição, entender exatamente por que um Transformer toma uma decisão ainda é um desafio.
  • Positional Encoding: Embora eficaz, a forma como a informação posicional é injetada (especialmente com seno/cosseno) pode parecer um pouco "ad-hoc" para alguns.

🏁 Conclusão

Os Transformers representam um marco na inteligência artificial. Ao introduzir o mecanismo de Self-Attention e abandonar a recorrência, eles superaram limitações significativas dos modelos anteriores, permitindo a criação de modelos muito maiores, mais poderosos e capazes de entender e gerar linguagem (e outros tipos de dados) com uma fluência sem precedentes. Eles são a espinha dorsal da revolução atual em IA generativa e modelos de linguagem grandes (LLMs).