微调是基于预训练的机器学习模型,进一步使用较小且特定的数据集进行训练。这能让模型更好地理解特定的主题或任务,从而使模型在理解和回答相关问题时更加出色。微调利用模型现有的知识,避免从头开始训练,这样不仅节省时间和资源,还能提高其在特定任务上的表现。
主要好处微调(Fine-tuning)的几个关键好处如下:
- 更省时省钱:微调相较于从头训练模型更加经济且更快。
- 提高性能:利用模型已有的知识,它可以帮助模型在特定任务上表现更好。
- 需要较少的数据:你只需用较少的任务特定数据就能取得不错的效果。
- 更容易的自定义:微调使你能够根据独特需求轻松定制强大的模型。
哈维公司是一家专注于法律技术的AI公司。他们使用法律数据和律师事务所特定信息对大型语言模型进行优化,以创建定制化的AI助手供法律专业人士使用。哈维的模型训练有素,能够处理复杂的法律任务,能够应对如下的查询:
“总结这份合同的关键点,并识别任何潜在的风险点。”
“加州在类似知识产权纠纷中有哪些相关先例?”
这种定制的方法让哈维能更好地回答法律问题,提供更准确和相关的答案。
使用 OpenAI 进行精调的高级操作步骤最关键的部分是准备数据集。完成之后,剩下的步骤就都变得简单多了。
- 准备训练数据集:将数据整理成JSONL文件格式,并确保数据质量高且多样化。数据应包含提示-响应对。
- 开始进行微调:登录OpenAI,进入“微调”部分,点击“新建”,选择一个模型,上传您的JSONL文件,并监控进度直至完成。
- 使用微调模型:在沙盒中选择您的模型,试用提示测试它,并在您的应用中使用它。
在准备数据以微调OpenAI模型时,训练数据的格式非常重要。这里有几个关于数据格式的关键点:
- 训练数据必须采用 JSONL(JSON Lines)格式。
- 文件中的每一行都必须是一个有效的 JSON 对象。
- 每个 JSON 对象不能跨行。
- 文件扩展名应该是 .jsonl。
- 确保您的示例高质量且多样化,充分代表您的任务。
- 至少包含 10 个示例,更多的示例通常能提高性能。
对于像GPT-4这样的聊天模型来说,一般情况下,结构应该是这样的。
{"messages": [{"role": "system", "content": "系统信息"},
{"role": "user", "content": "用户输入"},
{"role": "assistant", "content": "助手回复"}]}
- 每个示例都是一段完整的对话。
- “messages”数组就是对话的全部内容。
- 这些角色可以是系统、用户或助手。
在这个例子中,我使用了一个癌症数据集来展示整个流程。目标是根据电子健康记录(EHR)分类患者的文档,以确定患者目前是否有癌症,过去是否有癌症,是否未患癌症,或者亲属是否患有癌症。这里提供了一个简化的数据集用于说明。你可以按照这些步骤来调整你自己的数据集。
数据集中包含文本示例,每个条目根据所描述的癌症状态进行分类。类别有等:
- Cancer_present :描述正在经历的癌症治疗的文本。例如:“她目前正在接受乳腺癌化疗。”
- Cancer_past :指过去的癌症已被确认的文本。例如:“他收到了确认前列腺癌的阳性检测结果。”
- Cancer_relative :与他人癌症经历相关的文本。例如:“我妈妈与乳腺癌斗争了两年,现在病情有所好转。”
- No_Cancer :与患者没有癌症相关的文本。例如:“她的结肠癌检测结果是阴性。”
这里是一条数据。
{"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)
接下来,我将带你通过仪表板进行调整的过程,这可能是初学者的最佳入门方式。
使用openAI界面进行模型的精调 1. 访问细调界面:- 登录到 OpenAI 然后进入“Fine-tuning”部分
去微调部分
2. 开始微调选择一个基础模型,上传你的JSONL格式的文件,并给它取个名字。
选择一个模型并上传数据
请选择你想要微调的模型。(4o-mini)我用的是4o-mini。
请上传您的训练和验证数据集
设置超参数值。在进行微调时,仔细调整学习率、批量大小和训练周期。从推荐的默认设置开始,通过实验找到最适合您任务的最优设置。
第3步:调整超参数
以下是在OpenAI训练中使用的三个主要超参数。
- 学习率:
这控制模型学习的速度。较高的学习率意味着更快的学习,但可能忽略重要的细节。较低的学习率则学习更加细致,但需要更多的时间。 - 批量大小:
这是模型在更新它所知的内容之前查看的示例数量。较大的批量有助于学习更复杂的模式,但需要更多的内存。 - 训练轮数:
这是模型遍历所有训练数据的次数。更多的轮数意味着更多的训练机会,但轮数过多会导致模型记住数据而不是真正学习。范围:通常为1到10。我使用了10。
在仪表板上查看微调过程,直到完成为止。
我的第一次尝试失败了,因为我训练数据有问题。我解决了那个问题。
我的JSONL文件有误,因为每个JSON对象没有放在一行里。我得把这个问题解决一下。
我把那个弄好了,重新上传数据,之后一切都好了。
损失度量,比如损失值
这是我选定的超参数值。
使用的超参数有
这里是一些关键损失指标,例如随着训练进展需要跟踪的变化,如损失值。
监控训练和验证损失,确保微调过程顺利。损失减少表示模型学得不错。如果验证损失增加而训练损失减少,则需要注意是否出现过拟合。
花了15分钟完成了微调工作
5. 试试这个模型。现在让我们在实验平台上使用微调过的模型。
你也可以用代码查询
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打开新的可能性。
共同学习,写下你的评论
评论加载中...
作者其他优质文章