昇思+昇腾开发板+DeepSeek模型开发与适配
昇思+昇腾开发板+DeepSeek模型开发与适配
DeepSeek-R1-Distill-Qwen-1.5B介绍
- 模型特点:
- 基于Qwen2.5-Math-1.5B蒸馏
- 参数量1.5B,适合入门级推理任务
- 使用R1生成的80万条高质量数据监督微调(SFT)
- 保留原模型66%的推理能力1
- 模型对比:
模型 基础模型 适用场景 计算成本 1.5B Qwen2.5 基础数学推理 低 7B Qwen2.5 中级逻辑任务 中 14B Qwen2.5 高级问题解决 中高
开发板环境准备
硬件配置
- 香橙派OrangePi Alpro 20T(24G内存)1
- 昇腾AI处理器(集成8-20 TOPS算力)
软件栈
组件 | 版本要求 | 安装方式 |
---|---|---|
CANN | 8.0.0beta1 | 镜像内置 |
MindSpore | 2.5.0 | 需从2.4.10手动升级 |
MindSpore NLP | 0.4分支 | 源码编译 |
检查Python进程数
export TE_PARALLEL_COMPILER=1
export MAX_COMPILE_CORE_NUMBER=4
内存限制(每次新终端需运行)
bash mem_limit.sh
DeepSeek-R1-Distill-Qwen-1.5B介绍
- 蒸馏版模型特点:
- 选用Llama 3.1/3.3和Qwen 2.5的6个开源模型
- 用R1生成80万条高质量推理数据
- 基于监督微调(SFT)而非RL阶段
- 最小规模的DeepSeek蒸馏模型(1.5B参数)
开发板环境准备CheckList
组件 | 版本要求 |
---|---|
香橙派开发板 | OrangePi Alpro 20T 24G |
CANN | 社区版8.0.0beta1(镜像内置) |
MindSpore | 2.5.0(需从镜像内置2.4.10手动升级) |
MindSpore NLP | 0.4分支 |
网络调试方法
#设置环境变量
export RUN_SLOW=True#执行测试命令
pytest -v -s tests/transformers/models/qwen2/test_modeling_qwen2.py
开启同步模式定位问题
mindspore.set_context(pynative_synchronize=True)
经验分享
a. 针对算子缺失的处理方式
问题定位:
开启同步前:可以初步判断出来,是aclnn cumsum算子的问题,但由于异步执行,无法定位到具体是脚本中的哪一行报错。
开启同步后:确定了错误的具体位置,是modeling_qwen2.py的prepare_inputs_for_generation方法中调用cumsum算子时出现问题。
解决方案:Tensor.cumsum走的是aclnn的cumsum算子,而昇腾310B芯片暂不支持。将其切换成ops.cumsum,改为走aclop算子执行。
b. 针对损失函数报错的处理方式
问题定位:
在开启同步的前提下,可以看出是loss function,也就是CrossEntropyLoss的问题。
解决方案:
损失函数相关的问题,建议使用 mindspore.ops.primitive 中的接口替换。通过查阅文档可知,其中支持昇腾硬件的接口为 mindspore.ops.SoftmaxCrossEntropyWithLogits。
进一步查阅SoftmaxCrossEntropyWithLogits文档,会发现如下注意点:
该损失函数的labels输入需要one-hot格式。
logits和labels的数据类型需要一致。
输出并不是一个零维Tensor。
输出的是一个(loss, dlogits)的tuple,且loss是一个Tensor。
针对上述三点,需要对代码进行如下修改:
将损失函数(loss_fct)修改为 mindspore.ops.SoftmaxCrossEntropyWithLogits。
将labels修改为one-hot格式。
统一labels和logits的数据类型,计算获取loss。
按照原本默认的reduction='mean’转成零维Tensor。
修改后代码示例:
# ...
elif self.config.problem_type == "single_label_classification":# loss_fct = CrossEntropyLoss() # 原代码loss_fct = mindspore.ops.SoftmaxCrossEntropyWithLogits() # 1. 修改损失函数labels = nn.functional.one_hot(labels.view(-1), self.num_labels) # 2. labels转为one-hot# 3. 统一数据类型并计算loss, _ = loss_fct(pooled_logits.view(-1, self.num_labels), labels.to(pooled_logits.dtype))loss = loss.mean() # 4. 转为零维Tensor
# ...