Uma introdução aos Large Language Models

Do GPT-2 ao ChatGPT: A revolução dos Modelos de Linguagem e seu impacto na Inteligência Artificial de Linguagem

Nelson Frugeri, Jr
27 min readSep 21, 2024
Exploradores egípcios dentro de uma antiga pirâmide, desvendando segredos escondidos nas paredes cobertas de hieróglifos e símbolos misteriosos. À luz de suas tochas, eles revelam imagens e inscrições milenares, enquanto o ambiente sombrio e as sombras projetadas criam uma atmosfera de mistério e descoberta.

A partir de 2012, os avanços em IA com deep learning aceleraram tanto que, em menos de uma década, surgiu o GPT-2, o primeiro sistema capaz de escrever textos praticamente idênticos aos produzidos por humanos. Em 2022, o lançamento do ChatGPT trouxe uma revolução na interação com tecnologia e informação, alcançando rapidamente milhões de usuários. Inicialmente visto como um chatbot, o ChatGPT rapidamente transformou tarefas como tradução, geração de texto e sumarização, tornando-se uma ferramenta essencial para desenvolvedores, educadores e pesquisadores.

O sucesso do ChatGPT impulsionou mais pesquisas em torno dos LLMs, tanto proprietários quanto open source, que começaram a ser lançados em ritmo acelerado, eventualmente alcançando o desempenho do ChatGPT. Com isso, 2023 se tornou um marco na Inteligência Artificial de Linguagem (Language AI), focada no desenvolvimento de sistemas que compreendem e geram linguagem humana.

Embora os LLMs sejam o foco atual, eles já existiam há algum tempo, e modelos menores continuam a ser relevantes. O campo de Language AI vai além dos LLMs, com muitas outras técnicas e abordagens que ainda precisam ser exploradas.

Mas, principalmente, pretendemos responder às seguintes perguntas neste hands-on:

  • O que é Language AI?
  • O que são modelos de linguagem de grande escala?
  • Quais são os casos de uso e aplicações comuns dos modelos de linguagem de grande escala?
  • Como podemos usar os modelos de linguagem de grande escala nós mesmos?

O que é Language AI?

O termo inteligência artificial (IA) é comumente utilizado para descrever sistemas de computador projetados para executar tarefas que se aproximam da inteligência humana, como reconhecimento de fala, tradução de idiomas e percepção visual. Trata-se da inteligência do software, em contraste com a inteligência humana.

Aqui está uma definição mais formal de um dos pioneiros da área de inteligência artificial:

[Inteligência artificial é] a ciência e engenharia de criar máquinas inteligentes, especialmente programas de computador inteligentes. Está relacionada à tarefa similar de usar computadores para entender a inteligência humana, mas a IA não precisa se limitar a métodos que são observáveis biologicamente. — John McCarthy, 2007

Devido à natureza em constante transformação da IA, o termo tem sido utilizado para descrever uma grande variedade de sistemas, alguns dos quais podem não necessariamente incorporar um comportamento inteligente. Por exemplo, personagens em jogos de computador (NPCs [nonplayable characters]) muitas vezes são chamados de IA, embora muitos não sejam nada além de simples instruções if-else.

Language AI refere-se a um subcampo da IA que se concentra no desenvolvimento de tecnologias capazes de compreender, processar e gerar linguagem humana. O termo Language AI pode frequentemente ser utilizado de maneira intercambiável com Natural Language Processing (NLP) devido ao sucesso contínuo dos métodos de machine learning em solucionar problemas relacionados ao processamento de linguagem.

Usamos o termo Language AI para abranger tecnologias que, tecnicamente, podem não ser LLMs, mas ainda exercem um impacto considerável no campo, como os sistemas de recuperação que podem potencializar os LLMs.

Ao longo deste hands-on, queremos dar ênfase aos modelos que desempenharam um papel importante na formação do campo de Language AI. Isso significa explorar além dos LLMs isolados. Isso, no entanto, nos leva à questão: o que são large language models? Para começar a responder a essa pergunta neste hands-on, vamos primeiro explorar a história de Language AI.

Uma História Recente de Language AI

A história de Language AI abrange muitos desenvolvimentos e modelos que visam representar e gerar linguagem, como ilustrado na Figura 1–1.

Figura 1–1. Um vislumbre na história de Language AI.

A linguagem, no entanto, é um conceito complicado para computadores. O texto é de natureza não estruturada e perde seu significado quando representado por zeros e uns (caracteres individuais). Como resultado, ao longo da história de Language AI, houve um grande foco em representar a linguagem de uma maneira que de maneira estruturada para que possa ser mais facilmente utilizada por computadores. Exemplos dessas tarefas de Language AI são fornecidos na Figura 1–2.

Figura 1–2. Language AI é capaz de realizar muitas tarefas processando entrada textual.

Representando a Linguagem como um Bag-of-Words

Nossa história de Language AI começa com uma técnica chamada bag-of-words, um método para representar texto não estruturado. Foi mencionada pela primeira vez por volta da década de 1950, mas se tornou popular por volta dos anos 2000.

O bag-of-words funciona da seguinte maneira: vamos supor que temos duas sentenças para as quais queremos criar representações numéricas. O primeiro passo do modelo bag-of-words é a tokenização, o processo de dividir as sentenças em palavras ou subpalavras individuais (tokens), como ilustrado na Figura 1–3.

Figura 1–3. Cada sentença é dividida em palavras (tokens) ao separar por um espaço em branco.

O método mais comum para tokenização é a separação por um espaço em branco para criar palavras individuais. No entanto, isso tem suas desvantagens, pois algumas línguas, como o Mandarim, não possuem espaços em branco ao redor das palavras individuais. Vamos nos aprofundar sobre tokenização e como essa técnica influencia os modelos de linguagem. Como ilustrado na Figura 1–4, após a tokenização, combinamos todas as palavras únicas de cada sentença para criar um vocabulário que podemos usar para representar as sentenças.

Figura 1–4. Um vocabulário é criado ao reter todas as palavras únicas em ambas as sentenças.

Usando nosso vocabulário, simplesmente contamos com que frequência uma palavra em cada sentença aparece, literalmente criando um bag of words. Como resultado, um modelo de bag-of-words visa criar representações de texto na forma de números, também chamados de vetores ou representações vetoriais, conforme observado na Figura 1–5. Ao longo do hands-on, nos referimos a esses tipos de modelos como modelos de representação.

Figura 1–5. Um bag-of-words é criado contando palavras individuais. Esses valores são referidos como representações vetoriais.

Embora o bag-of-words seja um método clássico, ele não está de forma alguma completamente obsoleto. Exploraremos como ele ainda pode ser usado para complementar modelos de linguagem mais recentes.

Melhores Representações com Dense Vector Embeddings

Bag-of-words, embora seja uma abordagem elegante, tem uma falha. Ele considera a linguagem como nada mais do que um saco de palavras quase literal e ignora a natureza semântica, ou significado, do texto.

Lançado em 2013, o word2vec foi uma das primeiras tentativas bem-sucedidas de capturar o significado do texto em embeddings. Embeddings são representações vetoriais de dados que tentam capturar seu significado. Para fazer isso, o word2vec aprende representações semânticas de palavras treinando em grandes quantidades de dados textuais, como a totalidade da Wikipedia.

Para gerar essas representações semânticas, o word2vec utiliza redes neurais. Essas redes consistem em camadas interconectadas de nós que processam informações. Conforme ilustrado na Figura 1–6, redes neurais podem ter muitas camadas onde cada conexão tem um certo peso dependendo da entrada. Esses pesos são frequentemente referidos como os parâmetros do modelo.

Figura 1–6. Uma rede neural consiste em camadas interconectadas de nós onde cada conexão é uma equação linear.

Usando essas redes neurais, o word2vec gera embeddings de palavras observando quais outras palavras tendem a aparecer próximas em uma determinada frase. Começamos atribuindo a cada palavra em nosso vocabulário um vetor de embedding, digamos de 50 valores para cada palavra inicializados com valores aleatórios. Então, em cada etapa de treinamento, como ilustrado na Figura 1–7, pegamos pares de palavras dos dados de treinamento e um modelo tenta prever se elas são ou não prováveis de serem vizinhas em uma frase.

Durante esse processo de treinamento, o word2vec aprende a relação entre as palavras e destila essa informação no embedding. Se duas palavras tendem a ter os mesmos vizinhos, seus embeddings estarão mais próximos um do outro e vice-versa. Examinaremos mais de perto o procedimento de treinamento do word2vec.

Figura 1–7. Uma rede neural é treinada para prever se duas palavras são vizinhas. Durante esse processo, os embeddings são atualizados para estarem alinhados com a verdade fundamental.

Os embeddings resultantes capturam o significado das palavras, mas o que exatamente isso significa? Para ilustrar esse fenômeno, vamos simplificar um pouco e imaginar que temos embeddings de várias palavras, a saber, “apple” e “baby”. Os embeddings tentam capturar o significado representando as propriedades das palavras. Por exemplo, a palavra “baby” pode ter uma pontuação alta nas propriedades “newborn” e “human” enquanto a palavra “apple” tem uma pontuação baixa nessas propriedades.

Como ilustrado na Figura 1–8, os embeddings podem ter muitas propriedades para representar o significado de uma palavra. Como o tamanho dos embeddings é fixo, suas propriedades são escolhidas para criar uma representação mental da palavra.

Figura 1–8. Os valores das embeddings representam propriedades que são usadas para representar palavras. Podemos simplificar demais imaginando que dimensões representam conceitos (o que não é verdade), mas isso ajuda a expressar a ideia.

Na prática, essas propriedades são frequentemente bastante obscuras e raramente se relacionam a uma única entidade ou conceito identificável por humanos. No entanto, juntas, essas propriedades fazem sentido para um computador e servem como uma boa maneira de traduzir a linguagem humana para a linguagem de computador.

As embeddings são extremamente úteis, pois nos permitem medir a similaridade semântica entre duas palavras. Usando várias métricas de distância, podemos julgar quão próxima uma palavra está de outra. Como ilustrado na Figura 1–9, se comprimíssemos essas embeddings em uma representação bidimensional, você notaria que palavras com significados semelhantes tendem a estar mais próximas.

Figura 1–9. Embeddings de palavras que são semelhantes estarão próximas umas das outras no espaço dimensional.

Tipos de Embeddings

Existem muitos tipos de embeddings, como word embeddings e sentence embeddings, que são usados para indicar diferentes níveis de abstração (palavra versus sentença), como ilustrado na Figura 1–10.

Bag-of-words, por exemplo, cria embeddings em nível de documento, pois representa o documento inteiro. Em contraste, word2vec gera embeddings apenas para palavras.

Ao longo do hands-on, as embeddings terão um papel central, pois são utilizadas em muitos casos de uso, como classificação, clustering, busca semântica e retrieval augmented generation (RAG).

Figura 1–10. Embeddings podem ser criados para diferentes tipos de entrada.

Codificação e Decodificação de Contexto com Attention

O processo de treinamento do word2vec cria representações estáticas e baixáveis de palavras. Por exemplo, a palavra “bank” sempre terá o mesmo embedding, independentemente do contexto em que é usada. No entanto, “bank” pode se referir tanto a um banco financeiro quanto à margem de um rio. Seu significado, e portanto seus embeddings, devem mudar dependendo do contexto.

Um passo na codificação deste texto foi alcançado através de redes neurais recorrentes (RNNs). Estas são variantes de redes neurais que podem modelar sequências como uma entrada adicional.

Para fazer isso, essas RNNs são usadas para duas tarefas, codificar ou representar uma sentença de entrada e decodificar ou gerar uma sentença de saída. A Figura 1–11 ilustra este conceito mostrando como uma sentença como “I love llamas” é traduzida para o holandês “Ik hou van lama’s.”

Figura 1–11. Duas redes neurais recorrentes (decodificador e codificador) traduzindo uma sequência de entrada do inglês para o holandês.

Cada passo nesta arquitetura é autoregressivo. Ao gerar a próxima palavra, esta arquitetura precisa consumir todas as palavras geradas anteriormente, como mostrado na Figura 1–12.

Figura 1–12. Cada token de saída anterior é usado como entrada para gerar o próximo token.

A etapa de codificação visa representar a entrada da melhor forma possível, gerando o contexto na forma de um embedding, que serve como entrada para o decodificador. Para gerar essa representação, são utilizados embeddings como entradas para palavras, o que significa que podemos usar word2vec para as representações iniciais. Na Figura 1–13, podemos observar esse processo. Note como as entradas são processadas sequencialmente, uma de cada vez, assim como a saída.

Figura 1–13. Usando embeddings de word2vec, é gerado um embedding de contexto que representa toda a sequência.

Esse embedding de contexto, no entanto, torna difícil lidar com sentenças mais longas, uma vez que é meramente um único embedding representando toda a entrada. Em 2014, uma solução chamada attention foi introduzida, melhorando significativamente a arquitetura original. Attention permite que um modelo se concentre em partes da sequência de entrada que são relevantes entre si (“atendam” umas às outras) e amplifiquem seu sinal, como mostrado na Figura 1–14. Attention determina seletivamente quais palavras são mais importantes em uma determinada sentença.

Por exemplo, a palavra de saída “lama’s” é holandesa para “llamas”, razão pela qual a atenção entre ambas é alta. Da mesma forma, as palavras “lama’s” e “I” têm menor atenção, pois não são tão relacionadas.

Figura 1–14. A atenção permite que um modelo “preste atenção” a certas partes das sequências que podem se relacionar mais ou menos umas com as outras.

Ao adicionar esses mecanismos de atenção à etapa do decodificador, o RNN pode gerar sinais para cada palavra de entrada na sequência relacionada ao potencial de saída. Em vez de passar apenas um embedding de contexto para o decodificador, os estados ocultos de todas as palavras de entrada são passados. Este processo é demonstrado na Figura 1–15.

Como resultado, durante a geração de “Ik hou van lama’s,” o RNN acompanha as palavras às quais mais presta atenção para realizar a tradução. Comparado ao word2vec, essa arquitetura permite representar a natureza sequencial do texto e o contexto em que ele aparece ao “prestar atenção” à frase inteira. Essa natureza sequencial, no entanto, impede a paralelização durante o treinamento do modelo.

Attention Is All You Need

O verdadeiro poder da atenção, e o que impulsiona as incríveis habilidades dos grandes modelos de linguagem, foi explorado pela primeira vez no famoso artigo “Attention is all you need” lançado em 2017. Os autores propuseram uma arquitetura de rede chamada Transformer, que era baseada exclusivamente no mecanismo de atenção e removia a rede recorrente que vimos anteriormente. Comparado à rede recorrente, o Transformer poderia ser treinado em paralelo, o que acelerou tremendamente o treinamento.

No Transformer, os componentes de codificação e decodificação são empilhados uns sobre os outros, como ilustrado na Figura 1–16. Essa arquitetura permanece autoregressiva, precisando consumir cada palavra gerada antes de criar uma nova palavra.

Figura 1–16. O Transformer é uma combinação de blocos de encoder e decoder empilhados, onde a entrada passa por cada encoder e decoder.

Agora, tanto os blocos de encoder quanto os de decoder girariam em torno da atenção em vez de utilizar um RNN com recursos de atenção. O bloco de encoder no Transformer consiste em duas partes, self-attention e uma rede neural feedforward, que são mostradas na Figura 1–17.

Figura 1–17. Um bloco de encoder gira em torno da self-attention para gerar representações intermediárias.

Comparado aos métodos anteriores de atenção, a self-attention pode atender a diferentes posições dentro de uma única sequência, representando assim a sequência de entrada de forma mais fácil e precisa, como ilustrado na Figura 1–18. Em vez de processar um token de cada vez, ela pode ser usada para olhar a sequência inteira de uma só vez.

Figura 1–18. A self-attention atende a todas as partes da sequência de entrada para que possa “olhar” tanto para frente quanto para trás em uma única sequência.

Comparado ao encoder, o decoder possui uma camada adicional que presta atenção à saída do encoder (para encontrar as partes relevantes da entrada). Conforme demonstrado na Figura 1–19, esse processo é semelhante ao RNN attention decoder que discutimos anteriormente.

Figura 1–19. O decoder possui uma camada de atenção adicional que presta atenção à saída do encoder.

Como mostrado na Figura 1–20, a camada de self-attention no decoder mascara posições futuras para que ela preste atenção apenas às posições anteriores, evitando o vazamento de informações ao gerar a saída.

Figura 1–20. Prestar atenção apenas aos tokens anteriores para evitar “olhar para o futuro”.

Juntos, esses blocos de construção criam a arquitetura Transformer e são a base de muitos modelos impactantes em Language AI, como BERT e GPT-1, que abordaremos mais adiante neste hands-on. Ao longo deste hands-on, a maioria dos modelos que usaremos são baseados em Transformers.

Modelos de Representação: Modelos Apenas de Encoder

O modelo Transformer original é uma arquitetura de encoder-decoder que serve bem para tarefas de tradução, mas não pode ser facilmente usado para outras tarefas, como classificação de texto.

Em 2018, uma nova arquitetura chamada Bidirectional Encoder Representations from Transformers (BERT) foi introduzida, podendo ser aproveitada para uma ampla variedade de tarefas e servindo como a base de Language AI nos anos seguintes. BERT é uma arquitetura apenas de encoder que foca na representação da linguagem, como ilustrado na Figura 1–21. Isso significa que ele usa apenas o encoder e remove o decoder completamente.

Figura 1–21. A arquitetura de um modelo BERT base com 12 encoders.

Esses blocos de encoder são os mesmos que vimos antes: self-attention seguido por redes neurais feedforward. A entrada contém um token adicional, o token [CLS] ou token de classificação, que é usado como a representação para toda a entrada. Frequentemente, usamos esse token [CLS] como a embedding de entrada para o fine-tuning do modelo em tarefas específicas, como classificação.

Treinar essas pilhas de encoders pode ser uma tarefa difícil que o BERT aborda adotando uma técnica chamada masked language modeling. Como mostrado na Figura 1–22, esse método mascara uma parte da entrada para o modelo prever. Essa tarefa de previsão é difícil, mas permite que o BERT crie representações (intermediárias) mais precisas da entrada.

Figura 1–22. Treinar um modelo BERT usando masked language modeling.

Essa arquitetura e procedimento de treinamento tornam o BERT e arquiteturas relacionadas incríveis na representação da linguagem contextual. Modelos do tipo BERT são comumente usados para transfer learning, que envolve primeiro pré-treinar o modelo para language modeling e depois fazer o fine-tuning para uma tarefa específica. Por exemplo, ao treinar o BERT em toda a Wikipedia, ele aprende a entender a natureza semântica e contextual do texto. Então, como mostrado na Figura 1–23, podemos usar esse modelo pré-treinado para fazer o fine-tuning para uma tarefa específica, como classificação de texto.

Figura 1–23. Após o pré-treinamento do BERT no masked language model, nós o ajustamos para tarefas específicas.

Modelos pré-treinados têm a vantagem de já terem passado pela maior parte do processo de treinamento, o que torna o fine-tuning para tarefas específicas menos intensivo em termos de computação e dados. Modelos como o BERT, por exemplo, geram embeddings em várias etapas da sua arquitetura, tornando-se eficientes para extração de características sem a necessidade de ajustes para cada tarefa.

No hands-on, os modelos apenas com encoder serão chamados de modelos de representação, focados em representar a linguagem através de embeddings e que geralmente não geram texto. Já os modelos generativos, baseados em decoder, são focados na geração de texto e não são usados para criar embeddings. Nas imagens, modelos de representação serão indicados com um ícone de vetor, enquanto os generativos serão representados com um ícone de chat, diferenciando suas funções.

Modelos Generativos: Modelos Apenas com Decoder

Em 2018, uma arquitetura apenas com decoder foi introduzida para tarefas generativas, chamada Generative Pre-trained Transformer (GPT), agora referida como GPT-1. Semelhante ao BERT, o GPT-1 utiliza blocos de decoder empilhados, mas com foco na geração de texto. O GPT-1 foi treinado em um grande corpus de 7.000 livros e páginas da web, resultando em um modelo com 117 milhões de parâmetros, cada um representando um aspecto da compreensão do modelo sobre a linguagem.

Com o passar do tempo, os modelos foram ficando maiores e mais potentes. O GPT-2 expandiu para 1,5 bilhões de parâmetros, e o GPT-3 aumentou ainda mais, alcançando 175 bilhões de parâmetros, demonstrando uma evolução constante nas capacidades e desempenho dos modelos de linguagem.

Figura 1–24. A arquitetura de um GPT-1. Ele utiliza uma arquitetura apenas de decodificador e remove o bloco de atenção do codificador.
Figura 1–25. Os modelos GPT cresceram rapidamente em tamanho a cada iteração.

Modelos generativos baseados em decoders, especialmente os maiores, são comumente chamados de large language models (LLMs). Esses LLMs não se limitam apenas a modelos generativos, mas também incluem modelos de representação (baseados em encoders). Modelos generativos funcionam como máquinas de sequência para sequência, recebendo um texto e tentando completá-lo automaticamente. No entanto, o verdadeiro potencial desses modelos foi revelado ao serem treinados como chatbots, capazes de responder perguntas em vez de apenas completar textos.

Ao ajustar esses modelos, podemos criar modelos de instrução ou chat, que respondem a consultas e seguem direções específicas. Esses modelos geram respostas a prompts fornecidos pelo usuário, e por isso são frequentemente chamados de modelos de completude.

Figura 1–26. LLMs Generativos recebem uma entrada e tentam completá-la. Com modelos de instrução, isso vai além de apenas autocompletar e tenta responder à pergunta.

Uma parte vital desses modelos de completamento é algo chamado de comprimento de contexto ou janela de contexto. O comprimento de contexto representa o número máximo de tokens que o modelo pode processar, como mostrado na Figura 1–27. Uma janela de contexto grande permite que documentos inteiros sejam passados para o LLM. Note que, devido à natureza autoregressiva desses modelos, o comprimento de contexto atual aumentará à medida que novos tokens forem gerados.

Figura 1–27. O comprimento de contexto é o máximo de contexto que um LLM pode lidar.

O Ano da IA Generativa

LLMs tiveram um impacto tremendo no campo e levaram alguns a chamar 2023 de O Ano da IA Generativa com o lançamento, adoção e cobertura da mídia do ChatGPT (GPT-3.5). Quando nos referimos ao ChatGPT, estamos na verdade falando sobre o produto e não sobre o modelo subjacente. Quando foi lançado pela primeira vez, era alimentado pelo LLM GPT-3.5 e desde então cresceu para incluir várias variantes mais performáticas, como o GPT-4.

GPT-3.5 não foi o único modelo que fez seu impacto no Ano da IA Generativa. Como ilustrado na Figura 1–28, tanto LLMs de código aberto quanto proprietários chegaram ao público em um ritmo incrível. Esses modelos base de código aberto são frequentemente referidos como modelos de fundação e podem ser ajustados para tarefas específicas, como seguir instruções.

Figura 1–28. Uma visão abrangente do Ano da IA Generativa. Note que muitos modelos ainda estão ausentes desta visão geral!

Além da amplamente popular arquitetura Transformer, novas arquiteturas promissoras surgiram, como Mamba e RWKV. Essas novas arquiteturas tentam alcançar o desempenho do Transformer com vantagens adicionais, como janelas de contexto maiores ou inferência mais rápida.

Esses desenvolvimentos exemplificam a evolução do campo e destacam 2023 como um ano verdadeiramente agitado para a IA. Foi necessário todo o nosso esforço apenas para acompanhar os muitos desenvolvimentos, tanto dentro quanto fora da IA de Linguagem.

A Definição Mutável de um “Large Language Model”

Ao longo da história recente da IA de Linguagem, observamos que modelos generativos baseados em decoders, como os Transformers, são geralmente classificados como large language models (LLMs), especialmente quando são grandes em termos de parâmetros. No entanto, essa definição é bastante limitada. Por exemplo, se criarmos um modelo com as mesmas capacidades do GPT-3, mas 10 vezes menor, ele ainda se enquadraria como LLM? E se criarmos um modelo do tamanho do GPT-4 que realiza classificação de texto, mas sem capacidade generativa, ele seria um LLM?

Essas questões mostram como o termo “LLM” pode ser restritivo. O nome que damos a um modelo não altera seu funcionamento. Com o lançamento de novos modelos, a definição de LLM tende a evoluir, e o que consideramos grande hoje pode ser pequeno amanhã. Além disso, para nós, large language models incluem não apenas modelos generativos, mas também aqueles que podem ser executados em hardware de consumo e não geram texto.

Portanto, além dos modelos generativos, também exploraremos modelos com menos de 1 bilhão de parâmetros, como modelos de embedding, de representação e até bag-of-words, que podem potencializar os LLMs.

No paradigma de treinamento tradicional, um modelo é geralmente treinado para uma tarefa específica, como classificação, o que é considerado um processo de uma etapa.

Figura 1–29. O aprendizado de máquina tradicional envolve uma única etapa: treinar um modelo para uma tarefa-alvo específica, como classificação ou regressão.

Criar LLMs, em contraste, tipicamente consiste em pelo menos duas etapas:

Modelagem de linguagem

A primeira etapa, chamada de pré-treinamento, leva a maior parte do tempo de computação e treinamento. Um LLM é treinado em um vasto corpus de texto da internet, permitindo que o modelo aprenda gramática, contexto e padrões de linguagem. Esta fase ampla de treinamento ainda não é direcionada a tarefas ou aplicações específicas além de prever a próxima palavra. O modelo resultante é frequentemente referido como modelo de fundação ou modelo base. Esses modelos geralmente não seguem instruções.

Ajuste fino

A segunda etapa, ajuste fino ou às vezes pós-treinamento, envolve usar o modelo previamente treinado e treiná-lo ainda mais em uma tarefa mais específica. Isso permite que o LLM se adapte a tarefas específicas ou exiba comportamentos desejados. Por exemplo, poderíamos ajustar um modelo base para ter um bom desempenho em uma tarefa de classificação ou para seguir instruções. Isso economiza enormes quantidades de recursos porque a fase de pré-treinamento é bastante cara e geralmente requer dados e recursos computacionais que estão fora do alcance da maioria das pessoas e organizações. Por exemplo, o Llama 2 foi treinado em um conjunto de dados contendo 2 trilhões de tokens. Imagine a computação necessária para criar esse modelo!

Qualquer modelo que passe pela primeira etapa, pré-treinamento, consideramos um modelo pré-treinado, o que também inclui modelos ajustados. Esta abordagem de treinamento em duas etapas é visualizada na Figura 1–30.

Figura 1–30. Comparado ao machine learning tradicional, o treinamento de LLM adota uma abordagem em várias etapas. Passos adicionais de fine-tuning podem ser adicionados para alinhar ainda mais o modelo com as preferências do usuário.

Aplicações de Large Language Models: O Que os Torna Tão Úteis?

A natureza dos LLMs os torna adequados para uma ampla gama de tarefas. Com a geração de texto e prompting, parece quase que a sua imaginação é o limite. Para ilustrar, vamos explorar algumas tarefas e técnicas comuns:

Detectar se uma avaliação deixada por um cliente é positiva ou negativa

Isso é uma classificação (supervisionada) e pode ser tratada tanto com modelos apenas de encoder quanto de decoder.

Desenvolver um sistema para encontrar tópicos comuns em problemas de tickets

Isso é uma classificação (não supervisionada) para a qual não temos rótulos predefinidos. Podemos utilizar modelos apenas de encoder para realizar a classificação em si e modelos apenas de decoder para rotular os tópicos.

Construir um sistema para recuperação e inspeção de documentos relevantes

Um componente principal dos sistemas de modelos de linguagem é a capacidade de adicionar recursos externos de informação. Usando busca semântica, podemos construir sistemas que nos permitem acessar e encontrar facilmente informações para um LLM usar. Melhore seu sistema criando ou ajustando um modelo de embedding customizado.

Construir um chatbot LLM que possa utilizar recursos externos, como ferramentas e documentos

Isso é uma combinação de técnicas que demonstra como o verdadeiro poder dos LLMs pode ser encontrado através de componentes adicionais. Métodos como engenharia de prompt, geração aumentada por recuperação e ajuste de um LLM são todas peças do quebra-cabeça dos LLMs.

Construir um LLM capaz de escrever receitas com base em uma foto mostrando os produtos na sua geladeira

Isso é uma tarefa multimodal onde o LLM recebe uma imagem e raciocina sobre o que vê. Os LLMs estão sendo adaptados para outras modalidades, como Visão, o que abre uma ampla variedade de casos de uso interessantes.

As aplicações de LLM são incrivelmente satisfatórias de criar, pois são parcialmente limitadas pelas coisas que você pode imaginar. À medida que esses modelos se tornam mais precisos, usá-los na prática para criar casos de uso criativos, como jogos de interpretação de papéis e escrita de livros infantis, tornam-se cada vez mais divertidos.

Desenvolvimento e Uso Responsável de LLMs

O impacto dos LLMs tem sido e provavelmente continuará sendo significativo devido à sua ampla adoção. À medida que exploramos as incríveis capacidades dos LLMs, é importante manter em mente suas implicações sociais e éticas. Vários pontos-chave a considerar:

Viés e justiça

Os LLMs são treinados em grandes quantidades de dados que podem conter vieses. Os LLMs podem aprender com esses vieses, começar a reproduzi-los e potencialmente amplificá-los. Como os dados nos quais os LLMs são treinados raramente são compartilhados, permanece incerto quais vieses potenciais eles podem conter, a menos que você os teste.

Transparência e responsabilidade

Devido às incríveis capacidades dos LLMs, nem sempre é claro quando você está conversando com um humano ou um LLM. Como tal, o uso de LLMs ao interagir com humanos pode ter consequências não intencionais quando não há um humano no loop. Por exemplo, aplicativos baseados em LLM usados no campo médico podem ser regulamentados como dispositivos médicos, pois podem afetar o bem-estar de um paciente.

Geração de conteúdo prejudicial

Um LLM não necessariamente gera conteúdo verdadeiro e pode, com confiança, produzir texto incorreto. Além disso, eles podem ser usados para gerar fake news, artigos e outras fontes de informação enganosas.

Propriedade intelectual

O output de um LLM é sua propriedade intelectual ou do criador do LLM? Quando o output é semelhante a uma frase nos dados de treinamento, a propriedade intelectual pertence ao autor dessa frase? Sem acesso aos dados de treinamento, permanece incerto quando material protegido por direitos autorais está sendo usado pelo LLM.

Regulamentação

Devido ao enorme impacto dos LLMs, os governos estão começando a regulamentar aplicações comerciais. Um exemplo é o European AI Act, que regulamenta o desenvolvimento e a implantação de modelos de fundação, incluindo LLMs.

À medida que você desenvolve e usa LLMs, queremos enfatizar a importância das considerações éticas e incentivá-lo a aprender mais sobre o uso seguro e responsável de LLMs e sistemas de IA em geral.

Recursos Limitados São Tudo o Que Você Precisa

Os recursos de computação mencionados até agora referem-se, principalmente, às GPUs disponíveis em seu sistema. Uma GPU robusta tornará o treinamento e o uso de LLMs muito mais rápidos e eficientes. Um fator essencial na escolha de uma GPU é a quantidade de VRAM (memória de vídeo) disponível. Quanto mais VRAM, melhor, pois alguns modelos não podem ser utilizados sem memória suficiente.

Como o treinamento e o fine-tuning de LLMs pode ser caro em termos de GPU, aqueles sem GPUs poderosas são frequentemente chamados de GPU-poor. Isso reflete a demanda por recursos computacionais para treinar grandes modelos. Por exemplo, a Meta usou GPUs A100–80 GB para treinar a família de modelos Llama 2, e o custo total para aluguel dessas GPUs pode ultrapassar $5 milhões.

Infelizmente, não há uma regra fixa para determinar quanta VRAM é necessária, pois isso varia conforme a arquitetura, tamanho do modelo, compressão, tamanho do contexto e o backend utilizado. Este hands-on é destinado aos GPU-poor, com o objetivo de utilizar modelos que podem ser executados sem GPUs caras ou grandes orçamentos. O código será disponibilizado em instâncias do Google Colab, onde uma instância gratuita fornece uma GPU T4 com 16 GB de VRAM, o mínimo recomendado para trabalhar com LLMs.

Modelos Proprietários, Privados

LLMs de código fechado são modelos que não têm seus pesos e arquitetura compartilhados com o público. Eles são desenvolvidos por organizações específicas com seu código subjacente mantido em segredo. Exemplos de tais modelos incluem o GPT-4 da OpenAI e o Claude da Anthropic. Esses modelos proprietários geralmente são apoiados por um suporte comercial significativo e foram desenvolvidos e integrados dentro de seus serviços.

Você pode acessar esses modelos através de uma interface que se comunica com o LLM, chamada API (interface de programação de aplicativos), como ilustrado na Figura 1–31. Por exemplo, para usar o ChatGPT em Python, você pode usar o pacote da OpenAI para interagir com o serviço sem acessá-lo diretamente.

Figura 1–31. LLMs de código fechado são acessados por uma interface (API). Como resultado, detalhes do próprio LLM, incluindo seu código e arquitetura, não são compartilhados com o usuário.

Um grande benefício dos modelos proprietários é que o usuário não precisa ter uma GPU potente para usar o LLM. O provedor cuida da hospedagem e execução do modelo e geralmente possui mais capacidade computacional disponível. Não é necessário ter expertise em hospedagem e uso do modelo, o que reduz significativamente a barreira de entrada. Além disso, esses modelos tendem a ser mais performáticos do que seus equivalentes open source devido ao investimento significativo dessas organizações.

Um ponto negativo é que pode ser um serviço caro. O provedor gerencia o risco e os custos de hospedar o LLM, o que muitas vezes se traduz em um serviço pago. Além disso, como não há acesso direto ao modelo, não há método para ajustá-lo você mesmo. Por fim, seus dados são compartilhados com o provedor, o que não é desejável em muitos casos de uso comuns, como o compartilhamento de dados de pacientes.

Open Models

LLMs abertos são modelos que compartilham seus pesos e arquitetura com o público para uso. Eles ainda são desenvolvidos por organizações específicas, mas frequentemente compartilham seu código para criação ou execução do modelo localmente — com diferentes níveis de licenciamento que podem ou não permitir o uso comercial do modelo. Command R da Cohere, os modelos Mistral, Phi da Microsoft e os modelos Llama da Meta são todos exemplos de modelos abertos.

NOTA

Existem discussões em andamento sobre o que realmente representa um modelo open source. Por exemplo, alguns modelos compartilhados publicamente têm uma licença comercial permissiva, o que significa que o modelo não pode ser usado para fins comerciais. Para muitos, essa não é a verdadeira definição de open source, que afirma que o uso desses modelos não deve ter restrições. Da mesma forma, os dados nos quais um modelo é treinado, bem como seu código-fonte, raramente são compartilhados.

Você pode baixar esses modelos e usá-los em seu dispositivo, desde que tenha uma GPU potente que possa lidar com esses tipos de modelos, como mostrado na Figura 1–32.

Figura 1–32. LLMs open source são diretamente utilizados pelo usuário. Como resultado, detalhes do próprio LLM, incluindo seu código e arquitetura, são compartilhados com o usuário.

Uma grande vantagem desses modelos locais é que você, o usuário, tem controle total sobre o modelo. Você pode usar o modelo sem depender da conexão API, ajustá-lo e processar dados sensíveis através dele. Você não depende de nenhum serviço e tem total transparência dos processos que levam à saída do modelo. Esse benefício é ampliado pelas grandes comunidades que possibilitam esses processos, como a Hugging Face, demonstrando as possibilidades de esforços colaborativos.

Um ponto negativo é que você precisa de hardware potente para executar esses modelos e ainda mais quando treiná-los ou ajustá-los. Além disso, é necessário conhecimento específico para configurar e usar esses modelos.

Geralmente, preferimos usar modelos open source sempre que possível. A liberdade que isso proporciona para experimentar opções, explorar o funcionamento interno e usar o modelo localmente, sem dúvida, oferece mais benefícios do que usar LLMs proprietários.

Frameworks Open Source

Comparados aos LLMs de código fechado, os LLMs open source exigem que você use certos pacotes para executá-los. Em 2023, muitos pacotes e frameworks diferentes foram lançados que, cada um à sua maneira, interagem e fazem uso dos LLMs. Navegar por centenas e centenas de frameworks potencialmente úteis não é a experiência mais agradável.

Em vez de tentar cobrir todos os frameworks de LLM existentes (são muitos e continuam a crescer em número), nosso objetivo é fornecer uma base sólida para aproveitar os LLMs. A ideia é que você possa facilmente aprender a usar a maioria dos outros frameworks, pois todos funcionam de maneira muito semelhante.

A intuição que tentamos realizar é um componente importante disso. Se você tiver uma compreensão intuitiva não apenas dos LLMs, mas também de como usá-los na prática com frameworks comuns, expandir para outros deve ser uma tarefa simples.

Mais especificamente, focamos em pacotes de backend. Estes são pacotes sem uma GUI (interface gráfica do usuário) que são criados para carregar e executar qualquer LLM de forma eficiente em seu dispositivo, como llama.cpp, LangChain e o núcleo de muitos frameworks, Hugging Face Transformers.

Gerando Seu Primeiro Texto

Um componente importante do uso de modelos de linguagem é selecioná-los. A principal fonte para encontrar e baixar LLMs é o Hugging Face Hub. Hugging Face é a organização por trás do conhecido pacote Transformers, que há anos impulsiona o desenvolvimento de modelos de linguagem em geral.

No momento da escrita, você encontrará mais de 800.000 modelos na plataforma do Hugging Face para muitos propósitos diferentes, desde LLMs e modelos de visão computacional até modelos que trabalham com áudio e dados tabulares. Aqui, você pode encontrar quase qualquer LLM open source.

Embora exploremos todos os tipos de modelos ao longo dos próximos hands-on, vamos começar nossas primeiras linhas de código com um modelo generativo. O principal modelo generativo que usamos é o Phi-3-mini, que é um modelo relativamente pequeno (3,8 bilhões de parâmetros), mas bastante eficiente. Devido ao seu tamanho reduzido, o modelo pode ser executado em dispositivos com menos de 8 GB de VRAM. Se você realizar quantização poderá usar até menos de 6 GB de VRAM. Além disso, o modelo é licenciado sob a licença MIT, o que permite que o modelo seja usado para fins comerciais sem restrições!

Vamos começar! Quando você usa um LLM, dois modelos são carregados:

  • O próprio modelo generativo
  • Seu tokenizer subjacente

O tokenizer é responsável por dividir o texto de entrada em tokens antes de alimentá-lo ao modelo generativo. Você pode encontrar o tokenizer e o modelo no site da Hugging Face e só precisa passar os IDs correspondentes. Neste caso, usamos “microsoft/Phi-3-mini-4k-instruct” como o caminho principal para o modelo.

Podemos usar transformers para carregar tanto o tokenizer quanto o modelo. Note que assumimos que você tem uma GPU NVIDIA (device_map=”cuda”), mas você pode escolher um dispositivo diferente. Se você não tiver acesso a uma GPU, pode usar os notebooks gratuitos do Google Colab:


from transformers import AutoModelForCausalLM, AutoTokenizer

model = AutoModelForCausalLM.from_pretrained(
"microsoft/Phi-3-mini-4k-instruct",
device_map="cuda",
torch_dtype="auto",
trust_remote_code=True,
)

tokenizer = AutoTokenizer.from_pretrained("microsoft/Phi-3-mini-4k-instruct")

Executar o código iniciará o download do modelo e, dependendo da sua conexão com a internet, pode levar alguns minutos.

Embora agora tenhamos o suficiente para começar a gerar texto, há um truque interessante no transformers que simplifica o processo, nomeadamente o transformers.pipeline. Ele encapsula o modelo, o tokenizer e o processo de geração de texto em uma única função:

from transformers import pipeline

generator = pipeline(
"text-generation",
model=model,
tokenizer=tokenizer,
return_full_text=False,
max_new_tokens=500,
do_sample=False
)

Os seguintes parâmetros merecem destaque:

return_full_text

Ao definir este parâmetro como False, o prompt não será retornado, apenas a saída do modelo.

max_new_tokens

O número máximo de tokens que o modelo irá gerar. Ao definir um limite, evitamos saídas longas e desajeitadas, já que alguns modelos podem continuar gerando saída até atingirem sua janela de contexto.

do_sample

Se o modelo usa uma estratégia de amostragem para escolher o próximo token. Ao definir este parâmetro como False, o modelo sempre selecionará o próximo token mais provável.

Para gerar nosso primeiro texto, vamos instruir o modelo a contar uma piada sobre galinhas. Para isso, formatamos o prompt em uma lista de dicionários onde cada dicionário se relaciona a uma entidade na conversa. Nosso papel é o de “user” e usamos a chave “content” para definir nosso prompt:

# O prompt (entrada do usuário / consulta)
messages = [
{"role": "user", "content": "Crie uma piada engraçada sobre galinhas."}
]

# Gerar saída
output = generator(messages)
print(output[0]["generated_text"])

Por que as galinhas não gostam de ir à academia? Porque elas não conseguem quebrar a egg-sistência

E é isso! O primeiro texto gerado neste hands-on foi uma piada decente sobre galinhas.

Conclusão

Neste primeiro hands-on sobre GenAI, mergulhamos no impacto revolucionário que os LLMs tiveram no campo da IA de Linguagem. Isso mudou significativamente nossa abordagem para tarefas como tradução, classificação, sumarização e muito mais. Por meio de uma história recente da IA ​​de linguagem, exploramos os fundamentos de vários tipos de LLMs, desde uma representação simples de saco de palavras até representações mais complexas usando redes neurais.

Discutimos o mecanismo de atenção como um passo em direção à codificação do contexto dentro dos modelos, um componente vital do que torna os LLMs tão capazes. Abordamos duas categorias principais de modelos que usam esse mecanismo incrível: modelos de representação (somente codificador) como BERT e modelos generativos (somente decodificador) como a família de modelos GPT. Ambas as categorias são consideradas grandes modelos de linguagem.

No geral, o hands-on forneceu uma visão geral do cenário da IA ​​de linguagem, incluindo suas aplicações, implicações sociais e éticas e os recursos necessários para executar tais modelos. Terminamos gerando nosso primeiro texto usando Phi-3.

Nas próximas postagens, você aprenderá sobre alguns processos subjacentes. Começamos explorando a tokenização e as incorporações em dois componentes frequentemente subestimados, mas vitais, do campo da IA ​​de linguagem. O que se segue é uma análise aprofundada dos modelos de linguagem, onde você descobrirá os métodos precisos usados ​​para gerar texto.

O código fonte do nosso hands-on está disponível em meu GitHub, caso você tenha dúvidas, sugestões ou críticas, estou sempre a disposição no meu LinkedIn ou Twitter, será um prazer conversarmos. Se você achou esse lab útil, eu realmente aprecio se você recomendar este artigo compartilhando-o com seus amigos e colegas. Vou ficando por aqui, obrigado e até breve!

--

--

Nelson Frugeri, Jr

🤖 I productize and platformize the Data Science and Artificial Intelligence 🚀