跳至主要内容

理解提示调优:以更高精度强化您的语言模型

提示调优是一种在不修改模型内部架构的前提下,提高预训练语言模型性能的技术。

使用 AI 探索

在快速演进的大型语言模型(LLM)领域,掌握诸如提示调优等最新方法至关重要。该技术可应用于已训练好的基座模型,在不承担传统训练高计算成本的情况下提升性能。

本文将介绍提示调优的基本原理,并与微调和提示工程进行对比,讨论其显著优势。我们还将提供一个基于 HuggingFace 平台的实用示例,对bloomz-560m 模型进行提示调优。希望本指南能加深您对提示调优的理解,并激发您将其融入项目实践。

什么是提示调优?

提示调优是一种在不改变预训练语言模型核心架构的情况下提升其性能的技术。它并不修改模型的深层权重,而是通过调整引导模型生成的提示来达到目的。该方法基于引入“软提示”,即在输入序列开头插入的一组可调参数。

Diagram from "The Power of Scale for Parameter-Efficient Prompt Tuning" research paper.

图片来源

该图对比了传统的模型调优与提示调优。可以看到,模型调优需要为每个任务训练一个独立模型;而提示调优则通过调整任务相关的提示,在多个任务间复用同一个基座模型。

提示调优如何工作?

1. 软提示的初始化

软提示是人工构造的标记,会被添加到模型的输入序列中。其初始化方式多样,随机初始化较为常见,也可基于某些启发式方法。一旦初始化完成,软提示会附着在输入数据的开头。模型在处理该数据时,会同时考虑软提示与实际输入。

2. 前向传播与损失评估

训练过程通常类似于标准深度神经网络(DNN)的训练。首先进行前向传播,模型将组合后的输入逐层处理并产生输出。随后,使用损失函数将该输出与期望结果进行对比,衡量模型输出与真实值之间的差异。

反向传播

在反向传播阶段,误差会沿网络反向传播。但我们并不调整网络的权重,只修改软提示的参数。该过程会在多个 epoch 中反复进行,软提示逐步学会以能最小化特定任务误差的方式来引导模型处理输入。

迭代

前向传播、损失评估与反向传播的过程会在多个 epoch 中重复。随着时间推移,这些软提示会学会以持续降低损失分数的方式来塑造输入,从而在不损害模型底层能力的情况下提升任务特定性能。

提示调优 VS 微调 VS 提示工程

提示调优、微调与提示工程是三种用于改进预训练 LLM 在特定任务上表现的方法。它们并非互斥,各自适用于不同场景。

微调

微调最为消耗资源,需要围绕特定数据集与目标对模型进行全面再训练。这会调整预训练模型的权重,使其对数据中的细微差异更为敏感,但需要大量计算资源,也增加了过拟合风险。许多 LLM(如 ChatGPT)在完成通用的下一词预测训练后,会进一步进行微调,使其学会如何充当数字助理,从而比通用模型更有用。

提示调优

提示调优会调整一组额外的参数,即集成到模型输入处理流程中的“软提示”。该方法改变模型对输入提示的解读方式,而无需全面改动权重,在性能提升与资源效率之间取得平衡。尤其当计算资源有限或需要在多个任务间保持灵活性时,提示调优价值突出,因为应用该技术后,原始模型权重保持不变。

提示工程

提示工程则完全不涉及训练或再训练,完全依赖用户为模型设计提示。它需要对模型的处理能力有细致理解,并利用模型中蕴含的内在知识。提示工程不需要任何计算资源,因为它仅通过策略性地构造输入来达成目标。想了解更多,请查看 DataCamp 的开发者提示工程课程。

对比

上述技术为利用预训练模型能力提供了不同路径。选择哪一种取决于具体应用需求,例如可用计算资源、对模型定制化的要求,以及期望与模型学习参数交互的深度。

方法

资源消耗

是否需训练

最佳适用场景

微调

高

是

需要深度定制模型的任务

提示调优

低

是

在多任务间保持模型一致性

提示工程

无

否

零计算成本的快速适配

根据项目的具体需求,每种方法都有其用武之地。

提示调优的优势

提示调优具备多项关键优势,使其成为优化大型语言模型不可或缺的技术。

资源高效

提示调优保持预训练模型参数不变,大幅降低所需计算量。这种效率在资源受限环境中尤为关键,使得在不高成本的前提下使用复杂模型成为可能。随着基座模型平均规模不断增大,“冻结”模型参数更具吸引力,因为无需为每个任务部署单独模型。

快速部署

与全面微调不同,提示调优只需调整少量软提示参数。这加快了适配流程,使任务间切换更迅速并减少停机时间。

模型完整性与知识保留

通过保持模型的核心架构与权重不变,提示调优能保留预训练模型中原有的能力与知识。这对确保模型在各类应用中的可靠性与泛化性至关重要。

任务灵活性

提示调优仅需更换软提示,便可让单一基座模型服务于多个任务。这减少了为每个具体任务训练与维护独立模型的需求,提升了可扩展性并简化了模型管理。

减少人工参与

与需要精心构造提示、既易出错又耗时的提示工程相比,提示调优显著降低了人工干预。通过在训练中自动优化软提示,既能将人为错误降到最低,又能提升效率。

可比肩的性能

研究表明,对于大模型而言,提示调优可达到与微调相当的性能。随着模型规模增长,这一优势愈发明显,兼顾高效率与出色结果。

提示调优的分步实践

在本指南中,我们将对 BigScience 的bloomz-560m 模型进行提示调优。我们将使用 Hugging Face 生态中的 PEFT(参数高效微调)库。

尽管此处聚焦因果语言建模任务,PEFT 库还支持多种任务、模型与调优技术。您可在其文档页面查找其他模型与任务的兼容 PEFT 方法。

Screenshot taken from PEFT library documentation page.

1. 加载模型与分词器

首先,从 BigScience 的 bloomz-560m 模型加载模型与分词器。分词器用于处理文本输入,而基座模型负责因果语言建模任务。参数 trust_remote_code=True 允许您使用模型维护者为特定架构提供的自定义代码。

尽管这有助于获得完整功能,但仅在可信来源时才信任模型代码。避免使用未知或未验证创作者提供的不受信任代码,否则可能带来安全或稳定性风险。

from transformers import AutoModelForCausalLM, AutoTokenizer
model_name = "bigscience/bloomz-560m"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    trust_remote_code=True
)

2. 使用基座模型进行推理

在任何调优之前,都应先用未调优的基座模型进行推理以建立基线。例如使用提示语“I want you to act as a logistician.”,我们可以观察模型在未进一步调优时的生成效果。请务必在提示语后添加一个空格,否则模型可能不会生成任何内容。

这将作为调优后评估改进幅度的参照。

我们将使用自定义的 generate_text 函数以简化操作。

def generate_text(model, tokenizer, prompt_text, max_tokens):
    prompt_text = tokenizer(prompt_text, return_tensors="pt")
    outputs = model.generate(
        input_ids=prompt_text["input_ids"],
        attention_mask=prompt_text["attention_mask"],
        max_length=max_tokens,
        repetition_penalty=1.5,
        eos_token_id=tokenizer.eos_token_id
    )
    return tokenizer.batch_decode(outputs, skip_special_tokens=True)


initial_output = generate_text(model, tokenizer, "I want you to act as a logistician. ", 100)
print("Initial model output:", initial_output)

模型输出如下:

['I want you to act as a logistician. You will be able to: Analyze the data']

可见模型对上下文的把握还不够明确。

3. 数据集

数据集是提示调优的关键要素。我们使用 `awesome-chatgpt-prompts` 数据集进行调优。该数据集为调优提供动机性内容,确保模型相应地调整其响应。

from datasets import load_dataset

dataset_prompt = "fka/awesome-chatgpt-prompts"


data_prompt = load_dataset(dataset_prompt)
data_prompt = data_prompt.map(lambda x: tokenizer(x["prompt"]), batched=True)
train_prompts = data_prompt["train"].select(range(50))

我们对数据集进行分词,并准备一小部分样本用于训练。

4. 调优

接下来是最有趣的部分;我们使用 PEFT 库中的 PromptTuningConfig 类来配置提示调优。

from peft import  get_peft_model, PromptTuningConfig, TaskType, PromptTuningInit

tuning_config = PromptTuningConfig(
    task_type=TaskType.CAUSAL_LM, #This type indicates the model will generate text.
    prompt_tuning_init=PromptTuningInit.RANDOM,  #The added virtual tokens are initializad with random numbers
    num_virtual_tokens=4, #Number of virtual tokens to be added and trained.
    tokenizer_name_or_path=model_name
)

peft_model = get_peft_model(model, tuning_config)

训练参数通过 TrainingArguments 类进行设置。

from transformers import TrainingArguments
training_args = TrainingArguments(
    use_cpu=True, # This is necessary for CPU clusters.
    output_dir = "./",
    auto_find_batch_size=True, # Find a suitable batch size that will fit into memory automatically, you can also use a custom batch size
    learning_rate= 0.005,
    num_train_epochs=5 
    )

Trainer 对象负责管理训练过程。借助 DataCollatorForLanguageModeling,数据整理器可确保训练样本格式正确。随后通过 train 方法启动训练阶段,使 bloomz-560m 模型针对特定提示任务完成微调。

from transformers import Trainer, DataCollatorForLanguageModeling
trainer = Trainer(
    model=peft_model, # We pass in the PEFT version of the foundation model, bloomz-560M
    args=training_args, #The args for the training.
    train_dataset=train_prompts, #The dataset used to train the model.
    data_collator=DataCollatorForLanguageModeling(tokenizer, mlm=False) # mlm=False indicates not to use masked language modeling
    )
trainer.train()

5. 使用已调优模型进行推理

已调优的模型存储在 trainer 对象中,可通过 trainer.model 访问。继续使用 generate_text 函数对已调优模型进行推理!

tuned_output = generate_text(trainer.model, tokenizer, "I want you to act as a logistician. ", 100)
print("Tuned model output:", tuned_output)

已调优模型的输出如下:

['I want you to act as a logistician. You will be responsible for the logistics of your business.']

可以看到,模型如今已经了解“物流专员”的职责。欢迎您尝试不同的提示、模型与数据集!

深入探索生成式 AI

提示调优是一种强有力的工具,可让大型语言模型在特定任务上更高效。我们首先解释了其概念与工作机制,随后将其与微调和提示工程进行比较,最后讨论了其优势,并通过分步指南将提示调优应用于一个预训练模型。

随着生成式 AI 领域不断发展,紧跟最新进展尤为重要。为进一步提升您的技能与理解,Datacamp 提供了多种深入资源。推荐您阅读以下系列教程:

Dimitri Didmanidze

作者

Dimitri Didmanidze

我叫 Dimitri Didmanidze,是一名数据科学家,目前正在攻读数学硕士学位,研究方向为机器学习。我的学术历程还包括对基于 Transformer 的模型能力进行研究,并在大学层面授课,这些经历加深了我对复杂理论概念的理解。我也曾在银行业工作,将这些原理应用于解决真实世界中的数据难题。

主题