阿里千问大模型(Qwen2.5-VL-7B-Instruct)部署

参考链接

知乎帖子
B站视频
huggingface 镜像网站(不太全,比如 Qwen/Qwen2.5-VL-7B-Instruct就没有)
huggingface 5种下载方式汇总
通过huggingface-cli下载模型

在这里插入图片描述

不一样的部分是预训练权重的下载和demo

首先安装huggingface_hub

pip install -U huggingface_hub

设置镜像

export HF_ENDPOINT=https://hf-mirror.com

windows端需要添加系统变量。

名称:HF_ENDPOINT,值: "https://hf-mirror.com"

然后通过huggingface-cli下载模型,

huggingface-cli download --resume-download  Qwen/Qwen2.5-VL-7B-Instruct --local-dir ./ --local-dir-use-symlinks False --resume-download

参考:通过huggingface-cli下载模型

运行DEMO

加载模型方式

如果希望下载到指定的目录,可以往from_pretrained方法传入cache_dir 参数,如下所示:

import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained("internlm/internlm2-chat-7b", torch_dtype=torch.float16, trust_remote_code=True, cache_dir='/home/{username}/huggingface').cuda()

运行以下代码

import gradio as gr
from transformers import Qwen2_5_VLForConditionalGeneration, AutoProcessor
from qwen_vl_utils import process_vision_info
import torch

# 加载模型和处理器
model = Qwen2_5_VLForConditionalGeneration.from_pretrained(
    "Qwen/Qwen2.5-VL-7B-Instruct", 
    torch_dtype="auto", 
    device_map="auto"
)
processor = AutoProcessor.from_pretrained("Qwen/Qwen2.5-VL-7B-Instruct")

def process_image_and_text(image, text_prompt):
    if image is None:
        return "请上传一张图片。"
    
    # 构建消息格式
    messages = [
        {
            "role": "user",
            "content": [
                {
                    "type": "image",
                    "image": image,  # Gradio将自动处理图片路径
                },
                {"type": "text", "text": text_prompt if text_prompt else "Describe this image."},
            ],
        }
    ]
    
    try:
        # 准备推理输入
        text = 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(model.device)

        # 生成输出
        with torch.no_grad():
            generated_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
            )
        
        return output_text[0]
    
    except Exception as e:
        return f"处理过程中出现错误: {str(e)}"

# 创建Gradio界面
with gr.Blocks() as demo:
    gr.Markdown("# Qwen2.5-VL 图像理解演示")
    
    with gr.Row():
        with gr.Column():
            image_input = gr.Image(type="filepath", label="上传图片")
            text_input = gr.Textbox(
                placeholder="请输入提示语(如不输入,默认描述图片)", 
                label="提示语"
            )
            submit_btn = gr.Button("提交")
        
        with gr.Column():
            output = gr.Textbox(label="输出结果")
    
    submit_btn.click(
        fn=process_image_and_text,
        inputs=[image_input, text_input],
        outputs=output
    )

    gr.Examples(
        examples=[
            ["path/to/example1.jpg", "这张图片里有什么?"],
            ["path/to/example2.jpg", "描述图中的场景"],
        ],
        inputs=[image_input, text_input],
    )

# 启动应用
if __name__ == "__main__":
    demo.launch(share=True)

<think>好的,我现在需要帮助用户将Qwen2.5-VL模型转换为ONNX格式。首先,我得回忆一下用户提供的引用内容,看看有没有相关的导出步骤或注意事项。 根据引用[2],用户提到导出QwenVL模型比较复杂,需要修改transformers库中的modeling_qwen2_vl.py文件,将模型拆分成多个部分。特别是A模型是VIT部分,E模型是LLM,而BCD是一些切片操作。这可能意味着Qwen2.5-VL的结构比较复杂,不能直接整体导出为ONNX,需要分模块处理。另外,引用[2]还提到了一个GitHub issue链接,可能在导出E模型时会遇到题,需要参考该链接解决。 接下来,用户可能已经尝试过直接导出,但遇到了题。我需要考虑如何分步骤导出各个子模型。首先,拆分模型结构,可能需要像引用[2]中提到的将模型分为VIT、LLM和其他中间部分。然后,对每个部分单独进行ONNX导出。 对于PyTorch模型转ONNX,通常使用torch.onnx.export函数。但需要确保每个子模块能够独立运行,并且输入输出的形状正确。例如,VIT部分处理图像输入,生成视觉特征;LLM部分处理文本和视觉特征的融合,生成输出。中间的操作可能需要单独导出为ONNX模型,比如切片或拼接操作。 此外,引用[3]提到了修改模型加载的代码,比如指定device_map和torch_dtype。在导出ONNX时,可能需要将模型设置为评估模式,并且确保使用正确的数据类型(如FP16),同时处理可能的设备题(如CPU或CUDA)。 用户可能还需要注意动态输入尺寸的题,尤其是图像处理部分。Qwen2.5-VL支持动态调整图像尺寸,转换为token长度,这在导出ONNX时需要处理动态轴。例如,在torch.onnx.export中指定dynamic_axes参数,允许输入尺寸的变化。 另外,引用[2]提到导出E模型时的报错题,可能需要查看提供的GitHub链接中的解决方案。可能涉及到修改模型代码,避免某些不支持的操作,或者调整导出参数。 总结步骤可能是:1)拆分模型结构,处理各个子模块;2)修改模型代码以适应导出;3)逐个导出子模块为ONNX;4)验证导出的ONNX模型是否正确;5)处理动态输入和可能的错误。 还需要注意,转换过程中可能遇到的操作符不支持题,需要替换或自定义实现。比如,某些自定义的PyTorch操作可能在ONNX中没有对应实现,这时候需要重写或用现有操作组合替代。 最后,建议用户参考官方文档或社区资源,特别是提到的GitHub issue,可能已经有其他开发者遇到过类似题并提供了解决方案。此外,使用OpenVINO进行后续优化也是一个方向,如引用[1]中提到的,但当前题主要是转换到ONNX,可能需要先完成这一步再考虑优化。</think>根据Qwen2.5-VL模型结构和引用资料,导出ONNX格式需要分步骤处理: ### 一、模型拆分准备(关键步骤) 1. **结构拆解**:按照引用[2]说明,将原模型拆分为: - **A模型**:视觉主干网络VIT部分 - **B/C/D模型**:特征索引/切片操作模块 - **E模型**:语言大模型LLM部分 2. **代码修改**: ```python # 修改transformers库中modeling_qwen2_vl.py class SplitVIT(nn.Module): def forward(self, images): return self.vision_model(images) # 视觉特征提取 class SplitLLM(nn.Module): def forward(self, inputs_embeds, attention_mask): return self.llm(inputs_embeds, attention_mask) # 文本生成 ``` ### 二、分模块导出ONNX #### 1. 导出视觉模块(A模型) ```python vit_model = SplitVIT().eval() dummy_image = torch.randn(1, 3, 448, 448) # 动态尺寸需设置dynamic_axes torch.onnx.export( vit_model, dummy_image, "qwen_vit.onnx", input_names=["images"], output_names=["visual_features"], dynamic_axes={"images": {2: "height", 3: "width"}} ) ``` #### 2. 导出LLM模块(E模型) ```python llm_model = SplitLLM().eval() dummy_embeds = torch.randn(1, 256, 4096) # 输入维度需对齐实际配置 torch.onnx.export( llm_model, (dummy_embeds, torch.ones(1,256)), "qwen_llm.onnx", input_names=["inputs_embeds", "attention_mask"], output_names=["logits"], opset_version=15 # 需高于12 ) ``` ### 三、特殊处理(引用[2]注意事项) 1. **中间操作模块**: - 将B/C/D切片操作转换为ONNX需使用`torch.where`等可导出操作 - 示例坐标转换操作: ```python # 原代码中的坐标计算需改写为: def normalize_coord(coord, img_size): return coord / img_size * 2 - 1 # 显式数学运算 ``` 2. **报错处理**: - 如遇`RuntimeError: Exporting the operator ... is not supported`,参考[引用[2]的GitHub issue](https://github.com/DakeQQ/Native-LLM-for-Android/issues/10) - 常见解决方案:用`torch.clamp`替代`torch.clip`等操作符 ### 四、验证流程 ```python import onnxruntime as ort # 视觉特征提取验证 ort_session = ort.InferenceSession("qwen_vit.onnx") visual_feat = ort_session.run(None, {"images": np.random.rand(1,3,448,448).astype(np.float32)}) # LLM推理验证 ort_session_llm = ort.InferenceSession("qwen_llm.onnx") outputs = ort_session_llm.run(None, { "inputs_embeds": np.random.rand(1,256,4096), "attention_mask": np.ones((1,256)) }) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值