Conceitos e considerações importantes para desenvolvedores que criam soluções generativas de IA
Os Large Language Models (LLMs) são incríveis, mas mesmo eles têm suas limitações. Os desenvolvedores precisam entender essas limitações, o que os LLMs são capazes de "fora da caixa" e como ajustá-los para obter os melhores resultados para as soluções de IA generativas que estão construindo. Este artigo identifica vários desafios e fatores limitantes e explica maneiras comuns de superar esses desafios e assumir o controle do processo de geração de conteúdo, independentemente do tipo de recursos de IA generativa que você está criando em seu aplicativo.
Desafios de engenharia ao trabalhar com LLMs
Os desafios ou limitações mais significativos a serem observados ao trabalhar com LLMs:
Ponto de corte de conhecimento - Devido ao alto custo de treinamento de um LLM, seu corpo de conhecimento é limitado ao que eles foram treinados em um determinado momento no tempo. Sem plug-ins ou outras acomodações, eles não têm acesso a informações em tempo real, nem a dados privados.
Alucinação - Um LLM usa probabilidades estatísticas e um pouco de aleatoriedade para gerar informações. Existem mecanismos para manter as respostas geradas alinhadas à intenção do ser humano nas perguntas que são feitas e nas informações em que foram treinadas, mas é possível que criem respostas que não sejam precisas.
Transparência - Mais uma vez, devido à forma como os modelos são treinados, eles não têm mais acesso ao conhecimento básico em que foram treinados. E mesmo que o fizessem, não há garantia de que as informações fossem verdadeiras e fundamentadas em primeiro lugar. Além disso, não há nenhuma etapa de verificação para garantir que a resposta gerada seja precisa.
Nenhum conhecimento específico de domínio - Semelhante ao "corte de conhecimento", se você tem informações privadas, como documentos internos da empresa, o LLM não foi treinado sobre essas informações e, portanto, não tem conhecimento específico de domínio.
O que você pode fazer para mitigar os possíveis desafios ou problemas com LLMs e obter os melhores resultados possíveis para ajudar seus usuários e sua organização? Comece entendendo as maneiras pelas quais você pode complementar de onde o LLM está obtendo seus dados.
Entendendo onde os LLMs obtêm suas informações
Um bom ponto de partida para obter os melhores resultados de um LLM é entender onde ou como os LLMs obtêm suas informações. As categorias a seguir representam diferentes abordagens sobre como os LLMs interagem com várias fontes de informação para gerar respostas.
Retrieval-Off Generation (ROG) - É a forma tradicional de operação dos LLMs, onde o modelo gera respostas baseadas apenas no conhecimento em que foi treinado, sem acessar ou recuperar nenhuma informação externa durante o processo de geração. O conhecimento do modelo é estático, limitado ao que foi incluído em seus dados de treinamento até a data de corte. Além da escrita criativa, ele pode responder perguntas sobre informações prontamente disponíveis na internet.
Retrieval-Augmented Generation (RAG) - Combina os recursos generativos dos LLMs com a capacidade de recuperar informações de bancos de dados ou documentos externos em tempo real. O modelo consulta uma fonte externa para encontrar informações relevantes, que ele usa para informar sua resposta. Essa abordagem permite que o modelo forneça informações mais precisas e atualizadas do que poderia apenas com seu conhecimento pré-treinado. Os casos de uso incluem verificação de fatos, resposta a perguntas com base em dados em tempo real ou dados privados específicos do domínio.
Geração Centrada na Recuperação (RCG) - Coloca ainda mais ênfase no conteúdo recuperado externamente, muitas vezes estruturando respostas em torno das informações obtidas de fontes externas. O modelo pode incorporar diretamente grandes segmentos de texto recuperado em suas saídas, editando-os ou anotando-os para se ajustar à consulta do usuário. Essa abordagem pode ser vista como um híbrido entre métodos baseados em recuperação e generativos, onde o equilíbrio pode favorecer fortemente as informações recuperadas em detrimento das próprias capacidades generativas do modelo. Os casos de uso incluem a sumarização de um documento mais longo, assistência à pesquisa para fornecer comparações e explorações temáticas em vários documentos semelhantes e compilação ou agrupamento de diferentes fontes de material em uma produção combinada.
Um bom exemplo de Retrieval-Off Generation (ROG) é o ChatGPT. Por outro lado, se necessário, o Copilot (via Bing) estende o LLM usando fontes externas de fontes de notícias (e fornecendo links para essas fontes).
À primeira vista, a Geração Aumentada de Recuperação (RAG) e a Geração Centrada em Recuperação (RCG) soam semelhantes porque ambas envolvem a integração de informações externas no processo de geração da linguagem. No entanto, eles diferem na forma como priorizam e utilizam as informações recuperadas dentro do processo de geração.
Em sistemas RAG, a recuperação de dados externos é usada para aumentar as capacidades generativas de um modelo de linguagem pré-treinado. As informações recuperadas fornecem mais contexto ou dados específicos que o modelo usa para informar suas respostas. Aqui, o aspecto generativo do modelo de linguagem permanece central para a resposta, enquanto os dados recuperados atuam como um elemento de suporte para aumentar a precisão ou a profundidade.
Os sistemas RCG, por outro lado, dão maior ênfase à própria informação recuperada. Nesses sistemas, os dados recuperados geralmente são a peça central da resposta, com o papel do modelo generativo principalmente para refinar, formatar ou melhorar ligeiramente o texto recuperado. Essa abordagem é usada particularmente quando a precisão e a relevância direta da informação são primordiais, e menos síntese ou extrapolação criativa é necessária.
Os mecanismos de recuperação externa de dados que alimentam tanto o RAG quanto o RCG são discutidos em artigos sobre armazenamento vetorizado de incorporações de documentos versus ajuste fino de um LLM, as duas abordagens predominantes para complementar o conhecimento disponível para o LLM com base em seu treinamento inicial.
Compreender as distinções entre modelos de recuperação pode ajudar na escolha da abordagem certa para aplicações específicas, equilibrando a necessidade de síntese criativa versus a necessidade de precisão e fidelidade ao material de origem.
Entendendo os fatores que influenciam como a inferência funciona
Como você provavelmente está familiarizado com a interface de usuário baseada na Web do ChatGPT, entender como ele funciona para responder a perguntas pode ajudá-lo a entender conceitos que serão vitais ao criar recursos de IA generativa em seus próprios aplicativos.
Quando um usuário conversa com o ChatGPT, o design da interface do usuário dá a ilusão de uma sessão de bate-papo de longa duração que mantém o estado ao longo de várias trocas de ida e volta entre você e o LLM. Na realidade, para uma determinada sessão de bate-papo, todos os prompts e todas as respostas do LLM (também conhecidas como conclusões) são enviadas a cada novo prompt. Assim, à medida que sua conversa cresce, você está enviando cada vez mais texto para o LLM processar – todos os prompts e conclusões anteriores. O ChatGPT usa todo o contexto da sessão de bate-papo – não apenas o prompt atual – ao compor uma resposta ao prompt atual. Toda a sessão de bate-papo é chamada de janela de contexto.
Há um limite de comprimento de janela de contexto dependendo da versão do ChatGPT com a qual você trabalha. Qualquer parte da conversa de bate-papo que exceda o limite de comprimento da janela de contexto será ignorada ao redigir uma resposta ao prompt mais recente.
Conversas longas podem parecer uma boa ideia no início, mas longas janelas de contexto podem afetar a quantidade de computação necessária para processar o prompt e compor uma conclusão. Isso afeta a latência da resposta e quanto custa para a OpenAI processar a solicitação.
Qual é o limite da janela de contexto do ChatGPT? Ou melhor, com quantas palavras o ChatGPT pode trabalhar? O limite da janela de contexto depende do modelo, da versão e da edição do LLM com o qual você está trabalhando. Além disso, os comprimentos de contexto são medidos em tokens, não em palavras. Os tokens são as menores unidades de texto que o modelo pode entender e gerar. Essas unidades podem ser palavras, partes de palavras (como sílabas ou caules) ou até mesmo caracteres individuais. Os tokens estão no centro do processamento de linguagem natural (NLP).
O uso de tokens impacta duas considerações importantes para os desenvolvedores:
- O limite máximo da janela de contexto
- O preço por prompt e conclusão
O que é tokenização?
"Tokenização" é o processo de conversão de texto em tokens. É uma etapa crucial na preparação de dados para treinamento ou inferência (o processo de compor conclusões com base em prompts) com um LLM. O processo envolve várias etapas, incluindo a divisão de texto complexo em partes gerenciáveis (tokens), que o modelo pode processar. Esse processo pode ser simples, como dividir o texto por espaços e pontuação, ou mais complexo, envolvendo algoritmos sofisticados para lidar com diferentes linguagens, morfologias (a estrutura das palavras) e sintaxes (a disposição das palavras). Pesquisadores e desenvolvedores de LLM decidem sobre o método de tokenização com base no que estão tentando realizar. A OpenAI tem uma página útil que explica mais sobre tokenização e até tem uma calculadora que ilustra como uma frase ou parágrafo se divide em tokens.
Como a nota na parte inferior da página OpenAI Tokenizer afirma que, em textos típicos em inglês, um token é equivalente a cerca de quatro caracteres. Isso significa que, em média, 100 tokens são aproximadamente iguais a 75 palavras, ou três quartos de uma palavra por token.
A página OpenAI Tokenizer também fala sobre tiktoken, um pacote para Python e JavaScript que permite estimar programaticamente quantos tokens você usará para um determinado prompt enviado para a API OpenAI.
O uso do token afeta o faturamento
Cada API do Azure OpenAI tem uma metodologia de cobrança diferente. Para processar e gerar texto com a API de Conclusão de Bate-papo, você é cobrado com base no número de tokens enviados como um prompt e no número de tokens gerados como resultado (conclusão).
Cada modelo de LLM (ex. gpt-3.5, gpt-3.5-turbo, gpt-4, etc.) geralmente tem um preço diferente, que reflete a quantidade de computação necessária para processar e gerar tokens. Muitas vezes, o preço é apresentado como "preço por 1.000 tokens" ou "preço por um milhão de tokens".
Esse modelo de preços tem um impacto significativo na forma como você projeta as interações do usuário e na quantidade de pré e pós-processamento adicionado.
Sistema versus prompts do usuário
Até este ponto, a discussão se concentrou apenas em "prompts do usuário" – os prompts que compõem o intercâmbio entre um usuário e o ChatGPT.
A OpenAI introduziu o "prompt do sistema" (também conhecido como "instruções personalizadas"), que é um conjunto abrangente de instruções que você define e é adicionado a todas as suas conversas de bate-papo. Pense nisso como um conjunto de metainstruções que você deseja que o LLM sempre observe cada vez que você iniciar uma nova sessão de bate-papo. Por exemplo, você pode definir o prompt do sistema para "sempre responder na forma poética de haicai". A partir desse ponto, cada novo prompt para o ChatGPT resulta em um haicai contendo a resposta.
Embora "responder em forma de haicai" não seja um exemplo útil, ele ilustra a ideia de que você pode influenciar a conclusão de um LLM em seu prompt modificando o próprio prompt.
Por que você deseja modificar o prompt do usuário? Se você está criando um recurso ou aplicativo de IA generativa para um público profissional, que pode incluir funcionários da empresa, clientes e parceiros, sem dúvida você vai querer adicionar proteções para limitar o escopo de tópicos ou domínios que é permitido responder.
Mas modificar o prompt do usuário é apenas um método para melhorar a experiência de geração de texto para os usuários.
Métodos para melhorar a experiência de geração de texto para usuários no ChatGPT
Para melhorar os resultados da geração de texto, os desenvolvedores se limitam a simplesmente melhorar o prompt, e há muitas técnicas de engenharia prontas que podem ajudar. No entanto, se você estiver criando seu próprio aplicativo de IA generativa, há várias maneiras de melhorar a experiência de geração de texto para os usuários, e convém experimentar a implementação de todas elas:
- Modificar programaticamente os prompts do usuário
- Implementar um pipeline de inferência
- Retrieval-Augmented Generation (discutido em outros artigos)
- Ajuste fino (discutido em outros artigos)
Modificando programaticamente os prompts do usuário
De uma perspectiva programática, não há API especial para adicionar um prompt do sistema às conversas dos usuários. Você apenas acrescenta instruções ao prompt conforme necessário. No entanto, existem algumas técnicas para melhorar os prompts do usuário:
- Priming contextual: prompts do sistema de criação que definem explicitamente o contexto da conversa dentro do domínio desejado. Isso envolve fornecer uma breve descrição ou um conjunto de instruções no início de cada interação, orientando a IA a permanecer dentro do domínio do problema.
- Orientação baseada em exemplos: inclua exemplos dos tipos de perguntas e respostas relevantes para o seu domínio no prompt inicial. Isso ajuda a IA a entender o tipo de respostas esperadas.
Além disso, todas as técnicas de engenharia de prompts podem ser aplicadas. Se você puder fazer isso programaticamente de alguma forma, poderá melhorar o prompt do usuário em seu nome.
A ressalva a essa abordagem é que quanto mais longo o prompt, mais cara cada chamada para o LLM. Mesmo assim, esta é provavelmente a mais barata das abordagens que serão discutidas.
Implementando um pipeline de inferência
A próxima etapa além de modificar o prompt do usuário programaticamente é criar um pipeline de inferência inteiro.
Um pipeline de inferência é o processo de ponta a ponta que recebe a entrada bruta (como texto ou imagens) e a "limpa" antes de usá-la para executar seu prompt principal (pré-processamento) ou para verificar a conclusão para garantir que atenda às necessidades do usuário antes de exibi-la ao usuário (pós-processamento).
O pré-processamento pode envolver verificação de palavras-chave, pontuação de relevância ou transformação da consulta para melhor se ajustar à linguagem de domínio esperada. Por exemplo, você pode analisar o prompt inicial enviado pelo usuário e começar perguntando ao LLM se o prompt faz sentido, se está dentro dos limites do que você está disposto a aceitar, se é baseado em uma premissa defeituosa ou precisa ser reescrito para evitar certos vieses. Se o LLM analisar o prompt e encontrar problemas, você pode ir um passo além: peça ao LLM para reformular o prompt para potencialmente melhorar a resposta.
O pós-processamento pode envolver a validação da relevância e adequação da resposta ao domínio. Isso pode incluir remover ou sinalizar respostas que não se encaixam nos requisitos do domínio. Por exemplo, convém inspecionar a conclusão fornecida pelo LLM para garantir que ela atenda aos seus requisitos de qualidade e segurança. Você pode pedir ao LLM que avalie a resposta para ver se, de fato, atende aos requisitos aos quais você pediu que ele aderisse. Se isso não acontecer, você pode pedir ao LLM para modificar a conclusão e repetir isso até ter um resultado satisfatório.
Há uma ressalva para adicionar etapas de pré-processamento: cada vez que você adiciona uma chamada a um LLM em seu pipeline de inferência, aumenta a latência geral (tempo de resposta) e o custo de cada interação com o usuário. Como um desenvolvedor de software experiente, você provavelmente já está ciente desses tipos de compensações que devem ser feitas pela liderança que afetam o orçamento, o desempenho e a eficácia do sistema de software.
O artigo Building advanced Retrieval-Augmented Generation systems mergulha profundamente em etapas específicas da construção de um pipeline de inferência.
Outros fatores que influenciam a conclusão
Além de modificar programaticamente o prompt, criar um pipeline de inferência e outras técnicas, mais detalhes são discutidos em Augmenting a Large Language Model with Retrieval-Augmented Generation and Fine-tuning. Além disso, há parâmetros que podem ser modificados ao fazer chamadas para a API do Azure OpenAI.
A documentação do ponto de extremidade do Chat lista os parâmetros obrigatórios e opcionais a serem passados que podem afetar vários aspectos da conclusão. Se você estiver usando um SDK, consulte a documentação do SDK para o idioma de sua escolha. Se você quiser experimentar os parâmetros, você pode fazê-lo no Playground.
Temperatura: Controle a aleatoriedade da saída gerada pelo modelo. No zero, o modelo se torna determinístico, selecionando consistentemente o próximo token mais provável de seus dados de treinamento. A uma temperatura de 1, o modelo se equilibra entre escolher tokens de alta probabilidade e introduzir aleatoriedade na saída.
Max Tokens: Controla o comprimento máximo da resposta. A definição de um limite superior ou inferior pode afetar os detalhes e o escopo do conteúdo gerado.
Top P (Nucleus Sampling): Utilizado com a temperatura para controlar a aleatoriedade da resposta. O Top P limita a IA a considerar apenas a porcentagem P superior da massa de probabilidade ao gerar cada token. Valores mais baixos levam a um texto mais focado e previsível, enquanto valores mais altos permitem mais diversidade.
Penalidade de Frequência: Diminui a probabilidade de o modelo repetir a mesma linha ou frase. Aumentar esse valor ajuda a evitar redundância no texto gerado.
Penalidade de Presença: Incentiva o modelo a introduzir novos conceitos e termos na conclusão. Presence Penalty é útil para gerar saídas mais diversas e criativas.
Parar sequências: você pode especificar uma ou mais sequências para instruir a API a parar de gerar mais tokens. As sequências de armazenamento são úteis para controlar a estrutura da saída, como terminar uma conclusão no final de uma frase ou parágrafo.
Logit Bias: Permite modificar a probabilidade de tokens especificados aparecerem na conclusão. O Logit Bias pode ser usado para orientar a conclusão em uma determinada direção ou para suprimir conteúdo indesejado.
Noções básicas sobre as proteções do Microsoft OpenAI
Além de manter as respostas do LLM vinculadas a assuntos ou domínios específicos, você provavelmente também estará preocupado com os tipos de perguntas que seus usuários estão fazendo ao LLM. É importante considerar os tipos de respostas que está gerando.
Primeiro, as chamadas de API para o Microsoft OpenAI Services filtram automaticamente o conteúdo que considera potencialmente ofensivo e relatam isso a você em muitas categorias de filtragem.
Você pode usar a API de moderação do OpenAI diretamente para verificar explicitamente qualquer conteúdo em busca de conteúdo potencialmente prejudicial.
Em segundo lugar, você pode usar a Segurança de Conteúdo de IA do Azure para ajudar com moderação de texto, moderação de imagem, detecção de risco de jailbreak e detecção de material protegido. Isso combina uma configuração, configuração e experiência de relatório do portal com o código que você pode adicionar ao seu aplicativo para identificar conteúdo prejudicial.
Considerações finais que podem influenciar suas decisões de design de aplicativo
Entender tokenização, preços, janelas de contexto e implementar melhorias programáticas para melhorar a experiência de geração de texto dos usuários afeta como você projeta seu sistema de IA generativa. Aqui está uma pequena lista de coisas a serem consideradas e outras conclusões deste artigo que afetam suas decisões de design de aplicativo:
- Avalie a necessidade de usar o modelo de IA mais recente em relação a considerações de custo. Modelos mais baratos podem ser suficientes para as necessidades do seu aplicativo, equilibrando o desempenho com as restrições orçamentárias.
- Considere otimizar o comprimento da janela de contexto para gerenciar custos sem afetar significativamente a experiência do usuário. Cortar partes desnecessárias da conversa pode reduzir as taxas de processamento, mantendo interações de qualidade.
- Avalie como a tokenização e a granularidade de suas entradas e saídas afetam o desempenho. Entender como o LLM escolhido lida com a tokenização pode ajudá-lo a otimizar a eficiência de suas chamadas de API, potencialmente reduzindo custos e melhorando os tempos de resposta.
Se você quiser começar a experimentar a criação de uma solução de IA generativa imediatamente, recomendamos dar uma olhada em Introdução ao bate-papo usando sua própria amostra de dados para Python. Há versões do tutorial também disponíveis em .NET, Java e JavaScript.