Transformers Video Processor 完全指南:视频预处理、帧采样与 GPU 加速实战
【免费下载链接】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
Video Processor(视频处理器)是 Transformers 中负责将原始视频数据转换为视觉语言模型(VLM)可输入特征的组件,涵盖解码、缩放、归一化与帧采样等环节。本文围绕仓库中的 video_processors.md 官方文档展开,结合 video_processing_utils.py 与 video_utils.py 的源码实现,系统讲解AutoVideoProcessor的加载方式、fast processor 的 GPU 加速机制、帧采样策略及VideoMetadata的使用,帮助你为视频模型搭建一套完整、高效的预处理管线。
一、Video Processor 是什么
Video Processor 是一个负责"为视频模型准备输入特征、并处理后处理输出"的工具组件。它提供的变换包括缩放(resizing)、归一化(normalization)以及转换为 PyTorch 张量(conversion into PyTorch)。它扩展了图像处理器(image processor)的功能,让模型能够以一套区别于图片的参数来处理视频,充当原始视频数据与模型之间的桥梁,确保输入特征针对 VLM 完成优化。
从源码看,视频处理器以 BaseVideoProcessor 为基类,其顶层属性集中体现了预处理的全部可控环节(video_processing_utils.py):
| 类属性 | 默认值 | 含义 |
|---|---|---|
do_resize | None | 是否执行缩放 |
do_center_crop | None | 是否执行中心裁剪 |
do_rescale | None | 是否执行重缩放(像素值缩放) |
rescale_factor | 1 / 255 | 重缩放系数,将[0, 255]像素值映射到[0, 1] |
do_normalize | None | 是否执行归一化 |
do_convert_rgb | None | 是否转换为 RGB(含 RGBA 透明通道与白底融合) |
do_sample_frames | None | 是否进行帧采样 |
fps/num_frames | None | 帧采样参数(按帧率或固定帧数) |
return_metadata | False | 是否返回视频元数据 |
model_input_names | ["pixel_values_videos"] | 模型的输入键名 |
同时,VideosKwargs(定义于 processing_utils.py)以 TypedDict 的形式声明了所有可接受的预处理参数——do_convert_rgb、do_resize、size、resample、do_rescale、rescale_factor、do_normalize、image_mean、image_std、do_center_crop、do_pad、do_sample_frames、video_metadata、num_frames、fps、crop_size、data_format、input_data_format、device、return_metadata、return_tensors。调用处理器时传入的这些键会被validate_kwargs校验,并在preprocess中通过kwargs.setdefault自动补齐为实例默认值(video_processing_utils.py)。
与图像处理器的关系
Video Processor 与 Image Processor 共用同一套图像变换后端(TorchvisionBackend),其convert_to_rgb、resize、center_crop、rescale_and_normalize等核心操作建立在 torchvisiontransforms.v2之上(video_processing_utils.py)。关键差异在于:
- 多一维时间轴:视频是
(帧数, 通道, 高, 宽)的四维张量,而图片是三维; - 支持整段视频的批处理:
_preprocess中通过group_videos_by_shape将同尺寸视频分组后一次性执行批量变换,避免逐帧循环(video_processing_utils.py); - 额外提供解码与帧采样能力,这是图片处理器不具备的。
二、加载视频处理器:配置文件与优先级
配置文件命名
每个预训练模型的视频处理器配置应保存在video_preprocessor_config.json文件中,但较老的模型可能将配置保存在preprocessor_config.json中。后者优先级较低,且将在未来被移除。
从加载逻辑(get_video_processor_dict,video_processing_utils.py)可以还原出完整的解析优先级链:
- 首先尝试读取 v5 起标准化的
processor_config.json,若其中含有嵌套的"video_processor"键,则直接采用; - 否则依次尝试
video_preprocessor_config.json与preprocessor_config.json(即IMAGE_PROCESSOR_NAME),取先找到的文件; - 若本地传入的是配置文件路径本身(如
./my_model_directory/video_preprocessor_config.json),则直接加载该 JSON 文件。
常量定义见 utils/init.py,文件名同时被 video_processing_auto.py 复用。
使用 AutoVideoProcessor 加载
from transformers import AutoVideoProcessor processor = AutoVideoProcessor.from_pretrained("llava-hf/llava-onevision-qwen2-0.5b-ov-hf")AutoVideoProcessor(video_processing_auto.py)会根据模型的model_type在VIDEO_PROCESSOR_MAPPING(auto_mappings.py)中查找对应的处理器类,例如 Qwen2-VL / Qwen3-VL 系列映射到Qwen2VLVideoProcessor/Qwen3VLVideoProcessor,并支持trust_remote_code加载自定义处理器。
除了 Hub 上的模型 ID,from_pretrained还支持三种本地输入形式(video_processing_utils.py):
# 1) 本地目录(目录内含 video_preprocessor_config.json) processor = AutoVideoProcessor.from_pretrained("./test/saved_model/") # 2) 直接指向配置文件 processor = AutoVideoProcessor.from_pretrained("./test/saved_model/video_preprocessor_config.json") # 3) 加载时用 kwargs 覆盖配置,并回收未使用的参数 processor, unused = AutoVideoProcessor.from_pretrained( "llava-hf/llava-onevision-qwen2-0.5b-ov-hf", do_normalize=False, # 覆盖配置中的归一化开关 foo=False, # 非处理器属性,会被收集到 unused return_unused_kwargs=True, ) assert processor.do_normalize is False assert unused == {"foo": False}save_pretrained会将配置序列化为 JSON 写入save_directory/video_preprocessor_config.json,并支持push_to_hub推送(video_processing_utils.py)。
三、Fast Video Processor:GPU 加速与批量处理
传统逐帧处理的问题
如果使用基础图像处理器处理视频,其方式是把每一帧当作独立图片、逐帧应用变换。虽然可用,但效率不高——逐帧循环会产生大量 Python 层面的调度开销。
Fast processor 的批处理设计
AutoVideoProcessor默认加载fast video processors,其底层借助 torchvision 库:一次性处理整批视频,而不逐个遍历视频或帧(video_processing_auto.py 将映射中的类替换为 fast 版本)。这带来了GPU 加速能力,显著提升高吞吐任务的处理速度。fast video processor 对所有已注册的模型可用。
device 参数与 torch.compile
使用 fast video processor 时,可以设置device参数指定处理设备。默认行为是:如果输入是张量,则在输入所在设备上处理;否则在 CPU 上处理。device由device_validator校验,支持"cpu"、"cuda"等字符串或torch.device(processing_utils.py)。
为了获得更大提速,当使用加速器作为设备时,还可以用torch.compile编译处理器:
import torch from transformers.video_utils import load_video from transformers import AutoVideoProcessor # 自动选择当前可用的加速器(如 CUDA),否则回退到 CPU device = torch.accelerator.current_accelerator().type if torch.accelerator.is_available() else "cpu" video = load_video("video.mp4") processor = AutoVideoProcessor.from_pretrained("llava-hf/llava-onevision-qwen2-0.5b-ov-hf", device=device) processor = torch.compile(processor) processed_video = processor(video, return_tensors="pt")从源码看,device在preprocess中生效的位置是_prepare_input_videos(video_processing_utils.py):输入张量在转换为ChannelDimension.FIRST后,会通过video.to(device)迁移到指定设备,随后所有批量变换(缩放、裁剪、归一化)都在该设备上完成。
四、帧采样(Frame Sampling)
采样开关与两种策略
视频处理器会先解码视频,再挑选模型实际看到的帧。设置do_sample_frames=True开启采样,然后二选一:
num_frames:请求在视频中均匀分布的固定帧数;fps:请求每秒帧数的采样率。
传路径或 URL 时,处理器会自动解码视频,默认解码器是torchcodec;若未安装 torchcodec 且 torchvision 版本较旧,则回退到 torchvision 解码(video_processing_utils.py)。
from transformers import AutoVideoProcessor processor = AutoVideoProcessor.from_pretrained("Qwen/Qwen3-VL-4B-Instruct") inputs = processor(videos=["video.mp4"], do_sample_frames=True, fps=1, return_metadata=True, return_tensors="pt") print(inputs.pixel_values_videos.shape, inputs.video_grid_thw) print(inputs["video_metadata"][0].total_num_frames)返回的pixel_values_videos是模型可消费的视频张量;video_grid_thw等键由具体模型的处理器(如 Qwen3-VL)按需附加;video_metadata则在return_metadata=True时被写入输出(video_processing_utils.py)。
采样的底层实现
BaseVideoProcessor.sample_frames是默认采样函数(video_processing_utils.py),核心逻辑为:
# 按 fps 换算帧数:目标帧数 = 总帧数 / 视频fps * 目标fps num_frames = int(total_num_frames / metadata.fps * fps) # 均匀采样:torch.arange 在 [0, total_num_frames) 上等距取点 indices = torch.arange(0, total_num_frames, total_num_frames / num_frames).int()需要留意两个约束:
num_frames与fps互斥,同时传入会抛出ValueError;- 请求的帧数不能超过视频总帧数,否则同样报错。
当传入的是已解码的视频数组时,采样在内存中直接按video[indices]取帧(video_processing_utils.py);当传入的是路径或 URL 时,采样索引会在解码阶段由sample_indices_fn传给load_video,只解码被选中的帧,节省解码开销(video_utils.py)。
模型级默认值与裁剪约束
采样默认值因模型而异,请求的num_frames或fps只是一个起点而非保证。以 Qwen3-VL 为例:默认按fps=2采样,并将结果钳制在min_frames=4与max_frames=768之间,因此 1 秒的片段仍会得到 4 帧,而长视频的帧数会被截断在远低于真实帧数的上限。这一约束在多个模型的视频处理器中都能看到,例如:
- qwen2_vl/video_processing_qwen2_vl.py:默认
min_frames=4、max_frames=768; - cohere_compass/video_processing_cohere_compass.py:同样默认 4~768;
- ernie4_5_vl_moe/video_processing_ernie4_5_vl_moe.py:默认 16~180,并直接校验
num_frames是否落在区间内; - glm5_next/video_processing_glm5_next.py:仅设
max_frames=2048上限。
钳制逻辑典型写法为num_frames = min(max(num_frames, self.min_frames), self.max_frames, total_num_frames)(参见 cosmos3_edge/video_processing_cosmos3_edge.py)。
此外,带有temporal_patch_size的模型还有第二重约束:帧会按时间轴被分组为若干帧的 patch,若总数不能整除,最后一帧会被重复,直到帧数能被整除。
已解码数组 + video_metadata 的组合用法
如果传入的已是解码后的视频数组,但仍希望按模型特定的采样规则处理,就需要同时提供video_metadata。缺少元数据时,采样器不知道原始时长与 fps,按fps采样会发出警告并假设视频按 24 fps 录制。
import torch from transformers import AutoVideoProcessor from transformers.video_utils import VideoMetadata processor = AutoVideoProcessor.from_pretrained("Qwen/Qwen3-VL-4B-Instruct") video = torch.randint(0, 255, size=(100, 3, 1280, 1280)) # 100 帧的短视频,形状为 (帧数, 通道, 高, 宽) video_metadata = VideoMetadata(total_num_frames=100, fps=24, duration=4.1) inputs = processor( videos=[video], video_metadata=[video_metadata], do_sample_frames=True, num_frames=16, return_tensors="pt" )VideoMetadata是一个数据类(video_utils.py),支持字典式访问(inputs["video_metadata"][0]),字段包括:
| 字段 | 类型 | 说明 |
|---|---|---|
total_num_frames | int | 视频总帧数(必需) |
fps | float \| None | 原始帧率 |
width/height | int \| None | 原始宽高 |
duration | float \| None | 时长(秒) |
video_backend | str \| None | 解码后端(如"torchcodec") |
frames_indices | list[int] \| None | 实际采样到的帧索引 |
派生属性也很有用:timestamps给出每帧采样的秒级时间戳(frame_idx / fps),sampled_fps给出采样后的实际帧率(len(frames_indices) / total_num_frames * fps)。当video_metadata未显式传入时,make_batched_metadata会从数组长度推断total_num_frames,并将fps置为None(video_utils.py)——这正是按fps采样时发出警告并假设 24 fps 的根源。
五、完整处理流程:从视频到模型输入
综合源码,一次调用processor(videos, ...)的内部流程为(video_processing_utils.py):
- 参数校验与默认值补齐:
validate_kwargs校验传入键,validate_typed_dict做类型检查,未传参数回落到实例默认值; - 解码与采样(
_decode_and_sample_videos):输入标准化为批量列表;数组输入直接按索引采样,路径/URL 输入先解码(默认 torchcodec,回退 torchvision)再采样;列表形式的图片帧(常见于 chat template 场景)则逐帧走图片处理路径,且不支持采样(会报错提示设置do_sample_frames=False); - 设备迁移(
_prepare_input_videos):推断通道维度格式(FIRST/LAST),必要时 permute 到(帧, 通道, 高, 宽),再to(device); - 批量变换(
_preprocess):按形状分组 → RGB 转换 → 缩放 → 中心裁剪 → 融合的 rescale + normalize,最后恢复原顺序; - 结果封装:输出
BatchFeature,键为pixel_values_videos,可选附带video_metadata,并按return_tensors返回 PyTorch / NumPy 张量。
其中rescale_and_normalize将缩放与归一化融合执行:先以rescale_factor(默认1/255)把像素缩放到[0, 1],再用image_mean/image_std做标准化,与图像处理器保持一致的数值约定。
六、解码后端与依赖说明
视频的解码统一由 video_utils.py 中的load_video入口负责,内部通过VIDEO_DECODERS注册表(video_utils.py)按backend分发到不同实现:
| 后端 | 依赖 | 说明 |
|---|---|---|
torchcodec | torchcodec | 默认首选,FFmpeg 驱动,seek_mode="exact",支持指定解码设备 |
torchvision | torchvision<0.26 | 旧版回退;torchvision.io.read_video已在 0.26 移除,使用时会有弃用警告 |
pyav | av | load_video默认后端(文档示例中load_video("video.mp4")的默认值) |
decord | decord | CPU 解码 |
opencv | opencv-python | 不支持从 URL 加载 |
URL 输入会被下载到内存(httpx.get)再交给解码器,YouTube 链接则需要额外安装yt_dlp(video_utils.py)。对于常见的使用路径,建议安装torchcodec,这样 fast video processor 解码、采样、变换全链路都能保持最高效率;若使用较新的 torchvision,视频解码回退将不可用,必须依赖 torchcodec(错误信息见 video_utils.py)。
七、实操建议小结
- 优先使用
AutoVideoProcessor:自动匹配模型对应的 fast 视频处理器,获得批量处理与 GPU 加速,避免逐帧循环; - 高吞吐场景显式指定
device:让缩放、裁剪、归一化在加速器上完成,必要时配合torch.compile(processor); - 帧数预算先算后问:
num_frames与fps互斥且不能超过总帧数;长视频注意max_frames钳制,短视频注意min_frames抬升,二者以模型配置为准(如 Qwen3-VL 的 4~768); - 数组输入务必携带
video_metadata:否则按fps采样会退化到 24 fps 假设并产生警告;模型带temporal_patch_size时还会自动重复末尾帧以满足整除; - 解码依赖按需安装:处理器内部解码默认用 torchcodec,缺省且 torchvision 较新时会直接报错提示安装;需要采样时只解码被选中的帧,可显著降低 I/O。
本文涉及的源码均在仓库可查:基类与加载逻辑见 video_processing_utils.py,解码与元数据见 video_utils.py,参数声明见 processing_utils.py,自动映射见 auto_mappings.py 与 video_processing_auto.py,模型级采样约束可参考 qwen2_vl/video_processing_qwen2_vl.py 等具体实现。官方英文文档原文见 docs/source/en/video_processors.md。
【免费下载链接】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),仅供参考