🤖 roboto_origin_03 Wiki
首页 / RSL-RL / 日志系统与可视化集成

在强化学习的训练过程中,算法需要数小时甚至数天才能收敛。如果没有系统化的日志记录与可视化手段,开发者将难以判断策略是否在进步、超参数是否合理、或者训练是否早已发散。rsl_rl 的日志系统正是为了解决这一问题而设计:它以统一的接口收集训练指标,支持同时输出到本地控制台与多种可视化后端,并针对分布式训练和多算法变体(如 AMP)进行了专门适配。本文将拆解其核心架构、数据流转路径与配置方法,帮助初学者快速掌握训练监控的完整链路。

架构概览:统一入口与多后端适配

日志系统的顶层入口是 Logger 类,它并不直接操作网络请求或文件写入,而是通过一个符合 SummaryWriter 接口的 writer 对象代理所有持久化操作。这种设计让控制台输出、本地 TensorBoard 事件文件、以及 Weights & Biases (W&B) 或 Neptune 云端实验追踪可以在同一套代码中无缝切换。

LoggerAMP 继承自 Logger,专为对抗动作先验(AMP)算法扩展了风格奖励(style reward)与总奖励(total reward)的追踪能力。而在 writer 层,WandbSummaryWriterNeptuneSummaryWriter 均继承自 PyTorch 原生的 SummaryWriter,形成**“本地 TensorBoard 事件 + 云端实时同步”**的双写模式。下图展示了核心类之间的继承与组合关系。

classDiagram
    class SummaryWriter {
        +add_scalar(tag, value, step)
    }
    class Logger {
        +log_dir
        +cfg
        +writer
        +rewbuffer
        +lenbuffer
        +process_env_step(rewards, dones, extras)
        +log(it, loss_dict, ...)
        +save_model(path, it)
        -_prepare_logging_writer()
        -_store_code_state()
    }
    class LoggerAMP {
        +style_rewbuffer
        +total_rewbuffer
        +process_env_step(... style_rewards, total_rewards)
    }
    class WandbSummaryWriter {
        +store_config(env_cfg, train_cfg)
        +add_scalar(tag, value, step)
        +save_model(path, it)
    }
    class NeptuneSummaryWriter {
        +run
        +store_config(env_cfg, train_cfg)
        +add_scalar(tag, value, step)
        +save_model(path, it)
        -_map_path(path)
    }

    SummaryWriter <|-- WandbSummaryWriter
    SummaryWriter <|-- NeptuneSummaryWriter
    Logger <|-- LoggerAMP
    Logger --> WandbSummaryWriter : writer
    Logger --> NeptuneSummaryWriter : writer
    Logger --> SummaryWriter : writer

Sources: logger.py, wandb_utils.py, neptune_utils.py, amp_logger.py

生命周期:指标如何从环境流向仪表盘

日志系统的生命周期与训练循环紧密耦合,可拆分为环境步级累积迭代级汇总两个阶段。在 OnPolicyRunner.learn() 中,每一次环境交互后都会调用 logger.process_env_step() 将奖励、终止信号和环境附加信息写入内存缓冲;当一整批 Rollout 收集完毕、策略更新完成后,再调用 logger.log() 将缓冲区的统计量一次性输出到控制台并写入可视化后端。这种两阶段设计避免了高频 I/O 对训练吞吐的拖累。

sequenceDiagram
    participant Runner as OnPolicyRunner
    participant Logger as Logger
    participant Env as VecEnv
    participant Writer as SummaryWriter

    loop 每个环境步
        Runner->>Env: step(actions)
        Env-->>Runner: rewards, dones, extras
        Runner->>Logger: process_env_step(rewards, dones, extras)
        Logger->>Logger: 累加 cur_reward_sum / cur_episode_length
        Logger->>Logger: dones>0 时移入 rewbuffer / lenbuffer
    end

    Runner->>Logger: log(it, loss_dict, ...)
    Logger->>Logger: 计算 FPS、ETA 等性能指标
    Logger->>Writer: add_scalar("Loss/...", value, it)
    Logger->>Writer: add_scalar("Train/mean_reward", ..., it)
    Logger->>Runner: 打印格式化日志字符串

当某条环境轨迹终止(dones > 0)时,process_env_step 会把该轨迹的累积奖励与长度从 GPU Tensor 转移到 CPU 的 deque 缓冲中。deque 设置了最大长度 100,这意味着 log() 中汇报的永远是最近 100 个已完成回合的滑动平均,而非全部历史平均值,从而对训练动态变化更加敏感。若启用了 RND(随机网络蒸馏)探索模块,系统还会额外维护外在奖励与内在奖励的独立缓冲。

Sources: logger.py, on_policy_runner.py

多后端对比与配置方式

Logger 在初始化时通过配置字典中的 logger 字段决定实例化哪种 writer。三种可选后端的特性与必要配置如下表所示。

后端 配置键 环境变量/额外依赖 本地事件文件 云端同步 模型保存
TensorBoard logger: "tensorboard" 无(PyTorch 内置) ✅ 是 ❌ 否 ❌ 否
Weights & Biases logger: "wandb" pip install wandb<br>WANDB_USERNAME ✅ 是 ✅ 是 ✅ 是
Neptune logger: "neptune" pip install neptune<br>NEPTUNE_API_TOKEN<br>NEPTUNE_USERNAME ✅ 是 ✅ 是 ✅ 是

无论选择哪种后端,本地都会同时生成 TensorBoard 事件文件,这意味着即使实验结束后云端项目被清理,你依然可以用 tensorboard --logdir 离线查看曲线。W&B 与 Neptune 的 writer 还会在初始化时自动调用 store_config(),将训练配置、策略配置、算法配置以及环境配置同步到云端,确保实验完全可复现。

Sources: logger.py, wandb_utils.py, neptune_utils.py

指标命名空间与含义

log() 方法内部,所有标量指标都按语义分组,使用斜杠分隔的层级命名(如 Loss/value)。初学者在可视化面板中搜索时,可通过前缀快速过滤。以下是各命名空间的标准含义。

命名空间前缀 来源 说明
Loss/* loss_dict 策略损失、价值损失、熵损失等算法原始输出
Loss/learning_rate 优化器 当前迭代的学习率
Policy/mean_noise_std 策略网络 动作分布的平均标准差,反映探索强度
Perf/total_fps 计时器 每秒处理的环境步数
Perf/collection_time 计时器 Rollout 数据收集耗时
Perf/learning_time 计时器 策略更新耗时
Train/mean_reward rewbuffer 最近 100 回合的平均总奖励
Train/mean_episode_length lenbuffer 最近 100 回合的平均长度
Episode/* extras["episode"] 环境自定义的每回合统计量
Rnd/* RND 模块 外在奖励、内在奖励、RND 权重(若启用)
AMP/* LoggerAMP 风格奖励、总奖励(仅 AMP 算法)

特别需要注意的是,Train/mean_reward/timeTrain/mean_episode_length/time 使用 tot_time(总训练秒数)作为横轴,而非迭代次数,这有助于在对比不同批量大小或不同机器上的实验时,消除迭代速度差异带来的视觉扭曲。W&B 后端由于自身机制限制,暂不提供以时间为横轴的曲线。

Sources: logger.py, amp_logger.py

分布式训练下的日志去重

在多 GPU 分布式训练中,rsl_rl 使用 torch.distributed 启动多个进程,每个进程拥有独立的 Logger 实例。若所有进程同时写入同一个 W&B 项目或同一组 TensorBoard 文件,会导致数据重复、曲线混乱。因此 Logger 在初始化时检查 is_distributedgpu_global_rank仅当全局 rank 为 0 的主进程启用日志写入,其余进程的 disable_logs 被设为 True,其 writer 为空,所有 add_scalar 与文件操作均被跳过。控制台打印同样受此保护,确保终端输出不会被打乱。

Sources: logger.py, on_policy_runner.py

代码版本追踪:自动记录 Git 差异

可复现性不仅依赖超参数,还取决于代码版本。Logger 在初始化时会调用 _store_code_state(),自动探测 rsl_rl 包所在的 Git 仓库(也支持通过 add_git_repo_to_log() 追加用户项目仓库),将 git statusgit diff 输出到日志目录下的 git/*.diff 文件中。若使用 W&B 或 Neptune,这些 diff 文件还会被自动上传为实验附件,让你在数月后依然能精确还原实验时的代码状态。

Sources: logger.py, on_policy_runner.py

AMP 专用日志扩展

AMP(Adversarial Motion Prior)算法除了常规奖励外,还引入了风格奖励(衡量与参考动作相似度)和总奖励(任务奖励与风格奖励的插值)。LoggerAMP 继承 Logger 后重写了 process_env_step(),额外接收 style_rewardstotal_rewards 参数,并在每个回合结束时将其存入 style_rewbuffertotal_rewbuffer。在 log() 中,这两个缓冲区的均值被写入 AMP/mean_style_rewardAMP/mean_total_reward,帮助开发者观察策略在“完成任务”与“模仿参考动作”之间的权衡。

AMPRunner 在训练循环中负责从算法对象提取这两种奖励并传递给日志器,因此使用 AMP 算法的用户无需手动干预即可获得完整的 AMP 监控面板。

Sources: amp_logger.py, amp_runner.py

下一步

掌握了日志系统的结构后,你可以继续了解训练运行器如何管理整体生命周期,或者探索模型如何在训练中被保存与恢复,以便将日志曲线与具体检查点对应起来。