news 2026/9/21 20:43:42

Ray Tune 自定义训练函数中的检查点机制:tune.report 与 Checkpoint 的完整实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Ray Tune 自定义训练函数中的检查点机制:tune.report 与 Checkpoint 的完整实践

Ray Tune 自定义训练函数中的检查点机制:tune.report 与 Checkpoint 的完整实践

【免费下载链接】rayRay is an AI compute engine. Ray consists of a core distributed runtime and a set of AI Libraries for accelerating ML workloads.项目地址: https://gitcode.com/gh_mirrors/ra/ray

本文以 Ray 仓库中的示例脚本 custom_func_checkpointing.py(由文档片段 custom_func_checkpointing.rst 通过literalinclude直接引入)为主线,讲解如何在不使用 PyTorch/TensorFlow 等官方集成、仅使用纯 Python 自定义训练函数的情况下,通过ray.tune.report(metrics, checkpoint=...)API 实现断点保存与恢复(resume),并结合 trainable_fn_utils.py 与 Checkpoint 类实现 说明其底层机制。读完后你将掌握:自定义训练函数中检查点的写入与读取方式、Checkpoint对象的目录语义,以及Tuner层面超参搜索配置的完整可运行代码。

核心思路:用tune.report(checkpoint=...)报告检查点

当训练逻辑是自定义函数(而非 Ray 的 PyTorch/TF 等集成)时,Tune 无法替你感知训练状态,因此需要你主动做两件事:

  1. 写入:在训练循环中周期性地把状态(如当前 step、模型权重)序列化到一个目录中,然后通过tune.report(..., checkpoint=Checkpoint.from_directory(...))交给 Tune 持久化;
  2. 恢复:在训练函数入口处调用tune.get_checkpoint()获取最近一次已报告的检查点,反序列化后从断点继续。

示例完整代码如下(来自 custom_func_checkpointing.py):

import argparse import json import os import tempfile import time from ray import tune from ray.tune import Checkpoint def evaluation_fn(step, width, height): time.sleep(0.1) return (0.1 + width * step / 100) ** (-1) + height * 0.1 def train_func(config): step = 0 width, height = config["width"], config["height"] checkpoint = tune.get_checkpoint() if checkpoint: with checkpoint.as_directory() as checkpoint_dir: with open(os.path.join(checkpoint_dir, "checkpoint.json")) as f: state = json.load(f) step = state["step"] + 1 for current_step in range(step, 100): intermediate_score = evaluation_fn(current_step, width, height) with tempfile.TemporaryDirectory() as temp_checkpoint_dir: with open(os.path.join(temp_checkpoint_dir, "checkpoint.json"), "w") as f: json.dump({"step": current_step}, f) tune.report( {"iterations": current_step, "mean_loss": intermediate_score}, checkpoint=Checkpoint.from_directory(temp_checkpoint_dir), ) if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument( "--smoke-test", action="store_true", help="Finish quickly for testing" ) args, _ = parser.parse_known_args() tuner = tune.Tuner( train_func, run_config=tune.RunConfig( name="hyperband_test", stop={"training_iteration": 1 if args.smoke_test else 10}, ), tune_config=tune.TuneConfig( metric="mean_loss", mode="min", num_samples=5, ), param_space={ "steps": 10, "width": tune.randint(10, 100), "height": tune.loguniform(10, 100), }, ) results = tuner.fit() best_result = results.get_best_result() print("Best hyperparameters: ", best_result.config) best_checkpoint = best_result.checkpoint print("Best checkpoint: ", best_checkpoint)

脚本支持--smoke-test命令行参数:传入后stop中的training_iteration从默认的 10 降为 1,便于快速验证流水线。

train_func的恢复逻辑:tune.get_checkpoint()的语义

训练函数开头的关键代码是:

checkpoint = tune.get_checkpoint() if checkpoint: with checkpoint.as_directory() as checkpoint_dir: with open(os.path.join(checkpoint_dir, "checkpoint.json")) as f: state = json.load(f) step = state["step"] + 1

从源码结构看,trainable_fn_utils.py 中get_checkpoint()的实现是:

@PublicAPI(stability="stable") @_warn_session_misuse() def get_checkpoint() -> Optional[Checkpoint]: """Access the latest reported checkpoint to resume from if one exists.""" return get_session().loaded_checkpoint

即它返回的是当前 Train 会话(session)中最近加载的检查点;首次运行时没有任何历史检查点,返回None,训练函数从step = 0开始。当实验因故障恢复或断点续跑时,Tune 会把上一次报告的检查点装载进会话——这一点在 function_trainable.py 中可以看到闭环:

session.loaded_checkpoint = checkpoint_result.checkpoint

也就是说,每一次tune.report(..., checkpoint=...)的结果都会写回session.loaded_checkpoint,形成"报告 → 持久化 → 恢复时加载"的完整链路。

as_directory():把检查点当作只读本地目录

Checkpoint.as_directory()是上下文管理器。从 Checkpoint 实现 的文档说明可以确认其两种行为:

  • 本地目录检查点:直接返回原目录路径,不做拷贝,退出上下文后不做清理;
  • 远端存储检查点(如 S3 URI):下载到本地临时目录后返回路径,退出上下文时清理临时目录;
  • 若同一节点上多个进程并发访问同一检查点,只有一个进程真正执行下载,其余进程等待后共享同一份数据(通过TempFileLock文件锁实现)。

官方文档同时强调:返回的目录应视为只读,因为临时数据可能在退出上下文后被删除。示例中读取checkpoint.json恢复 step 的做法正是这种"目录即状态文件集合"的典型用法——检查点的物理形态就是一个目录,用户完全自由决定其中放什么(JSON、pickle、模型权重文件等)。

写入检查点:tune.report+Checkpoint.from_directory

训练循环中每步都执行一次检查点报告:

with tempfile.TemporaryDirectory() as temp_checkpoint_dir: with open(os.path.join(temp_checkpoint_dir, "checkpoint.json"), "w") as f: json.dump({"step": current_step}, f) tune.report( {"iterations": current_step, "mean_loss": intermediate_score}, checkpoint=Checkpoint.from_directory(temp_checkpoint_dir), )

这里有两个值得注意的细节:

  1. 先写临时目录,再包装成Checkpoint对象Checkpoint.from_directory(path)(源码)会以pyarrow.fs.LocalFileSystem()为后端构造Checkpoint,把"本地目录"变成"可被存储层持久化/迁移的检查点引用"。tune.report的 docstring 明确说明:提供checkpoint时,它会被持久化到配置的存储位置(persistent storage)。
  2. metrics 与 checkpoint 在同一次调用中报告tune.report的 源码 表明每次调用都会自动递增底层的training_iteration计数——示例main块中stop={"training_iteration": 10}正是以"报告次数"为停止条件,而非 epoch 数。docstring 也提醒:这个"iteration"的物理含义由用户按调用report的频率自行定义,不一定对应一个 epoch。

另外注意 trainable_fn_utils.py 中的实现细节:

@_copy_doc(TrainCheckpoint) class Checkpoint(TrainCheckpoint): # NOTE: This is just a pass-through wrapper around `ray.train.Checkpoint` # in order to detect whether the import module was correct `ray.tune.Checkpoint`. pass

ray.tune.Checkpoint只是ray.train.Checkpoint的透传包装类,专门用于检测导入模块是否正确;若你在report中传入了错误来源的Checkpoint实例,会触发 v2 迁移弃用警告(见 report 函数中的类型检查),因此务必从ray.tune导入Checkpoint,与示例文件开头的from ray.tune import Checkpoint保持一致。

Checkpoint类的更多能力(示例未用到但实用)

从 Checkpoint 完整实现 可以看到,该类还支持:

  • 远端构造Checkpoint("s3://bucket/path/to/checkpoint")会根据 URI scheme 推断文件系统,无需显式传入 filesystem;
  • to_directory(path=None):把检查点内容写到指定本地目录(或自动生成的临时目录),适用于需要持久保留下载内容的场景;
  • 元数据 APIset_metadata/get_metadata/update_metadata会把键值对以.metadata.json形式随检查点持久化,适合存放超参摘要、预处理器配置等;
  • 误用防护__fspath__被刻意实现为抛TypeError,强制你使用to_directory()/as_directory()而非把Checkpoint当普通路径拼接使用。

Tuner配置逐项解析

示例main块展示了完整的tune.Tuner调用,各部分含义如下:

配置项取值作用
train_func(位置参数)上面的训练函数Tune 自动包装为 Function Trainable
RunConfig.name"hyperband_test"实验名,用于标识运行目录
RunConfig.stop{"training_iteration": 1}(smoke)/10(默认)每个 trial 报告满指定 iteration 次数即停止
TuneConfig.metric"mean_loss"用于排序与早停的目标指标,每次report中提供
TuneConfig.mode"min"目标越小越好(loss 场景)
TuneConfig.num_samples5每个 trial 重复采样 5 次,以抑制单次随机性
param_space["steps"]10(常量)非随机超参,仅随配置下发,示例中实际未使用
param_space["width"]tune.randint(10, 100)在 [10, 100] 均匀取整
param_space["height"]tune.loguniform(10, 100)在 [10, 100] 对数均匀采样,适合量级跨度大的参数

训练结束后通过results.get_best_result()取最优 trial,并打印其configcheckpoint——best_result.checkpoint即最后一次报告的Checkpoint对象,可直接用as_directory()加载其中的checkpoint.json(或真实场景中的模型权重)用于部署/推理。

运行方式与适用前提

python python/ray/tune/examples/custom_func_checkpointing.py # 完整跑 10 次 iteration python python/ray/tune/examples/custom_func_checkpointing.py --smoke-test # 1 次 iteration 快速验证

适用前提与限制:

  • 训练函数运行在 Ray 集群的 worker 中,tune.report/tune.get_checkpoint只能在 Train 会话内调用(源码中由_warn_session_misuse()装饰器检测误用);
  • 检查点内容本身只是目录数据,Tune 不负责解释其结构,恢复逻辑(如step + 1)完全由用户编写;
  • 该模式与官方集成(如 cifar10_pytorch.py、pbt_convnet_function_example.py 中对tune.get_checkpoint()的同款用法)遵循同一套 API,因此从自定义函数迁移到框架集成时检查点代码基本可以平移。

小结

Ray Tune 的自定义函数检查点机制可归纳为三步闭环:用Checkpoint.from_directory把任意本地目录包装为检查点 → 随tune.report一起上报以触发持久化 → 恢复时经tune.get_checkpoint().as_directory()以只读目录形式读回。整套机制不依赖任何深度学习框架,检查点可以是 JSON、pickle 或模型权重文件的任意组合;而training_iteration随每次report自动递增的特性,使得RunConfig.stop可以按"报告次数"精确控制试验时长。

【免费下载链接】rayRay is an AI compute engine. Ray consists of a core distributed runtime and a set of AI Libraries for accelerating ML workloads.项目地址: https://gitcode.com/gh_mirrors/ra/ray

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 18:29:21

三步跑通 OpenToonz:从源码构建到主题定制与场记板工作流

三步跑通 OpenToonz:从源码构建到主题定制与场记板工作流 【免费下载链接】opentoonz OpenToonz - An open-source full-featured 2D animation creation software 项目地址: https://gitcode.com/GitHub_Trending/op/opentoonz OpenToonz 是一款开源的 2D 动…

作者头像 李华
网站建设 2026/9/20 18:26:48

Codex CLI 评测:用 TaoToken 供 Key,补齐 Go 仓库的表驱动测试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/20 18:24:35

BrewUI:让macOS包管理器Homebrew的依赖管理可视化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/20 18:21:40

从性能指标到系统校正:机械控制工程核心知识点全解析

简介:这是一份机械工程控制基础课程的系统性能指标与校正教学PPT,依据杨叔子主编教材编写,面向机械工程、自动化控制类专业学生及需要巩固控制理论的技术人员。课件共1个pptx文件,压缩包约1.09MB,结构紧凑、图文结合&a…

作者头像 李华