Prhub

#2566 fix: use wandb.sdk.lib.runid.generate_id for the wandb group suffix

原始 PR 作者 Shi-Dong 合并时间 2026-08-16 04:12 文件变更 1 提交数 2 评论 0 代码增减 +2 / -1

执行摘要

wandb 组后缀改用 sdk 内部 generate_id 修复启动崩溃

PR body 明确指出:每个带 --use-wandb 启动的 run 在较新 wandb 构建上都会在 startup 期间崩溃,报错 AttributeError: module 'wandb.util' has no attribute 'generate_id'。崩溃发生在 init_tracking 内部、任何模型或 checkpoint 加载之前,Ray job 一分钟内死亡,并且外层 CalledProcessError 让问题看起来像 launcher 或参数问题而非依赖不匹配。由于 args.wandb_random_suffix 是 examples/ 启动器的默认路径,实际上所有 wandb 跟踪的训练在安装较新 wandb 的镜像上都会被阻断。

值得快速阅读:这是一个小而典型的「依赖内部 API 漂移导致启动崩溃」修复案例,展示了如何精准定位隐性问题并验证行为兼容。值得关注的设计点是作者刻意不把 wandb 版本 pin 捆绑进紧急修复,而是留作单独决策。建议后续跟进:为 wandb_utils 增加针对 init_wandb_primary group 生成的测试,并考虑在 pyproject.toml 中约束 wandb 版本下限。

讨论亮点

该 PR 没有实质性的 review 讨论线程(review_comments_count 为 0)。审核方面:nblintao 与 Zhichenzzz 均 APPROVED。claude[bot] 仅发布了一条仓库配置提示,说明该仓库配置为人工 review,与本次变更无关。PR body 中包含一个有价值的权衡说明:是否在 pyproject.toml / uv.lock 中固定 wandb 版本是作者有意排除在外的后续事项,避免把版本选型决策混入这个紧急修复。

实现拆解

实现分为两步:

  1. 替换导入路径:在 miles/utils/tracking_utils/wandb_utils.py 顶部将 import wandb 后增加 from wandb.sdk.lib.runid import generate_id,将不再公开的 wandb.util.generate_id 替换为 wandb SDK 内部仍存在的 wandb.sdk.lib.runid.generate_id
  2. 替换调用点:在 init_wandb_primary 中构造 group 名称时,将 group = args.wandb_group + "_" + wandb.util.generate_id() 改为 group = args.wandb_group + "_" + generate_id(),保持 8 字符随机后缀的行为不变。

配套情况:

  • 测试:无直接对应测试文件变更;PR body 说明了验证方式——在 wandb 0.28.2 镜像上检查了函数签名与输出 charset,并在 8x H200 实跑中确认修复生效。
  • 配置:未在 pyproject.toml / uv.lock 中固定 wandb 版本,PR body 明确将其留作后续单独决策。
  • 该修改是纯依赖 wiring 变更,不影响其他模块;grep 确认这是仓库内唯一的 wandb.util 引用。
文件 模块 状态 重要度
miles/utils/tracking_utils/wandb_utils.py 跟踪工具 modified 5.56

关键符号

init_wandb_primary

关键源码片段

miles/utils/tracking_utils/wandb_utils.py dependency-wiring

这是唯一变更文件,也是 wandb 初始化的核心逻辑所在。修复将不再公开的 wandb.util.generate_id 替换为 wandb.sdk.lib.runid.generate_id,直接解除所有 --use-wandb 任务在启动阶段的崩溃。

# miles/utils/tracking_utils/wandb_utils.py
import logging
import os
from copy import deepcopyimport wandb
# 直接导入 sdk 内部的 runid helper:wandb.util.generate_id 在 0.28.2 已不再公开,
# 新路径的签名 (length: int = 8) -> str 与输出字符集与旧 helper 完全一致
from wandb.sdk.lib.runid import generate_idfrom miles.utils.env_report import decode_env_reportlogger = logging.getLogger(__name__)
​
​
def init_wandb_primary(args):
    if not args.use_wandb:
        args.wandb_run_id = None
        return
​
    # W&B 模式优先级:命令行参数 > 环境变量
    if args.wandb_mode:
        os.environ["WANDB_MODE"] = args.wandb_mode
​
    offline = _is_offline_mode(args)
​
    # 非 offline 模式下才做显式 login
    if (not offline) and args.wandb_key is not None:
        wandb.login(key=args.wandb_key, host=args.wandb_host)
​
    # 生成 group 后缀:每个 run 追加 8 位随机串,便于按 run 区分同一 group
    if args.wandb_random_suffix:
        group = args.wandb_group + "_" + generate_id()
        run_name = f"{group}-RANK_{args.rank}"
    else:
        group = args.wandb_group
        run_name = args.wandb_group
​
    init_kwargs = {
        "entity": args.wandb_team,
        "project": args.wandb_project,
        "group": group,
        "name": run_name,
        "config": _compute_config_for_logging(args),
    }
​
    if offline:
        init_kwargs["settings"] = _wandb_settings(mode="offline")
    else:
        init_kwargs["settings"] = _wandb_settings(mode="shared", x_primary=True)
​
    if args.wandb_dir:
        os.makedirs(args.wandb_dir, exist_ok=True)
        init_kwargs["dir"] = args.wandb_dir
​
    wandb.init(**init_kwargs)
    _init_wandb_common()

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

低风险,但需注意几点:

  1. 依赖内部 API 的脆弱性wandb.sdk.lib.runid.generate_id 属于 wandb SDK 内部模块路径,不在公共 API 承诺范围内,未来 wandb 仍可能再次移动或移除该 helper,问题存在复发可能。
  2. 无测试覆盖:本次改动没有新增或修改测试,缺少对 init_wandb_primary 中 group 后缀生成的回归保护;如果 wandb 再次变动 API,CI 无法拦住。
  3. 版本未固定:pyproject.toml / uv.lock 未 pin wandb 版本,下一次 base image 重建仍可能安装到不兼容版本,属于 PR body 明确承认的遗留风险。
  4. 改动本身仅 2 行,行为保持兼容(相同签名与输出格式),对现有运行无回归风险。

影响范围:所有使用 --use-wandb 且启用 --wandb-random-suffix(examples 启动器默认路径)的训练任务,在升级 wandb 后的镜像上会从启动即崩溃恢复为正常初始化。修复后 group 命名规则完全不变(原 group 名 + 下划线 + 8 位字母数字),dashboard 或日志中的 run 分组不受影响。对团队而言,这是一个消除隐性问题表象(CalledProcessError 误导向 launcher/参数问题)的关键修复,减少排障时间。

依赖内部 API 无测试覆盖 版本未固定

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论