首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

大型语言模型微调入门指南

作者 | Modal       译者 | 弯月

责编 | 夏萌

出品 | CSDN(ID:CSDNnews)

微调可以调整模型的权重,以更好地适应特定任务或领域,从而帮助我们更充分地利用预训练的大型语言模型。这意味着你能够以比纯粹的提示工程更低的成本和延迟获得更高质量的结果。在本文中,我们将简要介绍大型语言模型的微调,以及如何使用Modal实现最先进的微调技术。

为什么要对大型语言模型进行微调?

成本效益

与提示相比,微调通常可以更有效且更高效地引导大型语言模型的行为。在一组示例上训练模型不仅可以缩短精心设计的提示,还可以节省宝贵的输入标记,同时不会牺牲质量。另外,你可以使用一个更小的模型,这反过来会降低延迟和推断的成本。

例如,与 GPT-3.5 这类的现成模型相比,经过微调的Llama 7B模型在每个标记基础上的成本效益更高(约为50倍),并且性能相当。

常见用例

微调尤其适合强调基本模型中的固有知识、自定义响应的结构或语调,或教模型特定领域的指令。常见的用例包括:

结构化输出:生成结构化数据,如JSON或HTML。

风格一致:生成独特风格的文本,比如 The New Yorker or your CEO(https://github.com/modal-labs/doppel-bot)。

领域特有的指令:企业文件的分类。

对于需要将附加知识嵌入基本模型的任务,例如引用企业文件,检索增强生成(Retrieval Augmented Generation,RAG)这类的技术可能更合适。你还可以结合使用微调与RAG系统,通过微调省却提示标记,而 RAG 为添加输入上下文提供了空间。

通过 Modal 微调

Modal是一个无服务器的云计算平台,能够帮助你轻松在云中运行代码。微调最大的问题之一通常是基础设施开销,因为准备训练所需的GPU就需要耗费不少精力和成本。而 Modal 只需几行代码即可附加按需付费的GPU。

Modal提供了许多用于微调开源大型语言模型的即用模板:

Llama 2(https://github.com/modal-labs/llama-finetuning/tree/main)

Mistral(https://github.com/modal-labs/mistral-finetuning)

微调步骤

1.选择基础模型

可供我们选择的大型语言模型有很多,每个都有其独特的优势和劣势。许多模型声称在各种基准测试中是“市场上最好的开源大型语言模型”,但实际上你可能需要尝试多个模型,才能确定哪个最适合自己的用例。每个开源模型家族通常还会提供多个不同大小的模型,例如 Llama 2 7B 与 Llama 2 70B。

除了这些基础模型外,还有在特定数据集上进一步微调的模型。例如:

我们可以利用这些已经过微调的模型尝试微调。举个例子,如果你想生成结构化输出,那么 Code Llama 作为基础模型可能比普通的 Llama 2 更合适,因为前者已经过微调,能够生成成结构化输出(尽管可能不是你想要的格式)。

2.准备数据集

数据集的质量是否与你希望大型语言模型执行的任务密切关联对于成功微调至关重要。你可以根据微调策略和上述基础模型的选择,按照不同的说明来格式化这个数据集。常见的结构是 JSONL 或 CSV 文件,你可以通过其对象键轻松获取数据。例如:

为了评估训练运行的效果,你应该将数据集分割为训练集和验证集。

A.创建提示

在大多数情况下,数据集中的每个样本在传递到模型之前都必须转换为带有指令的字符串提示。在提示中加入指令有助于引导模型根据给定的输入生成最佳输出。每个训练样本最终的结构大致如下:

请注意,在推理模型的微调时,提示必须使用的模板与训练过程中使用的模板相同,这样才能获得最佳结果。

B.添加特殊token(可选)

你可能希望在创建提示时加入特殊token,这些token对于是模型和任务来说有着特定含义的符号。

在微调时,这些 token 可作以下用途:

标记响应的开始和结束。

分隔列表中的多个项。

突出显示输入或输出的特定部分。

特殊token有两种类型:

预定义的特殊token:大多数基于 Transformer 的模型都带有一组预定义的特殊token。例如,Llama-2 使用 作为表示系统提示的开始和结束的特殊token,而 BERT 则使用[CLS]、[SEP] 等。这些token具有特殊含义,在预训练和微调过程中都以特定方式使用。

自定义的特殊token:如果你有特定的用例需要额外的特殊token,则可以自行定义token。例如,在上面的示例中,### Instruction: 和 ### Input: 都是自定义的特殊token,分别用于告诉模型接下来是指令或输入。

如果你想使用自定义的特殊token,则需要实现一些额外的步骤:

添加token:首先将这些token添加到分词器的词汇表中。

调整模型大小:将token添加到分词器后,接下来你必须调整模型的token嵌入大小:

使用:添加完token后,你就可以在数据集中使用这些token了,而模型在微调过程中也可以识别它们。

值得注意的是,引入过多的新token可能会稀释嵌入空间,从而影响模型的性能。建议谨慎使用自定义的token,确保它们能为模型提供有意义的信息。

C.提示分词

到此为止,我们建立了完整的字符串提示,接下来我们需要分词。分词指的是将字符序列(如句子或段落)转换较小单元序列(即token)的过程。这些token有的只有一个字符,而有些可以是一个单词。我们必须让模型掌握上述特殊token的原因之一就是我们需要确保分词器不会将它们分割成更小的子token。

大多数大型语言模型都会使用专门的分词器,将文本token分割成子词或字符。因此,分词器与语言无关,而且还可以处理词汇表之外的单词。此外,这些分词器还可以帮助我们实现填充和截断策略,以处理数据集中序列长度的任何变化。请注意,加载模型时需要指定分词器的部分原因是每个模型使用的分词器都不相同。你可以使用 AutoTokenizer 来解决这个问题,它会自动为模型选择合适的分词器。

HuggingFace的 transformers 库加载分词器的示例代码如下:

3.训练

选择基础模型并准备好数据集之后,接下来我们就可以运行训练了。训练通常包含以下步骤:

加载预训练的基础模型;

提供分词后的基于指令的训练数据;

调整训练配置的超参数,如学习率、批大小和迭代次数等;

启动训练任务,并监控在验证数据集上的性能。

训练运行的时间取决于各种因素,包括训练超参数以及:

数据集的大小:数据集越大,微调所需的时间也越多。

GPU 的类型:GPU 越强大,训练模型的速度就越快。

基本模型的类型:模型越大,参数越多,架构越复杂,训练所需的时间也越长。

Modal允许你通过代码定义和打包环境、缓存模型权重以加快冷启动的速度,而且还能启动最多8个任何类型的GPU进行分布式训练,因此能够降低运行训练的难度,而且还可以确保可重复性。

4.使用高级微调策略

尽管微调大型语言模型具有许多优势,但前期可能会非常耗时,而且这是一项计算密集型任务。我们有许多策略可以使训练更快、更高效。以下是其中一些受欢迎的策略:

参数高效微调(Parameter-EfficientFine-Tuning,即PEFT)

大型语言模型是一个矩阵,是一个由数字(权重)填充的表,这些数字决定了其行为。传统微调通常需要据新数据略微调整所有权重。PEFT 实现了一系列技术,旨在冻结大多数参数,仅训练一小部分参数来减少内存需求,并加快微调速度。最受欢迎的PEFT技术是低秩自适应(Low-Rank Adaption,即LoRA),LoRA并非直接调整原始权重矩阵,而是简单地更新其顶部的一小部分矩阵,因此得名。这个小规模适配可以捕捉新任务所需的基本变化,同时保持原始矩阵冻结。为了获取最终结果,你需要结合原始权重与经过训练的适配器权重。

由于在使用LoRA进行微调时,只有一小部分权重会被更新,因为微调的速度明显更快。此外,相较于输出整个新模型,额外的“适配器”模型可以单独保存,从而大大减少内存使用。

量化

量化指的是将表示模型权重和激活的浮点数转换为整数。

例如,在8位量化中,连续的浮点值会被映射成到256个离散整数值。与原始的32位浮点表示相比,这可以大幅缩减模型大小。

QLoRA是一种最近开发的微调方法,它可以利用量化提高内存的使用效率,因此能够在一般的硬件上微调非常大的模型。

举个例子,Modal的Mistral微调模板同时使用了4位量化和 QLoRA 进行训练。

分布式训练

当在单个GPU上训练模型的速度过慢,或单个GPU中无法容纳模型的权重时,我们可以考虑分布式训练。让多个GPU处理训练状态和数据的一部分可以最大化吞吐量,即单位时间内可以处理的样本数量。

我们可以利用一些现成的框架实现跨多个GPU并行计算:

A. DeepSpeed

DeepSpeed是一个实现了ZeRO 的开源库。ZeRO是一种优化内存使用的新方法,可显著提高训练速度,而且还可以提高大型模型的训练效率,因为它可以跨多个处理器分割输入数据,还可以消除传统数据和模型并行训练方法中存在的内存冗余。

根据官方测试,ZeRO 能够使用400个GPU训练具有超过1000亿参数的模型,达到15Petaflops的吞吐量。

ZeRO/DeepSpeed的优势在于,它简化了训练过程。例如,它可以训练具有高达130亿参数的模型,而无需并行化处理模型。对于研究人员来说,模型的并行性非常复杂且难以实现,因此使用 ZeRO 有很大的帮助。

B. 完全分片数据并行(Fully Sharded Data Parallel,即FSDP)

FSDP通过跨多个 GPU 对模型参数进行分片的方式,可使用较少的 GPU 提高训练速度。

举个例子,假设一个模型有10亿个参数,而你有4个GPU,则每个GPU可能包含2.5亿个参数。使用 FSDP不仅可以并行更新这些参数,而且每个 GPU 只需加载前向或反向传递所需的参数,从而减小总体内存的使用。

FSDP是一个相对简单且易于入门的分布式训练方法。如果你不熟悉分布式并行训练,建议使用 FSDP,只有当 FSDP 没有提供你所需的尖端功能时再考虑使用 DeepSpeed。

Modal的llama-finetuning框架实现了使用FSDP进行训练。

5.使用额外的微调库

trl

TRL允许用户实现一个强化学习循环,模型会因生成某些输出而受到奖励。

例如,如果你想微调一个模型,让它生成有礼貌的响应,则可以设置一个奖励函数,根据礼貌对响应进行评分,并使用trl来训练模型。

accelerate

accelerate简化了在多个GPU或CPU上运行模型的过程,同时无需深入了解分布式计算原理。

总结

你可以根据特定的用例,通过微调大型语言模型的方式定制现有通用模型。

为了更高效地微调模型,你可以考虑使用 LoRA 或模型分片(使用FSDP等框架)等技术。Modal的Llama和Mistral微调模板实现了许多这类的技术,能够帮助你快速启动分布式训练任务。

你可以通过在 Modal 上微调 Llama 2 或Mistral 等开源模型获得一个定制的模型,这样不仅成本和延迟低于现有 API 服务,而且还非常适合自己的需求。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OzRDluuXVtNrR7r8umiE-LGA0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券