在地平线 RDK S100 上部署大模型:量化、转换与推理实践
在地平线 RDK S100 上部署大模型:量化、转换与推理实践
本文记录在地平线 RDK S100 上进行大语言模型(LLM)量化、格式转换与推理部署的完整流程,包括:
- 使用地平线官方 D-Robotics LLM SDK 在 BPU 上部署
- 使用 llama.cpp 在 CPU 上运行 GGUF 模型
- Hugging Face → GGUF → 量化 的完整流程
- 常见参数与性能优化建议
实验平台:
| 项目 | 说明 |
|---|---|
| 开发板 | Horizon Robotics RDK S100 |
| 推理后端 | BPU / CPU |
| 模型示例 | Qwen2.5-1.5B-Instruct |
| 模型格式 | HBM / GGUF |
| 推理框架 | D-Robotics LLM SDK / llama.cpp |
一、使用 D-Robotics 官方方案进行 BPU 推理
S100 的核心优势在于可通过 BPU(Brain Processing Unit)进行低功耗、高吞吐的大模型推理。
官方部署流程本质上分为:
HuggingFace 模型
↓
量化与编译
↓
HBM 模型
↓
S100 BPU 推理
其中:
HBM为地平线设备使用的模型格式- 模型需要在 x86 主机上完成转换
- 推理运行在 S100 板端
二、前期准备
2.1 SDK 部署包准备
下载并解压官方 SDK:
D-Robotics_LLM_{version}.tar.gz
建议目录结构:
~/llm/
└── D-Robotics_LLM_{version}/
后续所有操作均基于该目录。
2.2 安装 Miniforge3
如果系统已经安装 Conda,可跳过本节。
推荐使用 Miniforge3 管理 Python 环境,避免系统 Python 污染。
下载
wget -c https://mirrors.bfsu.edu.cn/github-release/conda-forge/miniforge/LatestRelease/Miniforge3-Linux-x86_64.sh
安装
chmod +x Miniforge3-Linux-x86_64.sh
bash Miniforge3-Linux-x86_64.sh
初始化环境:
source ~/miniforge3/bin/activate
2.3 创建专属 Python 环境
推荐单独创建一个用于模型转换与量化的环境:
conda create -n oellm python=3.10 -y
conda activate oellm
安装 SDK 依赖:
cd D-Robotics_LLM_{version}
pip install -r ./oellm_build/requirements.txt
2.4 安装编译与运行工具链
安装 SDK 提供的 wheel 包:
pip install ./oellm_build/hbdk4_compiler-{version}-cp310-cp310-manylinux_2_17_x86_64.whl
pip install ./oellm_build/hbdk4_runtime_aarch64_unknown_linux_gnu_nash-{version}-py3-none-any.whl
pip install ./oellm_build/leap_llm-{version}-py310-none-any.whl
说明:
| 组件 | 作用 |
|---|---|
| hbdk4_compiler | 模型量化与编译 |
| hbdk4_runtime | S100 Runtime |
| leap_llm | 大模型推理接口 |
三、LLM 模型量化与 HBM 转换
S100 无法直接运行 Hugging Face 原始模型,需要先转换为 HBM 格式。
官方工具 oellm_build 可完成:
- 模型切分
- 量化
- 图优化
- 编译
- HBM 生成
3.1 模型准备
以 Qwen2.5-1.5B-Instruct 为例:
git lfs install
git clone https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct
模型目录中应包含:
config.json
tokenizer.json
model.safetensors
3.2 执行量化与编译
oellm_build \
--model_name qwen2_5-1_5b \
--input_model_path ./Qwen2.5-1.5B-Instruct \
--output_model_path ./output_hbm \
--march nash-m \
--chunk_size 256 \
--cache_len 1024
生成结果:
output_hbm/
└── *.hbm
3.3 核心参数说明
| 参数 | 含义 | 建议 |
|---|---|---|
| --march | 目标芯片架构 | S100 常用 nash-m |
| --chunk_size | 模型分块大小 | 越大吞吐越高,但占用更多内存 |
| --cache_len | KV Cache 长度 | 决定上下文长度 |
| --device | 转换使用 GPU ID | 多 GPU 主机时使用 |
3.4 chunk_size 与 cache_len 的影响
chunk_size
主要影响:
- 推理吞吐
- 内存占用
- Prefill 阶段速度
经验值:
| chunk_size | 特点 |
|---|---|
| 128 | 内存占用低 |
| 256 | 推荐默认值 |
| 512+ | 更高吞吐,但容易 OOM |
cache_len
决定 KV Cache 大小。
上下文越长:
- 内存占用越高
- 首 token 延迟增加
经验建议:
| 场景 | 建议值 |
|---|---|
| 简单问答 | 1024 |
| Chat | 2048 |
| 长上下文 | 4096+ |
四、在 S100 上运行 HBM 模型
HBM 模型生成后,可拷贝到板端运行。
推荐目录结构:
/home/root/llm/
├── model/
├── config/
└── D-Robotics_LLM_{version}/
4.1 切换性能模式
官方建议在推理前切换至性能模式:
sh set_performance_mode.sh
该脚本会:
- 提升 CPU 频率
- 提升 BPU 频率
- 调整功耗策略
4.2 配置运行环境变量
lib=/home/root/llm/D-Robotics_LLM_{version}/oellm_runtime/lib
export LD_LIBRARY_PATH=${lib}:${LD_LIBRARY_PATH}
建议写入:
~/.bashrc
避免每次重复配置。
4.3 命令行推理测试
进入示例目录:
cd ./example/oellm_run
执行推理:
./oellm_run \
--hbm_path ../../model/Qwen2.5_1.5B_Instruct_1024.hbm \
--tokenizer_dir ../../config/Qwen2.5_1.5B_Instruct_config/ \
--template_path ../../config/Qwen2.5_1.5B_Instruct_config/Qwen2.5_1.5B_Instruct.jinja \
--model_type 7
如果成功,会进入交互式对话模式。
4.4 model_type 对应关系
不同模型需要不同类型编号:
| model_type | 模型 |
|---|---|
| 7 | Qwen2.5 |
| 其它 | 参考官方 SDK 文档 |
模型类型不匹配通常会导致:
- tokenizer 异常
- prompt 模板错误
- 输出乱码
4.5 服务化推理
官方还提供 Python Server:
python oellm_server.py \
--hbm_path <HBM_MODEL_PATH> \
--model_type <MODEL_TYPE_ID>
适合:
- HTTP 接口测试
- WebUI 对接
- OpenAI API 封装
五、使用 llama.cpp 在 CPU 上推理
除了 BPU 推理,还可以直接在 CPU 上运行 GGUF 模型。
优势:
- 更灵活
- 社区生态成熟
- 支持大量模型
- OpenAI API 兼容
- 无需 HBM 转换
缺点:
- 完全依赖 CPU
- 速度通常低于 BPU
六、编译 llama.cpp
项目地址:
6.1 获取源码
git clone https://github.com/ggml-org/llama.cpp
cd llama.cpp
6.2 安装依赖
python3 -m pip install -r requirements.txt
该依赖主要用于:
- HuggingFace → GGUF 转换
- tokenizer 处理
- 模型量化
根据官方文档,convert_hf_to_gguf.py 会自动读取:
- config.json
- tokenizer
- safetensors
- architecture metadata
最终生成 GGUF 文件。 (huggingface.co)
6.3 编译 llama.cpp
cmake -B build \
-DBUILD_SHARED_LIBS=OFF \
-DLLAMA_NATIVE=OFF \
-DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release -j$(nproc)
编译完成后,可执行文件位于:
build/bin/
包括:
| 程序 | 作用 |
|---|---|
| llama-cli | 命令行推理 |
| llama-server | OpenAI API 服务 |
| llama-quantize | GGUF 量化 |
| llama-bench | 性能测试 |
七、GGUF 转换与量化
llama.cpp 使用 GGUF 作为统一模型格式。
GGUF 的特点:
- 支持量化
- 支持 mmap
- 适合嵌入式设备
- 加载速度快
- 内存占用低
官方文档指出:GGUF 通过 memory mapping 与量化可降低设备内存带宽需求。 (huggingface.co)
7.1 HuggingFace 转 GGUF
python convert_hf_to_gguf.py \
<HF_MODEL_PATH> \
--outfile <OUTPUT_GGUF_PATH> \
--outtype f16
示例:
python convert_hf_to_gguf.py \
./Qwen2.5-1.5B-Instruct \
--outfile qwen2.5-1.5b-f16.gguf \
--outtype f16
常见 outtype:
| 类型 | 说明 |
|---|---|
| f16 | 半精度 |
| bf16 | Brain Float16 |
| q8_0 | 8bit |
| auto | 自动选择 |
需要注意:
convert_hf_to_gguf.py主要负责格式转换- 高压缩量化通常使用
llama-quantize
这是 llama.cpp 官方推荐流程。 (mintlify.com)
7.2 GGUF 二次量化
生成 f16 GGUF 后,可进一步量化:
./build/bin/llama-quantize \
qwen2.5-1.5b-f16.gguf \
qwen2.5-1.5b-q4_k_m.gguf \
q4_k_m
7.3 常见量化类型
| 量化类型 | 特点 | 推荐 |
|---|---|---|
| Q4_K_M | 平衡速度与质量 | 推荐 |
| Q5_K_M | 更高精度 | 推荐 |
| Q8_0 | 高质量 | 内存较大 |
| IQ4_XS | 极限压缩 | 小内存设备 |
经验上:
Q4_K_M是嵌入式设备最常用方案Q5_K_M质量更好但更占内存Q8_0更适合桌面 CPU
7.4 推荐量化选择
| 内存 | 推荐模型 |
|---|---|
| 4GB | 0.5B ~ 1.5B Q4 |
| 8GB | 3B Q4/Q5 |
| 16GB | 7B Q4 |
对于 S100:
- Qwen2.5-1.5B Q4_K_M 是较均衡选择
- 7B 模型通常会明显受限于内存带宽
八、使用 llama-cli 进行推理
最简单测试方式:
./build/bin/llama-cli \
-m qwen2.5-1.5b-q4_k_m.gguf \
-p "你好" \
-n 128
参数说明:
| 参数 | 说明 |
|---|---|
| -m | 模型路径 |
| -p | Prompt |
| -n | 最大生成 token |
8.1 多线程优化
./build/bin/llama-cli \
-m model.gguf \
-t $(nproc)
其中:
-t指定推理线程数- 通常设置为 CPU 核数
线程数过高可能导致:
- cache miss 增加
- 温度升高
- 功耗增加
九、启动 OpenAI API 服务
llama.cpp 提供 OpenAI 兼容接口:
./build/bin/llama-server \
-m model.gguf \
--port 8080 \
-c 2048 \
-t 4 \
-b 512 \
--mlock
启动后可通过:
http://<ip>:8080/v1/chat/completions
访问。
9.1 常用参数说明
| 参数 | 说明 |
|---|---|
| -c | 上下文长度 |
| -t | 推理线程数 |
| -b | Batch Size |
| -ub | Micro Batch |
| --mlock | 锁定内存 |
| --threads-http | HTTP 工作线程 |
| --no-cont-batching | 禁止连续 batching |
9.2 mlock 的作用
--mlock
可避免模型被 swap 到磁盘。
嵌入式设备建议开启。
否则会出现:
- 首 token 延迟极高
- 推理卡顿
- 系统抖动
9.3 Batch 参数调优
-b
控制 Prefill Batch。
更大:
- 吞吐更高
- 占用更多内存
-ub
控制 Decode 阶段微批。
通常:
ub <= b
经验值:
| 参数 | 推荐 |
|---|---|
| -b | 256 ~ 1024 |
| -ub | 128 ~ 512 |
十、S100 上的实际部署建议
10.1 优先选择小模型
S100 更适合:
- 0.5B
- 1.5B
- 3B
而不是:
- 14B
- 32B
原因:
- 内存带宽有限
- KV Cache 开销明显
- CPU 推理吞吐不足
10.2 推荐模型
| 模型 | 推荐方式 |
|---|---|
| Qwen2.5-0.5B | GGUF Q4 |
| Qwen2.5-1.5B | BPU / GGUF |
| TinyLlama | GGUF |
| Gemma 2B | GGUF |
10.3 BPU 与 CPU 推理对比
| 方案 | 优点 | 缺点 |
|---|---|---|
| BPU (HBM) | 功耗低、速度高 | 转换复杂 |
| CPU (GGUF) | 灵活、生态成熟 | 速度较慢 |
建议:
- 追求性能:使用 HBM + BPU
- 追求兼容性:使用 llama.cpp
十一、常见问题
11.1 convert_hf_to_gguf.py 失败
通常原因:
- transformers 版本不匹配
- tokenizer 缺失
- 模型架构不支持
建议:
pip install -U transformers
11.2 内存不足 OOM
解决方式:
- 使用更低量化
- 降低 context
- 减少 batch size
- 使用更小模型
11.3 推理速度慢
排查方向:
- 是否开启性能模式
- 是否使用 Release 编译
- 是否线程数过多
- 是否触发 swap
十二、参考资料
十三、总结
在 S100 上部署大模型主要有两条路线:
路线一:
HF → HBM → BPU 推理
路线二:
HF → GGUF → llama.cpp CPU 推理
其中:
- HBM 路线性能更高
- GGUF 路线生态更成熟
- 小模型更适合嵌入式部署
- Q4_K_M 是目前较均衡的量化方案
对于嵌入式设备,量化本质上是在:
- 模型质量
- 推理速度
- 内存占用
三者之间进行平衡。
Qwen2.5-1.5B 在 S100 上的实测结果
| 推理方案 | 模型格式 | 量化方式 | 推理后端 | 推理速度 | 精度损失 | Context 支持 | 优点 | 缺点 |
|---|---|---|---|---|---|---|---|---|
| D-Robotics LLM SDK | HBM | INT8 | S100 BPU | ~16 TPS | 很低 | 较短(受 cache_len 限制明显) | 功耗低、推理稳定、BPU 利用率高 | 上下文长度受限、模型转换流程复杂 |
| llama.cpp | GGUF | Q4_K_M | CPU | ~15 TPS | 极低 | 较长(可灵活配置 context) | 生态成熟、兼容性强、支持长上下文 | CPU 占用较高、功耗更高 |
实际体验总结
BPU (HBM INT8)
特点:
- 推理速度较稳定
- 精度损失控制很好
- 更适合低功耗持续运行
- 首 Token 延迟较低
问题:
cache_len对上下文限制明显- 长对话容易触发 KV Cache 不足
- 模型编译与部署链路较复杂
适合:
- 边缘设备
- 固定任务
- 短上下文问答
- Agent 执行类任务
llama.cpp (GGUF Q4_K_M)
特点:
- Q4_K_M 精度表现非常好
- 长上下文支持明显优于 HBM 方案
- 调试与部署更灵活
- OpenAI API 兼容性更好
问题:
- CPU 占用较高
- 长时间运行温度更高
- 功耗明显高于 BPU
适合:
- 本地 Agent
- 长对话
- RAG
- 开发测试环境
综合结论
在 S100 上:
- 如果追求:
- 更低功耗
- 更稳定吞吐
- 更高部署效率
推荐:
HBM + BPU INT8
- 如果追求:
- 更长上下文
- 更强兼容性
- 更灵活生态
推荐:
GGUF Q4_K_M + llama.cpp
目前来看:
Qwen2.5-1.5B Q4_K_M
是 S100 CPU 推理上的一个较均衡方案。