在rk3588上部署InternVL系列
在rk3588上部署InternVL2-1B
准备
首先要在hf上下载InternVL2-1B的模型传送门(镜像)
git clone https://hf-mirror.com/OpenGVLab/InternVL2-1B
还要安装rknn转换的必要软件,这里不多赘述
转换
将vision_model和mlp转为onnx的代码如下:
import numpy as np
import os
import torch
import torch.nn as nn
from transformers import AutoTokenizer, AutoModel
import torch.nn.functional as F
from PIL import Image
import torchvision.transforms as T
from torchvision.transforms import InterpolationMode
from transformers.modeling_utils import PreTrainedModel
IMAGENET_MEAN = (0.485, 0.456, 0.406)
IMAGENET_STD = (0.229, 0.224, 0.225)
def build_transform(input_size):
MEAN, STD = IMAGENET_MEAN, IMAGENET_STD
transform = T.Compose([
T.Lambda(lambda img: img.convert('RGB') if img.mode != 'RGB' else img),
T.Resize((input_size, input_size), interpolation=InterpolationMode.BICUBIC),
T.ToTensor(),
T.Normalize(mean=MEAN, std=STD)
])
return transform
def find_closest_aspect_ratio(aspect_ratio, target_ratios, width, height, image_size):
best_ratio_diff = float('inf')
best_ratio = (1, 1)
area = width * height
for ratio in target_ratios:
target_aspect_ratio = ratio[0] / ratio[1]
ratio_diff = abs(aspect_ratio - target_aspect_ratio)
if ratio_diff < best_ratio_diff:
best_ratio_diff = ratio_diff
best_ratio = ratio
elif ratio_diff == best_ratio_diff:
if area > 0.5 * image_size * image_size * ratio[0] * ratio[1]:
best_ratio = ratio
return best_ratio
def dynamic_preprocess(image, min_num=1, max_num=12, image_size=448, use_thumbnail=False):
orig_width, orig_height = image.size
aspect_ratio = orig_width / orig_height
# calculate the existing image aspect ratio
target_ratios = set(
(i, j) for n in range(min_num, max_num + 1) for i in range(1, n + 1) for j in range(1, n + 1) if
i * j <= max_num and i * j >= min_num)
target_ratios = sorted(target_ratios, key=lambda x: x[0] * x[1])
# find the closest aspect ratio to the target
target_aspect_ratio = find_closest_aspect_ratio(
aspect_ratio, target_ratios, orig_width, orig_height, image_size)
# calculate the target width and height
target_width = image_size * target_aspect_ratio[0]
target_height = image_size * target_aspect_ratio[1]
blocks = target_aspect_ratio[0] * target_aspect_ratio[1]
# resize the image
resized_img = image.resize((target_width, target_height))
processed_images = []
for i in range(blocks):
box = (
(i % (target_width // image_size)) * image_size,
(i // (target_width // image_size)) * image_size,
((i % (target_width // image_size)) + 1) * image_size,
((i // (target_width // image_size)) + 1) * image_size
)
# split the image
split_img = resized_img.crop(box)
processed_images.append(split_img)
assert len(processed_images) == blocks
if use_thumbnail and len(processed_images) != 1:
thumbnail_img = image.resize((image_size, image_size))
processed_images.append(thumbnail_img)
return processed_images
def load_image(image_file, input_size=448, max_num=12):
image = Image.open(image_file).convert('RGB')
transform = build_transform(input_size=input_size)
images = dynamic_preprocess(image, image_size=input_size, use_thumbnail=True, max_num=max_num)
pixel_values = [transform(image) for image in images]
pixel_values = torch.stack(pixel_values)
return pixel_values
# 加载本地模型
path = './InternVL2-1B'
save_path = 'onnx/InternVL2-1B_vision.onnx'
image_file = 'InternVL2-1B/examples/image1.jpg'
def export_vision_InternVL(model_path: str, save_path: str):
"""
Export the vision encoder and projector of Janus-Pro-1B model to ONNX format
"""
# 设置默认数据类型为 float32
torch.set_default_dtype(torch.float32)
vl_gpt = AutoModel.from_pretrained(model_path,torch_dtype = torch.float32,trust_remote_code=True)
# Move model to CPU and convert to float32
vl_gpt = vl_gpt.cpu().eval().float() # 确保模型是 float32
# Create a wrapper class for vision encoder + projector
class VisionWrapper(nn.Sequential):
def __init__(self, model):
super().__init__()
self.vision_town = model.vision_model
self.mlp = model.mlp1
self.vision_mlp = model.extract_feature
def forward(self, pixel_values):
projected_features = self.vision_mlp(pixel_values)
return projected_features
# Create wrapper instance and convert to float32
vision_wrapper = VisionWrapper(vl_gpt)
vision_wrapper.eval().float() # 确保包装器也是 float32
# Create dummy input with float32
batch_size = 1
num_channels = 3
height = 448 # InternVL2 default image size
width = 448
dummy_input = load_image(image_file=image_file, max_num=12).to(torch.float32).cpu()
# dummy_input = torch.randn(batch_size, num_channels, height, width, dtype=torch.float32)
# Export to ONNX with higher opset version
torch.onnx.export(
vision_wrapper,
dummy_input,
save_path,
export_params=True,
opset_version=16, # 使用高版本 opset 以支持 scaled_dot_product_attention
do_constant_folding=True,
input_names=['pixel_values'],
output_names=['projected_features'],
dynamic_axes={
'pixel_values': {0: 'batch_size'},
'projected_features': {0: 'batch_size'}
},
# 添加额外的配置
operator_export_type=torch.onnx.OperatorExportTypes.ONNX,
training=torch.onnx.TrainingMode.EVAL,
verbose=False
)
print(f"Successfully exported vision components to {save_path}")
# Verify the exported model
import onnxruntime
# Create inference session
ort_session = onnxruntime.InferenceSession(save_path)
# Run inference with dummy input
ort_inputs = {
'pixel_values': dummy_input.numpy()
}
ort_outputs = ort_session.run(None, ort_inputs)
# Compare with PyTorch output
torch_output = vision_wrapper(dummy_input)
# Check numerical accuracy with更宽松的容忍度
import numpy as np
np.testing.assert_allclose(
torch_output.detach().numpy(),
ort_outputs[0],
rtol=1e-1, # 放宽相对误差容忍度
atol=1e-2 # 放宽绝对误差容忍度
)
print("ONNX model verification successful!")
# 打印一些统计信息
torch_output_np = torch_output.detach().numpy()
onnx_output_np = ort_outputs[0]
abs_diff = np.abs(torch_output_np - onnx_output_np)
rel_diff = np.abs((torch_output_np - onnx_output_np) / (torch_output_np + 1e-7))
print(f"\nValidation Statistics:")
print(f"Max absolute difference: {np.max(abs_diff):.6f}")
print(f"Mean absolute difference: {np.mean(abs_diff):.6f}")
print(f"Max relative difference: {np.max(rel_diff):.6f}")
print(f"Mean relative difference: {np.mean(rel_diff):.6f}")
if __name__ == "__main__":
os.makedirs('onnx', exist_ok=True)
try:
import onnx
try:
onnx_version = onnx.__version__
except AttributeError:
try:
onnx_version = onnx.version.version
except AttributeError:
onnx_version = "Unknown"
print(f"ONNX version: {onnx_version}")
except ImportError:
print("ONNX not installed")
import onnxruntime
print(f"ONNX Runtime version: {onnxruntime.__version__}")
export_vision_InternVL(path, save_path)
将onnx转为rknn的代码如下:
from rknn.api import RKNN
import numpy as np
import os
model_path = "./onnx/InternVL2-1B_vision.onnx"
target_platform = "rk3588"
rknn = RKNN(verbose=False)
rknn.config(
target_platform=target_platform,
mean_values=[[0.5 * 255, 0.5 * 255, 0.5 * 255]],
std_values=[[0.5 * 255, 0.5 * 255, 0.5 * 255]],
)
rknn.load_onnx(model_path, inputs=['pixel_values'], input_size_list=[[1,3,448,448]])
rknn.build(do_quantization=False, dataset=None)
os.makedirs("rknn", exist_ok=True)
rknn.export_rknn("./rknn/" + model_path.split("/")[-1].split(".")[0] + "_{}.rknn".format(target_platform))
语言模型参考rkllm的Qwen模型转换
如有疑问或需求,请联系QQ:1198807618,欢迎各位批评指正
在rk3588上部署InternVL系列的更多相关文章
- 总想自己动动手系列·2·本地和外网(Liunx服务器上部署的web项目)按照自定义的报文格式进行交互(完结篇)
一.准备工作 (1)创建一个web-project工程,部署本地可正常访问,部署在云服务上可访问. (2)理解如何在web.xml文件中配置过滤器,和创建一个自定义的过滤器. (3)懂得如何打war包 ...
- 总想自己动动手系列·1·本地和外网(Liunx服务器上部署的web项目)按照自定义的报文格式进行交互(准备篇)
一.准备工作 (1)有一台属于自己的云服务器,并成功部署和发布一个web项目(当然,本质上来说Java-Project也没问题),通过外网IP可以正常访问该web项目. 需要说明的是:任何web项目, ...
- 在腾讯云上部署Hexo博客
推荐理由 ----搭建个人的空间博客目前深受个人开发者的追捧,然而博客的种类和平台有很多,Hexo是一个开源的静态博客生成器.相比于其他博客而言它只要是web容器就能用.除了闷头专研技术之外,程序员还 ...
- 在 Ubuntu 14.04 服务器上部署 Hexo 博客
版权声明:本文由宋秉金 原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/241080001487926962 来源:腾云阁 ...
- 在Nginx上部署ThinkPHP,解决Pathinfo问题
在Nginx上部署ThinkPHP,解决Pathinfo问题 事实上.要解决nginx不支持pathinfo的问题.有两个解决思路,一是不使用pathinfo模式,二是改动nginx的配置文件,使它支 ...
- .NET开发框架(五)-IIS上部署ASP.NET Core项目教程
系列教程:从初学者到架构师的一步步蜕变 本篇经验将和大家介绍如何在IIS上部署ASP.NET Core项目,希望对初学.NET CORE的童靴入门有所帮助! 1.打开VS,创建项目,选择ASP.NET ...
- 在CentOS上部署kubernetes1.9.0集群
原文链接: https://jimmysong.io/kubernetes-handbook/cloud-native/play-with-kubernetes.html (在CentOS上部署kub ...
- Tensorflow 模型线上部署
获取源码,请移步笔者的github: tensorflow-serving-tutorial 由于python的灵活性和完备的生态库,使得其成为实现.验证ML算法的不二之选.但是工业界要将模型部署到生 ...
- fedora上部署ASP.NET——(卡带式电脑跑.NET WEB服务器)
andrew,20130601,guilin 本文记录在树莓派(fedora)上部署ASP.NET MVC2 的过程. 本文共分为六部分,分别是前置条件,Apache的安装,Mysql的安装,安装mo ...
- CentOS 7 上部署Mono 4 和Jexus 5.6
概述 在这篇文章中我们将讨论如何在CentOS 7操作系统,安装 jexus. mono 和 配置 jexus,因此它将能够在这种环境中运行一个asp.net mvc 4 应用.这篇文章是描述如何在 ...
随机推荐
- 发那科机器人R2000iC齿轮箱维修方法步骤归纳
一.发那科机器人R2000iC齿轮箱常见故障类型及原因 齿轮磨损:长时间的重载工作或润滑不良可能导致齿轮磨损,表现为噪音增大.振动加剧等. 轴承故障:轴承承受了齿轮箱的径向和轴向载荷,其故障可能导致齿 ...
- N-gram基本原理
N-gram模型是一种语言模型(Language Model,LM),语言模型是一个基于概率的判别模型,它的输入是一句话(单词的顺序序列),输出是这句话的概率,即这些单词的联合概率(joint pro ...
- 软件工程: SDLC V模型
V型 V-model 代表一个开发过程,可以被认为是瀑布模型的扩展,是更通用的 V-model 的一个例子.不是以线性方式向下移动,而是在编码阶段之后向上弯曲工艺步骤,以形成典型的 V 形.V 模型展 ...
- Kubernetes - [04] 常用命令
kubectl 语法 kubectl [command] [TYPE] [NAME] [flags] command:指定在一个或多个资源商要执行的操作.例如:create.get.describe. ...
- LCP 11. 期望个数统计
地址:https://leetcode-cn.com/problems/qi-wang-ge-shu-tong-ji/ <?php /** 某互联网公司一年一度的春招开始了,一共有 n 名面试者 ...
- 使用电阻网络实现的vga驱动电路,fpga驱动vga显示器验证,代替gm7123芯片
之前驱动vga,要么是直接使用fpga管脚直接驱动,颜色为8原色 使用线缆 vs,hs,r,g,b一共五根线,三原色要么是0要么是1,所以色彩最多8种,rgb组合 若要实现真彩色驱动,如rgb888, ...
- 线上测试木舟物联网平台之如何通过HTTP网络组件接入设备
一.概述 木舟 (Kayak) 是什么? 木舟(Kayak)是基于.NET6.0软件环境下的surging微服务引擎进行开发的, 平台包含了微服务和物联网平台.支持异步和响应式编程开发,功能包含了物模 ...
- 后台返回文件URL,前端下载文件,即使设置文件名,下载的文件名称并不是自己所设置的问题
1.背景 项目中遇到这么一个问题,上传文件后,后台返回的是一个URL,前端需要通过点击下载这个文件 2.首次处理 当时一看是下载文件,觉得很简单,无非是通过创建a标签来实现,以下是我当时的代码,用的是 ...
- 这几天用ng5做了一个俄罗斯方块
为什么要做这个东西呢? 嗯 为了证明自己会ng吧,最主要的是这几天的工作全是静态页,实在无聊枯燥的很.当然了,肯定还有其他妙不可言的原因,这里不想说出来. 我也忘记我是什么时候有想到用ng做俄罗斯方块 ...
- 【Ubuntu】安装Eclipse
[Ubuntu]安装Eclipse 零.前言 Eclipse是一个使用很广泛的代码编辑软件,最近换了Ubuntu系统,需要安装一下,故记录. 壹.下载 Eclipse到官网下载,或者到镜像源下载,官网 ...