Qwen3-VL-2B-Instruct 转 RKNN + RKLLM 部署到 RK3588 实战记录
Qwen3-VL-2B-Instruct 转 RKNN + RKLLM 部署到 RK3588 实战记录
本文记录一次将
Qwen3-VL-2B-Instruct转换为瑞芯微 RK3588 可部署模型的完整过程。
多模态模型需要拆成两部分:Vision 部分导出为.rknn,LLM 部分导出为.rkllm。
一、背景说明
Qwen3-VL 属于视觉语言模型,整体可以理解为:
图片输入
↓
Vision Encoder / Projector
↓
图像特征
↓
Qwen3 LLM
↓
文本输出
在 RK3588 上部署时,通常需要拆成两份模型:
Vision + Projector → RKNN 模型
LLM → RKLLM 模型
最终需要得到两个文件:
qwen3-vl_vision_rk3588.rknn
qwen3-vl-2b-instruct_w8a8_rk3588.rkllm
本文使用的工程为:
rknn-llm
模型为:
Qwen/Qwen3-VL-2B-Instruct
二、环境说明
1. 模型与工程路径
本文中的路径仅作为示例,请按自己的实际路径替换。
Windows 侧模型路径:
E:\Desktop\lbcat4\Qwen3-VL-2B-Instruct
Linux 侧模型路径:
/home/kickpi/Qwen3-VL-2B-Instruct
Linux 侧工程路径:
/home/kickpi/rknn-llm
多模态转换目录:
/home/kickpi/rknn-llm/examples/multimodal_model_demo
2. 工具版本
本次成功使用的关键工具:
rknn-toolkit2: 2.3.0
rkllm-toolkit: 1.3.0
Python: 3.10
目标平台: RK3588
建议配置:
系统:Ubuntu x86_64
内存:至少 16GB,推荐 32GB 或以上
Swap:建议 32GB 或以上
磁盘:建议保留 80GB 以上空间
注意:rkllm-toolkit 工程里提供的是 linux_x86_64 的 wheel,因此导出 .rkllm 建议在 x86_64 Linux 环境中完成。
三、下载模型
可以直接从 HuggingFace 拉取:
git clone https://huggingface.co/Qwen/Qwen3-VL-2B-Instruct
模型目录中应包含:
config.json
model.safetensors
tokenizer.json
tokenizer_config.json
preprocessor_config.json
其中 model.safetensors 大约 4GB。
四、整体转换流程
整体流程如下:
Qwen3-VL-2B-Instruct
│
├── Vision 部分
│ ├── export_vision.py
│ ├── qwen3-vl_vision.onnx
│ └── export_vision_rknn.py
│ ↓
│ qwen3-vl_vision_rk3588.rknn
│
└── LLM 部分
├── make_input_embeds_for_quantize.py
├── data/inputs.json
└── export_rkllm.py
↓
qwen3-vl-2b-instruct_w8a8_rk3588.rkllm
五、导出 Vision ONNX
进入多模态示例目录:
cd ~/rknn-llm/examples/multimodal_model_demo
Qwen3-VL 使用通用脚本 export/export_vision.py,不要使用旧的 Qwen2-VL 专用脚本。
执行:
python export/export_vision.py \
--path /home/kickpi/Qwen3-VL-2B-Instruct \
--model_name qwen3-vl \
--batch_size 1 \
--height 448 \
--width 448 \
--device cpu
成功后会生成:
./onnx/qwen3-vl_vision.onnx
确认文件:
ls -lh ./onnx/qwen3-vl_vision.onnx
关于输入尺寸
Qwen3-VL 的 patch_size 是 16,本次使用:
height = 448
width = 448
转换 RKNN 时也必须保持相同尺寸。
六、ONNX 转 RKNN
这一步需要 rknn-toolkit2 环境。
执行:
python export/export_vision_rknn.py \
--path ./onnx/qwen3-vl_vision.onnx \
--model_name qwen3-vl \
--target-platform rk3588 \
--batch_size 1 \
--height 448 \
--width 448
如果目标板是 RK3576,则改为:
--target-platform rk3576
成功日志类似:
I rknn building ...
I rknn building done.
成功后生成:
./rknn/qwen3-vl_vision_rk3588.rknn
确认:
ls -lh ./rknn/
常见 Warning
可能会看到:
W load_onnx: The input 'grid_thw' will be removed from the model
Please don't forget to remove the corresponding 'mean'/'std' of 'grid_thw' in rknn.config!
本次实测不影响最终生成 .rknn。只要最后出现:
I rknn building done.
并且 .rknn 文件生成,就可以继续下一步。
七、生成 LLM 量化输入
rkllm-toolkit 导出 LLM 时需要量化校准数据。工程中已经提供了脚本:
data/make_input_embeds_for_quantize.py
执行:
python data/make_input_embeds_for_quantize.py \
--path /home/kickpi/Qwen3-VL-2B-Instruct \
--model_type qwen3vl
成功后生成:
data/llm_inputs.json
data/llm_inputs/
但是 export/export_rkllm.py 默认读取的是:
data/inputs.json
所以需要复制一份:
cp data/llm_inputs.json data/inputs.json
确认文件:
ls -lh data/llm_inputs.json
ls -lh data/inputs.json
ls -lh data/llm_inputs | head
本次生成的量化输入目录大小约为:
47M
八、安装 RKLLM 环境
建议单独创建环境,不要和 rknn-toolkit2 混用。
conda create -n rkllm130 python=3.10 -y
conda activate rkllm130
1. 安装 PyTorch CPU 版
pip install torch==2.6.0 torchvision==0.21.0 --index-url https://download.pytorch.org/whl/cpu
2. 安装 rkllm-toolkit
进入工程根目录:
cd ~/rknn-llm
安装 wheel:
pip install --no-deps rkllm-toolkit/packages/rkllm_toolkit-1.3.0-cp310-cp310-linux_x86_64.whl
3. 补充依赖
pip install \
colorlog==6.8.2 \
addict==2.4.0 \
easydict==1.13 \
einops==0.4.1 \
flatbuffers==24.3.25 \
jsonlines==4.0.0 \
jsonschema==4.23.0 \
tabulate==0.9.0 \
transformers-stream-generator==0.0.5 \
Jinja2==3.1.4 \
pillow==10.4.0 \
"protobuf>=4.21.6,<=4.25.4" \
pyarrow==21.0.0 \
safetensors==0.5.3 \
sentencepiece==0.2.0 \
datasets==4.1.1 \
accelerate==1.5.2 \
scipy \
matplotlib \
timm==1.0.19 \
"tiktoken>=0.7.0,<=0.9.0" \
transformers==4.57.0 \
optimum==1.23.3 \
-i https://mirrors.aliyun.com/pypi/simple
验证:
python -c "from rkllm.api import RKLLM; print('rkllm ok')"
python -c "from transformers import Qwen3VLForConditionalGeneration; print('qwen3vl ok')"
如果输出:
rkllm ok
qwen3vl ok
说明环境可用。
九、导出 RKLLM
进入多模态示例目录:
cd ~/rknn-llm/examples/multimodal_model_demo
执行:
python export/export_rkllm.py \
--path /home/kickpi/Qwen3-VL-2B-Instruct \
--target-platform rk3588 \
--num_npu_core 3 \
--quantized_dtype w8a8 \
--device cpu
本次实测日志如下:
INFO: rkllm-toolkit version: 1.3.0
WARNING: rkllm-toolkit only exports Qwen3ForCausalLM of Qwen3VLForConditionalGeneration!
Building model: 100%
Generating train split: 20 examples
Optimizing model: 100%| 28/28 [1:12:19]
INFO: Setting max_context_limit to 4096
INFO: Exporting the model, please wait ....
INFO: Model saved to ./rkllm/qwen3-vl-2b-instruct_w8a8_rk3588.rkllm!
最终生成:
./rkllm/qwen3-vl-2b-instruct_w8a8_rk3588.rkllm
确认:
ls -lh ./rkllm/
十、最终产物
转换完成后,应该得到两个核心模型文件:
Vision RKNN:
./rknn/qwen3-vl_vision_rk3588.rknn
LLM RKLLM:
./rkllm/qwen3-vl-2b-instruct_w8a8_rk3588.rkllm
这两个文件是一套完整的 Qwen3-VL 板端部署模型。
十一、板端运行参考
工程提供了 C++ demo:
examples/multimodal_model_demo/deploy
编译:
cd deploy
./build-linux.sh
将 demo 和模型推到板端后,运行示例大致如下:
./demo demo.jpg \
./qwen3-vl_vision_rk3588.rknn \
./qwen3-vl-2b-instruct_w8a8_rk3588.rkllm \
2048 \
4096 \
3 \
rk3588 \
"<|vision_start|>" \
"<|vision_end|>" \
"<|image_pad|>"
参数说明:
demo.jpg 输入图片
qwen3-vl_vision_rk3588.rknn Vision 模型
qwen3-vl-2b-instruct_w8a8.rkllm LLM 模型
2048 max_new_tokens
4096 max_context_len
3 rknn_core_num
rk3588 platform
<|vision_start|> 图像开始 token
<|vision_end|> 图像结束 token
<|image_pad|> 图像占位 token
十二、踩坑记录
1. Qwen3VLForConditionalGeneration 没有 visual 属性
报错:
AttributeError: 'Qwen3VLForConditionalGeneration' object has no attribute 'visual'
原因是不同版本 transformers 中 Qwen3-VL 的视觉模块挂载位置不同。
有的版本是:
model.visual
而旧脚本可能写的是:
vlm.visual
解决思路是兼容两种结构:
def get_visual_module(vlm):
if hasattr(vlm, "visual"):
return vlm.visual
if hasattr(vlm, "model") and hasattr(vlm.model, "visual"):
return vlm.model.visual
raise AttributeError(f"{type(vlm).__name__} has no visual module")
然后将脚本里的:
self.vpm = vlm.visual
替换为:
self.vpm = get_visual_module(vlm)
2. 导出 ONNX 时缺少 onnx
报错:
torch.onnx.errors.OnnxExporterError: Module onnx is not installed!
解决:
pip install onnx==1.18.0
3. ONNX 转 RKNN 被系统杀死
现象:
已杀死
通常是内存不足,被 Linux OOM Killer 杀掉。
建议:
sudo fallocate -l 32G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
free -h
如果磁盘空间充足,也可以使用 64GB swap。
4. 生成量化输入时缺少 torchvision
报错:
ModuleNotFoundError: No module named 'torchvision'
解决:
pip install torchvision -i https://mirrors.aliyun.com/pypi/simple
5. transformers 版本过旧
报错:
ImportError: cannot import name 'Qwen2_5_VLForConditionalGeneration' from 'transformers'
解决:
pip install transformers==4.57.0 -i https://mirrors.aliyun.com/pypi/simple
如果当前环境是 Python 3.8,建议新建 Python 3.10 环境。
6. 缺少 rkllm 模块
报错:
ModuleNotFoundError: No module named 'rkllm'
说明当前环境没有安装 rkllm-toolkit。
解决:
pip install --no-deps rkllm-toolkit/packages/rkllm_toolkit-1.3.0-cp310-cp310-linux_x86_64.whl
7. 缺少 colorlog
报错:
ModuleNotFoundError: No module named 'colorlog'
解决:
pip install colorlog==6.8.2 -i https://mirrors.aliyun.com/pypi/simple
8. RKLLM 优化阶段很慢
日志:
Optimizing model: 28/28 [1:12:19]
这是正常现象。本次在 CPU 环境下耗时约 1 小时 12 分钟。
建议:
1. 优先使用物理机或服务器,不建议使用低配虚拟机;
2. 有 NVIDIA GPU 且环境支持时,可以尝试 --device cuda;
3. 内存建议 32GB 以上;
4. 不建议中途停止,停止后通常需要重新跑。
十三、总结
Qwen3-VL 在 RK3588 上部署时,关键是将模型拆成两部分:
Vision → RKNN
LLM → RKLLM
本次最终成功产物:
qwen3-vl_vision_rk3588.rknn
qwen3-vl-2b-instruct_w8a8_rk3588.rkllm
实际经验是:
1. Vision ONNX 可以在 Windows 或 Linux 导出;
2. ONNX 转 RKNN 建议在 Linux 中完成;
3. RKLLM 导出必须使用 x86_64 Linux 环境;
4. 量化优化阶段耗时较长,CPU 下 1 小时以上属于正常;
5. 不同 transformers 版本可能导致模型结构路径不同,需要注意 visual 模块位置。
至此,Qwen3-VL-2B-Instruct 到 RK3588 的 RKNN + RKLLM 转换流程完成。
更多推荐
所有评论(0)