微调是基于预训练的机器学习模型,进一步使用较小且特定的数据集进行训练。这能让模型更好地理解特定的主题或任务,从而使模型在理解和回答相关问题时更加出色。微调利用模型现有的知识,避免从头开始训练,这样不仅节省时间和资源,还能提高其在特定任务上的表现。
微调(Fine-tuning)的几个关键好处如下:
哈维公司是一家专注于法律技术的AI公司。他们使用法律数据和律师事务所特定信息对大型语言模型进行优化,以创建定制化的AI助手供法律专业人士使用。哈维的模型训练有素,能够处理复杂的法律任务,能够应对如下的查询:
“总结这份合同的关键点,并识别任何潜在的风险点。”
“加州在类似知识产权纠纷中有哪些相关先例?”
这种定制的方法让哈维能更好地回答法律问题,提供更准确和相关的答案。
最关键的部分是准备数据集。完成之后,剩下的步骤就都变得简单多了。
在准备数据以微调OpenAI模型时,训练数据的格式非常重要。这里有几个关于数据格式的关键点:
对于像GPT-4这样的聊天模型来说,一般情况下,结构应该是这样的。
{"messages": [{"role": "system", "content": "系统信息"}, {"role": "user", "content": "用户输入"}, {"role": "assistant", "content": "助手回复"}]}
在这个例子中,我使用了一个癌症数据集来展示整个流程。目标是根据电子健康记录(EHR)分类患者的文档,以确定患者目前是否有癌症,过去是否有癌症,是否未患癌症,或者亲属是否患有癌症。这里提供了一个简化的数据集用于说明。你可以按照这些步骤来调整你自己的数据集。
数据集中包含文本示例,每个条目根据所描述的癌症状态进行分类。类别有等:
这里是一条数据。
{"messages": [{"role": "system", "content": "你的任务是将一段文本分类到以下类别标签中:['当前存在癌症', '曾经患有癌症', '亲属曾患癌症', '无癌症']"}, {"role": "user", "content": "她上个月被诊断出患有三期结肠直肠癌。"}, {"role": "assistant", "content": "当前存在癌症"}]}
高质量的数据样本非常重要。调整时至少需要10条数据记录。这里是用于训练模型进行分类的10条标记数据。
这里是 JSONL 格式的数据,即每行一个 JSON 对象的序列。下面这个就是用 JSONL 格式表示的数据。
{"messages": [{"role": "system", "content": "你的任务是将一段文本分类到以下类别标签之一:[\"Cancer_present\", \"Cancer_past\", \"Cancer_relative\", \"No_Cancer\"]."}, {"role": "user", "content": "她上个月被诊断出患有三期结肠癌。"}, {"role": "assistant", "content": "Cancer_present"}]} {"messages": [{"role": "system", "content": "你的任务是将一段文本分类到以下类别标签之一:[\"Cancer_present\", \"Cancer_past\", \"Cancer_relative\", \"No_Cancer\"]."}, {"role": "user", "content": "肿瘤科医生确认他的症状与癌症相关。"}, {"role": "assistant", "content": "Cancer_present"}]} {"messages": [{"role": "system", "content": "你的任务是将一段文本分类到以下类别标签之一:[\"Cancer_present\", \"Cancer_past\", \"Cancer_relative\", \"No_Cancer\"]."}, {"role": "user", "content": "她的最近扫描显示肺部有恶性肿瘤。"}, {"role": "assistant", "content": "Cancer_present"}]} {"messages": [{"role": "system", "content": "你的任务是将一段文本分类到以下类别标签之一:[\"Cancer_present\", \"Cancer_past\", \"Cancer_relative\", \"No_Cancer\"]."}, {"role": "user", "content": "她目前正在接受乳腺癌的化疗。"}, {"role": "assistant", "content": "Cancer_present"}]} {"messages": [{"role": "system", "content": "你的任务是将一段文本分类到以下类别标签之一:[\"Cancer_present\", \"Cancer_past\", \"Cancer_relative\", \"No_Cancer\"]."}, {"role": "user", "content": "他收到了一个阳性测试结果,确认患有前列腺癌。"}, {"role": "assistant", "content": "Cancer_present"}]} {"messages": [{"role": "system", "content": "你的任务是将一段文本分类到以下类别标签之一:[\"Cancer_present\", \"Cancer_past\", \"Cancer_relative\", \"No_Cancer\"]."}, {"role": "user", "content": "她在十几岁时患过癌症,但从那时起就一直在缓解中。"}, {"role": "assistant", "content": "Cancer_past"}]} {"messages": [{"role": "system", "content": "你的任务是将一段文本分类到以下类别标签之一:[\"Cancer_present\", \"Cancer_past\", \"Cancer_relative\", \"No_Cancer\"]."}, {"role": "user", "content": "经过五年无癌的生活,他仍然定期进行检查。"}, {"role": "assistant", "content": "Cancer_past"}]} {"messages": [{"role": "system", "content": "你的任务是将一段文本分类到以下类别标签之一:[\"Cancer_present\", \"Cancer_past\", \"Cancer_relative\", \"No_Cancer\"]."}, {"role": "user", "content": "她战胜了宫颈癌,之后一直很健康。"}, {"role": "assistant", "content": "Cancer_past"}]} {"messages": [{"role": "system", "content": "你的任务是将一段文本分类到以下类别标签之一:[\"Cancer_present\", \"Cancer_past\", \"Cancer_relative\", \"No_Cancer\"]."}, {"role": "user", "content": "他的测试结果证实他已经完全从皮肤癌中恢复。"}, {"role": "assistant", "content": "Cancer_past"}]} {"messages": [{"role": "system", "content": "你的任务是将一段文本分类到以下类别标签之一:[\"Cancer_present\", \"Cancer_past\", \"Cancer_relative\", \"No_Cancer\"]."}, {"role": "user", "content": "我妈妈与乳腺癌斗争了两年,现在处于缓解。"}, {"role": "assistant", "content": "Cancer_relative"}}
用一组较小的样本来测试模型的性能。这有助于通过反馈来调整超参数并选择最佳模型,确保模型能泛化到未见的数据上。
这是我的验证数据集。
{"messages": [{"role": "system", "content": "你的任务是将一段文本分类到以下类别标签中:[\"癌症存在\", \"癌症过去\", \"家族癌症\", \"无癌症\"]."}, {"role": "user", "content": "他的父亲因肺癌去世,这让他担心自己的患病风险。"}, {"role": "assistant", "content": "家族癌症"}]} {"messages": [{"role": "system", "content": "你的任务是将一段文本分类到以下类别标签中:[\"癌症存在\", \"癌症过去\", \"家族癌症\", \"无癌症\"]."}, {"role": "user", "content": "她的堂妹最近被诊断出早期宫颈癌。"}, {"role": "assistant", "content": "家族癌症"}]} {"messages": [{"role": "system", "content": "你的任务是将一段文本分类到以下类别标签中:[\"癌症存在\", \"癌症过去\", \"家族癌症\", \"无癌症\"]."}, {"role": "user", "content": "她因此担心,因为去年她的姐姐被诊断出乳腺癌。"}, {"role": "assistant", "content": "家族癌症"}]} {"messages": [{"role": "system", "content": "你的任务是将一段文本分类到以下类别标签中:[\"癌症存在\", \"癌症过去\", \"家族癌症\", \"无癌症\"]."}, {"role": "user", "content": "他的母亲目前正在与结肠癌抗争,所以他决定去做检查。"}, {"role": "assistant", "content": "家族癌症"}]} {"messages": [{"role": "system", "content": "你的任务是将一段文本分类到以下类别标签中:[\"癌症存在\", \"癌症过去\", \"家族癌症\", \"无癌症\"]."}, {"role": "user", "content": "她父亲的前列腺癌病史让她更加小心地关注自己的健康。"}, {"role": "assistant", "content": "家族癌症"}]}
现在我们可以开始调优了。这可以通过代码或界面来完成。
您也可以通过代码来触发调整。
from openai import OpenAI client = OpenAI() # 开始一个微调任务: client.fine_tuning.jobs.create( training_file="file-abc123", model="gpt-4o-mini" ) # 查看微调任务的状态 client.fine_tuning.jobs.retrieve("ftjob-abc123") # 取消这个任务 client.fine_tuning.jobs.cancel("ftjob-abc123") # 列出这10个微调任务的事件 client.fine_tuning.jobs.list_events(fine_tuning_job_id="ftjob-abc123", limit=10)
接下来,我将带你通过仪表板进行调整的过程,这可能是初学者的最佳入门方式。
去微调部分
选择一个基础模型,上传你的JSONL格式的文件,并给它取个名字。
选择一个模型并上传数据
请选择你想要微调的模型。(4o-mini)我用的是4o-mini。
请上传您的训练和验证数据集
设置超参数值。在进行微调时,仔细调整学习率、批量大小和训练周期。从推荐的默认设置开始,通过实验找到最适合您任务的最优设置。
以下是在OpenAI训练中使用的三个主要超参数。
在仪表板上查看微调过程,直到完成为止。
我的第一次尝试失败了,因为我训练数据有问题。我解决了那个问题。
我的JSONL文件有误,因为每个JSON对象没有放在一行里。我得把这个问题解决一下。
我把那个弄好了,重新上传数据,之后一切都好了。
损失度量,比如损失值
这是我选定的超参数值。
使用的超参数有
这里是一些关键损失指标,例如随着训练进展需要跟踪的变化,如损失值。
监控训练和验证损失,确保微调过程顺利。损失减少表示模型学得不错。如果验证损失增加而训练损失减少,则需要注意是否出现过拟合。
花了15分钟完成了微调工作
现在让我们在实验平台上使用微调过的模型。
你也可以用代码查询
from openai import OpenAI client = OpenAI() completion = client.chat.completions.create( model="Enter_the_fine_tuned_model_IDhere", messages=[ {"role": "system", "content": "你的任务是将一段文本分类为以下类别:[\"现患癌症\", \"既往癌症\", \"家族癌症史\", \"无癌症\"]。"}, {"role": "user", "content": "她结肠癌的检测结果是阴性!"} ] ) print(completion.choices[0].message)
现在这个模型已经准备好了。
虽然初始训练数据是免费的,但考虑整体成本很重要。
GPT-4O (原文)
- 训练(每百万个token 25元),
- 推理(每百万个token 3.75元),
- 输出(每百万个token 15元),
GPT-4O-min
- 训练:$3每百万标记,
- 推理:$0.3每百万标记,
- 输出:$1.25每百万标记,
对OpenAI模型进行微调是让AI更好地适应特定任务的一个好方法。通过准备好高质量的训练数据、挑选合适的模型并进行充分的训练,企业可以创建量身定制的AI解决方案,这些解决方案的表现通常会比通用模型更好。虽然这样做需要时间和资源,但它能带来更好的效果,同时还能节省资金。
不过,微调并不是每次都需要。适当调整提示就可以得到很好的效果,而无需额外的训练步骤。在决定是否进行微调之前,你需要考虑您的具体需求和数据。只要操作得当,可以为有效利用AI打开新的可能性。