代码
MindSpore Transformers支持DeepSeek-R1蒸馏全流程

MindSpore Transformers支持DeepSeek-R1蒸馏全流程

MindSpore Transformers支持DeepSeek-R1蒸馏全流程

模型蒸馏(Model Distillation)是一种知识迁移技术,旨在将大型、复杂的教师模型的知识转移到较小、效率更高的学生模型中。这种技术通常是通过让小模型(学生模型)学习大模型(教师模型)的预测结果,从而达到与大模型相近的思考和推理能力,以显著降低计算资源的需求、提高推理的性能。

DeepSeek-R1具有生成长思维链(CoT)的能力,这种能力可以通过蒸馏技术迁移到小模型上。小模型学习了R1模型中的知识后,即使不经过强化学习(RL),也能得到出色的推理效果。DeepSeek团队通过使用R1模型生成60万条CoT推理数据,蒸馏了Qwen和Llama这样的开源模型,成功验证了这一迁移能力。

MindSpore Transformers大模型使能套件基于昇腾AI算力,依托MindSpore AI框架提供的丰富的多维混合并行能力,亲和开源工具与通用数据格式,原生支持大模型蒸馏的端到端全流程开发,提供了高效、便捷的解决方案。

# 01

DeepSeek-R1蒸馏数据生产实践案例

蒸馏数据的生产主要包含服务化推理和拒绝采样两个步骤。首先部署DeepSeek-R1的推理服务,调用服务接口,使用种子数据集中的问题生成思维链数据。然后对生成的数据进行拒绝采样的后处理,筛选出回答正确的高质量数据。MindSpore Transformers提供了一个蒸馏数据生产流程的案例,使用MindSpore Transformers+MindIE实现R1模型的服务化部署,并采用开源种子数据集NuminaMath-1.5和开源拒绝采样工具生成思维链数据集。

本地部署DeepSeek-R1

DeepSeek-R1推理至少需要4台Atlas 800I A2(64G)服务器(基于BF16权重)。

1、准备环境

执行以下 Shell 命令,拉取MindSpore DeepSeek推理容器镜像:


docker pull swr.cn-central-221.ovaijisuan.com/mindformers/deepseek_v3_mindspore2.5.0-infer:20250217

执行以下命令启动容器:

docker run -itd --privileged  --name=Deepseek-R1 --net=host \
   --shm-size 500g \
   --device=/dev/davinci0 \
   --device=/dev/davinci1 \
   --device=/dev/davinci2 \
   --device=/dev/davinci3 \
   --device=/dev/davinci4 \
   --device=/dev/davinci5 \
   --device=/dev/davinci6 \
   --device=/dev/davinci7 \
   --device=/dev/davinci_manager \
   --device=/dev/hisi_hdc \
   --device /dev/devmm_svm \
   -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \
   -v /usr/local/Ascend/firmware:/usr/local/Ascend/firmware \
   -v /usr/local/sbin/npu-smi:/usr/local/sbin/npu-smi \
   -v /usr/local/sbin:/usr/local/sbin \
   -v /etc/hccn.conf:/etc/hccn.conf \
   swr.cn-central-221.ovaijisuan.com/mindformers/deepseek_v3_mindspore2.5.0-infer:20250217 \
   bash

注意:

l 上述镜像中包含在研版本代码,仅供试用体验,请勿用作商业用途。

l 起容器时,如果有部分宿主机的hostname是一致的,需要在起容器的时候修改容器的hostname,保证所有容器的hostname都不一致。

l 后续所有操作均在容器内操作。

2、下载模型

MindSpore版本的DeepSeek-R1已上传魔乐社区(https://modelers.cn/models/MindSpore-Lab/DeepSeek-R1),按照如下步骤从魔乐社区下载模型。

创建模型目录,并添加至白名单:


mkdir -p /home/work/DeepSeek-R1
export HUB_WHITE_LIST_PATHS=/home/work/DeepSeek-R1

执行以下 Python 脚本从魔乐社区下载昇思 MindSpore 版本的 DeepSeek-R1 文件至指定路径/home/work/DeepSeek-R1。下载的文件包含模型代码、权重、分词模型和示例代码,占用约 1.4TB 的磁盘空间:

from openmind_hub import snapshot_download

snapshot_download(
    repo_id="MindSpore-Lab/DeepSeek-R1",
    local_dir="/home/work/DeepSeek-R1",
    local_dir_use_symlink=False
)

注意:

l 模型路径可修改为自定义路径,确保该路径下有足够的磁盘空间(约 1.4TB)。

l 下载时间可能因网络环境而异,建议在稳定的网络环境下操作。

3、修改模型配置

修改模型配置文件/home/work/DeepSeek-R1/examples/predict_deepseek3_671B.yaml中的load_checkpoint参数为权重文件夹绝对路径,配置tokenizer_file参数和vocab_file参数为tokenizer.json文件绝对路径。

4、修改推理服务配置

准备rank_table_file.json,按照如下进行配置,其中各配置项需要配置为实际的值。


{
   "server_count": "4",
   "server_list": [
      {
         "device": [
            {
               "device_id": "0", 
               "device_ip": "...", 
               "rank_id": "0"
            },
            ...
            {
               "device_id": "8", 
               "device_ip": "...", 
               "rank_id": "8"
            }
         ],
         "server_ip": "...", 
         "container_ip": "..." 
      },
      ...
      {
         "device": [
            {
               "device_id": "0", 
               "device_ip": "...", 
               "rank_id": "24"
            },
            ...
            {
               "device_id": "8", 
               "device_ip": "...", 
               "rank_id": "31"
            }
         ],
         "server_ip": "...", 
         "container_ip": "..." 
      }
   ],
   "status": "completed",
   "version": "1.0"
}

配置说明:

配置项

配置说明

server_count

总节点数

server_list

节点列表,列表中第一个server为主节点

device

NPU设备列表

device_id

NPU设备ID,取值范围[0,8)

device_ip

NPU设备IP,可通过hccn_tool命令获取

rank_id

NPU设备全局ID,取值范围[0,总卡数)

server_id

节点IP

container_ip

容器IP,服务化部署时需要,若无特殊配置,则与server_ip相同

status

配置状态,不用修改

version

配置版本,不用修改

其中NPU设备IP通过如下命令获取:


for i in {0..7}; do hccn_tool -i $i -ip -g; done

执行以下命令配置服务化需要的环境变量,将MS_SCHED_HOST配置为实际的主节点IP、MIES_CONTAINER_IP配置为本节点IP、RANKTABLEFILE配置为rank_table_file.json的实际路径。

export MS_SCHED_HOST=192.168.1.1
export MS_SCHED_PORT=8080
export MS_ENABLE_LCCL=off
export HCCL_OP_EXPANSION_MODE=AIV
export MIES_CONTAINER_IP=192.168.1.1
export RANKTABLEFILE=./rank_table_file.json
export PYTHONPATH=/root/mindformers/:$PYTHONPATH

执行以下命令打开服务化配置文件config.json:

cd /usr/local/Ascend/mindie/latest/mindie-service/
vim conf/config.json

参数名

修改说明

ipAddress

修改为主节点IP

managementIpAddress

修改为主节点IP

httpsEnabled

配置为false

multiNodesInferEnabled

配置为true,开启多机推理

interCommTLSEnabled

若不需要安全认证,修改为false

interNodeTLSEnabled

若不需要安全认证,修改为false

modelName

自定义模型名,不影响服务化拉起

modelWeightPath

修改为模型文件夹绝对路径/home/work/DeepSeek-R1/examples

5、拉起推理服务

在所有机器上同时执行如下命令:


cd /usr/local/Ascend/mindie/latest/mindie-service/
./bin/mindieservice_daemon

执行命令后,首先会打印本次启动所用的所有参数,然后直到出现以下输出,则认为服务成功启动:

Daemon start success!

执行以下命令发送流式推理请求进行测试(IP地址和端口号需修改为实际值):


curl -w "\ntime_total=%{time_total}\n" -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"inputs": "请介绍一个北京的景点", "parameters": {"do_sample": false, "max_new_tokens": 128}, "stream": false}' http://127.0.0.1:9091/generate_stream &

生成数据

1、安装依赖

执行以下命令安装所需依赖:

pip install datasets tqdm aiofiles aiohttp uvloop

2、执行脚本

从魔乐社区获取调用推理服务生成数据的脚本generate_reasoning.py(https://modelers.cn/models/MindSpore-Lab/OpenR1-Qwen-7B/blob/main/scripts/generate\_reasoning.py),执行以下命令,使用种子数据集中的问题,生成CoT数据:

python generate_reasoning.py \
    --model "DeekSeek-R1"
    --dataset-name "AI-MO/NuminaMath-1.5" \
    --output-file "numinamath_r1_generations.jsonl" \
    --prompt-column "problem" \
    --uuid-column "problem" \
    --api-addr "api.host.name" \
    --num-generations 2 \
    --max-tokens 16384 \
    --max-concurrent 100

参数说明:

  • model: 推理服务的模型名,需要和服务化配置文件 config.json 中的modelName 一致。
  • **dataset-name:**种子数据集名称,配置为HuggingFace Datasets名称或本地的数据集路径。
  • **output-file:**输出CoT数据文件的文件名。
  • **prompt-column:**种子数据集中提示词的列名,使用此列的数据进行CoT数据生成。
  • **uuid-column:**种子数据集中uuid的列名,使用此列计算哈希值去重数据。
  • **api-addr:**推理服务api的地址,配置为 ip:port 。
  • **num-generations:**对于种子数据集中每个问题生成CoT数据的数量。
  • **max-tokens:**生成的CoT数据的最大Token数。
  • **max-concurrent:**请求的最大并发数量。

执行成功后,数据将保存在numinamath_r1_generations.jsonl中。

math-verify

1、安装依赖

执行以下命令安装所需依赖:

pip install math_verify

2、执行脚本

执行以下命令,利用math-verify库过滤错误数据,确保生成的cot数据中回答都是正确的:

python reject_sampling.py --src numinamath_r1_generations.jsonl --dst numinamath_r1_generations_filtered.jsonl

最后生成的数据将保存在numinamath_r1_generations_filtered.jsonl中。

# 02

使用蒸馏数据微调模型实践案例

本案例参考OpenR1-Qwen-7B,基于MindSpore Transformers大模型套件,利用OpenR1发布的DeepSeek-R1蒸馏数据OpenR1-Math-220K微调Qwen2.5-Math-7B-Instruct模型,并取得了和开源相当的评测分数。

准备环境

本案例复用DeepSeek-V3训练镜像。

执行以下 Shell 命令,拉取MindSpore DeepSeek训练容器镜像:

docker pull swr.cn-central-221.ovaijisuan.com/mindformers/deepseek_v3_mindspore2.4.10-train:20250209

执行以下命令启动容器:


image_name=swr.cn-central-221.ovaijisuan.com/mindformers/deepseek_v3_mindspore2.4.10-train:20250209
   docker_name=deepseek_v3
   docker run -itd -u root \
   --ipc=host --net=host \
   --privileged \
   --device=/dev/davinci0 \
   --device=/dev/davinci1 \
   --device=/dev/davinci2 \
   --device=/dev/davinci3 \
   --device=/dev/davinci4 \
   --device=/dev/davinci5 \
   --device=/dev/davinci6 \
   --device=/dev/davinci7 \
   --device=/dev/davinci_manager \
   --device=/dev/devmm_svm \
   --device=/dev/hisi_hdc \
   -v /etc/localtime:/etc/localtime \
   -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \
   -v /usr/local/Ascend/driver/tools/hccn_tool:/usr/local/bin/hccn_tool \
   -v /etc/ascend_install.info:/etc/ascend_install.info \
   -v /var/log/npu:/usr/slog \
   -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
   -v /etc/hccn.conf:/etc/hccn.conf \
   --name "$docker_name" \
   "$image_name" \
   /bin/bash

注意:

l上述镜像中包含在研版本代码,仅供试用体验,请勿用作商业用途。

l后续所有操作均在容器内操作。

执行如下命令拉取MindSpore Transformers代码,并编译安装:

git clone -b dev https://gitee.com/mindspore/mindformers.git
cd mindformers
git checkout b209ce38
bash build.sh

拉取所需配置和代码

案例所需的配置和代码已上传魔乐社区,使用如下命令拉取:

git clone https://modelers.cn/MindSpore-Lab/OpenR1-Qwen-7B.git

准备模型

本次微调使用的模型为Qwen2.5-Math-7B-Instruct,可以在HuggingFace(https://modelers.cn/link?target=https%3A%2F%2Fhuggingface.co%2FQwen%2FQwen2.5-Math-7B-Instruct)下载,并参考Qwen2.5(https://gitee.com/mindspore/mindformers/blob/dev/research/qwen2\_5/qwen2\_5.md#%E6%A8%A1%E5%9E%8B%E6%9D%83%E9%87%8D%E8%BD%AC%E6%8D%A2)权重转换。

预处理数据

由于数据集较大,我们采用离线tokenize的方式对数据集进行预处理。

首先在HuggingFace上下载OpenR1-Math-220K原始数据集,本项目已提供数据集处理所需要的脚本,放在./modules目录下,数据集转换的配置文件放在./dataset/dyn,其中,需要修改配置项data_files的值为各个parquet格式数据文件的路径、修改配置项vocab_file为Qwen2.5-Math-7B-Instruct模型vocab.json文件的路径、修改配置项merges_file为Qwen2.5-Math-7B-Instruct模型merges.txt文件的路径。

在MindSpore Transformers源码目录下执行以下命令:

python toolkit/data_preprocess/huggingface/datasets_preprocess.py --config /path/to/data_process_dyn.yaml --save_path /path/to/save_data --register_path /path/to/modules

参数说明:

参数

说明

config

数据集处理的yaml配置文件路径

save_path

处理后arrow格式文件的保存路径

register_path

外挂代码目录的路径,这里设置为./modules目录的路径

修改微调任务配置

按照如下示例修改微调任务的配置文件configs/finetune_qwen_2_5_7b_dyn.yaml:


...
output_dir: './output'                  # 训练结果保存路径,根据实际情况修改
load_checkpoint: '/path/to/checkpoint'  # 权重加载路径,根据实际情况修改
auto_trans_ckpt: True                   # 打开权重自动转换
resume_training: False                  # 断点续训时开启
...
train_dataset: &train_dataset
  data_loader:
    path: "/path/to/save_data"          # 落盘数据加载路径,根据实际情况修改
...

设置所需环境变量

执行以下命令设置环境变量:


export ACLNN_CACHE_LIMIT=10
export MS_DEV_RUNTIME_CONF="aclnn_cache_queue_length:128"

拉起微调任务

执行以下命令拉起微调任务:

cd mindformers
bash scripts/msrun_launcher.sh "run_mindformer.py --config /path/to/finetune_qwen_2_5_7b_dyn.yaml" 8

参数说明:

参数

说明

config

微调任务的配置文件路径

日志记录在output/msrun_log目录下,可以通过tail指令查看日志信息。

微调完成后,输出的权重文件在output/checkpoint目录下。

经实测,微调后模型的在MATH-500评测任务上与开源得分的对比如下表:

Model

MATH-500

DeepSeek-Distill-Qwen-7B

91.6

OpenR1-Qwen-7B (HuggingFace)

90.6

OpenR1-Qwen-7B (MindSpore Transformers)

89.8

OpenThinker-7B

89.6