news 2026/9/8 23:05:16

Qwen2-VL 多模态模型实战指南:在 Transformers 中用 PyTorch 完成图像与视频理解推理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Qwen2-VL 多模态模型实战指南:在 Transformers 中用 PyTorch 完成图像与视频理解推理

Qwen2-VL 多模态模型实战指南:在 Transformers 中用 PyTorch 完成图像与视频理解推理

【免费下载链接】transformers🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers

Qwen2-VL 是阿里巴巴 Qwen 团队在 Qwen-VL 基础上的大版本升级,本文以 qwen2_vl.md 文档为主体,结合仓库中该模型的配置、处理器与建模源码,系统讲解如何在 Transformers 中加载 Qwen2-VL 完成单图、单视频以及批量混合媒体推理,并深入解释 Naive Dynamic Resolution(动态分辨率)、M-RoPE(多模态旋转位置编码)、min_pixels/max_pixels 调参与 FlashAttention-2 加速背后的源码级原理。读完本文,你将掌握一套可直接运行、可精确控制显存与精度的 Qwen2-VL 图像/视频推理方案。

一、模型概览:Qwen2-VL 相比 Qwen-VL 带来了什么

Qwen2-VL 由阿里 Qwen 团队提出,是对 Qwen-VL 的一次重大架构升级。根据该模型官方博客摘要的说明,其核心改进可以概括为四个方面:更强的图像理解能力、进阶的视频理解能力、集成视觉智能体(visual agent)功能,以及更完善的多语言支持。在架构上,Qwen2-VL 通过Naive Dynamic Resolution Support(朴素动态分辨率支持)实现了对任意分辨率图像的处理,并引入M-RoPE(Multimodal Rotary Position Embedding,多模态旋转位置编码)来同时处理一维文本数据与多维视觉数据。

在仓库中,Qwen2-VL 的完整实现分布在src/transformers/models/qwen2_vl/目录下,包含 7 个 Python 文件,各自职责明确:

文件职责
configuration_qwen2_vl.py定义Qwen2VLConfigQwen2VLTextConfig(文本 LLM 部分)与Qwen2VLVisionConfig(视觉编码器部分)
image_processing_qwen2_vl.py动态缩放、patchify 等图像预处理
image_processing_pil_qwen2_vl.py基于 PIL 后端的图像处理变体
video_processing_qwen2_vl.py视频抽帧与预处理
processing_qwen2_vl.py串联图像/视频处理器与 tokenizer 的总处理器
modeling_qwen2_vl.pyPyTorch 模型实现(视觉塔 + 文本解码器 + 融合模型)
__init__.py模块导出

该模型于 2024-08-26 合入 Transformers,相关论文于 2024-09-18 在 HF Papers 发布;文档页面标注其支持 FlashAttention 与 Tensor parallelism,并注明了贡献者 simonJJJ。从源码结构看,Qwen2-VL 沿用了"视觉编码器 + PatchMerger 投影 + 类 Qwen2 文本解码器"的标准多模态大模型(VLM)形态,其文本解码器在 configuration_qwen2_vl.py 中通过Qwen2VLTextConfig独立配置,并且预设了完整的张量并行(colwise/rowwise)与流水线并行切分计划,这也是它能支持大规模并行推理的架构基础。

二、环境与模型加载约定

运行本示例需要:

  • 安装了torchtransformers(使用当前仓库源码),如需加载官方 checkpoint 还需要联网访问 Hugging Face Hub;
  • 支持半精度推理的 GPU(示例中使用device_map="auto"自动分配设备);
  • 模型建议以torch.bfloat16/torch.float16加载(官方发布权重即为 bf16)。

Qwen2-VL 的官方指令模型 checkpoint 形如Qwen/Qwen2-VL-7B-Instruct。加载时同时实例化两个对象:

from transformers import AutoProcessor, Qwen2VLForConditionalGeneration model = Qwen2VLForConditionalGeneration.from_pretrained("Qwen/Qwen2-VL-7B-Instruct", device_map="auto") processor = AutoProcessor.from_pretrained("Qwen/Qwen2-VL-7B-Instruct")

需要特别说明的是:Qwen2-VL 的对话输入必须经过 chat template 处理,即把对话组织为{"role": ..., "content": [...]}的消息列表后调用processor.apply_chat_template(..., tokenize=True, return_tensors="pt")。此时处理器会自动完成三件事:

  1. 把对话中的图片/视频经视觉处理器编码成pixel_values(视频为pixel_values与对应帧结构);
  2. 用占位符<|image_pad|>/<|video_pad|>把多模态内容插入文本序列;
  3. 同时输出文本所需的input_ids与描述视觉 token 空间网格的image_grid_thw/video_grid_thw张量。

这正是 processing_qwen2_vl.py 中Qwen2VLProcessor的关键逻辑:它会解析出 tokenizer 中的图像/视频占位 token,再在replace_image_tokenreplace_video_token方法中按网格信息计算出实际需要的占位符数量。

三、单媒体推理:让模型"看图说话"与"看懂视频"

3.1 图像输入推理

以下代码是图像理解最基础的用法:传入一张图片并让模型描述内容。

from transformers import AutoProcessor, Qwen2VLForConditionalGeneration # Load the model in half-precision on the available device(s) model = Qwen2VLForConditionalGeneration.from_pretrained("Qwen/Qwen2-VL-7B-Instruct", device_map="auto") processor = AutoProcessor.from_pretrained("Qwen/Qwen2-VL-7B-Instruct") conversation = [ { "role":"user", "content":[ { "type":"image", "url": "https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-VL/assets/demo.jpeg" }, { "type":"text", "text":"Describe this image." } ] } ] inputs = processor.apply_chat_template( conversation, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt" ).to(model.device) # Inference: Generation of the output output_ids = model.generate(**inputs, max_new_tokens=128) generated_ids = [output_ids[len(input_ids):] for input_ids, output_ids in zip(inputs.input_ids, output_ids)] output_text = processor.batch_decode(generated_ids, skip_special_tokens=True, clean_up_tokenization_spaces=True) print(output_text)

图片内容块中的"url"表示从远程地址加载图片;若使用本地文件,则改为"type": "image", "path": "/path/to/image.jpg"即可。解码环节用processor.batch_decode而非裸 tokenizer 解码,这样能确保skip_special_tokens与空格清理行为与模板一致。

3.2 视频输入推理

视频输入与图像输入结构几乎完全相同,只是在 content 中加入{"type": "video", "path": ...},并在apply_chat_template中增加fps参数控制抽帧密度:

# Video conversation = [ { "role": "user", "content": [ {"type": "video", "path": "/path/to/video.mp4"}, {"type": "text", "text": "What happened in the video?"}, ], } ] inputs = processor.apply_chat_template( conversation, fps=1, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt" ).to(model.device) # Inference: Generation of the output output_ids = model.generate(**inputs, max_new_tokens=128) generated_ids = [output_ids[len(input_ids):] for input_ids, output_ids in zip(inputs.input_ids, output_ids)] output_text = processor.batch_decode(generated_ids, skip_special_tokens=True, clean_up_tokenization_spaces=True) print(output_text)

这里的fps=1意味着每秒均匀采样一帧作为输入。在 video_processing_qwen2_vl.py 的源码中,fpsnum_frames互斥参数——当二者同时传入时会直接抛出ValueError("num_framesandfpsare mutually exclusive arguments, please use only one!")。若使用fps,处理器会结合视频元数据(总帧数、原生 fps)推算出应采样的帧数;若使用num_frames,则固定从视频中均匀采样指定数量的帧。两种方式最终都会把采样帧数对齐到temporal_patch_size(默认 2)的整数倍,保证后续时序维度可以整块切分。

四、批量混合媒体推理:一张 batch 里既有图又有视频还有纯文本

真实业务场景中,一个 batch 内往往混有不同类型与数量的媒体。Qwen2-VL 的处理器支持把图像、视频、纯文本对话任意混排后一次性前向推理。下面构造 4 个对话:单图对话、双图对话、纯文本对话、图+视频混合对话。

# Conversation for the first image conversation1 = [ { "role": "user", "content": [ {"type": "image", "path": "/path/to/image1.jpg"}, {"type": "text", "text": "Describe this image."} ] } ] # Conversation with two images conversation2 = [ { "role": "user", "content": [ {"type": "image", "path": "/path/to/image2.jpg"}, {"type": "image", "path": "/path/to/image3.jpg"}, {"type": "text", "text": "What is written in the pictures?"} ] } ] # Conversation with pure text conversation3 = [ { "role": "user", "content": "who are you?" } ] # Conversation with mixed media conversation4 = [ { "role": "user", "content": [ {"type": "image", "path": "/path/to/image3.jpg"}, {"type": "image", "path": "/path/to/image4.jpg"}, {"type": "video", "path": "/path/to/video.jpg"}, {"type": "text", "text": "What are the common elements in these media?"}, ], } ] conversations = [conversation1, conversation2, conversation3, conversation4] # Preparation for batch inference inputs = processor.apply_chat_template( conversations, fps=1, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt" ).to(model.device) # Batch Inference output_ids = model.generate(**inputs, max_new_tokens=128) generated_ids = [output_ids[len(input_ids):] for input_ids, output_ids in zip(inputs.input_ids, output_ids)] output_text = processor.batch_decode(generated_ids, skip_special_tokens=True, clean_up_tokenization_spaces=True) print(output_text)

可以看到,与单样本推理相比只改动了一处:把多个对话组装成conversations列表传给apply_chat_template,其余调用链完全一致。这得益于处理器会为 batch 内每一段对话独立统计媒体数量与网格信息,并最终 padding 到统一长度;纯文本对话(conversation3)的 content 可以直接写成字符串,处理器同样按模板处理。批量推理的输出与输入是一一对应的列表,output_text中第 i 个元素即第 i 段对话的生成结果。

五、实用技巧一:分辨率取舍与 min_pixels / max_pixels

Qwen2-VL 的核心卖点之一是Naive Dynamic Resolution:模型不做任何"等比缩到固定尺寸"的预处理,而是保留原始宽高比,把高分辨率图片切成若干 14×14 的 patch 再送入视觉编码器。因此,输入分辨率越高,视觉 patch 越多,理解细节越好,但计算量与 KV 显存也同步上升。

5.1 默认行为与像素上下限

默认情况下处理器使用图像原生分辨率(即不强制缩放到正方形)。用户可以通过min_pixelsmax_pixels控制单张图片参与编码的像素范围:

min_pixels = 224*224 max_pixels = 2048*2048 processor = AutoProcessor.from_pretrained("Qwen/Qwen2-VL-7B-Instruct", min_pixels=min_pixels, max_pixels=max_pixels)

该参数会持久化为该 processor 实例的缩放策略:低于min_pixels的图会被放大,高于max_pixels的图会被等比缩小。处理器类级别的默认值为shortest_edge = 56*56longest_edge = 28*28*1280(见 image_processing_qwen2_vl.py),对应 Qwen2-VL 训练时采用的默认像素区间。

5.2 显存受限时的降分辨率方案

在 GPU 显存有限的场景下,官方推荐把每张图的 token 开销压缩到 256~1024 之间:

min_pixels = 256*28*28 max_pixels = 1024*28*28 processor = AutoProcessor.from_pretrained("Qwen/Qwen2-VL-7B-Instruct", min_pixels=min_pixels, max_pixels=max_pixels)

这样每张图像最终约用 256~1024 个 token 编码。这里的数字28的来历是:模型视觉编码器的空间 patch size 为 14,而时间维度 patch(temporal patch)与空间 merge size 均为 2,14 × 2 = 28,因此像素维度总是按 28 的倍数对齐——例如256*28*28恰好对应 256 个 28×28 单元的像素量。

5.3 源码印证:smart_resize 的三条铁律

上述行为在源码中由smart_resize实现(image_processing_qwen2_vl.py),它严格保证三条约束:

  1. 宽高都能被 factor(=28)整除:先round(height / factor) * factor对齐;
  2. 总像素落在 [min_pixels, max_pixels] 内:超出上限则按比例缩小(math.floor),不足下限则放大(math.ceil);
  3. 尽量维持原始宽高比:通过缩放因子beta同时调整宽高。

另外,当图像的绝对宽高比大于 200(如超长条形图)时会抛出异常,提示"absolute aspect ratio must be smaller than 200"。resize阶段传入的factor=patch_size * merge_size,而patchify阶段则把图像按(grid_h, grid_w)切成grid_h × grid_w个 patch(image_processing_qwen2_vl.py),并输出image_grid_thw网格描述,模型端据此还原空间结构。

5.4 视觉 token 是如何计数的

图像经过视觉塔后,还要经过PatchMerger(源码见 modeling_qwen2_vl.py)把相邻的spatial_merge_size × spatial_merge_size(默认 2×2)个 patch 合并为 1 个 token 送入 LLM。因此单张图片最终占用的 LLM 侧 token 数等于image_grid_thw三个维度之积除以merge_size²。这个换算关系在 processing_qwen2_vl.py 的replace_image_token/replace_video_token中被用来决定文本序列中<|image_pad|>/<|video_pad|>的重复次数,也是5.2节"256~1024 tokens"估算的由来。

六、实用技巧二:多图/多视频输入与 add_vision_id 标注

当一次对话中出现多张图片或多个视频时,模型容易混淆"这段话到底在指哪张图"。为此,处理器支持在视觉内容前自动插入形如Picture 1:Video 1:的编号前缀,通过add_vision_id=True开启。下面是一段包含多轮对话、多图一视频的完整示例:

conversation = [ { "role": "user", "content": [ {"type": "image"}, {"type": "text", "text": "Hello, how are you?"} ] }, { "role": "assistant", "content": "I'm doing well, thank you for asking. How can I assist you today?" }, { "role": "user", "content": [ {"type": "text", "text": "Can you describe these images and video?"}, {"type": "image"}, {"type": "image"}, {"type": "video"}, {"type": "text", "text": "These are from my vacation."} ] }, { "role": "assistant", "content": "I'd be happy to describe the images and video for you. Could you please provide more context about your vacation?" }, { "role": "user", "content": "It was a trip to the mountains. Can you see the details in the images and video?" } ] # default: prompt_without_id = processor.apply_chat_template(conversation, add_generation_prompt=True) # Excepted output: '<|im_start|>system\nYou are a helpful assistant.<|im_end|>\n<|im_start|>user\n<|vision_start|><|image_pad|><|vision_end|>Hello, how are you?<|im_end|>\n<|im_start|>assistant\nI'm doing well, thank you for asking. How can I assist you today?<|im_end|>\n<|im_start|>user\nCan you describe these images and video?<|vision_start|><|image_pad|><|vision_end|><|vision_start|><|image_pad|><|vision_end|><|vision_start|><|video_pad|><|vision_end|>These are from my vacation.<|im_end|>\n<|im_start|>assistant\nI'd be happy to describe the images and video for you. Could you please provide more context about your vacation?<|im_end|>\n<|im_start|>user\nIt was a trip to the mountains. Can you see the details in the images and video?<|im_end|>\n<|im_start|>assistant\n' # add ids prompt_with_id = processor.apply_chat_template(conversation, add_generation_prompt=True, add_vision_id=True) # Excepted output: '<|im_start|>system\nYou are a helpful assistant.<|im_end|>\n<|im_start|>user\nPicture 1: <|vision_start|><|image_pad|><|vision_end|>Hello, how are you?<|im_end|>\n<|im_start|>assistant\nI'm doing well, thank you for asking. How can I assist you today?<|im_end|>\n<|im_start|>user\nCan you describe these images and video?Picture 2: <|vision_start|><|image_pad|><|vision_end|>Picture 3: <|vision_start|><|image_pad|><|vision_end|>Video 1: <|vision_start|><|video_pad|><|vision_end|>These are from my vacation.<|im_end|>\n<|im_start|>assistant\nI'd be happy to describe the images and video for you. Could you please provide more context about your vacation?<|im_end|>\n<|im_start|>user\nIt was a trip to the mountains. Can you see the details in the images and video?<|im_end|>\n<|im_start|>assistant\n'

对比两种输出可以清晰看到模板的编号规则:

  • 关闭add_vision_id时,每个视觉内容以<|vision_start|>开始、<|vision_end|>结束,中间是对应数量的<|image_pad|><|video_pad|>占位符;
  • 开启后,处理器按出现顺序对图片依次编号为Picture 1:Picture 2:Picture 3:(全部图片统一编号),对视频独立编号为Video 1:,前缀紧贴在<|vision_start|>之前。

注意示例的 content 里只写了{"type": "image"}而没有提供path/url——这是合法的"占位"写法,适用于先拿到媒体内容、后在apply_chat_template时通过额外参数传入实际像素的场景;若推理链路里没有真实像素注入,则必须保证媒体 token 数量与后面传入的视觉特征严格一致,否则会引发形状不匹配错误。

七、实用技巧三:用 FlashAttention-2 加速生成

长上下文 + 多图多视频会带来大量注意力计算,FlashAttention-2 可以从内核层面显著提速并降低显存。使用前需保证两点:

  1. 安装了与当前 CUDA/PyTorch 匹配的最新版 FlashAttention-2:
pip install -U flash-attn --no-build-isolation
  1. 硬件支持 FlashAttention-2(详见其官方仓库说明),并且模型以torch.float16torch.bfloat16精度加载——FlashAttention-2 只支持这两种半精度格式。

满足条件后,只需在加载模型时显式传入attn_implementation="flash_attention_2"

from transformers import Qwen2VLForConditionalGeneration model = Qwen2VLForConditionalGeneration.from_pretrained( "Qwen/Qwen2-VL-7B-Instruct", attn_implementation="flash_attention_2", device_map="auto")

从 modeling_qwen2_vl.py 的导入(ALL_ATTENTION_FUNCTIONSis_flash_attention_requestedmaybe_autocast等工具)可以看出,Qwen2-VL 的注意力已接入 Transformers 统一的可插拔注意力分发框架,除 flash_attention_2 外还支持 sdpa 等实现;若忘记半精度加载,框架会给出精度相关的警告或错误提示。作为对照,想要复现文档宣称的显存/速度收益,建议在相同输入下分别以 sdpa 与 flash_attention_2 各跑一次generate再做取舍。

八、配置体系与参数解读:三类 Config 怎么用

Qwen2-VL 是"双引擎"架构,因此配置被拆成视觉与文本两份独立 Config,再组装进顶层Qwen2VLConfig。三个配置类定义于 configuration_qwen2_vl.py。

8.1 Qwen2VLVisionConfig:视觉编码器

对应 7B-Instruct 模型,视觉塔是一个深度 32 层的类 ViT 网络。类中字段的默认值即官方 7B 权重所采用的配置:

字段默认值含义
depth32视觉 transformer 层数
embed_dim1280patch 嵌入维度
hidden_size3584隐藏层维度
hidden_act"quick_gelu"激活函数
mlp_ratio4MLP 隐藏层相对倍率
num_heads16注意力头数
in_channels3输入通道(RGB)
patch_size14空间 patch 尺寸
spatial_merge_size2空间方向 patch 合并粒度
temporal_patch_size2时间方向 patch 尺寸
initializer_range0.02参数初始化范围

(配置代码见 configuration_qwen2_vl.py。)

8.2 Qwen2VLTextConfig:文本解码器

文本侧与 Qwen2 系列解码器一脉相承(RMSNorm、SwiGLU MLP、GQA 注意力),默认vocab_size=152064、80 层、64 个 Q 头与 8 个 KV 头。值得关注的是,该 Config 声明了default_theta = 1000000.0(RoPE 基础频率),并设置了ignore_keys_at_rope_validation = {"mrope_section"}——这是因为文本词元的 RoPE 位置编码需要与视觉部分协同工作,验证时需要豁免 mrope 专用键(详见 configuration_qwen2_vl.py)。

此外该 Config 内置了完整的基础模型张量并行方案base_model_tp_planq_proj/k_proj/v_proj按 colwise、o_proj/down_proj按 rowwise 切分)与流水线并行方案base_model_pp_plan,说明模型从设计之初即为大规模并行部署预留了切分接口。

8.3 Qwen2VLConfig:顶层配置与特殊 token

顶层Qwen2VLConfig(configuration_qwen2_vl.py)把上述两份子配置通过text_config/vision_config字段组合起来,并维护一组关键 token id:

字段默认值含义
image_token_id151655<\|image_pad\|>占位符
video_token_id151656<\|video_pad\|>占位符
vision_start_token_id151652<\|vision_start\|>起始符
vision_end_token_id151653<\|vision_end\|>结束符
tie_word_embeddingsFalse是否绑定输入输出词嵌入

从代码细节看,Qwen2VLConfig.__post_init__会自动把 dict 形式的vision_config/text_config实例化为对应的子 Config 对象,并兼容从 Hub 加载的"扁平 dict 旧格式"(旧 checkpoint 把tie_word_embeddings存在 text_config 内,v5 前向兼容逻辑会将其提升到顶层),因此直接Qwen2VLConfig.from_pretrained("Qwen/Qwen2-VL-7B-Instruct")即可得到完整配置树。

九、深入源码:动态分辨率与 M-RoPE 的配合机制

理解 Qwen2-VL 的推理行为,关键在于理解它的两条设计主线:非均匀视觉 token 序列三维位置编码

第一步:视觉 token 不再等长。由于 Naive Dynamic Resolution,不同图片切出的 patch 数不同,进入 LLM 的视觉 token 数也不同。为此处理器产出了描述网格的image_grid_thw/video_grid_thw(格式为[batch, T, H, W]结构的合并网格)。模型在 modeling_qwen2_vl.py 的视觉塔前向中,先用Qwen2VLRotaryEmbedding/VisionRotaryEmbedding按网格生成三维的旋转位置编码,再执行包含 3D 注意力的视觉 transformer;视觉塔输出的特征再经PatchMerger合并(把时间、空间相邻的 2×2×2 patch 合并),得到与占位符数量严格一致的视觉 token 序列。

第二步:文本与视觉共用一套"三维 + 一维"位置编码。文本 token 只有序列维,而视觉 token 有 T、H、W 三个维度的"坐标"。模型通过get_rope_indexcompute_3d_position_ids(见 modeling_qwen2_vl.py 与 modeling_qwen2_vl.py)为每一段输入构造混合位置 id,文本部分用连续的 1D 位置,视觉部分用展平后的 3D 位置。随后apply_multimodal_rotary_pos_emb(modeling_qwen2_vl.py)按mrope_section把旋转位置嵌入拆分到不同维度通道上——这就是M-RoPE:一部分通道承载时间信息,另一部分承载空间(高/宽)信息,让模型在解码时能同时区分"第几帧、第几行、第几列"。

第三步:可选滑动窗口注意力。文本 Config 中的use_sliding_windowsliding_window=4096max_window_layers=80字段与layer_types一起决定了解码器各层使用full_attention还是sliding_attention。默认use_sliding_window=False时所有层都走全量注意力;开启后,modeling_qwen2_vl.py 中的create_sliding_window_causal_mask会被用于构造局部窗口掩码,可显著压缩超长视觉序列的注意力开销。

需要留意的是,M-RoPE 的完整细节(如通道切分配置)随 checkpoint 的rope_scaling/rope_parameters一起保存,加载时由 Config 的convert_rope_params_to_dict统一标准化(configuration_qwen2_vl.py),普通用户不必手工干预。

十、API 全景:文档标注的类都在哪里

原文档末尾通过 autodoc 罗列了本模型的全部公开 API,本文整理其对应实现位置,便于按需查阅:

类名作用源码位置
Qwen2VLConfig顶层总配置configuration_qwen2_vl.py
Qwen2VLVisionConfig视觉编码器配置configuration_qwen2_vl.py
Qwen2VLTextConfig文本解码器配置configuration_qwen2_vl.py
Qwen2VLImageProcessor图像预处理(preprocess)image_processing_qwen2_vl.py
Qwen2VLVideoProcessor视频抽帧与预处理(preprocess)video_processing_qwen2_vl.py
Qwen2VLImageProcessorPilPIL 后端图像预处理image_processing_pil_qwen2_vl.py
Qwen2VLProcessor图像+视频+tokenizer 总处理器(__call__apply_chat_templatebatch_decodeprocessing_qwen2_vl.py
Qwen2VLTextModel纯文本解码器模型(forward)modeling_qwen2_vl.py
Qwen2VLModel视觉+文本主干模型(forward /get_video_features/get_image_featuresmodeling_qwen2_vl.py
Qwen2VLForConditionalGeneration条件生成模型,提供generate接口(forward / 两个特征提取方法)modeling_qwen2_vl.py

其中Qwen2VLModel.get_image_features/get_video_featuresQwen2VLForConditionalGeneration上的同名方法,支持不经过文本对话模板、直接提取纯视觉特征的用法,适合做图像/视频检索、embedding 等非生成式下游任务。

十一、进阶验证与阅读建议

  • 单元测试是最好的"运行手册":仓库在 tests/models/qwen2_vl/ 下为该模型配备了 4 个测试文件——test_modeling_qwen2_vl.py 覆盖前向与生成逻辑、test_image_processing_qwen2_vl.py 覆盖图像预处理、test_video_processing_qwen2_vl.py 覆盖视频抽帧、test_processing_qwen2_vl.py 覆盖图像/视频/文本混合处理链路。阅读这些测试可以直观理解 grid_thw 形状、占位符替换、padding 等边界行为。
  • 处理器一致性Qwen2VLProcessor__call__会把对话拆解为视觉输入与文本输入两部分;单独调用时它会自动把图片喂给 image processor、视频喂给 video processor,因此在多模态推理时统一使用 processor 即可,无需手动管理三种预处理器的调用顺序。
  • 精度与框架限制:本文所有示例均以device_map="auto"半精度推理为前提;FlashAttention-2 仅在float16/bfloat16下可用。在 CPU 或无 GPU 环境运行时,请去掉device_map并使用torch.float32,同时预期推理耗时显著上升。

通过本文的组合方案——apply_chat_template组织多模态对话 +min_pixels/max_pixels控制 token 预算 +add_vision_id区分多视觉对象 + FlashAttention-2 内核加速,你可以在可控显存预算内,把 Qwen2-VL 的图片理解、视频理解与混合批量推理稳定落地到自己的业务流水线中。

【免费下载链接】transformers🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 23:00:42

Spring Boot Banner定制实战:从release包下载到项目接入全指南

简介&#xff1a;面向 Android 开发者的 Banner 组件库发布包&#xff0c;版本 1.4.10&#xff0c;核心解决广告位、推荐位等内容的自动轮播与循环展示需求&#xff0c;适用于新闻客户端、电商首页、运营活动页等常见场景。库内已封装自动播放间隔配置、多页面切换动画、无限循…

作者头像 李华