Prhub

#50285 [Refactor] Remove multiple dead codes

原始 PR 作者 yewentao256 合并时间 2026-08-03 22:59 文件变更 22 提交数 6 评论 5 代码增减 +1 / -405

执行摘要

跨 22 文件清理 405 行死代码,覆盖模型、量化与编译模块

PR 描述只有一句 Purpose Remove multiple dead codes,没有关联 Issue。从 patch 看,被删符号均已在仓库内无任何调用方:ScaledActivation 是 AWQ 时代的激活后缩放组件,SkyworkR1VDummyInputsBuilder 与 InternVL 基类实现逐行一致,CopyNumelCounter 的 copy_ 计数已不再被引用。清理目标是消除历史遗留冗余、降低维护噪音,并精简模块 import 依赖,而非修复具体缺陷。

值得快速精读,作为大规模死代码清理的标准参考:重点关注 hmellor 的拦截点(deprecation 工具保留)与作者在两个模型文件间同步清理重复方法的协作方式。如果团队有 agent 或自动审计流程,可以顺带落实「保护废弃兼容工具」的规则,避免未来误删。

讨论亮点

hmellor(vllm/config/utils.py):This one is useful to keep around for future deprecations——拦截了对 handle_deprecated 的误删;作者回复 OK get it back now 并在 commit fc5d7a8 中恢复。

hmellor(llava_onevision2.py):This method also exists in vllm/models/minimax_m3/common/mm_preprocess.py, should it be deleted from there too?——作者回复 Done,同步删除了重复实现。

hmellor:I wonder if it's worth adding something to our agents files to protect deprecation utilities during dead code audits?——提出用 agent 规则保护 deprecation 工具,本次未落地。

最后 hmellor 批准时补充 maybe one other method that can be deleted,未展开。关键结论:死代码清理应区分「死代码」与「承担兼容职责的工具」,后者需要保留。

实现拆解

  1. 模型层批量清理(约 14 个文件):删除 vllm/model_executor/layers/activation.py 的 ScaledActivation 及其依赖的 Tensor 并行分片导入;layers/conv.py 删除 CausalConv2dLayer 自定义因果 padding 封装;layers/quantization/fp8.py 删除 CopyNumelCounter(TorchDispatchMode 子类)与相关 import;models/nemotron_parse.py 删除 BartParallelLMHead;models/glm_ocr.py 清理 GlmOcrVisionPatchEmbed 残留;models/skyworkr1v.py 删除与基类重复的 SkyworkR1VDummyInputsBuilder,注册直接复用 BaseInternVLDummyInputsBuilder;models/idefics3.py、models/phi4mm.py、models/phi4mm_utils.py、models/vision.py、models/llava_onevision2.py、models/minimax_m3/common/mm_preprocess.py 等同步移除 _resize_output_size、cat_with_pad、get_llm_pos_ids_for_vision、_get_data_parser 等工具函数。
  2. 基础设施与编译路径清理:vllm/v1/core/kv_cache_utils.py 删除 need_extra_keys 与 is_kv_cache_page_size_uniform,块哈希与页面统一逻辑收敛到保留函数内部或调用方;vllm/compilation/passes/fx_utils.py 删除 is_auto_func、find_getitem、get_only_user 三个 fx 图工具;vllm/compilation/passes/vllm_inductor_pass.py 删除调试用途的 PrinterInductorPass。
  3. 入口与工具函数清理:vllm/entrypoints/chat_utils.py 删除 get_history_tool_calls_cnt;vllm/profiler/utils.py 删除 trim_string_front;vllm/utils/multi_stream_utils.py 清理无用枚举 AuxStreamType;vllm/model_executor/models/utils.py 删除 isin_list;layers/utils.py 删除 is_layer_moe_router_gate。
  4. 评审修正:vllm/config/utils.py 的 handle_deprecated 首次被列入删除名单,hmellor 指出它对未来 deprecation 仍有用,作者在后续 commit 中恢复;同时按 hmellor 建议追加删除 minimax_m3/common/mm_preprocess.py 中与 llava_onevision2 重复的 _get_data_parser。
  5. 测试与配套:本次无新增测试文件,也不涉及配置、schema 或部署改动;正确性依赖现有 CI(含模型回归与编译测试)以及删除前对全仓库引用的验证。
文件 模块 状态 重要度
vllm/model_executor/layers/activation.py 激活层 modified 8.3
vllm/model_executor/layers/conv.py 卷积层 modified 7.81
vllm/model_executor/models/skyworkr1v.py 视觉语言模型 modified 7.36
vllm/model_executor/layers/quantization/fp8.py 量化 modified 7.21
vllm/v1/core/kv_cache_utils.py KV 缓存 modified 7.1
vllm/compilation/passes/fx_utils.py 编译优化 modified 6.89
vllm/model_executor/models/idefics3.py 多模态模型 modified 6.56
vllm/model_executor/models/vision.py 视觉编码 modified 6.38

关键符号

ScaledActivation CausalConv2dLayer SkyworkR1VDummyInputsBuilder CopyNumelCounter need_extra_keys is_kv_cache_page_size_uniform BartParallelLMHead is_auto_func find_getitem get_only_user _resize_output_size cat_with_pad get_llm_pos_ids_for_vision PrinterInductorPass isin_list get_history_tool_calls_cnt trim_string_front is_layer_moe_router_gate _get_data_parser AuxStreamType

关键源码片段

vllm/model_executor/layers/activation.py data-contract

删除 ScaledActivation 类及 Tensor 并行相关导入(48 行),是本次最大的单点删除,涉及 AWQ 量化历史引用路径,也是公共符号删除风险最高的文件之一。

# vllm/model_executor/layers/activation.py
# PR #50285 移除了 ScaledActivation 类及其配套的 Tensor 并行导入:
# 它曾经用于 AWQ 等量化方法,在激活后除以 per-partition 的 scales,
# 并依赖 vllm.distributed 的 divide 与 rank/world_size 做切分。
# 全仓库已无任何模块引用它,因此同时清掉了这些导入依赖。
# 下方是保留的激活函数注册表,注册方式不受影响。
​
_ACTIVATION_REGISTRY = LazyDict(
    {
        "gelu": lambda: GELU(),
        "gelu_fast": lambda: FastGELU(),
        "gelu_new": lambda: NewGELU(),
        "gelu_pytorch_tanh": lambda: _get_gelu_pytorch_tanh(),
        "relu": lambda: nn.ReLU(),
        "relu2": lambda: ReLUSquaredActivation(),
        "silu": lambda: nn.SiLU(),
        "swish": lambda: nn.SiLU(),
        "quick_gelu": lambda: QuickGELU(),
        "tanh": lambda: nn.Tanh(),
        "sigmoid": lambda: nn.Sigmoid(),
        "xielu": lambda: XIELU(),
    }
)
vllm/model_executor/models/skyworkr1v.py data-contract

删除与 InternVL 基类完全重复的 SkyworkR1VDummyInputsBuilder(+1/-31),注册改为直接使用 BaseInternVLDummyInputsBuilder,示例了多模态 dummy 输入构建的统一化。

# vllm/model_executor/models/skyworkr1v.py
# 原先这里定义了一个局部类 SkyworkR1VDummyInputsBuilder,其
# get_dummy_text 返回 "<image>" * num_images,get_dummy_mm_data 则委托
# self._get_dummy_images(...) 构造占位图;这些实现与 InternVL 的
# BaseInternVLDummyInputsBuilder 完全一致,属于冗余复制。
# PR #50285 删除该类后,注册处理器时直接复用 InternVL 基类实现。
​
@MULTIMODAL_REGISTRY.register_processor(
    BaseInternVLMultiModalProcessor,
    info=SkyworkR1VProcessingInfo,
    dummy_inputs=BaseInternVLDummyInputsBuilder,
)
class SkyworkR1VChatModel(nn.Module, SupportsMultiModal, SupportsPP):
    """Skywork R1V 聊天模型,处理流程与 InternVL 复用同一套
    处理器与占位输入构造逻辑。"""
vllm/v1/core/kv_cache_utils.py core-logic

删除 need_extra_keys 与 is_kv_cache_page_size_uniform 两个核心工具函数(34 行),涉及前缀缓存哈希与 KV 页面统一逻辑的收敛。

# vllm/v1/core/kv_cache_utils.py
# PR #50285 删除了两个已无调用方的工具函数:
# - need_extra_keys(request):判定块是否需要附加 MM / LoRA /
# cache_salt 哈希键,调用方已改为内联等价判断;
# - is_kv_cache_page_size_uniform(spec):各层页面大小一致性判断,
# 统一逻辑已收敛到下面的 unify_kv_cache_spec_page_size。
# 下方保留函数是页面大小统一的核心入口。
​
def unify_kv_cache_spec_page_size(
    kv_cache_spec: dict[str, KVCacheSpec],
) -> dict[str, KVCacheSpec]:
    page_sizes = {layer.page_size_bytes for layer in kv_cache_spec.values()}
    if len(page_sizes) <= 1:
        # 所有层页面大小一致,无需统一,直接返回原 spec
        return kv_cache_spec
​
    max_page_size = max(page_sizes)
    new_kv_cache_spec = {}
    for layer_name, layer_spec in kv_cache_spec.items():
        if layer_spec.page_size_bytes == max_page_size:
            new_kv_cache_spec[layer_name] = layer_spec
        # 其余分支:优先扩大较小页面的 block size;
        # Mamba 状态页与 strided 视图后端则走物理页填充路径

评论区精华

handle_deprecated 不应被当作死代码删除 设计

hmellor 在 vllm/config/utils.py 评论 `This one is useful to keep around for future deprecations`,认为该工具承担未来废弃兼容职责,属于容易在死代码审计中被误伤的公共工具。

结论:作者接受意见,在 commit fc5d7a8 中恢复 handle_deprecated,删除名单剔除该符号。 · 已解决

重复的 _get_data_parser 是否同步清理 question

hmellor 指出 llava_onevision2.py 中被删的 _get_data_parser 在 vllm/models/minimax_m3/common/mm_preprocess.py 也存在同构实现,询问是否一并删除。

结论:作者回复 `Done`,minimax_m3 的 _get_data_parser 也被移除。 · 已解决

用 agent 规则保护 deprecation 工具 other

hmellor 提议在 agent 配置中加保护规则,避免未来自动审计再次误删 deprecation 工具;作者未明确回复。

结论:开放建议,本次未落地。 · 待处理

风险与影响

  1. 公共符号删除风险:ScaledActivation、CausalConv2dLayer 位于 vllm/model_executor/layers 常用子包,虽非 vLLM 承诺的公开 API,但外部模型插件或定制脚本可能直接 import;删除后这类外部引用会立即 ImportError,仓库内已验证无调用,但无法覆盖外部依赖。
  2. 配置分支覆盖不足:fp8.py 的 CopyNumelCounter 服务于 FP8 checkpoint 权重加载路径,kv_cache_utils.py 的 need_extra_keys 服务于 MM / LoRA / cache_salt 前缀缓存哈希路径,若相关逻辑只在特定模型与运行时组合下触发,而本次无新增测试,回归只能依赖现有 CI 覆盖。
  3. 编译 pass 工具不可复得:fx_utils.py 删除的 get_only_user、is_auto_func 若未来 Inductor pass 需要重建,只能从 git 历史恢复,删除时没有留下替代实现。

对最终用户无功能影响(纯删除、无行为变化);对依赖内部类的外部扩展存在兼容性影响。系统层面 import 图更精简,activation.py 不再依赖 vllm.distributed,conv.py 移除一层自定义 padding 封装,轻微改善模块导入开销。团队层面,22 个文件的瘦身降低后续阅读与搜索噪音,并积累了「死代码审计需保护 deprecation 工具」的评审经验。

公共符号删除 缺少测试配套 多模块跨面广

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论