一次训练迭代可能产生多次观测:损失、评估回报,以及随后修正的指标。把每次写入当成新迭代会打乱实验对齐,丢弃重复步又会损失信息。强化学习与演化学习框架 EvoRL 于北京时间 2026 年 11 月 12 日将本地 JSONL 记录功能合入 main,并在 11 月 13 日完成文件名后续调整。两次更新共同提供原始写入记录,以及独立的、按训练步对齐的分析视图。

概念插画:保留每次观测,按训练步整理合并后的视图。
让本地文件带上实验上下文
选择 recorders=[log,jsonl],即可在普通日志旁保存机器可读指标,无需额外的追踪服务 SDK。版本化快速入门文档说明了训练脚本共用的记录器配置,因此 JSONL 后端会收到项目、运行名称、解析后的配置、标签、输出路径和可选分组。
初始化时,这些上下文会写入元数据头。此后每次写入都会追加一个包含所提供整数 step 和嵌套 data 的 JSON 对象,并刷新文件缓冲区。原始文件保留到达顺序,包括乱序的训练步和重复写入。把实验输出目录移到独立分析机器时,配置与观测可以随同一个可读的本地文件一起转移。
读取时合并,记录时保留
从 evorl.recorders 导出的 load_jsonl_records(path) 会读取完整数据集,返回按训练步排序的列表。它递归合并同一步的字典:后续写入替换冲突值,未提及的指标保持不变。数组整体替换,后续 null 也会覆盖旧值。加载器跳过可选的首行元数据头,不把它放入指标列表。
例如,在第 10 步分别写入训练损失和评估回报,之后再修正该步的损失。原始文件保留全部三次写入;加载后的记录包含最新损失和原有评估回报。即使第 8 步记录更晚到达,排序后仍在第 10 步之前。这直接影响学习曲线:迭代身份由 step 决定,而不是文件行号或日志调用次数。
明确序列化会保留什么
实现及回归测试覆盖 NumPy、JAX 和 pandas 值。数组和 Series 转为列表;DataFrame 保留列和行数据,但不保留索引。NaN、无穷值及 pandas 缺失值转为 JSON null。如果 DataFrame 索引用于标识样本,应先将其转成显式列;这是由实际保存的表格结构决定的。
格式错误或不完整的行会触发带文件名和行号的错误,加载器不会默默丢弃被截断的末条记录。它会将完整数据集加载到内存,因此分析内存应按累积文件规模规划。应用自身名为 step 的指标仍保留在 data 内,与记录器外层的迭代字段区分。
每次运行使用独立目标路径
后续调整让 JSONL 和脚本创建的日志文件共用 sanitize_filename。它将 / 替换为 _,例如 MetaWorld/Hammer-v3 变成 MetaWorld_Hammer-v3。其他字符不变,元数据保留原始运行名称。两种文件分别使用 .jsonl 和 .log 扩展名。这取代了首次提交的百分号编码规则;文件名规范化并不保证唯一性。
重新初始化相同 JSONL 文件路径会覆盖原有内容。每次运行应使用独立输出目录或文件名,尤其要注意仅以斜杠和下划线区分的名称。在包含这两次提交的源码检出版本上使用上述配置,先加载一个小实验,检查元数据头、重复步合并结果和输出位置,再开展长时间运行。此前的 EvoRL 开发报道介绍了梯度、设备和指标形状的背景;本次更新让这些观测更容易在本地留存和重新分析。