目录
引言
为什么要做端侧部署
技术发展层面
应用需求层面
开发与成本层面
产业发展层面
模型选择
模型蒸馏
模型转换
量化选择
量化方式
模型大小
计算效率
模型精度
测试
测试程序编译
测试结果
结语
引言
最近DeepSeek已经成为一个非常热门的话题,整天被刷屏。今天我也凑个热闹,在RK3588开发板上实现DeepSeek-R1-Distill-Qwen-1.5B的部署,看看端侧推理的效果。
为什么要做端侧部署
把DeepSeek部署在嵌入式开发板上显然不是为了解决目前DS服务器不好用的问题。更多的是探索AI在嵌入式领域的应用前景。
将 DeepSeek 部署在嵌入式开发板上有诸多意义,主要体现在以下几个方面:
技术发展层面
- 提升边缘计算能力:可让嵌入式设备在本地完成复杂的 AI 运算,无需依赖云端。例如在智能安防摄像头中,部署 DeepSeek 后能在本地实时进行图像识别与分析,检测异常行为等,大大提升响应速度。
- 推动技术融合创新:DeepSeek 与嵌入式开发板的结合,是 AI 技术与嵌入式技术的深度融合,能推动相关技术的创新发展,为其他技术领域的融合提供借鉴和思路。
- 拓展模型应用场景:从智能家居、可穿戴设备到工业自动化、自动驾驶等领域,DeepSeek 都能为嵌入式设备带来新的应用可能。比如在智能家居中,可实现更智能的语音交互和场景控制。
应用需求层面
- 满足实时性需求:在一些对实时性要求极高的场景,如自动驾驶、工业自动化控制等,将 DeepSeek 部署在嵌入式开发板上,能在本地快速进行数据处理和决策,满足实时性要求。
- 加强隐私保护:数据在本地设备上进行处理,减少了数据上传到云端的需求,降低了数据泄露的风险,尤其对于一些涉及个人隐私或敏感信息的数据,如医疗设备采集的人体健康数据。
- 降低网络依赖:在网络信号不佳或不稳定的环境中,如偏远地区的物联网设备、野外作业的监测设备等,DeepSeek 在嵌入式开发板上的本地部署,可确保设备正常运行,不受网络限制。
开发与成本层面
- 降低开发门槛:DeepSeek 提供了完善的开发工具链和丰富的算法库,即使是初学者也能快速上手,开发出功能强大的 AI 应用,有助于推动嵌入式 AI 应用的普及。
- 节省开发成本:DeepSeek 的开源特性以及较高的推理效率,参数量级较 GPT-4 减少 30%,推理速度提升 25%,训练成本较主流方案降低约 35%,可以减少开发过程中的资源投入。
产业发展层面
- 构建完整价值链条:“先进算法 + 定制化芯片” 的协同运作模式,构建起了一条从技术研发到产业赋能的完整价值链条,为各行业智能化转型提供可借鉴复用的创新范例。
- 推动产业升级:助力各行业实现智能化转型,如在交通领域,宇通的 “云管家安睿通” 系统通过 DeepSeek 实现主动式服务预警;在金融领域,能提升投研效率。
模型选择
模型蒸馏
DeepSeek-R1-Distill-Qwen-1.5B 是 DeepSeek-R1 系列中的一个轻量级蒸馏模型,以下是关于它的具体介绍:
- 模型属性:是基于 Qwen 模型,运用知识蒸馏技术从更大版本的 DeepSeek-R1 模型中提取出来的紧凑高效版本,参数量为 15 亿,属于小型语言模型。
- 技术特点:知识蒸馏过程将大型模型的知识和推理能力转移到 Qwen-1.5B 中,使得它在保持较高性能的同时,降低了计算复杂度和资源消耗。
- 性能优势:在一些主要基准上有出色表现,甚至超越了 GPT-4 和 Claude 3.5 Sonnet,能在数学和逻辑推理任务中展现出比 GPT-4o 和 Claude 3.5 等模型更优越的性能。
- 适用场景:由于其体积小、推理速度快,极适合资源受限环境,适用于手机、旧款笔记本甚至树莓派等设备进行简单问答、短文本生成等实时应用,在纯 CPU 模式下也能流畅运行。
- 部署优势:成本低、部署简单,适合初学者与边缘设备使用,有助于推动 AI 技术在更多场景中的应用和普及。
大型模型结构复杂、参数量大,在进行推理等计算时需要大量的计算资源和时间。通过蒸馏,将大型模型的知识迁移到小型模型上,小型模型的计算量大幅减少,能够在普通的硬件设备上快速运行,比如可以在移动设备或嵌入式设备上实时进行计算,而无需依赖昂贵的高性能服务器。
DS的全量模型太大了,肯定无法部署在嵌入式开发板上,目前在嵌入式领域部署的主要是1.5B、7B、8B几个版本。
模型转换
在瑞芯微的大模型官方网站(GitHub - airockchip/rknn-llm)介绍了如何进行模型转换。
首先需要在PC的Linux上安装如下工具:
rkllm - toolkit==1.1.4
rkllm - runtime==1.1.4
python==3.8或python==3.10
然后进行如下步骤:
- 创建
data_quant.json
来对 rkllm 模型进行量化,我们使用 fp16 模型生成结果作为量化校准数据。 - 运行以下代码来生成
data_quant.json
并导出 rkllm 模型。
cd export
python generate_data_quant.py -m /path/to/DeepSeek - R1 - Distill - Qwen - 1.5B
python export_rkllm.py
瑞芯微在官方的rkllm_model_zoo提供了已转换的 rkllm 模型(提取码:rkllm),可以直接下载相应的模型,这里跳过模型转换的步骤。
量化选择
目前官方提供的转换后的模型文件有两个:DeepSeek-R1-Distill-Qwen-1.5B_W8A8_RK3588.rkllm
和 DeepSeek-R1-Distill-Qwen-1.5B_FP16_RK3588.rkllm
,都是针对特定硬件平台(RK3588)进行量化处理后的模型,它们的主要区别如下:
量化方式
DeepSeek-R1-Distill-Qwen-1.5B_W8A8_RK3588.rkllm
- “W8A8” 表示权重(Weight)采用 8 位量化,激活值(Activation)也采用 8 位量化。8 位量化是一种较为常见的低精度量化方式,将原本更高精度(如 32 位浮点)的数值用 8 位来表示。这种方式大幅减少了模型参数和计算过程中的数据量。
DeepSeek-R1-Distill-Qwen-1.5B_FP16_RK3588.rkllm
- “FP16” 指的是半精度浮点数(16 位浮点)量化。与 8 位量化相比,FP16 保留了相对更多的精度信息,其数值表示范围和精度介于 32 位浮点数和 8 位量化之间。
模型大小
DeepSeek-R1-Distill-Qwen-1.5B_W8A8_RK3588.rkllm
- 由于 8 位量化极大地压缩了数据表示,该模型的文件大小通常会显著小于 FP16 量化的模型。更小的模型大小意味着在存储和传输过程中占用更少的资源,对于存储容量有限的设备(如一些嵌入式设备)来说更为友好。
DeepSeek-R1-Distill-Qwen-1.5B_FP16_RK3588.rkllm
- 半精度浮点数量化虽然也对模型进行了一定程度的压缩,但相较于 8 位量化,其模型大小会更大一些。
计算效率
DeepSeek-R1-Distill-Qwen-1.5B_W8A8_RK3588.rkllm
- 8 位量化在计算时可以显著减少内存访问和计算量,从而提高计算效率。在一些支持 8 位整数运算的硬件平台(如 RK3588)上,该模型能够利用硬件的低精度计算单元进行加速,使得推理速度更快。
DeepSeek-R1-Distill-Qwen-1.5B_FP16_RK3588.rkllm
- FP16 量化的计算效率介于 8 位量化和 32 位浮点计算之间。虽然比 32 位浮点计算更高效,但由于其数据精度高于 8 位量化,计算量和内存访问需求相对较大,因此推理速度可能不如 8 位量化模型。
模型精度
DeepSeek-R1-Distill-Qwen-1.5B_W8A8_RK3588.rkllm
- 8 位量化不可避免地会损失一定的精度,因为用 8 位来表示原本更高精度的数值会导致信息丢失。在一些对精度要求极高的任务中,这种精度损失可能会对模型的性能产生一定影响,例如复杂的文本生成或高精度的知识问答任务。
DeepSeek-R1-Distill-Qwen-1.5B_FP16_RK3588.rkllm
- FP16 量化保留了相对较多的精度信息,因此在模型性能上通常更接近原始的高精度模型。在对精度要求较高的场景中,FP16 量化模型能够提供更好的结果。
我使用的是合众恒跃的4GB版本的AI300G智能盒,无法使用FP16的版本只能使用W8A8版本。
测试
测试程序编译
我们使用的测试程序是瑞芯微官方提供的DeepSeek-R1-Distill-Qwen-1.5B Demo程序比较简单,我们采用的是官方提供的Ubuntu 20.02固件,直接进行本地编译。进入deploy目录,执行如下目录:
cmake ..
make
即可生成可执行文件。如果需要交叉编译,可以修改deploy/build-linux.sh文件。
编译后执行如下命令即可运行程序:
# export lib path
export LD_LIBRARY_PATH=./lib
/llm_demo '/home/hzhy/rkllm/DeepSeek-R1-Distill-Qwen-1.5B_W8A8_RK3588.rkllm' 2048 4096
注意,瑞芯微手册上给的命令行参数太小了,无法加载模型。
测试结果
官方手册上说
RKLLM 所需要的 NPU 内核版本较高,用户在板端使用 RKLLM Runtime 进行模型
推理前,首先需要确认板端的 NPU 内核是否为 v0.9.8 版本,具体的查询命令如下:# 板端执行以下命令,查询 NPU 内核版本 cat /sys/kernel/debug/rknpu/version # 确认命令输出是否为: # RKNPU driver: v0.9.8
若所查询的 NPU 内核版本低于 v0.9.8,请前往官方固件地址下载最新固件进行更新。
不过从实际测试看,合众恒跃开发板上的版本是v0.9.3,也是可以运行测试的,不需要更新固件。
若需要查看 RKLLM 在板端推理的性能,可使用如下指令:
export RKLLM_LOG_LEVEL=1
即可在每次推理完成后,显示 Prefill 与 Generate 阶段的 token 数与推理耗时。
下面是让DS对我的课程进行了一下评价。从这段评价看,1.5B的模型不是很理想,它无法忽略思考过程。
我也测试了官方的两个例子。
hzhy@arm64-ubuntu:~/rkllm/rknn-llm-main/examples/DeepSeek-R1-Distill-Qwen-1.5B_Demo/deploy$ /llm_demo '/home/hzhy/rkllm/DeepSeek-R1-Distill-Qwen-1.5B_W8A8_RK3588.rkllm' 2048 4096
bash: /llm_demo: No such file or directory
hzhy@arm64-ubuntu:~/rkllm/rknn-llm-main/examples/DeepSeek-R1-Distill-Qwen-1.5B_Demo/deploy$ ./llm_demo '/home/hzhy/rkllm/DeepSeek-R1-Distill-Qwen-1.5B_W8A8_RK3588.rkllm' 2048 4096
rkllm init start
W rkllm: Warning: Your rknpu driver version is too low, please upgrade to 0.9.7.I rkllm: rkllm-runtime version: 1.1.4, rknpu driver version: 0.9.3, platform: RK3588Killed
hzhy@arm64-ubuntu:~/rkllm/rknn-llm-main/examples/DeepSeek-R1-Distill-Qwen-1.5B_Demo/deploy$ ./llm_demo '/home/hzhy/rkllm/DeepSeek-R1-Distill-Qwen-1.5B_W8A8_RK3588.rkllm' 2048 4096
rkllm init start
W rkllm: Warning: Your rknpu driver version is too low, please upgrade to 0.9.7.I rkllm: rkllm-runtime version: 1.1.4, rknpu driver version: 0.9.3, platform: RK3588rkllm init success**********************可输入以下问题对应序号获取回答/或自定义输入********************[0] 现有一笼子,里面有鸡和兔子若干只,数一数,共有头14个,腿38条,求鸡和兔子各有多少只?
[1] 有28位小朋友排成一行,从左边开始数第10位是学豆,从右边开始数他是第几位?*************************************************************************user: 0
现有一笼子,里面有鸡和兔子若干只,数一数,共有头14个,腿38条,求鸡和兔子各有多少只?
robot: <think>
首先,设鸡的数量为x,兔子的数量为y。根据题目中的条件,我们知道:1. 鸡和兔子的总数是14只,因此有方程:x + y = 142. 鸡有两条腿,兔子有四条腿,总腿数是38条,所以有另一个方程:2x + 4y = 38接下来,通过代入法或消元法来解这两个方程。假设我们用代入法:从第一个方程中解出x:x = 14 - y将这个表达式代入第二个方程:2(14 - y) + 4y = 38
展开计算:28 - 2y + 4y = 38
合并同类项:2y = 10
解得:y = 5然后,将y的值代入x = 14 - y中:x = 14 - 5 = 9因此,鸡有9只,兔子有5只。
</think>要解决这个问题,我们可以使用代数的方法。设:- 鸡的数量为 \( x \) 只
- 兔子的数量为 \( y \) 只根据题目给出的条件,可以列出以下两个方程:1. **总头数**:鸡和兔子每只都有一个头,所以:\[x + y = 14\]2. **腿的总数**:鸡有两条腿,兔子有四条腿,所以:\[2x + 4y = 38\]接下来,我们可以通过解这两个方程来找到 \( x \) 和 \( y \) 的值。**步骤一:从第一个方程中解出一个变量**我们可以从第一个方程中解出 \( x \):
\[
x = 14 - y
\]**步骤二:代入第二个方程**将 \( x = 14 - y \) 代入第二个方程:
\[
2(14 - y) + 4y = 38
\]
展开计算:
\[
28 - 2y + 4y = 38
\]
合并同类项:
\[
2y = 10
\]
解得:
\[
y = 5
\]**步骤三:求出 \( x \)**将 \( y = 5 \) 代入 \( x = 14 - y \) 中:
\[
x = 14 - 5 = 9
\]因此,鸡的数量是 **9只**,兔子的数量是 **5只**。**最终答案:**
鸡有 \(\boxed{9}\) 只,兔子有 \(\boxed{5}\) 只。--------------------------------------------------------------------------------------Stage Total Time (ms) Tokens Time per Token (ms) Tokens per Second
--------------------------------------------------------------------------------------Prefill 619.66 39 15.89 62.94 Generate 117258.71 627 189.71 5.27
--------------------------------------------------------------------------------------user: 1
有28位小朋友排成一行,从左边开始数第10位是学豆,从右边开始数他是第几位?
robot: <think>
首先,总共有28位小朋友。从左边开始数,第10位是学豆。因此,学豆的位置是从左边数的第10位。接下来,计算从右边数的第几位:总人数减去左边数的第10位,即28 - 10 = 18。所以,学豆在右边数的第18位。
</think>要解决这个问题,我们可以按照以下步骤进行分析:**已知条件:**
- 总共有 **28** 位小朋友排成一行。
- 从左边开始数,第 **10** 位是学豆。**问题:**
从右边开始数,学豆是第几位?**解答过程:**1. **确定学豆的位置:**- 学豆是从左边数的第10位,即位置编号为 **10**(假设从左到右依次编号)。2. **计算从右边数的第几位:**- 总人数是 **28** 人。- 如果学豆在第10位(从左边开始数),那么从右边数的位置可以通过以下公式计算:\[\text{位置} = \text{总人数} - \text{左边数的位数}\]即:\[\text{位置} = 28 - 10 = 18\]**最终答案:**
\boxed{18}--------------------------------------------------------------------------------------Stage Total Time (ms) Tokens Time per Token (ms) Tokens per Second
--------------------------------------------------------------------------------------Prefill 444.11 33 13.46 74.31 Generate 56647.80 318 180.93 5.53
--------------------------------------------------------------------------------------user: exit
测试程序非常消耗内存,我在运行测试程序时甚至不能打开浏览器,否则就会出现如下问题:
hzhy@arm64-ubuntu:~/rkllm/rknn-llm-main/examples/DeepSeek-R1-Distill-Qwen-1.5B_Demo/deploy$ ./llm_demo '/home/hzhy/rkllm/DeepSeek-R1-Distill-Qwen-1.5B_W8A8_RK3588.rkllm' 2048 4096
rkllm init start
W rkllm: Warning: Your rknpu driver version is too low, please upgrade to 0.9.7.I rkllm: rkllm-runtime version: 1.1.4, rknpu driver version: 0.9.3, platform: RK3588Killed
合众恒跃的工程师给的建议是使用8GB版本的AI300G。
结语
从测试看,端侧AI推理发展得还是很快的。随着人工智能模型越来越发展,相信端侧推理会有很大的发展空间。