Prompt Tuning
O ajuste de prompts adapta um modelo congelado a uma tarefa através do treino de alguns vetores de prompt suaves adicionados à entrada, permitindo que um modelo sirva várias tarefas.
O ajuste de prompts adapta um modelo fundacional pré-treinado a uma nova tarefa treinando um pequeno conjunto de vetores, chamado prompt suave, que é colocado antes da entrada enquanto todos os pesos do modelo permanecem congelados. O prompt suave ocupa o mesmo espaço que os embeddings de tokens do modelo, mas os seus vetores são aprendidos por retropropagação e não precisam de corresponder a nenhuma palavra real. Brian Lester, Rami Al-Rfou e Noah Constant, da Google, apresentaram o método em The Power of Scale for Parameter-Efficient Prompt Tuning, apresentado na EMNLP 2021. Observaram que um prompt de cinco tokens para o modelo T5-XXL, com 11 mil milhões de parâmetros, requer apenas 20 480 parâmetros por tarefa, e mostraram que, quando os modelos ultrapassam os milhares de milhões de parâmetros, o ajuste de prompts iguala a precisão do ajuste de todo o modelo.
Como funciona o ajuste de prompts#
Um modelo de linguagem de grande porte (LLM) transforma cada token de entrada num vetor de embedding antes de este chegar às camadas do transformer. O ajuste de prompts antepõe k vetores adicionais a essa sequência; Lester et al. testaram comprimentos de 1 a 150 e utilizaram 100 por predefinição. Durante o treino, a função de perda da tarefa é retropropagada pela rede congelada até à entrada, e o otimizador atualiza apenas os vetores do prompt. O resultado é um pequeno tensor por tarefa. Como o modelo em si nunca muda, remover o prompt repõe o comportamento original sem risco de esquecimento catastrófico, e uma única cópia implementada pode servir muitas tarefas em simultâneo, cada pedido de um lote com o seu próprio prompt suave, algo a que Lester et al. chamam inferência de tarefas mistas.
O exemplo seguinte em PyTorch ajusta um prompt suave de 8 vetores para análise de sentimentos num GPT-2 congelado dos Transformers da Hugging Face, com quatro avaliações de treino e oito reservadas para teste:
import torch
from torch.nn.functional import cross_entropy
from transformers import AutoModelForCausalLM, AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("gpt2")
model = AutoModelForCausalLM.from_pretrained("gpt2").requires_grad_(False) # freeze all 124M weights
embed = model.get_input_embeddings()
# Soft prompt: 8 trainable vectors in GPT-2's embedding space, initialized from the word " review"
soft_prompt = torch.nn.Parameter(embed.weight[tokenizer.encode(" review")].repeat(8, 1).clone())
optimizer = torch.optim.Adam([soft_prompt], lr=0.01)
labels = tokenizer.encode(" positive negative") # token ids for label 0 and label 1
# Reviews alternate between positive (label 0) and negative (label 1)
train = ["Loved every minute.", "A waste of time.", "Great story and acting.", "Boring and slow."]
test = ["What a wonderful film.", "I fell asleep halfway.", "A fantastic ending.", "Terrible dialogue."]
test += ["A joy to watch.", "Dull and predictable.", "Superb from start to end.", "I want my money back."]
def label_scores(text):
"""Score both label tokens after the soft prompt and the review."""
ids = tokenizer.encode(f"{text} Sentiment:", return_tensors="pt")
return model(inputs_embeds=torch.cat([soft_prompt[None], embed(ids)], dim=1)).logits[0, -1, labels]
def correct():
"""Count held-out reviews whose higher-scoring label is right."""
with torch.no_grad():
return sum(int(label_scores(text).argmax()) == i % 2 for i, text in enumerate(test))
print(f"Held-out reviews correct before tuning: {correct()}/8")
for step in range(30):
loss = sum(cross_entropy(label_scores(text), torch.tensor(i % 2)) for i, text in enumerate(train))
optimizer.zero_grad()
loss.backward()
optimizer.step()
print(f"After tuning: {correct()}/8, training {soft_prompt.numel():,} of {model.num_parameters():,} parameters")Apresenta Held-out reviews correct before tuning: 5/8 e, em seguida, After tuning: 7/8, training 6,144 of 124,439,808 parameters. Trinta passos de Adam em quatro exemplos alteraram apenas 6 144 números, 0,005% do modelo, e o GPT-2 congelado classificou corretamente mais duas avaliações inéditas.
Ajuste de prefixos e ajuste visual de prompts#
O ajuste de prompts pertence a uma família de métodos de prompt contínuo no âmbito do ajuste fino eficiente em parâmetros (PEFT). O ajuste de prefixos de Xiang Lisa Li e Percy Liang aprende vetores que são antepostos em cada camada do transformer, cerca de 0,1% dos parâmetros do GPT-2 ou do BART, e igualou o ajuste fino completo na geração de texto a partir de tabelas e na sumarização. O ajuste de prompts simplifica esta abordagem aprendendo vetores apenas na camada de entrada.
A ideia também se aplica à visão. O Visual Prompt Tuning (VPT), de Menglin Jia e colegas, antepõe tokens treináveis aos tokens de patches de um Vision Transformer (ViT) congelado, treinando menos de 1% dos parâmetros, e superou o ajuste fino completo em muitos cenários de classificação de imagens. Para modelos visão-linguagem, o Context Optimization (CoOp), de Kaiyang Zhou e colegas, substitui as palavras escritas manualmente num prompt CLIP, como "uma fotografia de", por vetores aprendidos. Em 11 conjuntos de dados, o CoOp superou os prompts criados manualmente com um ou dois exemplos etiquetados por classe e melhorou os resultados em cerca de 15%, em média, com 16 exemplos por classe.
Os detetores de vocabulário aberto adaptam-se de forma semelhante. O Ultralytics YOLOE transforma nomes de classes em embeddings de prompts de texto, e a sua receita de sondagem linear para conjuntos de dados personalizados funde os embeddings dos nomes das classes do conjunto de dados na convolução final de cada ramo de classificação. Depois, treina apenas essas camadas, mantendo congelados o backbone, o neck e o resto da cabeça.
Ajuste de prompts vs. métodos relacionados#
- Engenharia de prompts: Uma pessoa escreve o prompt como texto, por vezes chamado prompt rígido, e não se treina nada. O ajuste de prompts aprende o prompt a partir de dados etiquetados e requer acesso aos gradientes do modelo, pelo que se aplica a modelos com pesos abertos.
- Ajuste fino completo: Atualiza todos os pesos, produzindo uma cópia completa do modelo por tarefa e arriscando-se ao esquecimento catastrófico de competências anteriores. Lester et al. concluíram também que os modelos ajustados com prompts eram mais robustos à mudança de domínio do que os ajustados por completo.
- LoRA: Adiciona matrizes treináveis de posto baixo às camadas de pesos do modelo. O ajuste de prompts não altera as camadas e modifica apenas a entrada.
- Aprendizagem few-shot no prompt: Inclui exemplos etiquetados na janela de contexto como texto em cada pedido. Um prompt suave ajustado armazena o que os exemplos ensinam em alguns vetores e custa apenas k posições adicionais de entrada.










