Prhub

#38447 [Transformers v5] Vendor HCXVisionConfig for compatibility

原始 PR 作者 HanFa 合并时间 2026-05-04 12:19 文件变更 4 提交数 1 评论 5 代码增减 +79 / -9

执行摘要

自带 HCXVisionConfig 修复 Transformers v5 兼容性

Transformers v5引入的@strict配置验证要求所有属性在初始化时明确设置。上游远程的HCXVisionConfig__init__中仅在text_config is not None时才设置self.text_config,当Transformers v5创建空配置进行验证或比较时,get_text_config()因访问不存在属性而抛出AttributeError。本PR通过自带(vendor)修复的配置类解决此问题,详见关联Issue #38387和#45093。

推荐阅读。该PR展示了如何通过自带(vendor)上游配置类来修复Transformers v5兼容性问题,并涉及AutoConfig注册优先级的协作(关联Transformers PR #45093),对理解vLLM的配置加载机制以及跨仓库兼容性修复有参考价值。

讨论亮点

Gemini Code Assist机器人在Review中指出__init__self.hidden_size的fallback逻辑存在缺陷:属性映射循环已从text_config字典中移除了n_embd键,后续的text_config.get("n_embd")将始终返回None,导致fallback无法生效。建议直接从已实例化的self.text_config.hidden_size获取值。该建议被采纳,最终代码中self.hidden_size = self.text_config.hidden_size

实现拆解

分四步实现:

  1. vllm/transformers_utils/configs/hyperclovax.py中新增HCXVisionConfig:继承自PretrainedConfig,固定设置model_type = "hyperclovax_vlm"__init__方法接受text_configvision_config参数,先对text_config中的属性名进行映射(如n_embdhidden_size),然后始终将self.text_config初始化为None,若传入非空则通过AutoConfig.for_model生成实际配置对象。get_text_config方法在self.text_configNone时回退返回self,确保兼容Transformers v5的空校验。
  2. vllm/transformers_utils/config.py_CONFIG_REGISTRY中添加映射:将hyperclovax_vlm映射到HCXVisionConfig类,确保vLLM的配置加载路径能识别该模型类型;同时优化了注册注释,说明注册后可被AutoTokenizerAutoProcessor复用。
  3. vllm/transformers_utils/configs/__init__.py中注册类:将HCXVisionConfig加入_CLASS_TO_MODULE字典和__all__导出列表,使其可通过模块路径访问。
  4. tests/models/registry.py中移除版本限制:删除此前为HCXVisionForCausalLM设置的max_transformers_version和版本理由,因为自带的配置类已兼容Transformers v5,同时保留trust_remote_code=True以保证其他依赖远程代码的模型不受影响。
文件 模块 状态 重要度
vllm/transformers_utils/configs/hyperclovax.py 配置层 modified 8.2
vllm/transformers_utils/config.py 配置层 modified 5.59
vllm/transformers_utils/configs/__init__.py 配置层 modified 4.89
tests/models/registry.py 测试注册 modified 4.37

关键符号

HCXVisionConfig.__init__ HCXVisionConfig.get_text_config

关键源码片段

vllm/transformers_utils/configs/hyperclovax.py core-logic

核心文件,新增 HCXVisionConfig 类,修复 text_config 空初始化问题,是实现兼容性修复的主要修改。

# 文件 : vllm/transformers_utils/configs/hyperclovax.pyfrom transformers import AutoConfig
from transformers.configuration_utils import PretrainedConfig
​
​
class HCXVisionConfig(PretrainedConfig):
    """自带的 HyperCLOVAX 视觉配置类,修复 Transformers v5 兼容性。    上游远程配置在 `text_config=None` 时不初始化 `self.text_config`,
    导致 Transformers v5 的 `@strict` 验证在 `get_text_config()` 中
    抛出 `AttributeError`。本类始终初始化 `self.text_config = None`,
    并提供安全的回退逻辑。
    """
​
    model_type = "hyperclovax_vlm"
    keys_to_ignore_at_inference = ["past_key_values"]
​
    text_config_attribute_map = {
        "n_embd": "hidden_size",
        "n_positions": "max_position_embeddings",
        "n_head": "num_attention_heads",
        "n_layer": "num_hidden_layers",
    }
​
    def __init__(
        self,
        text_config=None,
        vision_config=None,
        use_nth_layer=-2,
        img_start_id=100009,
        decoder_max_length=4096,
        anyres=False,
        unpad=False,
        max_num_grids=-1,
        num_queries_vis_abstractor=-1,
        ignore_index=-100,
        proj_pos_emb=True,
        proj_prenorm=False,
        use_1x1_grid=False,
        **kwargs,
    ):
        # 将 text_config 中的旧属性名映射为新属性名
        for key, val in self.text_config_attribute_map.items():
            if text_config is not None and key in text_config:
                text_config[val] = text_config.pop(key)
​
        # 始终初始化 text_config 为 None,确保 @strict 验证不崩溃
        self.text_config = None
        if text_config is not None:
            _text_config = AutoConfig.for_model(text_config["model_type"])
            self.text_config = _text_config.from_dict(text_config)
            # 直接从已实例化的对象获取 hidden_size,避免映射键被移除后取不到值
            self.hidden_size = self.text_config.hidden_size
​
        self.vision_config = None
        if vision_config is not None:
            _vision_config = AutoConfig.for_model(vision_config["model_type"])
            self.vision_config = _vision_config.from_dict(vision_config)
​
        self.use_nth_layer = use_nth_layer
        self.decoder_max_length = decoder_max_length
        self.anyres = anyres
        self.unpad = unpad
        self.max_num_grids = max_num_grids
        self.num_queries_vis_abstractor = num_queries_vis_abstractor
        self.img_start_id = img_start_id
        self.ignore_index = ignore_index
        self.proj_pos_emb = proj_pos_emb
        self.proj_prenorm = proj_prenorm
        self.use_1x1_grid = use_1x1_grid
        super().__init__(**kwargs)
​
    def get_text_config(self, decoder=False):
        """返回文本子配置;若未设置则回退到视觉配置自身。"""
        if self.text_config is not None:
            return self.text_config
        return self

评论区精华

hidden_size fallback 逻辑缺陷 正确性

Gemini Code Assist bot 指出在 `__init__` 中,属性映射循环从 `text_config` 字典移除了 `n_embd` 键,后续的 `text_config.get("n_embd")` 无法获取值,导致 `self.hidden_size` 的 fallback 无效。建议改为从已实例化的 `self.text_config.hidden_size` 获取。

结论:开发者采纳了建议,最终代码使用 `self.hidden_size = self.text_config.hidden_size`。 · 已解决

风险与影响

风险较低。主要风险包括:

  • 未来冲突:若Transformers官方将来合并HyperCLOVAX配置(见upstream PR #44956),vLLM自带的版本可能与官方版本不一致,需及时移除本次修改(PR已标注TODO)。
  • 注册覆盖:通过AutoConfig.register注册自定义配置类可能影响其他依赖同一model_type的加载路径,但exist_ok=True确保了覆盖安全性。
  • 测试回归:测试仅验证了模型可以初始化,未验证完整推理流程,可能存在更深层兼容问题。

仅影响使用HCXVisionForCausalLM模型(HyperCLOVAX视觉系列)的用户。该修复使模型能在Transformers v5下正常加载,不再受版本限制。对vLLM其他模型无影响,但展示了通用的配置vendoring模式,可作为后续处理类似上游兼容问题的参考。

依赖上游修复 配置冲突风险 迁移待办

关联 Issue

#41250 :rotating_light: Validate config attributes
#44956 Add HyperCLOVAX SEED Think 14B
#45093 AutoConfig.register() ignored when trust_remote_code=True and auto_map is present
#45094 fix: prefer registered config over remote code in AutoConfig.from_pretrained
#38387 [Transformers v5] HCXVisionForCausalLM

完整报告

参与讨论