跳到主要内容大型语言模型微调入门指南 | 极客日志PythonAI算法
大型语言模型微调入门指南
大型语言模型微调通过调整模型权重以适应特定任务,相比提示工程能以更低成本获得更好效果。核心步骤包括选择基础模型、准备高质量数据集(含提示构建与分词)、配置训练参数及监控。进阶策略涵盖参数高效微调(如 LoRA)、量化(如 QLoRA)及分布式训练(如 DeepSpeed、FSDP),有效降低资源消耗。配合 TRL 和 Accelerate 等库,可实现从数据处理到模型部署的全流程优化。
微调可以调整模型的权重,以更好地适应特定任务或领域,从而帮助我们更充分地利用预训练的大型语言模型。这意味着你能够以比纯粹的提示工程更低的成本和延迟获得更高质量的结果。
为什么要对大型语言模型进行微调?
成本效益
与提示相比,微调通常可以更有效且更高效地引导大型语言模型的行为。在一组示例上训练模型不仅可以缩短精心设计的提示,还可以节省宝贵的输入标记,同时不会牺牲质量。另外,你可以使用一个更小的模型,这反过来会降低延迟和推理的成本。
例如,与 GPT-3.5 这类现成模型相比,经过微调的 Llama 7B 模型在每个标记基础上的成本效益更高(约为 50 倍),并且性能相当。
常见用例
微调尤其适合强调基本模型中的固有知识、自定义响应的结构或语调,或教模型特定领域的指令。常见的用例包括:
- 结构化输出:生成结构化数据,如 JSON 或 HTML。
- 风格一致:生成独特风格的文本,比如模仿《纽约客》或企业 CEO 的语气。
- 领域特有的指令:企业文件的分类或特定格式的数据提取。
对于需要将附加知识嵌入基本模型的任务,例如引用企业文件,检索增强生成(Retrieval Augmented Generation, RAG)这类的技术可能更合适。你还可以结合使用微调与 RAG 系统,通过微调省却提示标记,而 RAG 为添加输入上下文提供了空间。
基础设施选择
微调最大的问题之一通常是基础设施开销,因为准备训练所需的 GPU 就需要耗费不少精力和成本。无服务器云计算平台能够帮助你轻松在云中运行代码,只需几行代码即可附加按需付费的 GPU。
许多开源项目提供了用于微调的模板,例如针对 Llama 2 和 Mistral 的微调仓库,这些模板简化了环境配置和分布式训练的启动过程。
微调步骤
1. 选择基础模型
可供我们选择的大型语言模型有很多,每个都有其独特的优势和劣势。许多模型声称在各种基准测试中是'市场上最好的开源大型语言模型',但实际上你可能需要尝试多个模型,才能确定哪个最适合自己的用例。每个开源模型家族通常还会提供多个不同大小的模型,例如 Llama 2 7B 与 Llama 2 70B。
除了这些基础模型外,还有在特定数据集上进一步微调的模型。例如 Code Llama 作为基础模型可能比普通 Llama 2 更合适,因为它已经过微调,能够生成结构化输出。
2. 准备数据集
数据集的质量是否与你希望大型语言模型执行的任务密切关联对于成功微调至关重要。你可以根据微调策略和上述基础模型的选择,按照不同的说明来格式化这个数据集。常见的结构是 JSONL 或 CSV 文件,你可以通过其对象键轻松获取数据。
为了评估训练运行的效果,你应该将数据集分割为训练集和验证集。
A. 创建提示
在大多数情况下,数据集中的每个样本在传递到模型之前都必须转换为带有指令的字符串提示。在提示中加入指令有助于引导模型根据给定的输入生成最佳输出。每个训练样本最终的结构大致如下:
Instruction: [指令内容]
Input: [输入内容]
Output: [期望输出]
请注意,在推理模型的微调时,提示必须使用的模板与训练过程中使用的模板相同,这样才能获得最佳结果。
B. 添加特殊 Token(可选)
你可能希望在创建提示时加入特殊 token,这些 token 对于模型和任务来说有着特定含义的符号。在微调时,这些 token 可作以下用途:
- 标记响应的开始和结束。
- 分隔列表中的多个项。
- 突出显示输入或输出的特定部分。
- 预定义的特殊 token:大多数基于 Transformer 的模型都带有一组预定义的特殊 token。例如,Llama-2 使用
<s> 和 </s> 作为表示句子开始和结束的特殊 token,而 BERT 则使用 [CLS]、[SEP] 等。
- 自定义的特殊 token:如果你有特定的用例需要额外的特殊 token,则可以自行定义 token。例如,在上面的示例中,
### Instruction: 和 ### Input: 都是自定义的特殊 token。
如果你想使用自定义的特殊 token,则需要实现一些额外的步骤:
- 添加 token:首先将这些 token 添加到分词器的词汇表中。
- 调整模型大小:将 token 添加到分词器后,接下来你必须调整模型的 token 嵌入大小。
值得注意的是,引入过多的新 token 可能会稀释嵌入空间,从而影响模型的性能。建议谨慎使用自定义的 token,确保它们能为模型提供有意义的信息。
C. 提示分词
到此为止,我们建立了完整的字符串提示,接下来我们需要分词。分词指的是将字符序列(如句子或段落)转换较小单元序列(即 token)的过程。这些 token 有的只有一个字符,而有些可以是一个单词。我们必须让模型掌握上述特殊 token 的原因之一就是我们需要确保分词器不会将它们分割成更小的子 token。
大多数大型语言模型都会使用专门的分词器,将文本 token 分割成子词或字符。因此,分词器与语言无关,而且还可以处理词汇表之外的单词。此外,这些分词器还可以帮助我们实现填充和截断策略,以处理数据集中序列长度的任何变化。
HuggingFace 的 transformers 库加载分词器的示例代码如下:
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("path/to/model")
3. 训练
选择基础模型并准备好数据集之后,接下来我们就可以运行训练了。训练通常包含以下步骤:
- 加载预训练的基础模型;
- 提供分词后的基于指令的训练数据;
- 调整训练配置的超参数,如学习率、批大小和迭代次数等;
- 启动训练任务,并监控在验证数据集上的性能。
训练运行的时间取决于各种因素,包括训练超参数以及:
- 数据集的大小:数据集越大,微调所需的时间也越多。
- GPU 的类型:GPU 越强大,训练模型的速度就越快。
- 基本模型的类型:模型越大,参数越多,架构越复杂,训练所需的时间也越长。
云服务平台允许你通过代码定义和打包环境、缓存模型权重以加快冷启动的速度,而且还能启动多个 GPU 进行分布式训练,因此能够降低运行训练的难度,而且还可以确保可重复性。
4. 使用高级微调策略
尽管微调大型语言模型具有许多优势,但前期可能会非常耗时,而且这是一项计算密集型任务。我们有许多策略可以使训练更快、更高效。
参数高效微调(PEFT)
大型语言模型是一个矩阵,是一个由数字(权重)填充的表,这些数字决定了其行为。传统微调通常需要据新数据略微调整所有权重。PEFT 实现了一系列技术,旨在冻结大多数参数,仅训练一小部分参数来减少内存需求,并加快微调速度。
最受欢迎的 PEFT 技术是低秩自适应(Low-Rank Adaption, LoRA)。LoRA 并非直接调整原始权重矩阵,而是简单地更新其顶部的一小部分矩阵,因此得名。这个小规模适配可以捕捉新任务所需的基本变化,同时保持原始矩阵冻结。为了获取最终结果,你需要结合原始权重与经过训练的适配器权重。
由于在使用 LoRA 进行微调时,只有一小部分权重会被更新,因为微调的速度明显更快。此外,相较于输出整个新模型,额外的'适配器'模型可以单独保存,从而大大减少内存使用。
量化
量化指的是将表示模型权重和激活的浮点数转换为整数。例如,在 8 位量化中,连续的浮点值会被映射成到 256 个离散整数值。与原始的 32 位浮点表示相比,这可以大幅缩减模型大小。
QLoRA 是一种最近开发的微调方法,它可以利用量化提高内存的使用效率,因此能够在一般的硬件上微调非常大的模型。例如,Mistral 微调模板同时使用了 4 位量化和 QLoRA 进行训练。
分布式训练
当在单个 GPU 上训练模型的速度过慢,或单个 GPU 中无法容纳模型的权重时,我们可以考虑分布式训练。让多个 GPU 处理训练状态和数据的一部分可以最大化吞吐量,即单位时间内可以处理的样本数量。
我们可以利用一些现成的框架实现跨多个 GPU 并行计算:
- DeepSpeed:DeepSpeed 是一个实现了 ZeRO 的开源库。ZeRO 是一种优化内存使用的新方法,可显著提高训练速度,而且还可以提高大型模型的训练效率,因为它可以跨多个处理器分割输入数据,还可以消除传统数据和模型并行训练方法中存在的内存冗余。
- 完全分片数据并行(FSDP):FSDP 通过跨多个 GPU 对模型参数进行分片的方式,可使用较少的 GPU 提高训练速度。假设一个模型有 10 亿个参数,而你有 4 个 GPU,则每个 GPU 可能包含 2.5 亿个参数。使用 FSDP 不仅可以并行更新这些参数,而且每个 GPU 只需加载前向或反向传递所需的参数,从而减小总体内存的使用。
5. 使用额外的微调库
- TRL (Transformer Reinforcement Learning):TRL 允许用户实现一个强化学习循环,模型会因生成某些输出而受到奖励。例如,如果你想微调一个模型,让它生成有礼貌的响应,则可以设置一个奖励函数,根据礼貌对响应进行评分,并使用 trl 来训练模型。
- Accelerate:accelerate 简化了在多个 GPU 或 CPU 上运行模型的过程,同时无需深入了解分布式计算原理。
总结
你可以根据特定的用例,通过微调大型语言模型的方式定制现有通用模型。为了更高效地微调模型,你可以考虑使用 LoRA 或模型分片(使用 FSDP 等框架)等技术。通过云端平台微调 Llama 2 或 Mistral 等开源模型可以获得一个定制的模型,这样不仅成本和延迟低于现有 API 服务,而且还非常适合自己的需求。
相关免费在线工具
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- RSA密钥对生成器
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
- Mermaid 预览与可视化编辑
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
- curl 转代码
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online