kai119's picture
Upload folder using huggingface_hub
22fb4ec verified
==============
主要差异
==============
总览
=============
XTuner 可以复现 InternEvo (train_internlm) 仓库训练得到的开源模型
internlm/internlm2-chat-7b 的训练精度。
下面是 XTuner 和 InternEvo (train_internlm)
在相同数据集上训练相同基座模型的训练结果对比:
.. list-table::
:widths: 50 25 25
:header-rows: 1
* - 能力类别
- xtuner
- internevo
* - 全数据集平均(无智能体)
- 56.44
- 55.26
* - 全维度平均(无智能体)
- 49.58
- 48.96
* - 语言 Language
- 64.77
- 62.41
* - 知识 Knowledge
- 52.24
- 52.52
* - 推理 Reasoning
- 65.5
- 63.91
* - 数学 Mathematics
- 30.95
- 30.26
* - 代码 Coding
- 38.91
- 41.06
* - 长文本 LongEval
- 45.09
- 43.62
* - 智能体 Agent
- 44.85
- 43.97
* - 数学题智能体
- 37
- 37.19
* - CIBench
- 79.07
- 69.78
* - PluginEval
- 65.57
- 65.62
64 \* A100 的训练时间对比如下:
=========== ==========
xtuner internevo
=========== ==========
15 h 55 min 16h 09 min
=========== ==========
.. tip::
使用 XTuner 提供的序列并行算法可以进一步提升训练速度,使用方式请参考
\ :ref:`序列并行文档 <train_extreme_long_sequence>` \ 。
适配
==========
在从 InternEvo (train_internlm) 向 XTuner
迁移的过程中,我们需要关注模型、数据以及训练策略这三个方面的适配问题。后续内容将详细阐述如何进行适配。
模型
-------
InternEvo 在训练时读取和保存的模型权重满足以下目录结构(以 tp2pp2
为例):
.. code::
|-- root
|-- model_config.pt
|-- model_tp0_pp0.pt
|-- model_tp0_pp1.pt
|-- model_tp1_pp0.pt
|-- model_tp1_pp1.pt
其中,\ ``model_config.pt`` 保存模型权重的一些 meta 信息,其余 4
checkpoint 则分别保存 4 组 GPUs 上的模型权重。因此,InternEvo
训练过程中要求读取预训练权重的 tp、pp 策略与训练使用的 tp、pp
策略一致才能正常读取预训练权重进行训练。
XTuner 支持基于 Huggingface Hub 上的模型进行训练,如下修改 config
内容即可将基座模型从 internlm2-7b 切换为 internlm2-20b:
.. code:: diff
#######################################################################
# PART 1 Settings #
#######################################################################
# Model
- pretrained_model_name_or_path = 'internlm/internlm2-7b'
+ pretrained_model_name_or_path = 'internlm/internlm2-20b'
数据
---------
InternEvo
在训练过程中通常会把多条数据拼接为一个特定的最大长度,随后输入模型训练。其配置往往满足以下形式:
.. code:: python
data = dict(
seq_len=SEQ_LEN,
pack_sample_into_one=False,
min_length=MIN_LENGTH,
train_folder=TRAIN_FOLDER,
dataset_weights=DATASET_WEIGHTS,
...)
其中,数据配比 (``dataset_weights=DATASET_WEIGHTS``) 功能 XTuner
尚未支持。\ ``TRAIN_FOLDER`` 中的训练数据需要满足 ftdp tokenized
数据集格式:
.. code::
|-- TRAIN_FOLDER
|-- cn
| |-- dataset1
| | |-- data1.bin
| | |-- data1.bin.meta
| |-- dataset2
| | |-- data2.bin
| | |-- data2.bin.meta
在 XTuner 中实现在线数据集拼接策略需要参考
``xtuner/configs/internlm/internlm2_7b/internlm2_7b_w_internevo_dataset.py``
文件中的配置:
.. code:: diff
#######################################################################
# PART 1 Settings #
#######################################################################
# Data
- dataset_folder = '/path/to/sft/data/folder'
+ dataset_folder = TRAIN_FOLDER
- max_length = 32768
+ max_length = SEQ_LEN
#######################################################################
# PART 3 Dataset & Dataloader #
#######################################################################
train_dataset = dict(
type=build_packed_dataset,
dataset_cfg=dict(
type=load_intern_repo_tokenized_dataset,
data_order_path=None,
folder=dataset_folder,
- min_length=0,
+ min_length=MIN_LENGTH,
file_type='.bin'),
packed_length=max_length,
seed=1024)
.. note::
需要注意,由于训练数据喂给模型的先后顺序可能对训练结果造成影响,因此建议不要轻易修改上述配置中的 ``seed`` 选项。同时,可参考 \ :ref:`获取数据顺序 <case4-step3>` \ 进一步固定数据顺序。
训练策略
------------
Varlen Attention
~~~~~~~~~~~~~~~~~~~~~~~~~~
InternEvo 通过设置
`数据配置 <https://github.com/InternLM/InternEvo/blob/77c3b46bfe51f6bc245c4aba98639221b8618372/doc/usage.md#%E6%95%B0%E6%8D%AE%E9%85%8D%E7%BD%AE>`__
中的 ``pack_sample_into_one`` 参数为 False
来使用“变长注意力机制”(见下图右侧)。
.. code:: python
data = dict(
pack_sample_into_one=False,
...)
.. raw:: html
<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body><div align="center">
<img width="800" src="https://github.com/InternLM/InternEvo/blob/develop/doc/imgs/pack_into_one.png?raw=true" data-src="https://github.com/InternLM/InternEvo/blob/develop/doc/imgs/pack_into_one.png?raw=true" onerror="this.style.display = 'none';" />
<br /><br />
</div></body></html>
在 XTuner 中使用这一功能需要设置 config 中的 ``use_varlen_attn`` 配置为
True,即可保证训练行为与 InternEvo 一致:
.. code:: diff
...
#######################################################################
# PART 1 Settings #
#######################################################################
# Model
pretrained_model_name_or_path = 'internlm/internlm2-7b'
- use_varlen_attn = False
+ use_varlen_attn = True
...
.. warning::
需要注意,当设置 ``use_varlen_attn = True`` 后,请确保
``batch_size`` 被设置为 1,且 ``pack_to_max_length`` 被设置为
True
.. tip::
``use_varlen_attn = True`` 时 ``单卡 batch size 等于 2,拼接数据集至最大长度 2k``
的配置与 ``单卡 batch size 等于 1,拼接数据集至最大长度 4k`` 的配置训练行为是近似的,
因此 XTuner 目前只支持了 ``batch_size_per_device = 1`` 的情况。
梯度累积
~~~~~~~~~~~~~~
在 InternEvo 的配置中,与 batch_size 和 accumulative_counts
相关的配置有如下几个:
.. code:: python
data = dict(
# micro_num means the number of micro_batch contained in one gradient update
micro_num=MICRO_NUM,
# MICRO_BATCH_SIZE * SEQ_LEN = PACKED_LENGTH
micro_bsz=MICRO_BATCH_SIZE,
total_steps=TOTAL_STEP,
# 梯度累计,默认等于MICRO_NUM(BS)
gradient_accumulation=GRADIENT_ACCUMULATION,
...)
.. note::
InternEVO 中的 ``micro_num`` 等价于 XTuner 中的 ``gradient_accumulation``
.. note::
``total_steps`` 在 XTuner 中可以不手动指定,可通过 ``max_epochs`` 指定。
.. warning::
XTuner 目前只支持 ``micro_bsz = 1`` 。
.. tip::
为对齐以上配置,可参考 XTuner 中
``xtuner/configs/internlm/internlm2_7b/internlm2_7b_w_internevo_dataset.py``
文件中的配置,并进行如下修改:
.. code:: diff
#######################################################################
# PART 1 Settings #
#######################################################################
# Scheduler & Optimizer
- accumulative_counts = 1
+ accumulative_counts = MICRO_NUM # or GRADIENT_ACCUMULATION
- max_epochs = 1
+ max_epochs = MAX_EPOCHS
并行策略
---------------
ZeRO 系列显存优化
~~~~~~~~~~~~~~~~~~~~~~~
XTuner 支持使用 ZeRO 系列显存优化降低训练过程中的显存消耗:
.. code:: bash
# 单卡
xtuner train ${CONFIG_NAME_OR_PATH} --deepspeed deepspeed_zero2
# 多卡
(DIST) NPROC_PER_NODE=${GPU_NUM} xtuner train ${CONFIG_NAME_OR_PATH} --deepspeed deepspeed_zero2
(SLURM) srun ${SRUN_ARGS} xtuner train ${CONFIG_NAME_OR_PATH} --launcher slurm --deepspeed deepspeed_zero2
序列并行
~~~~~~~~~~~~~~~~~~~
InternEvo 中支持了 Data Parallel、Tensor Parallel、Pipeline Parallel 和
Sequence Parallel 四种并行策略。XTuner 目前支持了 Data Parallel 和
Sequence Parallel 两种并行策略,可满足基本全部的训练需求(搭配 zero3
显存优化策略可支持 70B 模型 256K 上下文训练)。
假定 InternEvo 训练过程中:tp_world_size = TP, pp_world_size = PP,
sequence_parallel = True。则训练的 global_batch_size 满足以下计算公式:
.. code::
# 多除的一个 TP 是因为启用了 sequence parallel
global_batch_size = num_gpus * batch_size_per_device * gradient_accumulate / TP / PP / TP
.. tip::
``use_varlen_attn = True`` 时, ``batch_size_per_device`` 只能为 1,此时若想对齐
``global_batch_size``,只需要在配置文件中综合调整
``gradient_accumulate`` 和 ``sequence_parallel_size`` 两项的数值:
.. code:: diff
+ from xtuner.parallel.sequence import SequenceParallelSampler
+ sequence_parallel_size = SP
- accumulative_counts = 1 # 1bs * 1acc * 64gpu = 64 batchsize
+ accumulative_counts = TP * PP * TP / SP
#######################################################################
# PART 3 Dataset & Dataloader #
#######################################################################
train_dataloader = dict(
- sampler=dict(type=DefaultSampler, shuffle=True),
+ sampler=dict(type=SequenceParallelSampler, shuffle=True),
...)