A eficácia de um modelo de linguagem grande depende muito das instruções que damos a ele. A engenharia de comando é o processo de criar perguntas de forma a obter o melhor resultado de um LLM. É uma etapa crucial na implementação de um recurso baseado em LLM.
A engenharia de comandos é um processo iterativo. Se você já testou diferentes LLMs, provavelmente notou que precisou ajustar o comando para alcançar um resultado melhor.
Isso também vale para modelos de tamanhos diferentes.
As interfaces de chat alimentadas por LLMs grandes, como o Gemini ou o ChatGPT, geralmente produzem resultados satisfatórios com pouco esforço de comando. No entanto, ao trabalhar com um LLM padrão e menor que não foi ajustado, é necessário adaptar sua abordagem.
LLMs menores são menos poderosos e têm um conjunto menor de informações para usar.
O que queremos dizer com "modelos de linguagem grandes menores"?
Definir tamanhos de LLM é complicado, e eles nem sempre são divulgados pelos criadores.
Neste documento, "LLMs menores" significa qualquer modelo com menos de 30 bilhões de parâmetros. Hoje, modelos com alguns milhões a alguns bilhões de parâmetros podem ser executados de forma realista no navegador, em dispositivos de consumo.
Onde os LLMs menores são usados?
- IA generativa no dispositivo/navegador, por exemplo, se você estiver usando o Gemma 2B com a API LLM Inference do MediaPipe (adequada até para dispositivos somente com CPU) ou o DistilBert no navegador com Transformers.js. O download de um modelo e a execução da inferência no dispositivo de um usuário só são possíveis com esses LLMs menores, para manter os downloads da Web razoáveis e adequados às restrições de memória e GPU/CPU de um dispositivo.
- IA generativa personalizada do lado do servidor. Modelos pequenos de peso aberto, como Gemma 2B, Gemma 7B ou Gemma 27B, estão disponíveis para você executar no seu próprio servidor e, opcionalmente, fazer um ajuste fino.
Primeiros passos
As interfaces de chat alimentadas por LLMs grandes, como o Gemini ou o ChatGPT, geralmente produzem resultados satisfatórios com pouco esforço de comando. No entanto, ao trabalhar com LLMs menores, é necessário adaptar sua abordagem. LLMs menores são menos poderosos e têm um conjunto menor de informações para usar.
Fornecer contexto e instruções de formato precisas
Para alcançar resultados ideais com LLMs pequenos, crie comandos mais detalhados e específicos.
Exemplo:
Based on a user review, provide a product rating as an integer between 1 and 5. \n
Only output the integer.
Review: "${review}"
Rating:
| Entrada (avaliação) | Saída (classificação) | |
|---|---|---|
| LLM maior (Gemini 1.5) | LLM menor (Gemma 2B) | |
| Adorei o ajuste! Distribui bem o peso e é surpreendentemente confortável, mesmo em caminhadas de um dia inteiro. Recomendaria. | 5 | 4 de 5 estrelas** |
| As alças são frágeis e começaram a machucar meus ombros sob cargas pesadas. | 1 | 2/5 |
Embora o Gemini 1.5 forneça a saída desejada com esse comando simples, a saída da Gemma não é satisfatória:
- O formato está incorreto. Solicitamos um número inteiro para a classificação.
- A classificação não parece muito precisa. A primeira avaliação é entusiasmada o suficiente para indicar uma avaliação de 5 estrelas.
Para corrigir isso, precisamos usar técnicas de engenharia de comando, Comandos de um, poucos e vários disparos e comandos com linha de raciocínio. Também precisamos fornecer instruções de formato claras e insistir que o modelo use toda a faixa de classificações.
Exemplo:
`Analyze a product review, and then based on your analysis give me the
corresponding rating (integer). The rating should be an integer between 1 and
5. 1 is the worst rating, and 5 is the best rating. A strongly dissatisfied
review that only mentions issues should have a rating of 1 (worst). A strongly
satisfied review that only mentions positives and upsides should have a rating
of 5 (best). Be opinionated. Use the full range of possible ratings (1 to
5). \n\n
\n\n
Here are some examples of reviews and their corresponding analyses and
ratings:
\n\n
Review: 'Stylish and functional. Not sure how it'll handle rugged outdoor
use, but it's perfect for urban exploring.'
Analysis: The reviewer appreciates the product's style and basic
functionality. They express some uncertainty about its ruggedness but
overall find it suitable for their intended use, resulting in a positive,
but not top-tier rating.
Rating (integer): 4
\n\n
Review: 'It's a solid backpack at a decent price. Does the job, but nothing
particularly amazing about it.'
Analysis: This reflects an average opinion. The backpack is functional and
fulfills its essential purpose. However, the reviewer finds it unremarkable
and lacking any standout features deserving of higher praise.
Rating (integer): 3
\n\n
Review: 'The waist belt broke on my first trip! Customer service was unresponsive too. Would not recommend.'
Analysis: A serious product defect and poor customer service experience naturally warrants the lowest possible rating. The reviewer is extremely unsatisfied with both the product and the company.
Rating (integer): 1
\n\n
Review: 'Love how many pockets and compartments it has. Keeps everything organized on long trips. Durable too!'
Analysis: The enthusiastic review highlights specific features the user loves (organization and durability), indicating great satisfaction with the product. This justifies the highest rating.
Rating (integer): 5
\n\n
Review: 'The straps are a bit flimsy, and they started digging into my shoulders under heavy loads.'
Analysis: While not a totally negative review, a significant comfort issue leads the reviewer to rate the product poorly. The straps are a key component of a backpack, and their failure to perform well under load is a major flaw.
Rating (integer): 1
\n\n
Now, here is the review you need to assess:
\n
Review: "${review}" \n`;
| Entrada (avaliação) | Saída com um LLM menor (Gemma 2B) |
|---|---|
Adorei o ajuste! Distribui bem o peso e é surpreendentemente confortável, mesmo em caminhadas de um dia inteiro. Recomendaria. |
Análise: essa avaliação é muito positiva e enfatiza o ajuste e o conforto do produto, indicando grande satisfação com ele. Isso justifica uma classificação alta. Classificação (número inteiro): 5 |
As alças são frágeis e começaram a machucar meus ombros sob cargas pesadas. |
**Análise**: a avaliação destaca um problema significativo de conforto com as alças. Também sugere que o produto pode não ser adequado para cargas pesadas ou passeios prolongados. **Classificação**: 1 (pior) |
Nosso comando mais elaborado, combinado com técnicas de comando de poucos disparos e de comandos com linha de raciocínio, oferece classificações mais precisas.
Esperar análise manual da saída
Embora seja sempre necessário limpar e interpretar manualmente a saída de um LLM, isso é especialmente verdadeiro para LLMs menores, que podem produzir resultados menos refinados e exigir comandos com linha de raciocínio.
No primeiro exemplo, usamos comandos com linha de raciocínio, então a saída incluiu uma análise e uma classificação. Precisamos analisar manualmente a classificação. Observe também a formatação inconsistente na saída da seção anterior: às vezes, o modelo gera markdown, mas nem sempre.
// Use try/catch to catch (parsing) errors
try {
// Parse the output for a rating
const int = /[1-5]/;
const ratingAsString = llmOutput.match(int)[0];
// Parse as int
const ratingAsInt = parseInt(ratingAsString);
// `checkRating` checks the rating is a number between 1 and 5, since the
// regEx may catch a number like "100"
const finalRating = checkRating(ratingAsInt);
} catch (e) {
console.error('Error', e);
}
Diferenças entre as APIs Mind
As APIs de nuvem de LLM, como a API Gemini ou a OpenAI, que normalmente são o ponto de entrada para LLMs maiores, oferecem recursos úteis de comandos. Por exemplo, o Gemini 1.5 Pro oferece instruções do sistema e modo JSON.
No momento, esses recursos nem sempre estão disponíveis para uso de modelos personalizados ou para LLMs menores acessados usando APIs de IA no navegador, como a API MediaPipe LLM Inference ou o Transformers.js. Embora isso não seja necessariamente uma limitação técnica, as APIs de IA no navegador tendem a ser mais leves.
Respeite os limites de tokens
Como o comando para LLMs menores precisa incluir exemplos ou instruções mais detalhadas, ele provavelmente será mais longo e ocupará mais do seu limite de tokens de entrada, se houver um.
Além disso, modelos menores tendem a ter um limite de tokens de entrada menor. Por exemplo, o Gemini 1.5 Pro tem um limite de 1 milhão de tokens de entrada, enquanto os modelos da Gemma têm uma janela de contexto de 8 mil tokens.
Use funções de contagem de tokens para evitar atingir o limite.
Adaptar as estimativas de tempo
Considere o design e o teste de comandos nas estimativas de tempo de engenharia.
Devido às diferenças de API e aos limites de token, provavelmente você vai precisar de mais tempo e esforço para criar um comando para um LLM menor do que para um maior. Testar e validar a saída do LLM também pode exigir mais esforço.
Engenharia de comandos x ajuste fino?
Para desenvolvedores da Web, a engenharia de comando é a maneira preferida de aproveitar a IA generativa em vez de treinamento e ajuste personalizados. No entanto, mesmo a engenharia de comandos avançada pode não ser suficiente em alguns casos de uso, principalmente se você estiver usando um LLM menor.
Use o ajuste fino quando:
- Você precisa de acurácia e desempenho de alto nível para uma tarefa específica. O ajuste de detalhes altera diretamente os parâmetros internos do modelo para otimizar os resultados.
- Você tem dados bem selecionados, relevantes para sua tarefa e já rotulados com saídas preferenciais. Você precisa desses dados para um ajuste fino eficaz.
- Você usa o modelo para a mesma finalidade repetidamente. O ajuste fino pode ser feito uma vez e reutilizado para uma tarefa específica.