文章目录
- 一. 开始微调
- 1. 选择合适的基础模型
- 2. 微调和少样本学习
- 2.1. 对比微调和少样本学习
- 2.2. 微调需要的数据量
- 二. 使用OpenAI API进行微调
- 1. 数据生成
- 1.1. JSONL的数据格式
- 1.2. 数据生成工具
- 1.3. 数据文件的细节注意
- 2. 上传数据来训练模型
- 3. 创建微调模型
- 4. 列出微调作业
- 5. 取消微调作业
- 二. 微调的应用
- 1. 法律文本分析
- 2. 自动代码审查-类Copilot
- 3. 财务文档摘要
- 4. 技术文档翻译
- 5. 为专业领域生成内容
- 三. 微调的成本
OpenAI提供了许多可直接使用的GPT模型。尽管这些模型在各种任务上表现出色,但针对特定任务或上下文对这些模型进行微调,可以进一步提高它们的性能。
一. 开始微调
假设你想为公司创建一个电子邮件自动回复生成器。由于你的公司所在的行业使用专有词汇,因此你希望生成器给出的电子邮件回复保持一定的写作风格。要做到这一点,有两种策略:要么使用之前介绍的提示工程技巧来强制模型输出你想要的文本,要么对现有模型进行微调。
本文对微调进行讨论。
微调的基本逻辑
- 收集大量数据:对于这个例子,你需要收集大量电子邮件,其中包含关于特定业务领域的数据、客户咨询及针对这些咨询的回复。然后,你可以使用这些数据微调现有模型,以使模型学习公司所用的语言模式和词汇。
- 微调后的新模型:微调后的模型本质上是
基于OpenAI提供的原始模型构建的新模型
,其中模型的内部权重被调整
,以适应特定问题,从而能够在相关任务上提高准确性。
通过对现有模型进行微调,你可以创建一个专门针对特定业务所用语言模式和词汇的电子邮件自动回复生成器。
下图展示了微调过程,也就是使用特定领域的数据集来更新现有GPT模型的内部权重
。微调的目标是使新模型能够在特定领域中做出比原始GPT模型更好的预测。
需要注意的是:新模型仍然在OpenAI服务器上
即使你使用自己的数据对LLM进行了微调,
新模型也仍然保存在OpenAI的服务器上
。你需要通过OpenAI API与新模型进行交互,而不是在本地使用它。
1. 选择合适的基础模型
在微调时,必须使用基础模型,而不能使用InstructGPT系列中的模型。
目前,微调仅适用于davinci、curie、babbage和ada这几个基础模型。这些模型都在准确性和所需资源之间做出了权衡。
开发人员可以为应用程序选择最合适的模型:
- 较小的模型(ada和babbage)可能在简单任务或资源有限的应用程序中更快且更具成本效益
- 较大的模型(curie和davinci)则提供了更强的语言处理和生成能力,从而适用于需要更高准确性的复杂任务。
微调后的专有能力
- 上述模型不属于InstructGPT系列,它们没有经过RLHF阶段。
- 通过微调这些
基础模型
,比如根据自定义数据集调整它们的内部权重,你可以针对特定的任务或领域定制模型。- 虽然没有InstructGPT系列的处理能力和推理能力,但是它们提供了强大的基础,让你可以利用其预训练的处理能力和生成能力来构建专门的应用程序。
2. 微调和少样本学习
2.1. 对比微调和少样本学习
模型是否进行了更新
- 微调是指针对特定任务在一组数据上
重新训练现有模型
,以提高模型的性能并使其回答更准确。在微调过程中,模型的内部参数得到更新
。- 少样本学习则是通过提示词向模型提供
有限数量的好例子
,以指导模型根据这些例子给出目标结果。在少样本学习过程中,模型的内部参数不会被修改。
都可以用来增强GPT模型
- 微调可以帮助我们得到
高度专业化的模型
,更准确地为特定任务提供与上下文相关的结果。这使得微调非常适合有大量数据可用的场景。这种定制化确保模型生成的内容更符合目标领域的特定语言模式、词汇和语气。- 少样本学习是一种更灵活的方法,其数据使用率也更高,因为它不需要重新训练模型。当只有有限的示例可用或需要快速适应不同任务时,这种技巧非常有益。
2.2. 微调需要的数据量
微调通常需要用到大量数据。可用示例的缺乏往往限制了我们使用这种技巧。
- 简单任务:为了了解微调所需的数据量,可以假设对于相对简单的任务或仅需稍微调整的模型,通过几百个提示词示例才能获得相应的目标结果。当预训练的GPT模型在任务上表现良好但需要微调以更好地与目标领域对齐时,这种方法是有效的。
- 复杂任务:对于更复杂的任务或需要更多定制化的应用场景,模型可能需要使用成千上万个示例进行训练。前述的电子邮件自动回复生成器正是这样一个应用场景。
- 专业性强的任务:针对非常专业的任务微调模型,可能需要数十万甚至数百万个示例。这种微调规模可以显著地提高模型的性能,并使模型更好地适应特定领域。
ing
迁移学习是指将从一个领域学到的知识应用于不同但相关的领域。正因为如此,你有时可能会听到人们在谈论微调时提到迁移学习。
二. 使用OpenAI API进行微调
本节使用OpenAI API来微调LLM。我们将学习如何准备数据、上传数据,并使用OpenAI API创建一个经过微调的模型。
1. 数据生成
1.1. JSONL的数据格式
更新LLM需要提供一个包含示例的数据集
。该数据集是一个JSONL文件,其中每一行对应一个<提示词:补全文本>
对,如下示例:
{"prompt": "<prompt text>", "completion": "<completion text>"}
{"prompt": "<prompt text>", "completion": "<completion text>"}
{"prompt": "<prompt text>", "completion": "<completion text>"}
...
JSONL文件是文本文件,其中每一行表示一个单独的JSON对象。你可以使用它来高效地存储大量数据。
1.2. 数据生成工具
OpenAI提供了一个工具,可以帮助你生成此训练文件。
- 该工具接受各种文件格式(CSV、TSV、XLSX、JSON或JSONL)作为输入,只要它们
包含<提示词,文本补全
,输出即可直接用于微调过程的JSONL文件。- 该工具还会验证数据,并提供改进数据质量的建议。
安装:当执行pip install openai时,该工具会自动安装。
终端使用此工具:
$ openai tools fine_tunes.prepare_data -f <LOCAL_FILE>
1.3. 数据文件的细节注意
- 工具建议:该工具会提出一系列建议来改善最终文件的结果。你既可以接受这些建议,也可以不接受,还可以指定选项
-q
,从而自动接受所有建议。- 分为训练集和验证集:如果你有足够的数据,那么该工具会询问你是否要将数据分为训练集和验证集。这是一种推荐的做法。
- 算法将使用训练集来微调模型参数。
- 验证集则用于衡量模型在未用于更新参数的数据上的性能。
- 示例审核:对LLM的微调受益于高质量示例,最好由专家审核。
- 当使用已有数据集进行微调时,请确保对数据进行筛查,以排除具有冒犯性的内容或不准确的内容。如果数据集过大而无法手动审核所有内容,则可以检查随机样本。
2. 上传数据来训练模型
准备好数据后,需要将其上传到OpenAI服务器。OpenAI API提供了不同的函数来操作文件。以下是一些重要函数。
上传文件:
openai.File.create(
file=open("out_openai_completion_prepared.jsonl", "rb"),
purpose='fine-tune'
)
# 两个参数是必需的:file和purpose。
# 在微调时,将purpose设置为fine-tune。这将验证用于微调的下载文件格式。
此函数的输出是一个字典,你可以在id字段中检索文件ID。目前,文件的总大小可以达到1 GB 。
删除文件:
openai.File.delete("file-z5mGg(...)")
列出所有已上传的文件:
openai.File.list()
3. 创建微调模型
如下:微调已上传文件是一个简单的过程。
openai.FineTune.create(
training_file='', # 给定数据集
model='', # 根据给定的数据集优化指定的模型
validation_file='',
suffix='' #
)
主要的输入参数
字段名称 | 类型 | 描述 |
---|---|---|
training_file | string | 这是唯一的必填参数,包含已上传文件的 ID。数据集必须格式化为 JSONL 文件。每个训练示例是一个带有 prompt 键和 completion 键 的 JSON 对象 |
model | string | 指定用于微调的基础模型。可选项有 ada, babbage, curie, davinci,或曾之前微调过的模型。默认的基础模型是 curie |
validation_file | string | 包含验证数据的已上传文件。该文件中的数据将仅在微调过程中用来生成验证指标 |
suffix | string | 这是一个最多由 40 个字符组成的字符串,它将被添加到自定义模型名称中 |
该函数的响应
包含排队作业的详细信息,如作业的状态、fine_tune_id,以及过程结束时模型的名称。
4. 列出微调作业
可以通过以下函数获取OpenAI服务器上的所有微调作业
openai.FineTune.list()
# 结果是一个字典,包含所有微调模型的信息。
5. 取消微调作业
可以通过以下函数立即中断在OpenAI服务器上运行的作业:
openai.FineTune.cancel()
# 只有一个必需的参数:fine_tune_id。
# 该参数是以ft-开头的字符串,例如ft-Re12otqdRaJ(...)。
# 它是在使用openai.FineTune.create创建作业后获得的。
# 如果你丢失了fine_tune_id,那么可以使用openai.FineTune.list检索它。
二. 微调的应用
微调提供了一种强大的技术手段,有助于提升模型在各类应用场景中的性能。再次提醒,微调的成本比基于提示工程的技术更高,因此在大多数情况下并非必需。不过当需要使用它时,微调可以显著地改善效果。
1. 法律文本分析
场景
在这个案例中,LLM被用来处理法律文本并提取有价值的信息。这些文档通常使用特定的行话写成,这使非专业人士很难理解其内容。
微调
通过在
特定主题
的法律语料库上对LLM进行微调,或者针对特定类型的最终用户,该模型可以更好地处理法律文本,并在执行与该特定类型的最终用户相关的任务时变得更加熟练。
成果
通过微调可以使模型专门针对特定领域完成任务,或协助非专业人士参与法律程序。
使用大量数据微调LLM,以分析法律文本,使其能够更好地处理超出提示工程技术能力范围的细微差别
。
2. 自动代码审查-类Copilot
在这个案例中,微调可以帮助模型分析开发人员编写的代码,并提出改进建议。
- 这需要在包含代码片段和注释的数据集上训练模型,使模型能够处理特定语言的语法、语义和最佳实践。
- 请注意,这个案例类似于
GitHub对Copilot的用法
,该工具旨在通过实时提供对代码和整个函数的建议来帮助开发人员编写代码。
举例:
你可以使用微调来训练模型完成特定任务,比如代码审查,如下例子:
JSONL文件可以包含代码及相应的审查评论。这将帮助模型学习如何提供准确且相关的代码质量反馈。以下是一个例子。
{"prompt": "Review the following Python code:
'def sum(a, b): return a + b\nresult = sum(5, '5')'",
"completion": "Type error: The 'sum' function is adding an integer
and a string. Consider converting the string to an integer using
int() before passing it to the function."}
3. 财务文档摘要
针对收益报告、财务报表和分析师报告等财务文档,经过微调的LLM可以生成简明、准确的摘要。
在与财务记录明确相关的数据集上微调后,LLM可以更准确地理解财务文档的术语和上下文。
这样一来,你便可以给模型提供一个包含财务文档及其理想摘要的JSONL文件。
比如,模型可以将央行关于上调利率的详细报告压缩成简洁而富有信息的摘要。要调整现有模型以获得更好的财务文档摘要,你需要拥有大量样本摘要。
{"prompt": "The central bank announced a 0.25% increase in the benchmark
interest rate, citing concerns about inflationary pressures.
This move is expected to affect borrowing costs for consumers
and businesses.",
"completion": "Bank increases rate 0.25% for inflation worry. May
affect people, business borrowing costs."}
4. 技术文档翻译
与少样本学习相比,使用微调后的模型来翻译技术文档可以显著地改善翻译效果。主要原因是,技术文档通常包含专业词汇和复杂的句子结构,少样本学习无法有效处理这种复杂性。
对于技术文档翻译的用例,该文件应该包括将技术文本翻译为目标语言的翻译内容
。
5. 为专业领域生成内容
一个经过微调的模型可以针对高度专业化的主题生成高质量、引人入胜且与上下文相关的内容。
微调模型可以显著提高客户服务聊天机器人的性能,使模型更好地理解和响应特定领域的客户查询。客户服务场景具备天然的优势,即容易收集典型客户服务对话的高质量问答集,通过用户反馈形成回路,再通过微调持续改进模型的响应质量。这使模型能够更准确地识别客户问题的本质,并提供合适的解决方案。比如,模型可以学习如何处理账户查询、故障排除或产品推荐等具体问题。
三. 微调的成本
使用微调模型的成本不低。你不仅需要支付模型训练费用,而且在模型准备好后,每次进行预测时需要支付的费用也会比使用OpenAI提供的基础模型略高一些。在我们撰写本书之时,费用如表所示,不过具体的费用会有所变化。
模型 | 训练 | 使用 |
---|---|---|
ada | 每千个标记 0.0004 美元 | 每千个标记 0.0016 美元 |
babbage | 每千个标记 0.0006 美元 | 每千个标记 0.0024 美元 |
curie | 每千个标记 0.0030 美元 | 每千个标记 0.0120 美元 |
davinci | 每千个标记 0.0300 美元 | 每千个标记 0.1200 美元 |
作为比较,gpt-3.5-turbo模型的定价是每千个输出标记0.0020美元。可见,gpt-3.5-turbo模型的性价比最高。要了解最新的模型定价,请访问OpenAI的Pricing页面。