Prhub

#7740 [training_utils] fix: finalize MLflow run on finish to record end time

原始 PR 作者 harryge00 合并时间 2026-09-07 10:43 文件变更 3 提交数 1 评论 0 代码增减 +33 / -0

执行摘要

修复 MLflow 运行结束记录,确保 UI 显示正确的结束时间和持续时间。

PR body 明确指出动机:verl 使用裸的 mlflow.start_run()(非上下文管理器形式)启动 MLflow 运行,如果没有显式调用 mlflow.end_run(),运行将停留在 RUNNING 状态,UI 显示结束时间和持续时间为 (unknown)。

该 PR 修复了一个具体且影响用户体验(监控)的 bug,改动小而聚焦,测试覆盖完整,风险低。建议精读,以了解日志后端(特别是 MLflow)生命周期管理的实现细节,以及如何为类似后端添加 finish 支持。

讨论亮点

本次 PR 未提供具体的代码评审讨论内容,仅包含一个审批(APPROVED)。因此,没有讨论亮点可提炼。

实现拆解

  1. 在 Tracking.finish() 中增加 MLflow 后端处理:在 verl/utils/tracking.py 的 Tracking.finish() 方法中,增加对 "mlflow" 键的检查与处理,调用其 finish() 方法。这遵循了同一方法中对 wandb、tensorboard 等其他后端的统一关闭模式,确保所有日志后端都能被正确终止。
  2. 为 _MlflowLoggingAdapter 类添加 finish() 方法:在 verl/utils/tracking.py 中,为 _MlflowLoggingAdapter 类新增一个 finish() 方法。该方法会检查 mlflow.active_run() 是否返回一个非 None 值(即是否有活动的运行),若有则调用 mlflow.end_run()。此守卫逻辑确保了调用安全性,避免在无活动运行时抛出异常。
  3. 添加单元测试覆盖:在两个测试文件中添加了三个测试用例,以验证新功能的正确性。tests/utils/test_mlflow_key_sanitization.py 中新增了两个测试,分别验证当有活动运行和无活动运行时,_MlflowLoggingAdapter.finish() 的行为是否正确。tests/utils/test_tracking_on_cpu.py 中新增了一个测试,验证 Tracking.finish() 能够正确且仅一次地调用 MLflow 适配器的 finish() 方法。这些测试被已有的 CI 工作流收集,无需额外配置。
文件 模块 状态 重要度
verl/utils/tracking.py 日志工具 modified 6.23
tests/utils/test_mlflow_key_sanitization.py MLflow 测试 modified 5.4
tests/utils/test_tracking_on_cpu.py 跟踪测试 modified 4.9

关键符号

Tracking.finish _MlflowLoggingAdapter.finish

关键源码片段

verl/utils/tracking.py core-logic

核心变更文件,集成了 MLflow 后端的关闭逻辑。

    def finish(self, exit_code: int = 0):
        """Flush and finalize every configured backend exactly once."""
        # 防止重复执行的幂等性守卫
        if getattr(self, "_finished", False):
            return
        self._finished = True
        loggers = getattr(self, "logger", {})
​
        # 其他后端处理 ...
        if "clearml" in loggers:
            loggers["clearml"].finish()
        # 新增:处理 mlflow 后端的关闭
        if "mlflow" in loggers:
            loggers["mlflow"].finish()
        if "trackio" in loggers:
            loggers["trackio"].finish()
        # ... 后续其他后端处理

评论区精华

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

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

风险与影响

风险较低。变更限于日志后端的生命周期管理,不影响训练核心逻辑。主要风险点在于 mlflow.end_run() 的调用可能在某些极端边缘情况下(如进程被强制终止)未执行,但当前实现已通过 Tracking.__del__ 方法进行了兜底,整体风险可控。新增的单元测试进一步降低了回归风险。

对用户的影响是积极的。所有配置了 trainer.logger=["console", "mlflow"] 的用户,在训练任务正常结束(或 Tracking 对象被销毁)后,其 MLflow UI 中的运行状态将正确显示为 FINISHED,并记录准确的结束时间和运行时长。此变更无需用户修改任何配置。对系统的影响是增强了 MLflow 集成的健壮性和可观测性。对团队的影响是修复了一个影响 MLflow 监控准确性的具体 bug,使得基于 MLflow 的训练监控更加可靠。

边缘 case 依赖 `__del__`

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论