引言
年初,Deepseek引领了一波本地部署大语言模型的浪潮,本地部署模型意义之一在于可以有效保护数据隐私。相较于文本数据,图像数据通常包含更多敏感信息,因此对于视觉模型而言,本地部署显得更为重要。
本文将介绍在华硕IOT PE1100N嵌入式终端(Jetson Orin NX 16G) 上,本地部署和运行通义千问最新发布的Qwen2.5-VL-3B-Instruct视觉大模型。
本机环境
在终端通过jtop指令,可以获取到本机的基本信息,其中有几项信息本文需重点关注:
处理器架构:aarch64Python版本:3.10.12Jetpack版本:6.0CUDA版本:12.2.140

基础环境搭建
安装最新Transformers框架
pip install git+https://github.com/huggingface/Transformers accelerate
此步骤,阿里推荐使用源码编译安装的方式,是为了确保安装最新的Transformers框架,以便导入最新的qwen2_5_vl模块。
安装qwen-vl-utils工具
pip install qwen-vl-utils==0.0.8
安装运算库
sudo apt-get install libopenblas-base libopenmpi-dev libomp-dev
安装modelscope
pip install modelscope
本文中,modelscope主要用于模型的高速下载。
专有环境搭建
PE1100N终端搭载的是Jetson Orin NX模组,具备GPU加速能力,因此一些AI相关的关键组件,需要安装与平台适配的编译版本。由于平台架构是aarch64,而非常见的x86_64架构,因此组件的官方github仓库通常不会为该平台编译发布可执行文件。对此,一般有两种解决方法:
下载源码,本机自行编译安装找找是否有好心人在同平台编译好了whl,直接下载安装
本文选择第二种,牢记下面这个网址,它提供了Jetson平台,不同Jetpack版本,不同CUDA版本,编译好的whl。
网址:https://pypi.jetson-ai-lab.dev/

根据本机的Jetpack 6.0/CUDA 12.2环境,找到对应/jp6/cu122的入口,里面常用的组件均已编译提供:

缺少相关组件时,优先在该目录查找是否存在对应的whl文件。如果存在,直接下载到本地,然后通过pip指令进行安装。
安装torch
pip install --no-cache /home/asusiot/lc/torch-2.4.0-cp310-cp310-linux_aarch64.whl
在终端,通过下面三行指令,验证torch是否可以识别到cuda:
python>>> import torch>>> torch.cuda.is_available()

安装torchvision
pip install --no-cache /home/asusiot/lc/torchvision-0.19.0a0+48b1edf-cp310-cp310-linux_aarch64.whl
安装triton
pip install --no-cache /home/asusiot/lc/triton-3.1.0-cp310-cp310-linux_aarch64.whl
安装flash_attn
安装flash_attn过程比较曲折,我发现安装/jp6/cu122目录下的flash_attn-2.5.7,无法正常运行,报如下错误:

于是我尝试下载安装jp6/cu126目录下的flash-attn-2.7.2.post1,可以正常运行。
pip install --no-cache /home/asusiot/lc/flash_attn-2.7.2.post1-cp310-cp310-linux_aarch64.whl
如果运行时还提示缺少某些组件,参照上述方法,进行安装补全即可。
推理代码
import torchfrom transformers import Qwen2_5_VLForConditionalGeneration, AutoTokenizer, AutoProcessorfrom qwen_vl_utils import process_vision_infofrom modelscope import snapshot_downloadmodel_dir = snapshot_download("Qwen/Qwen2.5-VL-3B-Instruct")## default: Load the model on the available device(s)#model = Qwen2_5_VLForConditionalGeneration.from_pretrained(# model_dir, torch_dtype=torch.bfloat16, device_map="auto"#)# We recommend enabling flash_attention_2 for better acceleration and memory saving, especially in multi-image and video scenarios.model = Qwen2_5_VLForConditionalGeneration.from_pretrained(model_dir,torch_dtype=torch.bfloat16,attn_implementation="flash_attention_2",device_map="auto",)# default processerprocessor = AutoProcessor.from_pretrained(model_dir)# The default range for the number of visual tokens per image in the model is 4-16384.# You can set min_pixels and max_pixels according to your needs, such as a token range of 256-1280, to balance performance and cost.# min_pixels = 256*28*28# max_pixels = 1280*28*28# processor = AutoProcessor.from_pretrained("Qwen/Qwen2.5-VL-3B-Instruct", min_pixels=min_pixels, max_pixels=max_pixels)messages = [{"role": "user","content": [{"type": "image","image": "/home/asusiot/lc/qwen25vl/demo.jpg?x-oss-process=image/watermark,g_center,image_YXJ0aWNsZS9wdWJsaWMvd2F0ZXJtYXJrLnBuZz94LW9zcy1wcm9jZXNzPWltYWdlL3Jlc2l6ZSxQXzQwCg,t_20",},{"type": "text", "text": "你看到了什么"},],}]# Preparation for inferencetext = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)image_inputs, video_inputs = process_vision_info(messages)inputs = processor(text=[text],images=image_inputs,videos=video_inputs,padding=True,return_tensors="pt",)inputs = inputs.to("cuda")# Inference: Generation of the outputgenerated_ids = model.generate(**inputs, max_new_tokens=128)generated_ids_trimmed = [out_ids[len(in_ids) :] for in_ids, out_ids in zip(inputs.input_ids, generated_ids)]output_text = processor.batch_decode(generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False)print(output_text)
代码首次运行时,会自动从modelscope下载模型文件到本地。
运行效果

没错,正如模型所描述的,该照片是我在成都西岭雪山景点的一个随拍。简单测试了一下,不同分辨率、不同信息量的图片,模型推理时间从几秒到十几秒不等。当然,这是未经量化处理的模型。
小结
本文在华硕IOT-PE1100N嵌入式终端(Jetson Orin NX 16G) 上,实际部署和运行了视觉大模型Qwen2.5-VL-3B-Instruct,该部署方法同样适用于其它搭载Jetson模组的嵌入式终端,也可为其它视觉模型的部署提供参考。另外,本文部署运行的是原始模型文件,未做特别的优化处理。后续,可以考虑通过模型量化等方式提升推理速度,并进一步降低内存占用。
最后,感谢华硕IOT对本文提供的硬件支持!
更多信息,请关注公众号“ETRD”获取。

