微调
学习如何为您的应用定制模型
更多内容,详见官方指南https://platform.openai.com/docs/guides/fine-tuning
介绍:
1. 提供比prompt更高质量的结果
2.训练出超过prompt包含的examples。prompt包含几十个examples,微调数据集能到几十万。
3.由于prompt更短,节约token
4.更低的请求延时
GPT已经在大量的文本上 pre-trained(预训练),为了高效的使用模型,prompt包含Instructions,有时还有几个examples。使用demonstrations 展示如何执行任务通常称为few-shot learing(小样本学习)。
Fine-Tuning通过训练比适配prompt更多的examples,改进few-shot learing(小样本学习),让您在大量任务中取得更好的结果。一旦模型经过Fine-Tuning,就不再需要在prompt中写那么多examples。
微调包括下面几个步骤:
1.选择预训练模型。这个模型在大规模数据上预训练过,与你的任务类型和数据相关的模型。
2.准备特定任务的数据集
3.训练您的微调模型
4.超参数调整
5.评估您的微调模型
6.使用您的微调模型
哪些模型可以进行微调?
目前可对以下型号进行微调:
gpt-3.5-turbo-0613
(推荐)babbage-002
davinci-002
何时使用微调?
微调可以使模型更好的适应特点应用,但这需要花费时间和精力。建议首先尝试使用prompt engineering(提示词工程)、prompt chaining(将复杂任务分解为多个prompt)、和函数调用来获得良好效果。主要原因是:
1.对于许多任务,刚开始可能模型效果不好,通过更好的prompt取得很好的结果,可能不需要微调
2.更新迭代prompt或其他策略比Fine-Tuning更快得到反馈,而微调需要创建数据集,创建training job(训练任务)
3.在仍然需要Fine-Tuning的情况下,最初的prompt-engineering不会浪费,在微调数据中使用好的prompt(或者将prompt chaining/tool和Fine-Tuning结合),有助于我们看到最好的结果
微调常见用例
微调可以改善结果的常见情况
1.设置风格、基调、格式或者其他定性方面
2.提高期望输出的可靠性
3.纠正未能遵循复杂prompt的错误
4.以特定方式处理边缘情况
5.执行难以在prompt中表达的新技能或者任务
准备你的数据集
如果您已经优化过prompt,模型依然有明确的问题,即您确定了微调是正确方案,您需要准备训练模型的数据,您应该创建一组多样化的对话,这些对话类似于要求模型在推理后做出的响应。
数据集中的每个conversation的格式都应该与Chat completion API生成的一致,特别是消息列表,每个messages有role、content和optional name。
至少一些training examples,应该直接针对target case,而这些target case在prompt模型没有按要求运行。数据中提供的assistant messages应该是您希望的,模型提供的理想responses。
examples 格式
在这个事例中,我们创建一个偶尔给出讽刺语气response的聊天机器人,这是我们为dataset(数据集)创建的三个training examples(会话)。
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What's the capital of France?"}, {"role": "assistant", "content": "Paris, as if everyone doesn't know that already."}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who wrote 'Romeo and Juliet'?"}, {"role": "assistant", "content": "Oh, just some guy named William Shakespeare. Ever heard of him?"}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "How far is the Moon from Earth?"}, {"role": "assistant", "content": "Around 384,400 kilometers. Give or take a few, like that really matters."}]}
对话聊天的格式用于微调 gpt-3.5-turbo模型。
制作prompt
通常建议的微调之前,采用最适合模型的一组Instructions和prompt,并将其包含在每个training examples(训练事例)中。特别是training examples相对较少(例如低于100个)时,这将能让你达到更好更通用的结果。
example个数
为了微调模型,您至少需要10个examples。一般训练50~100个examples进行微调,能够在gpt-3.5-turbo模型上有明显改善,但实际需要多少examples还要看具体用例。
我们建议精心设计50个demonstrations开始 ,看看模型在微调后是否有提升的迹象。在某些情况下,这可能就足够了,不过即使模型没有达到实际生产的质量,明显的改进也是个好兆头,表示提供更多数据能够继续改善模型。如果没有改善的迹象,在扩展到有限的examples set前,您可能需要重新思考如何为模型设置任务,重新调整数据。
训练和测试数据集splits
收集初始数据集后,建议切分为训练和测试两部分。当提交包含训练和测试文件的微调作业时,将提供训练过程中两者的统计数据。这些统计数据将成为提升模型的初始信号。此外,尽早构建测试数据集,有助于在测试集上生成samples评估训练后的模型。
token限制
每个training examples限制为4096个tokens。训练时,超出4096的部分被截断。每个job训练的最大token为5000万。
检查数据格式
制作好数据集,在进行微调前,检查数据格式非常重要。为此,创建一个Python脚本,您可以使用它来查找潜在的错误、预估token数和微调的成本。
https://github.com/openai/openai-cookbook/blob/main/examples/Chat_finetuning_data_prep.ipynb
验证数据之后,需要上传文件,才能进行微调作业
import os
import openai
openai.api_key = os.getenv("OPENAI_API_KEY")
openai.File.create(
file=open("mydata.jsonl", "rb"),
purpose='fine-tune'
)
创建Fine-Tuning模型
确保数据集的数量和结构正确,上传文件之后,下一步是创建Fine-Tuning job,
使用OpenAI SDK开始微调工作
openai.FineTuningJob.create(training_file="file-abc123", model="gpt-3.5-turbo")
model是您开始使用的模型。
开始fine-tuning job后,可能需要一些时间才能完成。训练模型可能需要几分钟或者几小时,这取决于模型和数据集的大小。
使用fine-tuned模型
job完成后,模型能够用来推理。在某些情况下,您的模型可能需要几分钟开始准备去处理请求。
如果对模型的请求处理超时或者找不到模型名称,可能是因为您的模型仍在加载中,如果出现这种情况,请在几分钟后再试。
completion = openai.ChatCompletion.create(
model="ft:gpt-3.5-turbo:my-org:custom_suffix:id",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello!"}
]
)
print(completion.choices[0].message)
您可以通过传递模型名称来获取请求。
分析您的fine-tuned模型
训练过程中以下指标:training loss(训练损失)、training token accuracy(训练精度)、test loss(测试损失)、 test token accuracy(测试精度)。这些统计指标旨在提供合理的检查,评估训练是否顺畅,loss应该降低,accuracy应该升高。训练时,可以查看一些有用的度量指标。
{
"object": "fine_tuning.job.event",
"id": "ftevent-abc-123",
"created_at": 1693582679,
"level": "info",
"message": "Step 100/100: training loss=0.00",
"data": {
"step": 100,
"train_loss": 1.805623287509661e-5,
"train_mean_token_accuracy": 1.0
},
"type": "metrics"
}
查看训练过程的指标,step
、train_loss
、train_accuracy
、valid_loss
和valid_mean_token_accuracy
step,train_loss,train_accuracy,valid_loss,valid_mean_token_accuracy
1,1.52347,0.0,,
2,0.57719,0.0,,
3,3.63525,0.0,,
4,1.72257,0.0,,
5,1.52379,0.0,,
虽然指标很有用,但是评估fine-tuned模型生成的samples可以提供模型质量最相关的感知。建议base model和fine-tuned model在test set上生成samples,一一对比samples。理想状态下,测试集应该包括实际生产中可能输入到模型中完整分布。
如果手动评估太耗时,请考虑使用我们的Evals 库来自动执行评估。
迭代数据质量
如果fine-tuned结果不如预期,请考虑以下方式调整training dataset
1. 整理examples去解决仍然存在的问题
如果模型在某些方面仍然表现不好,请添加training examples,直接向模型展示如何正确完成这些方面。
2.检查现有examples是否正确
如果您的模型有语法、逻辑或格式错误,请检查您的数据是否存在相同问题。例如,如果模型说“我将为您安排这次会议”(实际上不应该如此),请查看现有examples是否教导模型说它可以做它不能做的新事情。
3.考虑数据的平衡性和多样性
如果数据中60%的assistant responses回答“我无法回答这个问题”,但是在推理中只有5%的responses应该这么说,您可能会得到过多的拒绝。
4.确保您的training examples包含responses所需的所有信息
如果我们希望模型根据用户个人特征来赞美用户,training examples包含先前对话中没有特征的assistant 赞美,模型可能会对学习产生幻觉信息
5.确保所有的training examples都采用相同格式,正如推理所预期的。
迭代数据量
一旦对examples数量和分布满意,您就可以考虑扩大training examples的规模。这往往有助于模型更好地学习任务,尤其围绕可能的"边缘情况"。我们期望每次training examples数量增加一倍,都会有类似的提升。您可以通过以下方式粗略的估计增加training examples规模所带来的的质量提升
1.对当前数据集进行微调
2.对当前数据集的一半进行微调
3.观察对比两者之间的质量差距
一般来说,如果必须做出权衡,较少量的高质量数据通常比较大量的低质量数据更有效。
迭代超参数
允许指定fine-tuning模型的epoch,建议初始化训练不指定epochs,以便我们根据数据集尺寸为您选择默认值,在观察到以下情况时进行调整:
1.如果模型没有像预期那样遵循训练数据,将epoch数量增加1或2
这对于单个的理想completion任务很常见(一个小的理想completion集合也是相似的)。一些任务包括分类、实例提取或者结构化解析。这些任务,通常您可以根据参考答案计算出最终准确性指标。
2.如果模型的多样性低于预期,则将epoch数量减少1或2
这对于有许多可能completions任务中更为常见。