基于LoRA技术的Mistral模型高效微调框架
mistral-finetune是一个基于LoRA技术的轻量级框架,通过仅训练1-2%的额外权重来实现Mistral模型的高效微调。该框架支持多GPU单节点训练,适合A100或H100 GPU使用。它提供简化的数据格式要求和验证工具,支持指令跟随和函数调用等多种训练模式,适用于各类微调需求。
mistral-finetune
是一个轻量级代码库,能够实现Mistral模型的内存高效和高性能微调。
它基于LoRA,这是一种训练范式,其中大部分权重被冻结,只有1-2%的额外权重以低秩矩阵扰动的形式被训练。
为了最大效率,建议使用A100或H100 GPU。该代码库针对多GPU单节点训练设置进行了优化, 但对于较小的模型,如7B,单个GPU就足够了。
注意
- 本仓库的目标是提供一个简单的、有指导的入口点来微调Mistral模型。 因此,它相当有主见(特别是在数据格式方面),并不旨在涵盖 多种模型架构或硬件类型。 对于更通用的方法,你可以查看一些其他优秀的项目,如 torchtune。
2024年8月13日: Mistral Large v2现在与mistral-finetune
兼容!
model_id_or_path
设置为下载的检查点目录。seq_len
设置为<= 8192。2024年7月19日: Mistral Nemo现在与mistral-finetune
兼容!
model_id_or_path
设置为下载的检查点目录。pip install --upgrade mistral-common
以获取支持Tekkenizer的版本(>=1.3.1
)。seq_len
设置为<= 16384。要开始使用Mistral LoRA微调,请按以下步骤操作:
cd $HOME && git clone https://github.com/mistralai/mistral-finetune.git
cd mistral-finetune
pip install -r requirements.txt
我们建议微调以下官方Mistral模型之一,您可以在此处下载:
模型 | 链接 | 校验和 |
---|---|---|
7B Base V3 | 7B Base | 0663b293810d7571dad25dae2f2a5806 |
7B Instruct v3 | 7B Instruct v3 | 80b71fcb6416085bcb4efad86dfb4d52 |
8x7B Base V1 | 8x7B Base | (HF 链接) |
8x7B Instruct V1 | 8x7B Instruct | 8e2d3930145dc43d3084396f49d38a3f |
8x22 Instruct V3 | 8x22 Instruct | 471a02a6902706a2f1e44a693813855b |
8x22B Base V3 | 8x22B Base | a2fa75117174f87d1197e3a4eb50371a |
12B Instruct | 12B Instruct (Mistral-Nemo) | 296fbdf911cb88e6f0be74cd04827fe7 |
12B Base | 12 Base (Mistral-Nemo) | c5d079ac4b55fc1ae35f51f0a3c0eb83 |
Mistral Large 2 | 123B Instruct (Large v2) | fc602155f9e39151fba81fcaab2fa7c4 |
重要提示:对于8x7B Base V1和8x7B Instruct V1,在微调之前需要使用我们的v3分词器并将词汇表大小扩展到32768。有关此过程的详细说明,请参阅"模型扩展"部分。
例如,要下载7B-base模型,您可以运行以下命令:
mkdir -p ~/${HOME}/mistral_models cd ${HOME} && wget https://models.mistralcdn.com/mistral-7b-v0-3/mistral-7B-v0.3.tar tar -xf mistral-7B-v0.3.tar -C mistral_models
确保修改您的训练脚本,并将下载文件夹的路径添加为model_id_or_path
。
例如,修改example/7B.yaml以包含$HOME/mistral_models/7B
的绝对路径:
model_id_or_path: "/Users/johndoe/mistral_models/7B"
为确保有效训练,mistral-finetune
对训练数据的格式有严格要求。
所有数据文件必须以jsonl格式存储。
您可以构建两种类型的数据文件:
预训练数据对应于存储在"text"
键中的纯文本数据。例如:
{"text": "文档1中包含的文本"} {"text": "文档2中包含的文本"}
目前支持两种不同类型的指令跟随数据:
"messages"
键中的对话数据。每个列表项是一个包含"content"
和"role"
键的字典。"role"
是一个字符串,可以是"user"、"assistant"或"system"之一。只有当"role" == "assistant"时才会计算损失。例如:{ "messages": [ { "role": "user", "content": "文档1中包含的用户交互1" }, { "role": "assistant", "content": "文档1中包含的机器人交互1" }, { "role": "user", "content": "文档1中包含的用户交互2" }, { "role": "assistant", "content": "文档1中包含的机器人交互2" } ] } { "messages": [ { "role": "user", "content": "文档2中包含的用户交互1" }, { "role": "assistant", "content": "文档2中包含的机器人交互1" }, { "role": "user", "content": "文档2中包含的用户交互2" }, { "role": "assistant", "content": "文档2中包含的机器人交互2", "weight": 0, # 不对交互2进行训练 }, { "role": "user", "content": "文档2中包含的用户交互3" }, { "role": "assistant", "content": "文档2中包含的机器人交互3" } ] }
"messages"
键中的对话数据。每个列表项是一个包含"role"
和"content"
或"tool_calls"
键的字典。"role"
是 一个字符串,可以是"user"、"assistant"、"system"或"tool"之一。只有当"role" == "assistant"时才会计算损失。
注意:在函数调用中,"tool_calls"的"id"和"tool_call_id"是随机生成的恰好9个字符的字符串。我们建议在数据准备脚本中自动生成这些字符串,就像这里所做的那样。例如:
{ "messages": [ { "role": "system", "content": "你是一个有权访问以下函数的有用助手,你可以在需要时使用这些函数来帮助用户" }, { "role": "user", "content": "你能帮我生成"listen"这个词的字谜吗?" }, { "role": "assistant", "tool_calls": [ { "id": "TX92Jm8Zi", "type": "function", "function": { "name": "generate_anagram", "arguments": "{\"word\": \"listen\"}" } } ] }, { "role": "tool", "content": "{\"anagram\": \"silent\"}", "tool_call_id": "TX92Jm8Zi" }, { "role": "assistant", "content": ""listen"这个词的字谜是"silent"。" }, { "role": "user", "content": "太神奇了!你能为"race"这个词生成一个字谜吗?" }, { "role": "assistant", "tool_calls": [ { "id": "3XhQnxLsT", "type": "function", "function": { "name": "generate_anagram", "arguments": "{\"word\": \"race\"}" } } ] } ], "tools": [ { "type": "function", "function": { "name": "generate_anagram", "description": "生成给定单词的字谜", "parameters": { "type": "object", "properties": { "word": { "type": "string", "description": "要生成字谜的单词" } }, "required": [ "word" ] } } } ] }
在开始训练之前,你应该验证你的数据集格式是否正确,并估算训练时间。你可以使用./utils/validate_data脚本来完成这个任务。
注意,这一步对于确保数据格式正确至关重要。
让我们通过一个简单的例子来训练一个指令遵循模型:
创建数据文件夹并进入该文件夹。
cd $HOME && mkdir -p data && cd $HOME/data
将数据加载到Pandas DataFrame中。
注意:确保已安装pandas和pyarrow(pip install pandas pyarrow
)。
import pandas as pd df = pd.read_parquet('https://huggingface.co/datasets/HuggingFaceH4/ultrachat_200k/resolve/main/data/test_gen-00000-of-00001-3d4cd8309148a71f.parquet')
df_train=df.sample(frac=0.95,random_state=200) df_eval=df.drop(df_train.index)
df_train.to_json("ultrachat_chunk_train.jsonl", orient="records", lines=True) df_eval.to_json("ultrachat_chunk_eval.jsonl", orient="records", lines=True)
修改example/7B.yaml,包含$HOME/data/ultrachat_chunk_train.jsonl
的绝对路径以及训练的数据集混合权重,并包含$HOME/data/ultrachat_chunk_eval.jsonl
用于评估,例如:
data:
instruct_data: "/Users/johndoe/data/ultrachat_chunk_train.jsonl"
eval_instruct_data: "/Users/johndoe/data/ultrachat_chunk_eval.jsonl"
现在你可以验证你的训练yaml文件,确保数据格式正确,并估算训练时间。
cd $HOME/mistral-finetune
python -m utils.validate_data --train_yaml example/7B.yaml
完成后,你应该会看到一份错误报告,其中包含许多如下的错误:
数据集/Users/johndoe/data/ultrachat_chunk_eval.jsonl的第1412行格式不正确。最后一个角色应该是:[assistant]中的一个,但得到的是user
数据集/Users/johndoe/data/ultrachat_chunk_eval.jsonl的第1413行格式不正确。最后一个角色应该是:[assistant]中的一个,但得到的是user
数据集/Users/johndoe/data/ultrachat_chunk_eval.jsonl的第1414行格式不正确。最后一个角色应该是:[assistant]中的一个,但得到的是user
数据集/Users/johndoe/data/ultrachat_chunk_eval.jsonl的第1415行格式不正确。最后一个角色应该是:[assistant]中的一个,但得到的是user
许多对话似乎以'user'角色结束,这是不必要的,因为我们只训练'assistant'消息,这样会不必要地处理数据。
你可以使用./utils/reformat_data.py来修正数据:
cd $HOME/mistral-finetune
python -m utils.reformat_data $HOME/data/ultrachat_chunk_train.jsonl
python -m utils.reformat_data $HOME/data/ultrachat_chunk_eval.jsonl
你应该会看到一些样本被跳过。
在修正数据集后,再次运行脚本
cd $HOME/mistral-finetune
python -m utils.validate_data --train_yaml example/7B.yaml
你应该会得到数据输入和训练参数的摘要:
训练状态
--------------------
{
"expected": {
"eta": "00:52:44",
"data_tokens": 25169147,
"train_tokens": 131072000,
"epochs": "5.21",
"max_steps": 500,
"data_tokens_per_dataset": {
"/Users/johndoe/data/ultrachat_chunk_train.jsonl": "25169147.0"
},
"train_tokens_per_dataset": {
"/Users/johndoe/data/ultrachat_chunk_train.jsonl": "131072000.0"
},
"epochs_per_dataset": {
"/Users/johndoe/data/ultrachat_chunk_train.jsonl": "5.2"
}
},
}
将max_steps
设置为500会导致大约遍历数据集5次,这是合理的,但可能有点太多。下面显示了一个推荐的设置,在8xH100集群上只需30分钟。
接下来,让我们看一个更高级的用例,即在函数调用上微调模型。 函数调用要求数据格式如上面所解释的。让我们看一个例子。
创建数据文件夹并进入该文件夹。
cd $HOME && mkdir -p data && cd $HOME/data
将数据加载到Pandas DataFrame中。
注意:确保已安装pandas和pyarrow(pip install pandas pyarrow
)。
import pandas as pd df = pd.read_parquet('https://huggingface.co/datasets/Locutusque/function-calling-chatml/resolve/main/data/train-00000-of-00001-f0b56c6983b4a78f.parquet')
df_train=df.sample(frac=0.95,random_state=200) df_eval=df.drop(df_train.index)
df_train.to_json("glaive_train.jsonl", orient="records", lines=True) df_eval.to_json("glaive_eval.jsonl", orient="records", lines=True)
如我们所见,该数据集不符合所需的函数调用格式,因此需要重新格式化。除其他事项外,"from"应重命名为"user",多余的"\n"字符应被删除。
对于这个数据集,你可以使用./utils/reformat_data_glaive.py
:
cd $HOME/mistral-finetune
python -m utils.reformat_data_glaive $HOME/data/glaive_train.jsonl
python -m utils.reformat_data_glaive $HOME/data/glaive_eval.jsonl
运行这个命令将确保大多数样本符合正确的格式。
注意:不可能编写适用于所有类型数据集的重新格式化脚本。 如果你有尚未遵循上述所需格式的数据集,你很可能需要 自己创建一个重新格式化脚本(mistral-chat或chat-gpt是你最好的朋友!)。
现在你可以通过在example/7B.yaml
中将data.instruct_data
和data.eval_instruct_data
分别设置为
$HOME/data/glaive_train.jsonl
和$HOME/data/glaive_eval.jsonl
来验证数据集。
重新格式化的数据集仍然有一些错误,可以通过--create_corrected
来移除。为此,确保添加
--create_corrected
,如下所示:
cd $HOME/mistral-finetune
python -m utils.validate_data --train_yaml example/7B.yaml --create_corrected
运行此命令将显示几个错误并保存两个新数据集 $HOME/data/glaive_train.jsonl.corrected
和 $HOME/data/glaive_eval.jsonl.corrected
。确保在 example/7B.yaml
中使用这两个数据集并再次运行该命令。现在数据集应该格式正确了!
在按照数据集验证部分操作后 ,我们现在可以开始训练了。
为了加快训练速度,我们建议将 max_steps 设置为仅 300。确保将 run_dir
定义为您的实验文件夹,并可选择设置 wandb_project
为 Weights & Biases 项目以进行日志记录,例如:
max_steps: 300
run_dir: "/Users/johndoe/ultra_chat_test"
wandb.project: ultra_chat
您也可以选择设置 wandb
保存训练配置并开始训练!确保将 --nproc-per-node
设置为可用的 GPU 数量。
cd $HOME/mistral-finetune
torchrun --nproc-per-node 8 --master_port $RANDOM -m train example/7B.yaml
在 8 个 H100 节点上训练 ultra-chat 应该需要大约 30 分钟,结果权重应该能得到约 6.3 的 MT Bench 分数。
在 8 个 H100 节点上训练 glaive 应该需要大约 1 小时,结果权重应该能很好地用于函数调用。
示例 mistral-finetune/examples/7B
定义了合理的学习率、权重衰减等参数...但建议您根据使用情况自定义这些设置。
通常,训练配置应填写以下参数:
model_id_or_path
定义开始训练的模型。这可以是预训练模型的路径或本地模型目录。run_dir
定义存储训练检查点和指标的目录。seq_len
定义训练的序列长度。这是模型将处理的输入序列的最大长度。样本会被打包以达到 seq_len
长度,以获得最大的训练效率。batch_size
定义每个 GPU 使用的训练样本数。注意:所有 GPU 上的总有效批量大小(以 token 为单位)等于 num_gpus
x batch_size
x seq_len
。max_steps
定义最大训练步数。这是训练过程将运行的总迭代次数。可以根据您的具体训练情况进行调整。训练期间看到的总 token 数是 max_steps
x num_gpus
x batch_size
x seq_len
。optim.lr
定义学习率。这是优化器的初始学习率。optim.weight_decay
定义权重衰减。权重衰减是一种正则化技术,通过惩罚大权重来防止过拟合。我们建议保持在 0.1。optim.pct_start
定义用于学习率预热阶段的总训练步数百分比,然后开始降低。它对应于 PyTorch 的 OneCycleLR 中的 pct_start。lora.rank
定义 LoRA(低秩适应)适配器的大小。我们建议 64 或更小,这调整了 LoRA 中使用的低秩分解的秩。seed
定义初始化和数据洗牌/采样的随机种子。设置种子确保结果的可重复性。log_freq
定义日志记录频率。这指定多少步记录一次训练指标。data.instruct_data
是用于训练的指令数据的路径。此字段必须按上述格式填写一个或多个数据源。每个数据源应该是一个 jsonl 文件的路径,或者是包含 jsonl 文件的目录路径,后面跟着一个权重来定义该数据集的重要性:<path/to/data_source>:<weight>
。例如:data.instruct_data: "/path/to/data1.jsonl:5.,/path/to/data2.jsonl:1.,/path/to/dir_of_jsonls:1."
data.data
是可选的额外预训练数据的路径,格式如上所述。注意,此字段可以留空。data.eval_instruct_data
是可选的评估指令数据的路径,用于在每 eval_freq
步进行交叉验证。交叉验证指标显示为 loss
和 perplexity
。eval_freq
定义多少步评估一次模型。这指定在验证集上评估模型的间隔。no_eval
是启用或禁用中间评估的标志。将其设置为 False 可在训练期间进行定期评 估。ckpt_freq
定义多少步保存一次检查点。这指定保存模型状态的间隔。save_adapters
定义是只保存训练好的 LoRA 检查点,还是将训练好的 LoRA 直接合并到基础模型中并保存。注意:当设置 save_adapters=False
时,确保您有足够的 CPU 和 GPU 内存在单个进程上保存完整模型(这通常只适用于 7B 模型)。wandb.key
用于传递您的 Weights & Biases (wandb) API 密钥以进行日志记录。这允许您将训练指标记录到 wandb 仪表板。wandb.project
定义 wandb 项目名称。训练运行将在 wandb 界面中的此项目中记录。一旦您的模型训练完成,您应该尝试进行推理。我们推荐使用 mistral-inference。
确保正确安装了 mistral_inference
:
pip install mistral_inference
假设您的 lora.safetensors
保存在 $HOME/ultra_chat_test/checkpoints/checkpoint_000300/consolidated/lora.safetensors
下,您可以使用 mistral_inference
与模型聊天,例如:
mistral-chat /mnt/slow/runs/patrick/mistral-finetune/7B/ --max_tokens 256 --temperature 1.0 --instruct --lora_path $HOME/ultra_chat_test/checkpoints/checkpoint_000300/consolidated/lora.safetensors
我们已添加了对 Weights and Biases 的明确支持,以帮助您监控和可视化您的训练运行。这种集成允许您轻松记录各种指标并跟踪实验。
要在 mistral-finetune
中使用 Weights and Biases,请按照以下步骤操作:
安装 Weights and Biases:
确保您已安装 wandb
库。您可以使用 pip 安装:
pip install wandb
一旦训练开 始,您可以通过访问您的 wandb 项目仪表板实时监控进度。所有指标,包括训练损失、评估损失、学习率等,都将被记录和可视化。
有关如何使用 wandb 的更多详细信息,请访问 Weights and Biases 文档。
重要提示:请注意,只能微调与 v3 分词器兼容的 mistral 模型,这意味着模型的词汇表大小为 32768 - 而不是 32000。但是,可以使用以下方法轻松将词汇表大小为 32000 的旧版本扩展到 32768:
python -m utils.extend_model_vocab --original_model_ckpt /folder/to/old/model --extended_model_ckpt /folder/to/extended/model
扩展完成后,可以使用 /folder/to/extended/model
中新创建的模型检查点进行微调。
- 微调 MoE 的最佳实践是什么?
我们在微调 MoE 模型时观察到更高程度的性能变异。用不同的种子微调 MoE 模型导致性能高度变异并不罕见。我们没有在密集模型中观察到如此高的变异。因此,我们建议在 MoE 模型上运行多个相同的微调过程实例,并选择表现最好的一个。
- 我如何确定模型训练过程中使用的 token 数量?
您可以使用以下脚本来查找:https://github.com/mistralai/mistral-finetune/blob/main/utils/validate_data.py。这个脚本接受一个 .yaml 训练文件作为输入,并返回模型正在训练的 token 数量。
- 如果遇到 CUDA 内存不足错误,我该怎么办?
一个可能的解决方案是减少每个 GPU 的批量大小。批量大小等于 seq_len
x batch_size
。尝试将 batch_size
设置为 1 并减少 seq_len
。您可以在 .yaml 文件中定义 batch_size
和 seq_len
。
AI助力,做PPT更简单!
咔片是一款轻量化在线演示设计工具,借助 AI 技术,实现从内容生成到智能设计的一站式 PPT 制作服务。支持多种文档格式导入生成 PPT,提供海量模板、智能美化、素材替换等功能,适用于销售、教师、学生等各类人群,能高效制作出高品质 PPT,满足 不同场景演示需求。
选题、配图、成文,一站式创作,让内容运营更高效
讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。
专业的AI公文写作平台,公文写作神器
AI 材料星,专业的 AI 公文写作辅助平台,为体制内工作人员提供高效的公文写作解决方案。拥有海量公文文库、9 大核心 AI 功能,支持 30 + 文稿类型生成,助力快速完成领导讲话、工作总结、述职报告等材料,提升办公效率,是体制打工人的得力写作神器。
OpenAI Agents SDK,助力开发者便捷使用 OpenAI 相关功能。
openai-agents-python 是 OpenAI 推出的一款强大 Python SDK,它为开发者提供了与 OpenAI 模型交互的高效工具,支持工具调用、结果处理、追踪等功能,涵盖多种应用场景,如研究助手、财务研究等,能显著提升开发效率,让开发者更轻松地利用 OpenAI 的技术优势。
高分辨率纹理 3D 资产生成
Hunyuan3D-2 是腾讯开发的用于 3D 资产生成的强大工具,支持从文本描述、单张图片或多视角图片生成 3D 模型,具备快速形状生成能力,可生成带纹理的高质量 3D 模型,适用于多个领域,为 3D 创作提供了高效解决方案。
一个具备存储、管理和客户端操作等多种功能的分布式文件系统相关项目。
3FS 是一个功能强大的分布式文件系统项目,涵盖了存储引擎、元数据管理、客户端工具等 多个模块。它支持多种文件操作,如创建文件和目录、设置布局等,同时具备高效的事件循环、节点选择和协程池管理等特性。适用于需要大规模数据存储和管理的场景,能够提高系统的性能和可靠性,是分布式存储领域的优质解决方案。
用于可扩展和多功能 3D 生成的结构化 3D 潜在表示
TRELLIS 是一个专注于 3D 生成的项目,它利用结构化 3D 潜在表示技术,实现了可扩展且多功能的 3D 生成。项目提供了多种 3D 生成的方法和工具,包括文本到 3D、图像到 3D 等,并且支持多种输出格式,如 3D 高斯、辐射场和网格等。通过 TRELLIS,用户可以根据文本描述或图像输入快速生成高质量的 3D 资产,适用于游戏开发、动画制作、虚拟现实等多个领域。
10 节课教你开启构建 AI 代理所需的一切知识
AI Agents for Beginners 是一个专为初学者打造的课程项目,提供 10 节课程,涵盖构建 AI 代理的必备知识,支持多种语言,包含规划设计、工具使用、多代理等丰富内容,助您快速入门 AI 代理领域。
AI Excel全自动制表工具
AEE 在线 AI 全自动 Excel 编辑器,提供智能录入、自动公式、数据整理、图表生成等功能,高效处理 Excel 任务,提升办公效率。支持自动高亮数据、批量计算、不规则数据录入,适用于企业、教育、金融等多场景。
基于 UI-TARS 视觉语言模型的桌面应用,可通过自然语言控制计算机进行多模态操作。
UI-TARS-desktop 是一款功能强大的桌面应用,基于 UI-TARS(视觉语言模型)构建。它具备自然语言控制、截图与视觉识别、精确的鼠标键盘控制等功能,支持跨平台使用(Windows/MacOS),能提供实时反馈和状态显示,且数据完全本地处理,保障隐私安全。该应用集成了多种大语言模型和搜索方式,还可进行文件系统操作。适用于需要智能交互和自动化任务的场景,如信息检索、文件管理等。其提供了详细的文档,包括快速启动、部署、贡献指南和 SDK 使用说明等,方便开发者使用和扩展。
最新AI工具、AI资讯
独家AI资源、AI项目落地
微信扫一扫关注公众号