!3023 [pytorch][md]update docs for pretrain and finetuning

Merge pull request !3023 from HanhuiChen/2.1.0
This commit is contained in:
HanhuiChen
2025-07-16 08:13:42 +00:00
committed by i-robot
parent 548341674c
commit d94b7fbfd5
9 changed files with 415 additions and 201 deletions

View File

@@ -1,90 +1,234 @@
# MindSpeed-LLM 单样本指令微调
# 大模型指令微调
## 指令微调简介
## 使用场景
指令微调Instruction Fine-Tuning是一种使预训练模型能够理解和执行自然语言指令的微调方法广泛应用于大规模语言模型。通过在多任务、多样化的数据集上进行微调指令微调使得模型在应对各种任务时更加灵活并更具泛化能力。
大模型虽然在预训练后拥有强大的语言能力但它们往往缺乏任务意识或交互能力。通过在多任务、多样化的数据集上进行微调指令微调Instruction Fine-Tuning使得模型在应对各种任务时更加灵活并更具泛化能力。
指令微调首先收集多个不同任务的数据集,并将每个任务转换为指令形式的输入,帮助大模型在多样化任务上提升泛化能力。具体来说,就是通过“指令-输出”的配对样本,使用有监督学习的方式,让模型学会执行具体任务。指令微调的基本原理如下:
## 指令微调原理
![指令微调原理](../../../../sources/images/instruction_finetune/General_pipline_of_instruction_tuning.png)
*图源:[Instruction Tuning for Large Language Models: A Survey.](https://arxiv.org/pdf/2308.10792v5)*
指令微调的核心思想是通过多任务和多样化指令数据集,训练模型以理解和执行数据集中不同任务的指令。具体来说,指令微调首先收集多个不同任务的数据集,并将每个任务转换为指令形式的输入,帮助大模型在多样化任务上提升泛化能力。该过程不仅包括直接的监督训练,还可结合人类反馈进行进一步优化。指令微调的基本原理如下
根据指令微调的数据格式,可分为以下三种常见的使用场景
![指令微调原理](../../../../sources/images/instruction_finetune/General_pipline_of_instruction_tuning.png)
### 单样本微调
**MindSpeed-LLM支持的指令微调在微调效果保持一致的前提下MindSpeed-LLM可以表现出优异性能**
每条数据为一个独立的任务样本,包括指令和目标回复。适合用于问答、翻译、单轮任务等。
## 指令微调示例
- 数据格式示例
`1x8`的集群配置下,使用`Atlas 900 A2 PODc`进行全参数微调。**以LLaMA2-7B模型在TP8PP1切分后生成的权重作为输入进行指令微调示例。**
```json
{
"instruction": "请将下面的句子翻译成英文:我爱自然语言处理。",
"response": "I love natural language processing."
}
```
`Alpaca`数据预处理部分详见[**Alpaca风格数据的说明文档**](datasets/alpaca_dataset.md)。
### [多样本pack微调](./multi_sample_pack_finetune.md)
`ShareGPT`数据预处理部分详见[**ShareGPT风格数据的说明文档**](datasets/sharegpt_dataset.md)
为了提高训练效率,将多个样本拼接打包成一个长序列,减少填充,提高显存利用率
`Pairwise`数据预处理部分详见[**Pairwise风格数据的说明文档**](datasets/pairwise_dataset.md)。
- 原始样本:
**接下来将以Alpaca数据集作为输入进行全参数微调示例。**
```json
[
{
"instruction": "请将以下句子翻译成英文:我们正在开发一款新的人工智能助手。",
"response": "We are developing a new AI assistant."
},
{
"instruction": "请列出三个可再生能源的例子。",
"response": "太阳能、风能和水能是三种常见的可再生能源。"
}
]
```
### 初始化环境变量
- 拼接后输入示例:
`source /usr/local/Ascend/ascend-toolkit/set_env.sh`
```json
<bos> Instruction: 请将以下句子翻译成英文:我们正在开发一款新的人工智能助手。
Response: We are developing a new AI assistant. <eos>
Instruction: 请列出三个可再生能源的例子。
Response: 太阳能、风能和水能是三种常见的可再生能源。 <eos>
```
`source /usr/local/Ascend/nnal/atb/set_env.sh`
### [多轮对话微调](./multi-turn_conversation.md)
### 启动脚本
用于训练模型进行连续对话,保留上下文信息。每条样本包含一轮以上的用户和模型对话。
使用LLaMA2-7B模型目录下的[微调脚本](../../../../examples/legacy/llama2/tune_llama2_7b_full_ptd.sh)。
- 数据示例:
#### 模型脚本环境变量声明:
脚本中的环境变量配置见[环境变量说明](../../features/environment_variable.md)
```json
{
"conversations": [
{"role": "user", "content": "你好"},
{"role": "assistant", "content": "你好,有什么我可以帮你的吗?"},
{"role": "user", "content": "什么是强化学习?"},
{"role": "assistant", "content": "强化学习是一种让智能体通过试错方式学习策略的方法。"}
]
}
```
#### 填写相关路径
- 构造的输入示例:
`DATA_PATH`:指定数据预处理后的保存路径。
```json
<user>: 你好
<assistant>: 你好,有什么我可以帮你的吗?
<user>: 什么是强化学习?
<assistant>: 强化学习是一种让智能体通过试错方式学习策略的方法。
```
## 使用方法
`TOKENIZER_MODEL`:指定模型的分词器路径(例如`tokenizer.model`)。
本章节介绍如何基于预训练语言模型,使用单样本格式数据完成指令微调任务,其他数据格式请参考[多样本pack微调](./multi_sample_pack_finetune.md)和[多轮对话微调](./multi-turn_conversation.md)。该使用方法是基于Qwen3-8B模型和单台`Atlas 900 A2 PODc`1x8集群进行全参数微调。大模型微调主要包含以下流程
`CKPT_LOAD_DIR`:指向权重转换后保存的路径。
![微调流程图](../../../../sources/images/instruction_finetune/process_of_instruction_tuning.png)
`CKPT_SAVE_DIR`:指向用户指定的微调后权重保存路径(例如指定保存到`ckpt`文件夹下)。
第一步,请参考[安装指导](../../install_guide.md)完成环境安装。请注意由于Qwen3要求使用`transformers>=4.51.0`因此Python需使用3.9及以上版本。请在训练开始前配置好昇腾NPU套件相关的环境变量如下所示
因此,根据之前的示例,路径应填写如下:
```bash
DATA_PATH="./finetune_dataset/alpaca"
CKPT_SAVE_DIR="./ckpt/"
TOKENIZER_MODEL="./model_from_hf/llama-2-7b-hf/"
CKPT_LOAD_DIR="./model_weights/llama-2-7b-legacy/"
```shell
source /usr/local/Ascend/ascend-toolkit/set_env.sh # 以具体的ascend-toolkit路径为主
source /usr/local/Ascend/nnal/atb/set_env.sh # 以具体的nnal路径为主
```
#### 指令微调相关参数
第二步,准备好模型权重和微调数据集。模型权重下载请参考[Dense模型](../../models/dense_model.md)、[MOE模型](../../models/moe_model.md)和[SSM模型](../../models/ssm_model.md)文档中对应模型的下载链接。以[Qwen3-8B](https://huggingface.co/Qwen/Qwen3-8B/tree/main)模型为例,完整的模型文件夹应该包括以下内容:
【--is-instruction-dataset】
```shell
.
├── README.md # 模型说明文档
├── config.json # 模型结构配置文件
├── generation_config.json # 文本生成时的配置
├── merges.txt # tokenizer的合并规则文件
├── model-00001-of-00005.safetensors # 模型权重文件第1部分共5部分
├── model-00002-of-00005.safetensors # 模型权重文件第2部分
├── model-00003-of-00005.safetensors # 模型权重文件第3部分
├── model-00004-of-00005.safetensors # 模型权重文件第4部分
├── model-00005-of-00005.safetensors # 模型权重文件第5部分
├── model.safetensors.index.json # 权重分片索引文件,指示各个权重参数对应的文件
├── tokenizer.json # Hugging Face格式的tokenizer
├── tokenizer_config.json # tokenizer相关配置
└── vocab.json # 模型词表文件
```
用于指定微调过程中采用指令微调数据集,以确保模型依据特定指令数据进行微调
数据集准备请参考[Alpaca风格数据集](datasets/alpaca_dataset.md)、[ShareGPT风格数据集](datasets/sharegpt_dataset.md)和[Pairwise风格数据集](datasets/pairwise_dataset.md)的相关内容,目前已支持`.parquet`, `.csv`, `.json`, `.jsonl`, `.txt`, `.arrow`的格式的数据文件
【--prompt-type】
第三步,进行[权重转换](../checkpoint_convert.md)即将模型原始的HF权重转换成Megatron权重以Qwen3-8B模型在TP1PP4切分为例详细配置请参考[Qwen3-8B权重转换脚本](../../../../examples/mcore/qwen3/ckpt_convert_qwen3_hf2mcore.sh)。需要修改脚本中的以下参数配置:
用于指定模型模板能够让base模型微调后能具备更好的对话能力。`prompt-type`的可选项可以在[`templates`](../../../../configs/finetune/templates.json)文件内查看。
```shell
--load-dir ./model_from_hf/qwen3_hf/ # HF权重路径
--save-dir ./model_weights/qwen3_mcore/ # Megatron权重保存路径
--tokenizer-model ./model_from_hf/qwen3_hf/tokenizer.json # HF的tokenizer路径
--target-tensor-parallel-size 1 # TP切分大小
--target-pipeline-parallel-size 4 # PP切分大小
```
【--variable-seq-lengths】
确认路径无误后运行权重转换脚本:
支持以动态的序列长度进行微调默认padding到`8`的整数倍,可以通过`--pad-to-multiple-of`参数来修改padding的倍数。
```shell
bash examples/mcore/qwen3/ckpt_convert_qwen3_hf2mcore.sh
```
#### 运行脚本
第四步,进行数据预处理。因为不同数据集使用的处理方法不同,请先确认好预处理的数据格式,详细使用说明跳转到以下文档:
- [Alpaca微调数据使用文档](datasets/alpaca_dataset.md)
- [ShareGPT微调数据使用文档](datasets/sharegpt_dataset.md)
- [Pairwise微调数据使用文档](datasets/pairwise_dataset.md)
接下来将以Alpaca数据集为例执行数据预处理详细配置请参考[Qwen3数据预处理脚本](../../../../examples/mcore/qwen3/data_convert_qwen3_instruction.sh)。需要修改脚本内的路径:
```shell
source /usr/local/Ascend/ascend-toolkit/set_env.sh # 修改为真实的ascend-toolkit路径
......
--input ./dataset/train-00000-of-00001-a09b74b3ef9c3b56.parquet # 原始数据集路径
--tokenizer-name-or-path ./mdoel_from_hf/qwen3_hf # HF的tokenizer路径
--output-prefix ./finetune_dataset/alpaca # 保存路径
......
```
数据预处理相关参数说明:
- `handler-name`:指定数据集的处理类,常用的有`AlpacaStylePairwiseHandler``SharegptStyleInstructionHandler``AlpacaStylePairwiseHandler`等。
- `tokenizer-type`指定处理数据的tokenizer常用是的`PretrainedFromHF`。
- `workers`:处理数据集的并行数。
- `log-interval`:处理进度更新的间隔步数。
- `enable-thinking`:快慢思考模板开关,可设定为`[true,false,none]`,默认值是`none`。开启后,会在数据集的模型回复中添加`<think>`和`</think>`并参与到loss计算所有数据被当成慢思考数据当关闭后空的CoT标志将被添加到数据集的用户输入中不参与loss计算所有数据被当成快思考数据设置为`none`时适合原始数据集时混合快慢思考数据的场景。**目前只支持Qwen3系列模型**。
- `prompt-type`用于指定模型模板能够让base模型微调后能具备更好的对话能力。`prompt-type`的可选项可以在[`templates`](../../../../configs/finetune/templates.json)文件内查看。
相关参数设置完毕后,运行数据预处理脚本:
```shell
bash examples/mcore/qwen3/data_convert_qwen3_instruction.sh
```
第五步,配置模型微调脚本,详细的参数配置请参考[Qwen3-8b微调脚本](../../../../examples/mcore/qwen3/tune_qwen3_8b_4K_full_ptd.sh)。脚本中的环境变量配置见[环境变量说明](../../features/environment_variable.md)。模型微调可在单机或者多机上运行,以下是单机运行的相关参数配置说明:
```shell
# 单机配置
GPUS_PER_NODE=8
MASTER_ADDR=locahost
MASTER_PORT=6000
NNODES=1
NODE_RANK=0
WORLD_SIZE=$(($GPUS_PER_NODE * $NNODES))
```
环境变量确认无误后,需要修改相关路径参数和模型切分配置:
```shell
CKPT_LOAD_DIR="your model ckpt path" # 指向权重转换后保存的路径
CKPT_SAVE_DIR="your model save ckpt path" # 指向用户指定的微调后权重保存路径
DATA_PATH="your data path" # 指定处理后的数据路径
TOKENIZER_PATH="your tokenizer path" # 指定模型的tokenizer路径
TP=1 # 模型权重转换的tp大小在本例中是1
PP=4 # 模型权重转换的pp大小在本例中是4
```
微调脚本相关参数说明
- `DATA_PATH`:数据集路径。请注意实际数据预处理生成文件末尾会增加`_input_ids_document`等后缀,该参数填写到数据集的前缀即可。例如实际的数据集相对路径是`./finetune_dataset/alpaca/alpaca_packed_input_ids_document.bin`等,那么只需要填`./finetune_dataset/alpaca/alpaca`即可。
- `is-instruction-dataset`:用于指定微调过程中采用指令微调数据集,以确保模型依据特定指令数据进行微调。
- `variable-seq-lengths`在不同的mini-batch间支持以动态的序列长度进行微调默认padding到`8`的整数倍,可以通过`pad-to-multiple-of`参数来修改padding的倍数。假设微调时指定`--seq-length`序列长度为1024开启`--variable-seq-lengths`后序列长度会padding到真实数据长度的8整数倍。如下图所示
![variable-seq-lengths图示](../../../../sources/images/instruction_finetune/variable_seq_lengths.png)
第六步,启动微调脚本。参数配置完毕后,如果是单机运行场景,只需要在一台机器上启动微调脚本:
```bash
bash examples/legacy/llama2/tune_llama2_7b_full_ptd.sh
bash examples/mcore/qwen3/tune_qwen3_8b_4K_full_ptd.sh
```
### 指令微调序列场景说明
根据序列类型的不同我们需要选择对应的微调脚本和不同的数据预处理方式这里以llama2的指令微调举例
如果是多机运行,则需要在单机的脚本上修改以下参数
```shell
# 多机配置
# 根据分布式集群实际情况配置分布式参数
GPUS_PER_NODE=8 # 每个节点的卡数
MASTER_ADDR="your master node IP" # 都需要修改为主节点的IP地址不能为localhost
MASTER_PORT=6000
NNODES=2 # 集群里的节点数,以实际情况填写,
NODE_RANK="current node id" # 当前节点的RANK多个节点不能重复主节点为0, 其他节点可以是1,2..
WORLD_SIZE=$(($GPUS_PER_NODE * $NNODES))
```
最后确保每台机器上的模型路径和数据集路径等无误后,在多个终端上同时启动预训练脚本即可开始训练。
第七步,进行模型验证。完成微调后,需要进一步验证模型是否具备了预期的输出能力。我们提供了简单的模型生成脚本,只需要加载微调后的模型权重,便可观察模型在不同生成参数配置下的回复,详细配置请参考[Qwen3-8B推理脚本](../../../../examples/mcore/qwen3/generate_qwen3_8b_ptd.sh)。需要在脚本中修改以下参数:
```bash
CKPT_DIR="your model save ckpt path" # 指向微调后权重的保存路径
TOKENIZER_PATH="your tokenizer path" # 指向模型tokenizer的路径
```
然后运行推理脚本:
```bash
bash examples/mcore/qwen3/generate_qwen3_8b_ptd.sh
```
此外,若想要验证模型在不同任务下的表现,请参考[模型评估](../evaluation/evaluation_guide.md)来更全面评估微调效果。
## 使用约束
序列类型的不同其对应的微调脚本和数据预处理方式也不同这里以Qwen3的指令微调举例
| 序列长度 | 特点 | 训练脚本 | 数据预处理方式 |
|--------|--------------------------------|----|---------------------------------------------------------|
| 动态长度序列 | sample吞吐高 | 训练脚本需要使用`--variable-seq-lengths`参数 | 使用默认预处理脚本,如`data_convert_llama2_instruction.sh` |
| 样本拼接序列 | token吞吐高支持长序列并行 | 训练脚本文件命名上会有`pack`标识 | 使用带pack标识的预处理脚本,如`data_convert_llama2_pretrain_pack.sh` |
| 固定长度序列 | 性能低,不推荐使用 | 训练脚本文件命名上会有`pad`标识 | 使用默认预处理脚本,如`data_convert_llama2_instruction.sh` |
| 固定长度序列 | 性能低,不推荐使用 | 训练时不使用`--variable-seq-lengths`参数 | 使用默认预处理脚本,如`data_convert_qwen3_instruction.sh` |
| 动态长度序列 | sample吞吐高 | 训练脚本需要使用`--variable-seq-lengths`参数 | 使用默认预处理脚本,如`data_convert_qwen3_instruction.sh` |
| 样本拼接序列 | token吞吐高支持长序列并行 | 训练脚本需要使用`--reset-position-ids`参数,不启用`--variable-seq-lengths` | 使用pack配置的预处理脚本详见[多样本pack微调](./multi_sample_pack_finetune.md) |
您可以根据自己的使用场景,灵活选择对应类型的指令微调训练脚本和数据预处理脚本。
## 参考文献
[Zhang, S., Dong, L., Li, X., Zhang, S., Sun, X., Wang, S., Li, J., Hu, R., Zhang, T., Wu, F., & Wang, G. (2023). *Instruction Tuning for Large Language Models: A Survey*.](https://arxiv.org/pdf/2308.10792v5)
请根据自己的使用场景,灵活选择对应类型的指令微调训练脚本和数据预处理脚本。

View File

@@ -1,90 +1,74 @@
### 大模型分布式预训练
# 大模型分布式预训练
#### 1. 准备工作
## 使用场景
参考[安装指导](../../install_guide.md),完成环境安装,参考[权重转换](../checkpoint_convert.md)和[预训练数据处理](pretrain_dataset.md)完成权重准备和数据预处理。
大模型预训练Pretraining是语言模型发展的核心步骤目标是让模型通过大规模无标签语料学习语言规律与世界知识。预训练过程更关注语言建模本身而非具体任务执行。以GPT类模型为例它是一种典型的自回归语言模型其核心思想是基于历史上下文预测下一个标记。预训练的过程就是通过反复优化这种预测能力模型逐渐学会如何理解语境、保持句子连贯性并掌握更高层次的语言结构为多种下游任务提供通用的语言表示能力。
预训练数据通常为纯文本格式,无任务导向,例如:
#### 2. 配置预训练参数
#### 模型脚本环境变量声明:
脚本中的环境变量配置见[环境变量说明](../../features/environment_variable.md)
legacy分支的预训练脚本保存在 example/legacy 中各模型文件夹下pretrain_xxx_xx.sh
mcore分支的预训练脚本保存在 example/mcore 中各模型文件夹下pretrain_xxx_xx.sh
需根据实际情况修改路径和参数值:
**示例:**
examples/legacy/llama2/pretrain_llama2_7b_ptd.sh *(legacy分支)*
examples/mcore/llama2/pretrain_llama2_7b_ptd.sh *(mcore分支)*
路径配置:包括**权重保存路径**、**权重加载路径**、**词表路径**、**数据集路径**
```shell
# 根据实际情况配置权重保存、权重加载、词表、数据集路径
# 注意:提供的路径需要加双引号
CKPT_SAVE_DIR="./ckpt/llama-2-7b" # 训练完成后的权重保存路径
CKPT_LOAD_DIR="./model_weights/llama-2-7b-mcore/" # 权重加载路径,填入权重转换时保存的权重路径
TOKENIZER_MODEL="./model_from_hf/llama-2-7b-hf/tokenizer.model" # 词表路径,填入下载的开源权重词表路径
DATA_PATH="./dataset/enwiki_text_document" # 数据集路径,填入数据预处理时保存的数据路径
```
【--tokenizer-type】
参数值为PretrainedFromHF时 词表路径仅需要填到模型文件夹即可不需要到tokenizer.model文件
**示例:**
```shell
TOKENIZER_PATH="./model_from_hf/llama-2-7b-hf/"
--tokenizer-name-or-path ${TOKENIZER_PATH}
```json
{"text": "今天是个好天气,我们一起去爬山。"}
{"text": "深度学习正在改变世界。"}
{"text": "AI的出现推动了人类社会的发展。"}
```
参数值不为PretrainedFromHF时例如Llama2Tokenizer需要指定到tokenizer.model文件
## 使用方法
**示例:**
本章节以Qwen3-8B模型为例介绍了预训练启动方法。如果需要使用数据集pack模式请参考[大模型预训练pack模式](./pretrain_eod.md)。大模型分布式预训练主要包含以下流程:
```shell
TOKENIZER_MODEL="./model_from_hf/llama-2-7b-hf/tokenizer.model"
--tokenizer-model ${TOKENIZER_MODEL} \
```
![预训练流程图](../../../../sources/images/pretrain/process_of_pretraining.png)
【--data-path】
支持多数据集训练,参数格式如下
格式一数据集权重根据提供的weight参数
```shell
--data-path "dataset1-weight dataset1-path dataset2-weight dataset2-path"
```
**示例:**
```shell
--data-path "0.5 ./dataset/enwiki_text_document1 0.5 ./dataset/enwiki_text_document2"
```
格式二(根据数据集的长度推出数据集的权重)
```shell
--data-path "dataset1-path dataset2-path"
```
**示例:**
```shell
--data-path "./dataset/enwiki_text_document1 ./dataset/enwiki_text_document2"
```
【单机运行】
第一步,请在训练开始前参考[安装指导](../../install_guide.md)完成环境安装。请注意由于Qwen3要求使用`transformers>=4.51.0`因此Python需使用3.9及以上版本。环境搭建完成后确保在预训练开始前已经配置好昇腾NPU套件相关的环境变量如下所示
```shell
GPUS_PER_NODE=8
source /usr/local/Ascend/ascend-toolkit/set_env.sh # 以具体的ascend-toolkit路径为主
source /usr/local/Ascend/nnal/atb/set_env.sh # 以具体的nnal路径为主
```
第二步,数据预处理。首先准备好原始数据集,常见的预训练数据集有:
- [Alpaca数据集](https://huggingface.co/datasets/tatsu-lab/alpaca)
- [Enwiki数据集](https://huggingface.co/datasets/lsb/enwiki20230101)
- [C4数据集](https://huggingface.co/datasets/allenai/c4)
- [ChineseWebText](https://huggingface.co/datasets/CASIA-LM/ChineseWebText)
接下来以[Enwiki数据集](https://huggingface.co/datasets/lsb/enwiki20230101)为例执行数据预处理,详细的脚本配置可参考[Qwen3预训练数据处理脚本](../../../../examples/mcore/qwen3/data_convert_qwen3_pretrain.sh),需要修改脚本中的以下路径:
```shell
source /usr/local/Ascend/ascend-toolkit/set_env.sh # 修改为真实的ascend-toolkit路径
......
--input ./dataset/train-00000-of-00042-d964455e17e96d5a.parquet # 原始数据集路径
--tokenizer-name-or-path ./mdoel_from_hf/qwen3_hf # HF的tokenizer路径
--output-prefix ./finetune_dataset/alpaca # 保存路径
......
```
数据预处理相关参数说明:
- `input`:可以直接输入到数据集目录或具体文件,如果是目录,则处理全部文件, 支持`.parquet``.csv``.json``.jsonl``.txt``.arrow`格式, 同一个文件夹下的数据格式需要保持一致。
- `handler-name`:当前预训练默认使用 `GeneralPretrainHandler`,支持的是预训练数据风格,提取数据的`text`列,格式如下:
```shell
[
{"text": "document"},
{"other keys": "optional content"}
]
```
- `json-keys`:从文件中提取的列名列表,默认为 `text`,可以为 `text`, `input`, `title` 等多个输入,结合具体需求及数据集内容使用,如:
```shell
--json-keys text input output
```
- `n-subs`:数据预处理并行加速参数。当需要预处理的数据集比较大时,可以通过并行处理进行加速,方法为设置参数`--n-subs`,通过该参数设置并行处理数量。在数据预处理过程会将原始数据集切分为`n_sub`个子集对子集进行并行处理然后合并从而实现加速。建议预处理数据集超过GB级别时加上该参数。
相关参数设置完毕后,运行数据预处理脚本:
```shell
bash examples/mcore/qwen3/data_convert_qwen3_pretrain.sh
```
第三步,配置模型预训练脚本,详细的参数配置请参考[Qwen3-8B预训练脚本](../../../../examples/mcore/qwen3/pretrain_qwen3_8b_4K_ptd.sh)。脚本中的环境变量配置见[环境变量说明](../../features/environment_variable.md)。单机运行的配置说明如下:
```shell
GPUS_PER_NODE=8 # 节点的卡数
MASTER_ADDR=locahost
MASTER_PORT=6000
NNODES=1
@@ -92,7 +76,42 @@ NODE_RANK=0
WORLD_SIZE=$(($GPUS_PER_NODE * $NNODES))
```
【多机运行】
环境变量确认无误后,需要在脚本中修改相关路径参数和模型切分配置:
```shell
# 注意:提供的路径需要加双引号
CKPT_SAVE_DIR="your model save ckpt path" # 训练完成后的权重保存路径
CKPT_LOAD_DIR="your data path" # 权重加载路径,填入权重转换时保存的权重路径
TOKENIZER_PATH="your tokenizer path" # 词表路径,填入下载的开源权重词表路径
DATA_PATH="your model ckpt path" # 数据集路径,填入数据预处理时保存的数据路径
TP=1 # 模型权重转换的tp大小在本例中是1
PP=4 # 模型权重转换的pp大小在本例中是4
```
脚本内的相关参数说明:
- `DATA_PATH`:数据集路径。请注意实际数据预处理生成文件末尾会增加`_text_document`,该参数填写到数据集的文件前缀即可。例如实际的数据集相对路径是`./finetune_dataset/alpaca/alpaca_text_document.bin`等,那么只需要填`./finetune_dataset/alpaca/alpaca_text_document`即可。
- `tokenizer-type`参数值为PretrainedFromHF时 词表路径仅需要填到模型文件夹即可不需要到tokenizer.model文件参数值不为PretrainedFromHF时例如Qwen3Tokenizer需要指定到tokenizer.model文件。示例如下
```shell
# tokenizer-type为PretrainedFromHF
TOKENIZER_PATH="./model_from_hf/Qwen3-8B/"
--tokenizer-name-or-path ${TOKENIZER_PATH}
# tokenizer-type不为PretrainedFromHF
TOKENIZER_MODEL="./model_from_hf/Qwen3-8B/tokenizer.model"
--tokenizer-model ${TOKENIZER_MODEL} \
```
第四步,预训练脚本配置完毕后,运行脚本启动预训练。
```shell
bash examples/mcore/qwen3/pretrain_qwen3_8b_4K_ptd.sh
```
如果是多机运行,那么需要在[Qwen3-8B预训练脚本](../../../../examples/mcore/qwen3/pretrain_qwen3_8b_4K_ptd.sh)中修改以下参数:
```shell
# 根据分布式集群实际情况配置分布式参数
@@ -104,41 +123,8 @@ NODE_RANK="current node id" # 当前节点的RANK多个节点不能重复
WORLD_SIZE=$(($GPUS_PER_NODE * $NNODES))
```
最后确保每台机器上的模型路径和数据集路径等无误后,在多个终端上同时启动预训练脚本即可开始训练。如果使用多机训练,且没有设置数据共享,需要在训练启动脚本中增加`no-shared-storage`参数。设置此参数之后将会根据布式参数判断非主节点是否需要load数据并检查相应缓存和生成数据。
#### 3. 启动预训练
## 使用约束
##### 初始化环境变量
`source /usr/local/Ascend/ascend-toolkit/set_env.sh`
`source /usr/local/Ascend/nnal/atb/set_env.sh`
【legacy分支】
```shell
bash examples/legacy/模型文件夹/pretrain_xxx_xxx.sh
```
**示例:** *(以llama2-7B为例)*
```shell
bash examples/legacy/llama2/pretrain_llama2_7b_ptd.sh
```
【mcore分支】
```shell
bash examples/mcore/模型文件夹/pretrain_xxx_xxx.sh
```
**示例:**
```shell
bash examples/mcore/llama2/pretrain_llama2_7b_ptd.sh
```
**注意**
- "--save-interval" 用于设定运行多少个epoch后存储权重。
- 如需存储日志到脚本文件中请在运行路径目录下创建logs文件夹。
- 多机训练需在多个终端同时启动预训练脚本(每个终端的预训练脚本只有NODE_RANK参数不同其他参数均相同)
- 如果使用多机训练,且没有设置数据共享,需要在训练启动脚本中增加`--no-shared-storage`参数设置此参数之后将会根据布式参数判断非主节点是否需要load数据并检查相应缓存和生成数据
- 如需存储日志到脚本文件中,请在运行路径目录下创建`logs`文件夹

View File

@@ -1,45 +1,129 @@
# 大模型分布式预训练——pack模式
# 大模型分布式预训练pack模式
## EOD Reset训练场景
## 使用场景
预训练任务中,通常一个批次中输入进模型的文本序列是由多个文档doc拼接得到。在默认情况下多个文档视为同一序列,互相间的self attention没有掩盖。在特定情况下如果多个文档不可以被直接拼接成一个序列即要求多个文档间要求独立此时文档间不能互相做self attention在这种情况下attention mask和position ids需要在每个文档结束的位置EOD被重新设置
在大模型的预训练任务中,一个训练批次中输入序列通常由多个文档拼接而成。默认情况下,模型会将这些文档视为一个连续的序列,不会对它们之间的self attention进行遮挡,这意味着不同文档之间可以相互建立上下文依赖
MindSpeed-LLM支持多样本pack模式预训练,即多个样本进行拼接的时候,使用文档结束符(eod)将不同的文档分割开在训练过程中进行不同doc之间self attention的隔离。使用此功能,只需在数据预处理和训练脚本中添加相应参数即可。
然而,在某些特定场景下,不同文档之间需要相互独立,不能共享上下文信息。例如,当文档之间存在语义不相关性或需要保持训练目标隔离时,必须禁止它们之间的 self attention。此时模型需要在每个文档的结束位置EOD重新设置attention mask和position ids以实现文档级别的注意力隔离。为提升token的利用率预训练过程中可以采用pack技术,即多个较短的样本拼接成一个完整的训练序列。在此过程中模型无法自动识别不同样本的边界因此需要在每条样本末尾显式插入EOD token以标识边界并指导后续的attention mask构建。要启用该功能,用户只需在数据预处理和训练脚本中设置相应参数即可实现高效且语义明确的预训练过程
## 使用说明
大模型分布式预训练pack模式主要包含以下流程
可参考llama3-8b脚本[pack预训练数据处理](../../../../examples/mcore/llama3/data_convert_llama3_pretrain_pack.sh)[pack模式预训练](../../../../examples/mcore/llama3/pretrain_llama3_8b_pack_ptd.sh)
![预训练流程图](../../../../sources/images/pretrain/process_of_pretraining.png)
#### 数据预处理
在[预训练数据预处理](pretrain_dataset.md)基础上,加上`--append-eod`参数即可进行pack预训练模式的数据预处理:
第一步,请在训练开始前参考[安装指导](../../install_guide.md)完成环境安装。请注意由于Qwen3要求使用`transformers>=4.51.0`因此Python需使用3.9及以上版本。环境搭建完成后确保在预训练开始前已经配置好昇腾NPU套件相关的环境变量如下所示
```shell
python ./preprocess_data.py \
--input ./dataset/train-00000-of-00001-a09b74b3ef9c3b56.parquet \
--tokenizer-name-or-path ./model_from_hf/llama3_hf/ \
--output-prefix ./dataset/enwiki \
--workers 4 \
--log-interval 1000 \
--tokenizer-type PretrainedFromHF \
--append-eod # 预训练数据预处理添加此参数使能pack模式预训练
source /usr/local/Ascend/ascend-toolkit/set_env.sh # 以具体的ascend-toolkit路径为主
source /usr/local/Ascend/nnal/atb/set_env.sh # 以具体的nnal路径为主
```
#### 训练脚本
第二步,数据预处理。首先准备好原始数据集,常见的预训练数据集有:
- [Alpaca数据集](https://huggingface.co/datasets/tatsu-lab/alpaca)
- [Enwiki数据集](https://huggingface.co/datasets/lsb/enwiki20230101)
- [C4数据集](https://huggingface.co/datasets/allenai/c4)
- [ChineseWebText](https://huggingface.co/datasets/CASIA-LM/ChineseWebText)
在[普通预训练](pretrain.md)基础上,加上`--reset-position-ids`参数即可进行pack模式预训练。
接下来以[Enwiki数据集](https://huggingface.co/datasets/lsb/enwiki20230101)为例执行数据预处理,详细的脚本配置可参考[Qwen3预训练数据处理脚本](../../../../examples/mcore/qwen3/data_convert_qwen3_pretrain.sh),需要修改脚本中的以下内容:
```shell
# examples/mcore/llama3/pretrain_llama3_8b_pack_ptd.sh
.....
ACCELERATE_ARGS="
--swap-attention \
--use-mc2 \
--reuse-fp32-param \
--reset-position-ids \ # 在普通预训练脚本中添加此参数进行pack模式预训练
--use-distributed-optimizer \
--overlap-grad-reduce \
--overlap-param-gather \
"
....
```
source /usr/local/Ascend/ascend-toolkit/set_env.sh # 修改为真实的ascend-toolkit路径
......
--input ./dataset/train-00000-of-00042-d964455e17e96d5a.parquet # 原始数据集路径
--tokenizer-name-or-path ./mdoel_from_hf/qwen3_hf # HF的tokenizer路径
--output-prefix ./finetune_dataset/alpaca # 保存路径
--append-eod # 添加此参数开启pack模式数据预处理
......
```
数据预处理相关参数说明:
- `input`:可以直接输入到数据集目录或具体文件,如果是目录,则处理全部文件, 支持`.parquet``.csv``.json``.jsonl``.txt``.arrow`格式, 同一个文件夹下的数据格式需要保持一致。
- `handler-name`:当前预训练默认使用 `GeneralPretrainHandler`,支持的是预训练数据风格,提取数据的`text`列,格式如下:
```shell
[
{"text": "document"},
{"other keys": "optional content"}
]
```
- `json-keys`:从文件中提取的列名列表,默认为 `text`,可以为 `text`, `input`, `title` 等多个输入,结合具体需求及数据集内容使用,如:
```shell
--json-keys text input output
```
- `n-subs`:数据预处理并行加速参数。当需要预处理的数据集比较大时,可以通过并行处理进行加速,方法为设置参数`--n-subs`,通过该参数设置并行处理数量。在数据预处理过程会将原始数据集切分为`n_sub`个子集对子集进行并行处理然后合并从而实现加速。建议预处理数据集超过GB级别时加上该参数。
- `append-eod`:该参数的作用是将文档结束标记`EOD`显示地添加到每条数据的末尾,防止模型学习无意义的关联。还参数使能后的效果如下:
![append-eod示意图](../../../../sources/images/pretrain/append-eod.png)
相关参数设置完毕后,运行数据预处理脚本:
```shell
bash examples/mcore/qwen3/data_convert_qwen3_pretrain.sh
```
第三步,配置模型预训练脚本,详细的参数配置请参考[Qwen3-8B预训练脚本](../../../../examples/mcore/qwen3/pretrain_qwen3_8b_4K_ptd.sh)。脚本中的环境变量配置见[环境变量说明](../../features/environment_variable.md)。单机运行的配置说明如下:
```shell
GPUS_PER_NODE=8 # 节点的卡数
MASTER_ADDR=locahost
MASTER_PORT=6000
NNODES=1
NODE_RANK=0
WORLD_SIZE=$(($GPUS_PER_NODE * $NNODES))
```
环境变量确认无误后,需要在脚本中修改相关路径参数和模型切分配置:
```shell
# 注意:提供的路径需要加双引号
CKPT_SAVE_DIR="your model save ckpt path" # 训练完成后的权重保存路径
CKPT_LOAD_DIR="your data path" # 权重加载路径,填入权重转换时保存的权重路径
TOKENIZER_PATH="your tokenizer path" # 词表路径,填入下载的开源权重词表路径
DATA_PATH="your model ckpt path" # 数据集路径,填入数据预处理时保存的数据路径
TP=1 # 模型权重转换的tp大小在本例中是1
PP=4 # 模型权重转换的pp大小在本例中是4
```
以上通用配置完成后要开启pack模式训练需要在[Qwen3-8B预训练脚本](../../../../examples/mcore/qwen3/pretrain_qwen3_8b_4K_ptd.sh)基础上,加上`--reset-position-ids`参数该参数开启时模型将在每个EOD之后将对position id从0开始重新编号从而隔离不同句子间的位置计算。该参数的使能效果如下图所示
![reset-position-ids图示0](../../../../sources/images/pretrain/reset-position-ids.png)
脚本内的其他相关参数说明:
- `DATA_PATH`:数据集路径。请注意实际数据预处理生成文件末尾会增加`_text_document`,该参数填写到数据集的前缀即可。例如实际的数据集相对路径是`./finetune_dataset/alpaca/alpaca_text_document.bin`等,那么只需要填`./finetune_dataset/alpaca/alpaca_text_document`即可。
- `tokenizer-type`参数值为PretrainedFromHF时 词表路径仅需要填到模型文件夹即可不需要到tokenizer.model文件参数值不为PretrainedFromHF时例如Qwen3Tokenizer需要指定到tokenizer.model文件。示例如下
```shell
# tokenizer-type为PretrainedFromHF
TOKENIZER_PATH="./model_from_hf/Qwen3-8B/"
--tokenizer-name-or-path ${TOKENIZER_PATH}
# tokenizer-type不为PretrainedFromHF
TOKENIZER_MODEL="./model_from_hf/Qwen3-8B/tokenizer.model"
--tokenizer-model ${TOKENIZER_MODEL} \
```
第四步,预训练脚本配置完毕后,运行脚本启动预训练。
```shell
bash examples/mcore/qwen3/pretrain_qwen3_8b_4K_ptd.sh
```
如果是多机运行,那么需要在[Qwen3-8B预训练脚本](../../../../examples/mcore/qwen3/pretrain_qwen3_8b_4K_ptd.sh)中修改以下参数:
```shell
# 根据分布式集群实际情况配置分布式参数
GPUS_PER_NODE=8 # 每个节点的卡数
MASTER_ADDR="your master node IP" # 都需要修改为主节点的IP地址不能为localhost
MASTER_PORT=6000
NNODES=2 # 集群里的节点数,以实际情况填写,
NODE_RANK="current node id" # 当前节点的RANK多个节点不能重复主节点为0, 其他节点可以是1,2..
WORLD_SIZE=$(($GPUS_PER_NODE * $NNODES))
```
最后确保每台机器上的模型路径和数据集路径等无误后,在多个终端上同时启动预训练脚本即可开始训练。如果使用多机训练,且没有设置数据共享,需要在训练启动脚本中增加`no-shared-storage`参数。设置此参数之后将会根据布式参数判断非主节点是否需要load数据并检查相应缓存和生成数据。
## 使用约束
- 数据预处理阶段的`append-eod`参数需要和预训练阶段的`reset-position-ids`参数搭配一起使用。如果只开`append-eod`的话,文档末尾添加了 `<EOD>`但位置编码不重置不同文档的token编号连续模型仍可能学习跨文档的位置信息如果只开`reset-position-ids`,触发位置重置需要 `<EOD>`,如果没加`append-eod`,重置逻辑根本不会生效。因此这两个参数需要同时开启。

View File

@@ -11,7 +11,7 @@
<tbody>
<tr>
<td rowspan="1">环境安装指导</td>
<td><a href="pytorch/install_guide.md">install_guide.md</a></td>
<td><a href="./pytorch/install_guide.md">install_guide.md</a></td>
<td></td>
</tr>
<tr>
@@ -70,6 +70,10 @@
<td rowspan="1"><a href="pytorch/solutions/finetune/multi_sample_pack_finetune.md">multi_sample_pack_finetune</a></td>
<td rowspan="1">多样本Pack微调方案</td>
</tr>
<tr>
<td rowspan="1"><a href="pytorch/solutions/finetune/multi-turn_conversation.md">multi-turn_conversation</a></td>
<td rowspan="1">多轮对话微调方案</td>
</tr>
<tr>
<td rowspan="1"><a href="pytorch/solutions/finetune/lora_finetune.md">lora_finetune</a></td>
<td rowspan="1">模型lora微调方案</td>
@@ -78,10 +82,6 @@
<td rowspan="1"><a href="pytorch/solutions/finetune/qlora_finetune.md">qlora_finetune</a></td>
<td rowspan="1">模型qlora微调方案</td>
</tr>
<tr>
<td rowspan="1"><a href="pytorch/solutions/finetune/multi-turn_conversation.md">multi-turn_conversation</a></td>
<td rowspan="1">多轮对话微调方案</td>
</tr>
<tr>
<td rowspan="3">模型推理方法</td>
<td rowspan="1"><a href="pytorch/solutions/inference/inference.md">inference</a></td>

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB