当前位置: 首页 > news >正文

AutoImageProcessor代码分析

以下是对 AutoImageProcessor 类的整理,按照类属性、类方法、静态方法、实例属性和实例方法分类,并对每个方法的功能进行了描述。

类属性

无显式定义的类属性。


全局方法

IMAGE_PROCESSOR_MAPPING_NAMES

1. 遍历 IMAGE_PROCESSOR_MAPPING_NAMES 字典
for model_type, image_processors in IMAGE_PROCESSOR_MAPPING_NAMES.items():
  • 目的:遍历所有模型类型及其对应的图像处理器类名。
  • 变量说明
    • model_type:模型的类型字符串,例如 'vit''bert' 等。
    • image_processors:一个元组,包含慢速和(可选)快速图像处理器类名,例如 ('ViTImageProcessor', 'ViTImageProcessorFast')
2. 解包图像处理器类名
slow_image_processor_class, *fast_image_processor_class = image_processors
  • 目的:拆分图像处理器类名,分别获取慢速和快速版本的类名。
  • 解释
    • slow_image_processor_class:慢速图像处理器类名,必定存在(即 image_processors 的第一个元素)。
    • fast_image_processor_class:列表,包含剩余的快速图像处理器类名(可能为空,如果没有快速版本)。
3. 检查视觉库(如 PIL)是否可用
if not is_vision_available():
    slow_image_processor_class = None
  • 目的:如果视觉库不可用,则无法使用慢速图像处理器,将其类名设为 None
  • 函数
    • is_vision_available():检查 PIL(或其他必要视觉库)是否可用。
  • 结果
    • 如果 PIL 不可用,slow_image_processor_class 被设为 None
4. 检查快速图像处理器的可用性
if not fast_image_processor_class or fast_image_processor_class[0] is None or not is_torchvision_available():
    fast_image_processor_class = None
else:
    fast_image_processor_class = fast_image_processor_class[0]
  • 目的:根据条件确定是否可以使用快速图像处理器,并适当设置其类名。
  • 解释
    • 条件判断内容:
      • not fast_image_processor_class:没有提供快速图像处理器类名。
      • fast_image_processor_class[0] is None:快速图像处理器类名为 None
      • not is_torchvision_available()torchvision 库不可用。
    • 如果以上任何一个条件为真,表示无法使用快速图像处理器,将 fast_image_processor_class 设为 None
    • 否则,获取实际的快速图像处理器类名(列表的第一个元素)。
5. 更新 IMAGE_PROCESSOR_MAPPING_NAMES 字典
IMAGE_PROCESSOR_MAPPING_NAMES[model_type] = (slow_image_processor_class, fast_image_processor_class)
  • 目的:将当前模型类型的图像处理器类名更新为根据可用性调整后的结果。
  • 结果
    • IMAGE_PROCESSOR_MAPPING_NAMES 中,每个 model_type 的值变为一个包含可能为 None 的慢速和快速图像处理器类名的元组。
总结

这段代码的核心作用是:

  • 动态调整可用的图像处理器类名:根据环境中安装的库(如 PIL、torchvision),将不可用的图像处理器类名设为 None

  • 确保后续实例化安全:在使用图像处理器时,如果某个版本(慢速或快速)不可用,程序不会尝试加载,从而避免运行时错误。

IMAGE_PROCESSOR_MAPPING

1. 创建懒加载的映射 IMAGE_PROCESSOR_MAPPING
IMAGE_PROCESSOR_MAPPING = _LazyAutoMapping(CONFIG_MAPPING_NAMES, IMAGE_PROCESSOR_MAPPING_NAMES)
  • 目的:创建一个懒加载的映射,将模型配置类映射到对应的图像处理器类。
  • 解释
    • _LazyAutoMapping:一个用于延迟加载的映射类,只有在实际使用时才会加载对应的模块或类。
    • CONFIG_MAPPING_NAMES:模型配置名称映射,用于将模型类型映射到配置类。
    • IMAGE_PROCESSOR_MAPPING_NAMES:之前更新的图像处理器类名映射。

总结

这段代码的核心作用是:

  • 映射模型配置到图像处理器:最终生成的 IMAGE_PROCESSOR_MAPPING 映射,用于在程序中根据模型配置自动找到适当的图像处理器类。

get_image_processor_class_from_name

函数功能概述

def get_image_processor_class_from_name(class_name: str):
    ...

函数 get_image_processor_class_from_name 的作用是根据提供的类名字符串 class_name,返回对应的图像处理器类对象。它在预定义的映射和可用的模块中查找类名,尝试导入相应的模块并获取类对象。如果未找到类名,且可能是由于依赖库缺失导致的,则在主 transformers 模块中查找,以返回一个适当的占位符类,从而在实例化时提供有用的错误信息。


1. 特殊处理 BaseImageProcessorFast
if class_name == "BaseImageProcessorFast":
    return BaseImageProcessorFast
  • 目的:如果传入的类名是 "BaseImageProcessorFast",直接返回 BaseImageProcessorFast 类对象。
  • 解释:这是一个特殊情况处理,避免在后续过程中不必要的查找。
2. 在 IMAGE_PROCESSOR_MAPPING_NAMES 中查找类名
for module_name, extractors in IMAGE_PROCESSOR_MAPPING_NAMES.items():
    if class_name in extractors:
        module_name = model_type_to_module_name(module_name)
        module = importlib.import_module(f".{module_name}", "transformers.models")
        try:
            return getattr(module, class_name)
        except AttributeError:
            continue
  • 目的:遍历 IMAGE_PROCESSOR_MAPPING_NAMES 字典,查找是否有匹配的类名。
  • 步骤
    • 遍历
      • module_name:模型类型的名称,例如 'vit'
      • extractors:与模型类型关联的图像处理器类名元组,包含慢速和快速版本的类名。
    • 检查:如果 class_nameextractors 中,表示找到了对应的图像处理器类。
    • 转换模块名称
      • 使用 model_type_to_module_name 函数将 module_name 转换为符合模块导入的名称格式。
    • 导入模块
      • 使用 importlib.import_module 动态导入模块,模块路径为 transformers.models.{module_name}
    • 获取类对象
      • 使用 getattr 从模块中获取类对象。
      • 如果成功,返回类对象。
      • 如果发生 AttributeError,表示类未在模块中定义,继续下一次循环。
3. 在额外注册的内容中查找类名
for _, extractors in IMAGE_PROCESSOR_MAPPING._extra_content.items():
    for extractor in extractors:
        if getattr(extractor, "__name__", None) == class_name:
            return extractor
  • 目的:检查在运行时动态注册的额外内容中,是否存在匹配的类名。
  • 解释
    • 遍历 IMAGE_PROCESSOR_MAPPING_extra_content,这是在运行时通过 register 方法添加的额外映射。
    • 对于每个 extractor,检查其 __name__ 属性是否与 class_name 匹配。
    • 如果找到匹配的类,返回类对象。
4. 处理可能缺少的依赖
main_module = importlib.import_module("transformers")
if hasattr(main_module, class_name):
    return getattr(main_module, class_name)
  • 目的:如果在以上步骤未找到类名,且可能是由于依赖库缺失导致的,则在主 transformers 模块中查找。
  • 解释
    • 导入主模块 transformers
    • 使用 hasattr 检查主模块中是否存在名为 class_name 的属性。
    • 如果存在,使用 getattr 获取并返回类对象。
  • 原因:当某些依赖库(如 PIL、torchvision 等)缺失时,相关的图像处理器类会被定义为占位符类(通常在主模块中),在实例化时会抛出友好的错误信息,提示用户安装缺失的依赖。
5. 返回 None 表示未找到类
return None
  • 目的:如果所有查找都未能找到匹配的类名,返回 None
  • 解释:调用该函数的代码应当处理 None 的返回值,可能会抛出异常或采取其他措施。

函数工作流程总结
  1. 特殊情况处理:如果类名是 "BaseImageProcessorFast",直接返回对应的类对象。

  2. 在预定义映射中查找:遍历 IMAGE_PROCESSOR_MAPPING_NAMES,尝试导入对应的模块并获取类对象。

  3. 在动态注册的内容中查找:检查在运行时注册的额外内容中是否存在匹配的类。

  4. 处理缺失依赖的情况:在主 transformers 模块中查找,如果类存在,返回占位符类。

  5. 未找到类:如果以上步骤均未找到匹配的类名,返回 None


函数调用示例
  • 示例 1:类名在预定义映射中

    • 调用 get_image_processor_class_from_name("ViTImageProcessor")
    • IMAGE_PROCESSOR_MAPPING_NAMES 中找到对应的模型类型 'vit'
    • 导入模块 transformers.models.vit
    • 获取并返回 ViTImageProcessor 类。
  • 示例 2:类名在动态注册的内容中

    • 假设用户通过 AutoImageProcessor.register 方法注册了自定义的图像处理器。
    • 调用 get_image_processor_class_from_name("CustomImageProcessor")
    • _extra_content 中找到并返回 CustomImageProcessor 类。
  • 示例 3:缺少依赖库导致类无法导入

    • 调用 get_image_processor_class_from_name("SomeImageProcessor")
    • 由于缺少依赖,模块导入失败或类未定义。
    • 在主 transformers 模块中查找,返回占位符类。
    • 当实例化该占位符类时,提示用户安装缺失的依赖库。

类方法

方法名称类型功能说明
from_pretrained类方法根据预训练模型的名称或路径,自动加载对应的图像处理器配置,并实例化相应的图像处理器类。该方法会解析配置文件,确定使用哪个具体的图像处理器类,并根据需要下载和加载模型的配置和参数。

方法签名

@classmethod
@replace_list_option_in_docstrings(IMAGE_PROCESSOR_MAPPING_NAMES)
def from_pretrained(cls, pretrained_model_name_or_path, *inputs, **kwargs):
  • @classmethod:该方法是一个类方法,意味着它不需要实例化类就可以被调用,第一个参数是类本身 cls
  • @replace_list_option_in_docstrings(IMAGE_PROCESSOR_MAPPING_NAMES):这是一个装饰器,用于在文档字符串中替换图像处理器映射名称的列表选项,方便生成更完整的文档。
  • 参数
    • pretrained_model_name_or_path:预训练模型的名称或路径。
    • *inputs:可变位置参数,供子类扩展使用。
    • **kwargs:可变关键字参数,用于传递其他配置项。

方法功能概述

from_pretrained 方法的主要功能是:

  • 根据给定的预训练模型名称或路径,加载对应的图像处理器配置文件。
  • 解析配置,确定要实例化的具体图像处理器类。
  • 根据用户指定或默认的选项,决定是否使用快速版本的图像处理器(如果可用)。
  • 处理远程代码加载(如果配置在远程仓库中且被允许)。
  • 最终实例化并返回合适的图像处理器对象。

1. 处理过时参数和准备工作

use_auth_token = kwargs.pop("use_auth_token", None)
if use_auth_token is not None:
    warnings.warn(
        "The `use_auth_token` argument is deprecated and will be removed in v5 of Transformers. Please use `token` instead.",
        FutureWarning,
    )
    if kwargs.get("token", None) is not None:
        raise ValueError(
            "`token` and `use_auth_token` are both specified. Please set only the argument `token`."
        )
    kwargs["token"] = use_auth_token
  • 目的:处理过时的参数 use_auth_token,并引导用户使用新的参数 token
  • 解释
    • 如果用户在 kwargs 中传递了 use_auth_token,则发出警告,提示该参数已弃用,应该使用 token
    • 如果同时传递了 tokenuse_auth_token,则抛出错误,要求用户只使用 token
    • 最终,将 use_auth_token 的值赋给 kwargs["token"]
config = kwargs.pop("config", None)
use_fast = kwargs.pop("use_fast", None)
trust_remote_code = kwargs.pop("trust_remote_code", None)
kwargs["_from_auto"] = True
  • 目的:从关键字参数中提取配置项,为后续处理做准备。
  • 解释
    • config:用户可能传递的模型配置对象,如果没有则为 None
    • use_fast:决定是否使用快速版本的图像处理器的布尔值,默认值为 None,后续会根据情况设置。
    • trust_remote_code:是否信任并允许从远程仓库加载自定义代码。
    • kwargs["_from_auto"] = True:在关键字参数中添加标记,指示该调用是通过 AutoImageProcessor 进行的。

2. 确定图像处理器配置文件名

if "image_processor_filename" in kwargs:
    image_processor_filename = kwargs.pop("image_processor_filename")
elif is_timm_local_checkpoint(pretrained_model_name_or_path):
    image_processor_filename = CONFIG_NAME
else:
    image_processor_filename = IMAGE_PROCESSOR_NAME
  • 目的:确定要加载的图像处理器配置文件的文件名。
  • 解释
    • 如果用户在 kwargs 中指定了 image_processor_filename,则使用用户指定的文件名。
    • 如果预训练模型是一个本地的 timm 检查点,则使用 CONFIG_NAME(通常为 'config.json')。
      - 否则,使用默认的 IMAGE_PROCESSOR_NAME(通常为 'preprocessor_config.json')。

3. 加载图像处理器配置

try:
    # 主路径,适用于所有 Transformers 模型和本地 TimmWrapper 检查点
    config_dict, _ = ImageProcessingMixin.get_image_processor_dict(
        pretrained_model_name_or_path, image_processor_filename=image_processor_filename, **kwargs
    )
except Exception as initial_exception:
    # 回退路径,适用于 Hub 上的 TimmWrapper 检查点
    try:
        config_dict, _ = ImageProcessingMixin.get_image_processor_dict(
            pretrained_model_name_or_path, image_processor_filename=CONFIG_NAME, **kwargs
        )
    except Exception:
        raise initial_exception
    # 如果加载的不是 timm 配置字典,则抛出初始异常
    if not is_timm_config_dict(config_dict):
        raise initial_exception
  • 目的:尝试加载图像处理器的配置字典。
  • 解释
    • 首先尝试使用确定的 image_processor_filename 来加载配置,ImageProcessingMixin.get_image_processor_dict。
    • 如果发生异常(如文件不存在),则可能是因为模型是一个 timm 模型,需要使用 'config.json' 来加载。
    • 如果两次尝试都失败,或者加载的配置不是 timm 配置,则抛出最初的异常。

4. 解析图像处理器类型和自动映射

image_processor_type = config_dict.get("image_processor_type", None)
image_processor_auto_map = None
if "AutoImageProcessor" in config_dict.get("auto_map", {}):
    image_processor_auto_map = config_dict["auto_map"]["AutoImageProcessor"]
  • 目的:从配置字典中提取图像处理器类型和自动映射信息。
  • 解释
    • image_processor_type:尝试获取 image_processor_type,这通常是图像处理器类的名称。
    • image_processor_auto_map:如果配置中存在 auto_map,并且其中包含 AutoImageProcessor,则获取对应的映射信息。

5. 兼容旧的特征提取器配置

if image_processor_type is None and image_processor_auto_map is None:
    feature_extractor_class = config_dict.pop("feature_extractor_type", None)
    if feature_extractor_class is not None:
        image_processor_type = feature_extractor_class.replace("FeatureExtractor", "ImageProcessor")
    if "AutoFeatureExtractor" in config_dict.get("auto_map", {}):
        feature_extractor_auto_map = config_dict["auto_map"]["AutoFeatureExtractor"]
        image_processor_auto_map = feature_extractor_auto_map.replace("FeatureExtractor", "ImageProcessor")
  • 目的:处理旧版本的配置,其中使用了 FeatureExtractor 而不是 ImageProcessor
  • 解释
    • 如果没有获取到 image_processor_typeimage_processor_auto_map,则尝试从旧的 feature_extractor_type 中获取。
    • FeatureExtractor 替换为 ImageProcessor,以获取新的类型名称。

6. 从模型配置中获取图像处理器类型

if image_processor_type is None and image_processor_auto_map is None:
    if not isinstance(config, PretrainedConfig):
        config = AutoConfig.from_pretrained(
            pretrained_model_name_or_path,
            trust_remote_code=trust_remote_code,
            **kwargs,
        )
    image_processor_type = getattr(config, "image_processor_type", None)
    if hasattr(config, "auto_map") and "AutoImageProcessor" in config.auto_map:
        image_processor_auto_map = config.auto_map["AutoImageProcessor"]
  • 目的:如果在图像处理器配置中未找到类型信息,则尝试从模型的配置中获取。
  • 解释
    • 如果 config 不是 PretrainedConfig 的实例,则使用 AutoConfig.from_pretrained 加载模型配置。
    • 尝试从模型配置中获取 image_processor_type
    • 检查模型配置中是否存在 auto_map,并获取 AutoImageProcessor 的映射信息。

7. 确定是否使用快速版本的图像处理器并获取相应的类

image_processor_class = None
if image_processor_type is not None:
    if use_fast is None:
        use_fast = image_processor_type.endswith("Fast")
        if not use_fast:
            logger.warning_once(
                "Using a slow image processor as `use_fast` is unset and a slow processor was saved with this model. "
                "`use_fast=True` will be the default behavior in v4.48, even if the model was saved with a slow processor. "
                "This will result in minor differences in outputs. You'll still be able to use a slow processor with `use_fast=False`."
            )
    if use_fast and not is_torchvision_available():
        logger.warning_once(
            "Using `use_fast=True` but `torchvision` is not available. Falling back to the slow image processor."
        )
        use_fast = False
    if use_fast:
        if not image_processor_type.endswith("Fast"):
            image_processor_type += "Fast"
        for _, image_processors in IMAGE_PROCESSOR_MAPPING_NAMES.items():
            if image_processor_type in image_processors:
                break
        else:
            image_processor_type = image_processor_type[:-4]
            use_fast = False
            logger.warning_once(
                "`use_fast` is set to `True` but the image processor class does not have a fast version. "
                " Falling back to the slow version."
            )
        image_processor_class = get_image_processor_class_from_name(image_processor_type)
    else:
        image_processor_type = (
            image_processor_type[:-4] if image_processor_type.endswith("Fast") else image_processor_type
        )
        image_processor_class = get_image_processor_class_from_name(image_processor_type)
  • 目的:根据 use_fast 选项和可用性,决定使用快速或慢速版本的图像处理器,并获取对应的类。
  • 解释
    • 如果 use_fast 未设置,则根据 image_processor_type 是否以 'Fast' 结尾来推断。
    • 如果需要使用快速版本,但 torchvision 不可用,则警告并退回使用慢速版本。
    • 如果使用快速版本且类型名称未以 'Fast' 结尾,则添加 'Fast'
    • 检查调整后的 image_processor_type 是否在已知的映射中,如果不存在,则回退到慢速版本。
    • 使用 get_image_processor_class_from_name 函数,根据类型名称获取对应的图像处理器类。

8. 处理远程代码加载和实例化图像处理器

has_remote_code = image_processor_auto_map is not None
has_local_code = image_processor_class is not None or type(config) in IMAGE_PROCESSOR_MAPPING
trust_remote_code = resolve_trust_remote_code(
    trust_remote_code, pretrained_model_name_or_path, has_local_code, has_remote_code
)
if image_processor_auto_map is not None and not isinstance(image_processor_auto_map, tuple):
    image_processor_auto_map = (image_processor_auto_map, None)
if has_remote_code and trust_remote_code:
    if not use_fast and image_processor_auto_map[1] is not None:
        _warning_fast_image_processor_available(image_processor_auto_map[1])
    if use_fast and image_processor_auto_map[1] is not None:
        class_ref = image_processor_auto_map[1]
    else:
        class_ref = image_processor_auto_map[0]
    image_processor_class = get_class_from_dynamic_module(class_ref, pretrained_model_name_or_path, **kwargs)
    _ = kwargs.pop("code_revision", None)
    if os.path.isdir(pretrained_model_name_or_path):
        image_processor_class.register_for_auto_class()
    return image_processor_class.from_dict(config_dict, **kwargs)
elif image_processor_class is not None:
    return image_processor_class.from_dict(config_dict, **kwargs)
  • 目的:处理是否需要从远程加载自定义的图像处理器类,并实例化图像处理器对象。
  • 解释
    • 判断是否存在远程代码(has_remote_code)和本地代码(has_local_code)。
    • 使用 resolve_trust_remote_code 函数,确定是否信任远程代码(trust_remote_code)。
    • 如果存在远程代码且被信任:
      • 根据 use_fast 以及可用性,选择快速或慢速版本的类引用 class_ref
      • 使用 get_class_from_dynamic_module 函数,从远程模块中获取类定义。
      • 如果模型路径是本地目录,则注册该类以供自动类使用。
      • 使用 from_dict 方法,根据配置字典实例化图像处理器对象并返回。
        -
        如果存在本地图像处理器类,则直接使用配置字典实例化并返回。

9. 使用默认映射尝试获取图像处理器类

elif type(config) in IMAGE_PROCESSOR_MAPPING:
    image_processor_tuple = IMAGE_PROCESSOR_MAPPING[type(config)]
    image_processor_class_py, image_processor_class_fast = image_processor_tuple
    if not use_fast and image_processor_class_fast is not None:
        _warning_fast_image_processor_available(image_processor_class_fast)
    if image_processor_class_fast and (use_fast or image_processor_class_py is None):
        return image_processor_class_fast.from_pretrained(pretrained_model_name_or_path, *inputs, **kwargs)
    else:
        if image_processor_class_py is not None:
            return image_processor_class_py.from_pretrained(pretrained_model_name_or_path, *inputs, **kwargs)
        else:
            raise ValueError(
                "This image processor cannot be instantiated. Please make sure you have `Pillow` installed."
            )
  • 目的:如果上述方法都未能成功,则使用预定义的映射 IMAGE_PROCESSOR_MAPPING 尝试获取图像处理器类。
  • 解释
    • 检查模型配置的类型是否在 IMAGE_PROCESSOR_MAPPING 中。
    • 根据 use_fast 和可用性,选择快速或慢速版本的类,并使用 from_pretrained 方法实例化。

10. 抛出异常

raise ValueError(
    f"Unrecognized image processor in {pretrained_model_name_or_path}. Should have a "
    f"`image_processor_type` key in its {IMAGE_PROCESSOR_NAME} of {CONFIG_NAME}, or one of the following "
    f"`model_type` keys in its {CONFIG_NAME}: {', '.join(c for c in IMAGE_PROCESSOR_MAPPING_NAMES.keys())}"
)
  • 目的:如果所有方法都失败,无法识别或实例化图像处理器,则抛出异常。
  • 解释
    • 提示用户未能识别给定模型的图像处理器类型。
    • 建议检查模型的配置文件中是否包含 image_processor_type,并列出了支持的模型类型。

静态方法

方法名称类型功能说明
register静态方法注册新的模型配置类和对应的图像处理器类,以扩展 AutoImageProcessor 的支持范围。通过此方法,用户可以添加自定义的模型和图像处理器,使其能够被 AutoImageProcessor 自动识别和加载。

实例方法

方法名称类型功能说明
__init__实例方法初始化方法,被设计为抛出异常。提示用户不应直接实例化 AutoImageProcessor 类,而应该使用 from_pretrained 类方法来实例化具体的图像处理器。

实例属性

由于 AutoImageProcessor 类的 __init__ 方法被设计为抛出异常,因此不能直接实例化该类,因此不存在实例属性。


end

好的,以下是对函数 get_image_processor_class_from_name 的解释。


相关文章:

  • Python设计模式 - 适配器模式
  • 二十四、实战开发 uni-app x 项目(仿京东)- 前后端实现登录注册
  • 在线生成自定义二维码
  • 失物招领|校园失物招领系统|基于Springboot的校园失物招领系统设计与实现(源码+数据库+文档)
  • 【 <二> 丹方改良:Spring 时代的 JavaWeb】之 Spring Boot 中的异常处理:全局异常与自定义异常
  • 【自学笔记】Linux基础知识点总览-持续更新
  • 利用Dify编制用户问题意图识别和规范化回复
  • C#单例模式
  • 常考计算机操作系统面试习题(二)(中)
  • Windows——电脑无法正常上网的一种解决办法
  • 统计学重要概念:自由度
  • 《Python实战进阶》第43集:使用 asyncio 实现异步编程
  • Amdahl 定律
  • react 中 key 的使用
  • 抗积分饱和(Anti-Windup)常见的处理方法
  • SpringBoot原理篇-SpringBoot配置优先级-Bean管理-起步依赖原理-自动配置两种方案-源码跟踪-自定义starter
  • 不同的CMS系统开源许可证对二次开发有哪些具体的限制?
  • 运维面试题(七)
  • 【矩阵快速幂】 P10502 Matrix Power Series|省选-
  • 蓝桥杯 之 最短路径算法
  • 美国多地爆发集会抗议特朗普政府多项政策
  • 国际著名学者Charles M. Lieber全职受聘清华深圳国际研究生院
  • 4月制造业PMI为49%,比上月下降1.5个百分点
  • 民营经济促进法出台,自今年5月20日起施行
  • 南部战区位南海海域进行例行巡航
  • 证据公布!菲律宾6人非法登上铁线礁活动