Qwen3-VL-2B 在 RK3576 上的部署实践:RKNN + RKLLM 全流程

本文记录一次完整、可复现的工程实践:

RK3576 平台上,将多模态大模型 Qwen3-VL-2B 拆分并部署到 NPU 上运行。

目标不是介绍工具功能,而是让读者:

按照本文步骤执行代码,最终在板端成功跑起多模态推理 Demo。


一、整体部署流程总览(先看全局)

在 RK 平台上,多模态模型无法以单一模型部署,必须拆分为两个子模型:

  • Vision Encoder → .rknn
  • LLM Decoder → .rkllm

整体流程如下:

本文最终产物:

复制代码
qwen3-vl_vision_rk3576.rknn
qwen3-vl-2b-instruct_w8a8_rk3576.rkllm

二、环境准备(必须一致)

1️⃣ 主机环境(模型转换)

项目 版本
OS Ubuntu 22.04 x86_64
Python 3.10
工具 Miniforge / Conda

2️⃣ 开发板环境

项目 说明
芯片 RK3576
系统 Linux
推理 NPU

三、模型准备

拉取 Qwen3-VL-2B 模型(HuggingFace / ModelScope 均可):

bash 复制代码
git clone https://huggingface.co/Qwen/Qwen3-VL-2B-Instruct

假设模型路径为:

bash 复制代码
/workspace/Qwen3-VL-2B-Instruct

四、LLM 部分:RKLLM 转换与量化(核心)

4.1 加载模型

ini 复制代码
from rkllm.api import RKLLM

llm = RKLLM()

ret = llm.load_huggingface(
    model="/workspace/Qwen3-VL-2B-Instruct",
    device="cpu",
    dtype="float16",
)

if ret != 0:
    raise RuntimeError("load_huggingface failed")

说明:

  • 使用 CPU 转换,避免显存不足
  • FP16 对 w8a8 量化足够

4.2 构建量化数据集(关键步骤)

多模态模型不能直接量化原始图像输入,需要先构造 inputs_embeds

ini 复制代码
inputs_embeds = model.get_input_embeddings()(inputs["input_ids"])

image_mask = inputs["input_ids"] == model.config.image_token_id
image_embeds = model.visual(
    inputs["pixel_values"],
    grid_thw=inputs["image_grid_thw"]
)

inputs_embeds[image_mask] = image_embeds

inputs_embeds 保存为 numpy,用于量化校准:

javascript 复制代码
import numpy as np
np.save("inputs_embeds.npy", inputs_embeds.cpu().numpy())

最终生成 inputs.json,作为 RKLLM 的校准数据集。


4.3 构建并导出 RKLLM 模型

ini 复制代码
ret = llm.build(
    do_quantization=True,
    quantized_dtype="w8a8",
    quantized_algorithm="normal",
    target_platform="RK3576",
    num_npu_core=2,
    dataset="data/inputs.json"
)

if ret != 0:
    raise RuntimeError("build failed")

llm.export_rkllm(
    "qwen3-vl-2b-instruct_w8a8_rk3576.rkllm"
)

五、Vision 部分:ONNX → RKNN

5.1 导出 Vision ONNX

css 复制代码
python export_vision.py \
  --path /workspace/Qwen3-VL-2B-Instruct \
  --model_name qwen3-vl \
  --height 448 \
  --width 448

输出:

复制代码
qwen3-vl_vision.onnx

5.2 ONNX 转 RKNN

css 复制代码
python export_vision_rknn.py \
  --path qwen3-vl_vision.onnx \
  --target-platform rk3576 \
  --height 448 \
  --width 448

输出:

复制代码
qwen3-vl_vision_rk3576.rknn

六、板端部署与运行

6.1 拷贝文件到开发板

vbnet 复制代码
qwen3-vl_vision_rk3576.rknn
qwen3-vl-2b-instruct_w8a8_rk3576.rkllm
demo
lib/

6.2 设置运行环境

bash 复制代码
export LD_LIBRARY_PATH=./lib:$LD_LIBRARY_PATH

6.3 运行 Demo

bash 复制代码
./demo demo.jpg \
  qwen3-vl_vision_rk3576.rknn \
  qwen3-vl-2b-instruct_w8a8_rk3576.rkllm \
  256 2048 2 \
  "<|vision_start|>" "<|vision_end|>" "<|image_pad|>"

参数说明:

  • vision_start / vision_end:标识视觉 embedding 边界
  • image_pad:多图或补齐占位符

七、结果验证

运行成功后,终端会输出模型对图片内容的描述或回答。

至此,一个 完整的端侧多模态推理流程部署完成


八、实践总结

  1. RK 平台多模态模型必须拆分
  2. RKLLM 的核心是量化与运行时管理
  3. 量化数据准备是成功关键
  4. w8a8 是当前最稳妥的工程选择
相关推荐
先吃饱再说8 小时前
判断回文字符串,从一行代码到双指针优化
算法
黄敬峰11 小时前
深入理解算法核心:从递归思想、数组扁平化到快速排序
算法
得物技术12 小时前
从狂野代码到按目标生产:得物推荐 AI Harness 的工程化实践|AICon 演讲整理
人工智能·算法·架构
AI小老六15 小时前
SkillOpt 架构拆解:把 Skill 文本当参数,用执行轨迹训练 Agent
后端·算法·ai编程
胡萝卜术16 小时前
从“分数打架”到“排名投票”:为什么你的ChatBI必须用RRF?
算法·设计模式·面试
Asize17 小时前
初识DFS 与 BFS:递归、队列与图遍历
算法
罗西的思考1 天前
机器人 / 强化学习】HIL-SERL:人类在环驱动的具身智能进化框架
人工智能·算法·机器学习
美团技术团队1 天前
LongCat 开源 VitaBench 2.0:长期动态智能体基准新标杆
人工智能·算法
To_OC2 天前
LC 207 课程表:刚学图论那会儿,我连这是拓扑排序都没看出来
javascript·算法·leetcode