Transformers 图像处理器深度解析:双后端架构、后端选择与视觉模型预处理实战
2026/9/7 2:50:14 网站建设 项目流程

Transformers 图像处理器深度解析:双后端架构、后端选择与视觉模型预处理实战

【免费下载链接】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

本文以 Transformers 官方文档docs/source/en/image_processors.md为核心,系统讲解图像处理器(Image Processor)如何将图像转换为模型可消费的像素张量。读完后,你将能够熟练加载 torchvision / PIL 双后端处理器、理解_preprocess批处理流水线在源码中的真实执行路径,并掌握与数据增强(augmentation)衔接、以及对检测/分割任务的 Padding 拼接等完整实战方案。

图像处理器把图像转成pixel values——即代表图像颜色与尺寸的张量,它是视觉模型的输入。为了保证预训练模型收到正确的输入,图像处理器会执行 center-crop 或 resize、对像素值做 normalize 或 rescale 等操作,使图像与模型预训练时所见完全一致。所有处理器的配置(图像尺寸、是否 normalize / rescale 等)都保存在 preprocessor_config.json 对应的仓库文件中,用ImageProcessingMixin.from_pretrained即可从模型仓库或本地目录加载:

from transformers import AutoImageProcessor image_processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224")

把一张图像传入处理器,并设置return_tensors="pt",即可得到 PyTorch 张量。你可以打印输入来观察图像作为张量的形态(下方用本地文件路径演示,实际项目中可替换为任意来源的 PIL 图像):

from PIL import Image image = Image.open("image.jpg").convert("RGB") inputs = image_processor(image, return_tensors="pt") print(inputs["pixel_values"].shape) # 观察 batch、channels、height、width

双后端架构:Torchvision 与 PIL

这是当前版本图像处理器最核心的设计变化。图像处理器采用基于后端(backend)的架构,提供两种实现:

  • TorchvisionBackend—— 默认的后端,基于 torchvision 实现,GPU 加速,对torch.Tensor批输入最快可比 PIL 后端快数十倍。所有模型都支持该后端;新模型仅支持这一种。
  • PilBackend—— 基于 PIL/NumPy 的替代实现,可移植、仅 CPU。仅对较老模型可用,适合精确复现原始实现的数值输出。

从源码结构看,两个后端都继承自BaseImageProcessor,分别定义在 image_processing_backends.py 中。BaseImageProcessor的类 docstring 清晰地给出了继承层级:

BaseImageProcessor (this class) ├── TorchvisionBackend (GPU-accelerated, torch.Tensor) │ └── ModelImageProcessor (e.g. LlavaNextImageProcessor) └── PilBackend (portable CPU, np.ndarray) └── ModelImageProcessorPil (e.g. CLIPImageProcessorPil)

加载后的处理器可以通过backend属性检查当前生效的后端。在源码中,两个后端各自实现了一个backend属性:TorchvisionBackend.backend返回"torchvision"PilBackend.backend返回"pil"(见 image_processing_backends.py)。因此:

print(image_processor.backend) # 'torchvision' 或 'pil'

每个图像处理器都继承自ImageProcessingMixin,该 Mixin 提供了~ImageProcessingMixin.from_pretrained~ImageProcessingMixin.save_pretrained两个方法。save_pretrained会把配置写入名为preprocessor_config.json的 JSON 文件(常量IMAGE_PROCESSOR_NAME),from_pretrained则优先从processor_config.json的嵌套字段image_processor读取,找不到时再回退到独立的preprocessor_config.json,加载逻辑可参见 get_image_processor_dict。

两种加载方式

你可以用AutoImageProcessor加载,也可以直接从模型特定类加载。

方式一:AutoImageProcessor

Auto 类 API 提供了便捷方法,无需直接指定图像处理器所属的模型。用~AutoImageProcessor.from_pretrained并传入backend参数可选择后端。当backend被省略(默认)时,若安装了 torchvision 则选择 torchvision,否则用 PIL。注意backend="pil"仅对老模型支持;新模型只暴露 torchvision 后端。

注意:一小批较老模型(Chameleon、Flava、Idefics3、SmolVLM)使用 Lanczos 插值,其默认后端取决于 torchvision 版本。当 torchvision > 0.27 时,Lanczos 被原生支持,这些模型默认使用 torchvision;老版本 torchvision 会回退到 BICUBIC,因此默认改为 PIL 以保留原始输出。显式传入backend="torchvision"可覆盖默认。

from transformers import AutoImageProcessor # 默认:安装了 torchvision 就选 torchvision,否则选 pil image_processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224") # 显式请求 torchvision 后端 image_processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224", backend="torchvision") # 显式请求 PIL 后端(仅支持该后端的模型可用) image_processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224", backend="pil")

后端的实际解析发生在_resolve_backend函数中:它把已废弃的use_fast标志转换为显式backend字符串,并在backendNone时按“是否为 Lanczos 处理器 / torchvision 是否可用”来决定默认后端(见 image_processing_auto.py)。其中 Lanczos 处理器的名单由源码中的_LANCZOS_IMAGE_PROCESSORS常量维护,与文档中提到的四个模型完全一致。若某个后端缺失,_load_class_with_fallback会尝试相反的后端并打印告警,确保总能加载到一个可用实现。

方式二:模型特定类

每个图像处理器都关联到一个特定的预训练视觉模型,其配置中包含模型期望的尺寸与归一化参数。

直接从模型特定类加载 torchvision 后端处理器:

from transformers import ViTImageProcessor image_processor = ViTImageProcessor.from_pretrained("google/vit-base-patch16-224")

对支持该后端的模型,可用带Pil后缀的类加载 PIL 后端,适合需要与原始实现数值完全一致的场景:

from transformers import ViTImageProcessorPil image_processor = ViTImageProcessorPil.from_pretrained("google/vit-base-patch16-224")

从源码结构看,AutoImageProcessor内部维护了一张IMAGE_PROCESSOR_MAPPING_NAMES映射,其键为model_type,值为{"torchvision": ..., "pil": ...}的类名字典,绝大多数视觉模型都成对注册了两个后端(见 auto_mappings)。这也解释了为什么Pil后缀类是成对存在的约定。

Torchvision 后端处理器与设备控制

TorchvisionBackend默认后端。确保安装了 torchvision 后,用backend="torchvision"加载(或直接省略backend,因为可用时会自动选中 torchvision):

from transformers import AutoImageProcessor processor = AutoImageProcessor.from_pretrained("facebook/detr-resnet-50", backend="torchvision")

可以用device参数控制处理所在的设备。默认情况下,若输入是张量则在与输入相同的设备上处理,否则回退到 CPU。下面的例子在加速器上执行处理:

import torch from torchvision.io import read_image from transformers import DetrImageProcessor device = torch.accelerator.current_accelerator().type if torch.accelerator.is_available() else "cpu" images = read_image("image.jpg") processor = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50") images_processed = processor(images, return_tensors="pt", device=device)

从源码看,设备控制落在TorchvisionBackend.process_imagedevice参数上:单张图像会被转换、按通道维度重排后,若传入了device就调用image.to(device)(见 image_processing_backends.py)。这正是文档中device参数能引导批处理落到 GPU 的底层依据。

关于性能:官方文档给出的基准测试来自配备 NVIDIA A10G Tensor Core GPU 的实例,对比了 DETR 与 RT-DETR 在完整流水线(含 padding / 编译批处理)下 torchvision 后端相对 PIL 后端的加速。这些是文档声明的测试结果,实际数值会随硬件与 torchvision 版本变化。

动态分辨率

大多数图像处理器会把每张图像 resize 到固定分辨率。动态分辨率(dynamic resolution)则允许部分模型保留原始宽高比,并让预处理后的数据量随图像增长——细节丰富的照片会得到比小图标更多的 patch,从而让模型把算力花在真正有内容的地方。

图像如何被切分是模型特定的:

  • 有些模型把图像裁切成可变数量的固定尺寸 patch,并由min_patchesmax_patches等参数约束上下界;
  • 另一些模型把图像 resize 到最合适的分辨率,该分辨率要么从一个预定义的宽高比列表中挑选,要么由一个像素预算(pixel budget)推导而来。

具体参数、默认值与输出形状,请以对应模型的文档页为准。

预处理流水线:resize、rescale、normalize

Transformers 的视觉模型期望输入是像素值的 PyTorch 张量,其形状为批次大小 × 通道数 × 高度 × 宽度。图像处理器负责把图像转换为像素值,具体方式是 resize(center crop)图像,并把像素值 normalize / rescale 到模型期望的数值范围。

这里必须区分图像预处理(preprocessing)图像增强(augmentation)

  • 图像增强对图像做改动(亮度、颜色、旋转等),目的是制造新的训练样本或防止过拟合;
  • 图像预处理对图像做改动,目的是匹配预训练模型的期望输入格式。

通常先做增强(提升性能),再做预处理,然后送入模型。增强可以用任意库(如 Albumentations、Kornia),预处理则用图像处理器。官方指南使用 torchvision 的 transforms 模块来做增强。

源码中的_preprocess执行路径

从 BaseImageProcessor 的 docstring 可看到,整体调用链为:

__call__() → preprocess() → _preprocess_image_like_inputs() → _prepare_image_like_inputs() (per image 调用 process_image) → _preprocess() (批处理: resize, crop, ...)

TorchvisionBackend._preprocess(见 image_processing_backends.py)展示了“按形状分组 → 批量操作 → 重排还原”的高效策略:

  1. group_images_by_shape把相同形状的图片堆叠成 batch;
  2. 对每个形状组执行resizedo_resize时);
  3. 再次分组后执行center_croprescale_and_normalize
  4. do_pad,最后调用pad
  5. reorder_images把结果还原为原始顺序,返回BatchFeature(data={"pixel_values": ...})

其中rescale_and_normalize是一个融合操作:当同时需要 rescale 与 normalize 时,它会把rescale_factor折叠进image_meanimage_std(乘以1/rescale_factor),从而少一次张量遍历——这是 torchvision 后端更快的重要来源之一。

预处理实战:与数据增强衔接

以 food101 数据集为例,先加载一个小样本:

from datasets import load_dataset dataset = load_dataset("ethz/food101", split="train[:100]")

从 transforms 模块用ComposeAPI 把RandomResizedCropColorJitter串联起来:前者随机裁剪并缩放图像,后者随机调整颜色。

随机裁剪的目标尺寸可以从图像处理器中读取。对某些模型,需要精确的 height 和 width;对另一些模型,只需shortest_edge

from torchvision.transforms import RandomResizedCrop, ColorJitter, Compose size = ( image_processor.size["shortest_edge"] if "shortest_edge" in image_processor.size else (image_processor.size["height"], image_processor.size["width"]) ) _transforms = Compose([RandomResizedCrop(size), ColorJitter(brightness=0.5, hue=0.5)])

对图像应用 transforms 并转成 RGB,然后把增强后的图像交给图像处理器返回像素值。do_resize设为False,是因为图像已在增强步骤中由RandomResizedCropresize 过。若不做增强,图像处理器会自动用image_meanimage_std(来自 preprocessor 配置)完成 resize 与归一化:

def transforms(examples): images = [_transforms(img.convert("RGB")) for img in examples["image"]] examples["pixel_values"] = image_processor(images, do_resize=False, return_tensors="pt")["pixel_values"] return examples

用 [~datasets.Dataset.set_transform] 把组合好的“增强 + 预处理”函数应用到整个数据集,实现按需计算:

dataset.set_transform(transforms)

把像素值还原成图像,以查看图像被增强和预处理后的样子:

import matplotlib.pyplot as plt img = dataset[0]["pixel_values"] plt.imshow(img.permute(1, 2, 0))

批处理 Padding:以 DETR 为例

对目标检测、分割等其他视觉任务,图像处理器还包含后处理方法,把模型的原始输出转换为有意义的预测,如边界框或分割图。

某些模型(如 DETR)训练时应用 scale augmentation,会导致一个 batch 内图像尺寸不同,而不同尺寸的图像无法直接堆叠成 batch。解决办法是用特殊填充值0对图像做 padding,并用pad方法完成填充、自定义 collate 函数把它们拼在一起:

def collate_fn(batch): pixel_values = [item["pixel_values"] for item in batch] encoding = image_processor.pad(pixel_values, return_tensors="pt") labels = [item["labels"] for item in batch] batch = {} batch["pixel_values"] = encoding["pixel_values"] batch["pixel_mask"] = encoding["pixel_mask"] batch["labels"] = labels return batch

从源码看,TorchvisionBackend.pad默认fill_value=0,在未显式给出pad_size时取所有图像的最大高宽(get_max_height_width),同样按形状分组、用 torchvision 的tvF.pad批量填充;当return_mask=True时会额外生成标记真实图像区域的pixel_mask(见 image_processing_backends.py)。PilBackend.pad则用np.pad以同样的语义实现,保证两个后端在 padding 行为上保持一致。

小结

  • 图像处理器把图像转成batch × channels × height × width的像素张量,是视觉模型的标准输入;
  • 加载用AutoImageProcessor或模型特定类,配置来自preprocessor_config.json,由ImageProcessingMixin.from_pretrained读取;
  • 双后端架构:默认TorchvisionBackend(GPU 加速、批处理更快、可传device指定设备),PilBackend(CPU、可移植、精确复现数值);用backend参数选择,用processor.backend检查;
  • 预处理流水线resize → center crop → rescale + normalize → pad_preprocess中“按形状分组 + 批量操作 + 融合归一化”实现;
  • 增强(augmentation)与预处理(preprocessing)分工不同,先增强再预处理;检测/分割任务用pad+ 自定义collate_fn处理变尺寸 batch。

【免费下载链接】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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询