大语言模型(LLMs)在过去一年取得了显著进步。从ChatGPT爆发以来,后来逐步发展了众多开源大模型LLMs,如Meta AI的Llama 2、Mistrals Mistral & Mixtral模型,TII Falcon等。这些LLMs能够胜任多种任务,包括聊天机器人、问答和自动摘要,而且无需进行额外的训练。但是,如果你想为你的应用定制模型,可能需要在你的数据集上对模型进行微调,以获得比直接使用或训练更小型模型更高质量的结果。
本文将介绍如何使用Hugging Face的TRL、Transformers框架和数据集来微调开放的大语言模型。我们将按照以下步骤进行:
-
明确我们的使用场景
-
设置开发环境
-
创建和准备数据集
-
使用**
trl
和SFTTrainer
**微调LLM -
测试和评估LLM
-
将LLM部署到生产环境
注意:本文是为了在消费者级别的GPU(24GB)上运行而编写的,例如NVIDIA A10G或RTX 4090/3090,但也可以轻松地适应在更大的GPU上运行。
一、定义我们的使用场景
微调LLM时,了解你的使用场景和要解决的问题至关重要。这将帮助你选择合适的模型,或者帮助你创建一个数据集来微调你的模型。如果你还没有定义你的使用场景,你可能需要重新思考。并非所有的使用场景都需要微调,建议在微调你自己的模型之前,先评估和尝试已经微调过的模型或基于API的模型。
例如,我们将使用以下使用场景:
我们想要微调一个模型,它可以基于自然语言指令生成SQL查询,然后可以集成到我们的BI工具中。目标是减少创建SQL查询所需的时间,并使非技术用户更容易创建SQL查询。
将自然语言转换为SQL查询是一个很好的微调LLM的使用场景,因为它是一个复杂的任务,需要对数据和SQL语言有深入的理解。
二、设置开发环境
首先,我们需要安装Hugging Face的库,包括trl、transformers和datasets,以及Pytorch。trl是一个新库,建立在transformers和datasets之上,它简化了微调大语言模型的过程,包括rlhf(强化学习从人类反馈中学习)和对齐开放LLM。如果你对trl还不太熟悉,不用担心,它是一个新工具,旨在让微调过程更加便捷。
# 安装Pytorch和其他库
!pip install "torch==2.1.2" tensorboard
# 安装Hugging Face库
!pip install --upgrade \
"transformers==4.36.2" \
"datasets==2.16.1" \
"accelerate==0.26.1" \
"evaluate==0.4.1" \
"bitsandbytes==0.42.0" \
# "trl==0.7.10" # \
# "peft==0.7.1" \
# 从github安装peft & trl
!pip install git+https://github.com/huggingface/trl@a3c5b7178ac4f65569975efadc97db2f3749c65e --upgrade
!pip install git+https://github.com/huggingface/peft@4a1559582281fc3c9283892caea8ccef1d6f5a4f--upgrade
如果你的GPU采用的是Ampere架构(如NVIDIA A10G或RTX 4090/3090)或更新版本,你可以利用Flash Attention技术。Flash Attention通过优化注意力机制的计算过程,并采用一些经典技术(如分块和重新计算)来显著提高计算速度,并降低内存消耗。简而言之,这项技术可以将训练速度提升至原来的三倍。想要了解更多详情,可以访问FlashAttention的官方页面。
注意:如果你的计算机内存不足96GB且拥有大量CPU核心,你可能需要调整_MAX_JOBS的数值。在我们的测试中,使用的是g5.2xlarge实例,设置了4_个作业。
import torch; assert torch.cuda.get_device_capability()[0] >= 8, 'Hardware not supported for Flash Attention'
# install flash-attn
!pip install ninja packaging
!MAX_JOBS=4 pip install flash-attn --no-build-isolation
安装Flash Attention可能需要一段时间(大约10到45分钟)。
我们将利用Hugging Face Hub作为一个远程模型版本控制服务。这意味着在训练过程中,我们的模型、日志和相关信息将自动上传到Hugging Face Hub。为了使用这项服务,你需要在Hugging Face上注册一个账户。注册完成后,我们会使用huggingface_hub
包中的登录工具来登录你的账户,并在本地磁盘上保存你的访问令牌。
from huggingface_hub import login
login(
token="", # 在此处添加您的token
add_to_git_credential=True
)
三、创建和准备数据集
一旦您确定微调是正确的解决方案,我们需要准备一个数据集来训练我们的模型。这个数据集应该是多样化的任务示范,展示了你想要解决的问题。创建数据集的方法有很多,比如:
-
利用现有的开源数据集,如
Spider
-
利用大语言模型生成合成数据集,如
Alpaca
-
雇佣人类来创建数据集,如
Dolly
-
结合以上方法,如
Orca
每种方法都有其自身的优势和劣势,并取决于预算、时间和质量要求。例如,使用现有数据集是最简单的,但可能不针对你的特定使用场景,而人工创建数据集虽然准确度高,但成本和时间消耗也大。也可以将几种方法结合起来创建指令数据集,如_Orca: Progressive Learning from Complex Explanation Traces of GPT-4_所示。
在我们的示例中,我们将使用一个名为 sql-create-context
的现有数据集,它包含了自然语言指令、数据库模式定义以及相应的SQL查询样本。
随着trl的最新版本发布,我们现在支持流行的指令和对话数据集格式。这意味着我们只需将数据集转换为支持的格式之一,trl就会自动处理后续步骤。支持的格式包括:
- 对话格式
{"messages": [{"role": "system", "content": "You are..."}, {"role": "user", "content": "..."}, {"role": "assistant", "content": "..."}]}{"messages": [{"role": "system", "content": "You are..."}, {"role": "user", "content": "..."}, {"role": "assistant", "content": "..."}]}{"messages": [{"role": "system", "content": "You are..."}, {"role": "user", "content": "..."}, {"role": "assistant", "content": "..."}]}
- 指令格式
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}{"prompt": "<prompt text>", "completion": "<ideal generated text>"}{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
我们将使用Hugging Face的Datasets库来加载我们的开源数据集,并将其转换为对话格式。在这种格式中,我们将在系统消息中包含数据库模式定义,作为我们助手的信息。然后,我们将数据集保存为jsonl文件,这样就可以用于微调我们的模型。我们对数据集进行了随机下采样,只保留了10,000个样本。
注意:如果你已经有了一个数据集,比如通过与OpenAI合作获得的,你可以跳过这一步,直接进行微调。
from datasets import load_dataset
# 将数据集转换为OAI消息
system_message = """您是SQL查询翻译的文本。用户将用英语向您提问,您将根据提供的SCHEMA生成SQL查询。
SCHEMA:
{schema}"""
def create_conversation(sample):
return {
"messages": [
{"role": "system", "content": system_message.format(schema=sample["context"])},
{"role": "user", "content": sample["question"]},
{"role": "assistant", "content": sample["answer"]}
]
}
# 从hub加载数据集
dataset = load_dataset("b-mc2/sql-create-context", split="train")
dataset = dataset.shuffle().select(range(12500))
# 将数据集转换为OAI消息
dataset = dataset.map(create_conversation, remove_columns=dataset.features,batched=False)
# 将数据集拆分为10000个训练样本和2500个测试样本
dataset = dataset.train_test_split(test_size=2500/12500)
print(dataset["train"][345]["messages"])
# 将数据集保存到磁盘
dataset["train"].to_json("train_dataset.json", orient="records")
dataset["test"].to_json("test_dataset.json", orient="records")
四、使用trl和SFTTrainer微调大语言模型
现在,我们准备开始微调我们的模型。我们将使用trl中的SFTTrainer来微调我们的模型。它简化了对开放的大语言模型进行监督式微调的过程。SFTTrainer是transformers库中Trainer的一个衍生类,它继承了所有核心功能,如日志记录、评估和模型检查点,并增加了一些实用功能,例如:
-
数据集格式转换,支持对话和指令格式
-
仅在数据集完成时进行训练,忽略掉提示信息
-
数据集打包,以提高训练效率
-
参数高效微调(PEFT)支持,包括Q-LoRA技术
-
为对话微调准备模型和标记器(例如添加特殊标记)
在我们的示例中,我们将利用数据集格式转换、数据集打包和参数高效微调(PEFT)功能。我们将采用QLoRA技术,这是一种通过量化来减少大型语言模型在微调过程中的内存占用,同时保持模型性能的方法。
标签:tokenizer,LLMs,模型,Hugging,dataset,import,model,Face,我们 From: https://blog.csdn.net/python1234_/article/details/141671002