import transformers spends 1-3 s in an eager importlib.metadata.packages_distributions() when torch >= 2.14 is installed (Python 3.12)

安装 torch 2.14 及以上版本(其 .dist-info 已不再包含 top_level.txt )时, import transformers 会在模块导入阶段同步执行 importlib.metadata.packages_distributions() ,触发对每个 RECORD 文件

快速结论:安装 torch 2.14 及以上版本(其 .dist-info 已不再包含 top_level.txt)时,import transformers 会在模块导入阶段同步执行 importlib.metadata.packages_distributions(),触发对每个 RECORD 文件的 Path.exists() 扫描,导致额外 1–3 秒的启动耗时。优先排查 torch 版本与顶层 packages_distributions() 的耗时。

适用环境:Issue 报告的测量环境为 Windows 11、Python 3.12.10、torch 2.14.0+cu130、transformers 5.17.0,共 152 个已安装分发(其中 71 个缺少 top_level.txt,约 29k 行 RECORD)。其他平台/Python 版本未见明确验证。

最快修复方案:暂无确认的一步修复方案。Issue 中提出的方向是:将模块级的 PACKAGE_DISTRIBUTION_MAPPING 改为惰性计算并缓存的访问器(如 functools.cache),对应的 PR #49612 已提交待审,但 Issue 讨论链中未显示其合并或正式发布。

注意事项:该改动只消除 transformers 侧导入时的 RECORD 扫描,并不会改变 torch 侧缺少 top_level.txt 的事实;相关上游 pytorch 问题 #201346 已标记完成,后续 torch 轮子可能降低该开销,但 Issue 未确认新版本的实际效果。PR #49612 的合并状态需自行核实,不要直接套用未发布的补丁。

问题场景

用户在使用 Transformers(import transformers)时发现导入变慢。在安装 torch 2.14.0 及更高版本、且 Python 为 3.12 的环境中,单个 import transformers 可能耗时数秒,其中约 1.9 秒来自包分发映射的构建。该开销发生在任何脚本、WebUI 或模型加载代码执行之前,属于纯导入期开销。

报错原文

import transformers spends 1-3 s in an eager importlib.metadata.packages_distributions() when torch >= 2.14 is installed (Python 3.12)

原因分析

最可能的原因是 src/transformers/utils/import_utils.py(main 分支第 51 行)在模块导入时立即构建 PACKAGE_DISTRIBUTION_MAPPING = importlib.metadata.packages_distributions()。自 torch 2.14 起,其 .dist-info 不再包含 top_level.txt,Python 3.12 的标准库只能从 RECORD 文件推断顶层包名:packages_distributions → _top_level_inferred → dist.files,并对 RECORD 的每一行执行一次 Path.exists()。torch 2.14 的 RECORD 约有 14.7k 行,实测会触发约 29k 次 os.stat 调用,其中 torch 自身约占 0.9 秒。

由于 #48615 之后 _is_package_available 已可在候选包名下回退到 importlib.metadata.version(),该映射更像是提示性的信息,而非唯一来源,因此 Issue 提议改为惰性缓存的访问器。

环境排查

  • 确认 Python 版本是否为 3.12(Issue 的推断逻辑依赖 Python 3.12 标准库行为)。
  • 确认已安装的 torch 版本是否为 2.14.0 或更高,并检查其 .dist-info 目录是否缺少 top_level.txt(Issue 确认 2.14.0+cu130 仅有 INSTALLER、METADATA、RECORD、REQUESTED、WHEEL、direct_url.json、entry_points.txt 及许可证文件)。
  • 确认 transformers 版本(Issue 实测为 5.17.0)。
  • 统计已安装分发数量,特别是缺少 top_level.txt 的分发数量;它们会各自触发 RECORD 扫描。
  • CUDA 版本、显卡型号在 Issue 中未作为变量说明,不构成排查项。

解决步骤

  1. 先定位耗时来源:在目标环境单独测量 importlib.metadata.packages_distributions() 的耗时,再用 cProfile 确认 os.stat 调用次数是否集中在 torch 的 RECORD 扫描上。
  2. 若确认耗时来自该映射构建,可优先尝试跟踪 PR #49612 的进展:该 PR 将模块级映射改为带 functools.cache 的 get_package_distribution_mapping() 访问器,并为向后兼容增加模块级 __getattr__。
  3. 关注 torch 上游:pytorch/pytorch#201346 已标记完成,Issue 推测后续 torch 轮子可能恢复或降低该开销;可优先尝试升级到修复后的 torch 版本,并重新计时验证。
  4. 在上述方案落地前,不要自行修改 import_utils.py 的模块级调用,除非你已评估过直接引用 PACKAGE_DISTRIBUTION_MAPPING 的代码路径(包括 flash-attn 相关检查)。

验证方法

在冷/热缓存下多轮计时 import transformers,并与单独计时 importlib.metadata.packages_distributions() 的结果对照;用 cProfile 确认导入期不再出现由 RECORD 扫描产生的大量 os.stat 调用(平台相关,Windows 上表现为文件状态检查开销)。若应用 PR #49612 或升级 torch,需确认原有依赖该映射的 flash-attn 可用性检查行为未发生回退。

参考来源

huggingface/transformers #49591

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 31479

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注