Hydra 输出/工作目录(Working Directory)机制全解析:自动目录、.hydra 产物与原目录访问

Hydra 输出/工作目录(Working Directory)机制全解析:自动目录、.hydra 产物与原目录访问 Hydra 输出/工作目录Working Directory机制全解析自动目录、.hydra 产物与原目录访问【免费下载链接】hydraHydra is a framework for elegantly configuring complex applications项目地址: https://gitcode.com/GitHub_Trending/hyd/hydraHydra 作为一个面向复杂应用优雅配置的框架会自动为每次运行创建独立输出目录让用户彻底告别手动指定新目录的麻烦。本文基于 Hydra 0.11 教程中《Output/Working directory》一文的完整脉络系统讲解 Hydra 工作目录的生成规则、.hydra目录内的三类配置产物、应用日志的落盘位置以及如何在应用中安全地访问原始工作目录并给出可在当前仓库中直接验证的源码与配置依据。工作目录是什么一次运行、一个目录Hydra 解决的核心痛点之一是每次运行应用时你都需要手动为输出如数据库 dump 文件、日志、模型产物指定一个新目录。Hydra 的做法是为每次运行自动创建一个工作目录并让你的代码在该目录内执行。工作目录承担两类职责存储应用自身的输出例如数据库 dump 文件、训练日志、中间产物存储Hydra 为该次运行生成的输出最终配置、日志等。也就是说工作目录既是应用的沙盒也是 Hydra 审计每次运行痕迹的地方。从配置源码看默认的输出目录模式定义在 hydra/conf/hydra/output/default.yaml# package hydra run: dir: outputs/${now:%Y-%m-%d}/${now:%H-%M-%S} sweep: dir: multirun/${now:%Y-%m-%d}/${now:%H-%M-%S} subdir: ${hydra.job.num}可以看到普通单次运行run的输出目录为outputs/日期/时间多任务扫描sweep/multirun则为multirun/日期/时间/job序号。${now:...}是 Hydra 内置的当前时间解析器${hydra.job.num}是当前子任务的序号这两处均以 OmegaConf 插值interpolation方式在运行时求值。每次运行都会生成新的工作目录当你用hydra.main()装饰应用入口后每一次运行都会自动生成一个全新的、以时间戳命名的目录。以教程中的my_app.py为例import os hydra.main() def my_app(_cfg): print(Working directory : {}.format(os.getcwd()))连续运行两次工作目录各不相同$ python my_app.py Working directory : /home/omry/dev/hydra/outputs/2019-09-25/15-16-17 $ python my_app.py Working directory : /home/omry/dev/hydra/outputs/2019-09-25/15-16-19目录名2019-09-25/15-16-17正是由hydra.run.dir中outputs/${now:%Y-%m-%d}/${now:%H-%M-%S}生成的外层按日期分组内层按时分秒细分。由于精确到秒即使短时间内多次运行也不会冲突。工作目录里到底有什么查看其中一个工作目录的完整结构$ tree outputs/2019-09-25/15-16-17 outputs/2019-09-25/15-16-17 ├── .hydra │ ├── config.yaml │ ├── hydra.yaml │ └── overrides.yaml └── my_app.log目录由两部分组成1. Hydra 输出目录默认为.hydra其中包含三个文件config.yaml用户指定的完整配置的最终转储dump即经过 defaults 合并、命令行覆盖之后生效的完整配置快照hydra.yamlHydra 自身配置的转储包含运行目录模式、日志配置、job 元数据等 Hydra 内部参数overrides.yaml本次运行使用的命令行覆盖项忠实记录了这一次到底改了什么参数对实验复现与审计极其重要。2. 应用日志文件本例为my_app.logHydra 的 job logging 系统为该次运行创建的标准日志文件应用内通过logging模块输出的内容都会写入这里。日志文件名与应用的 Python 模块名对应my_app.py→my_app.log。这三个 yaml 文件是 Hydra 可复现性reproducibility设计的直接体现任何一次运行只要拿到.hydra目录就能精确还原当时的完整配置与覆盖参数。在应用中访问原始工作目录Hydra 执行应用时会把当前工作目录切换到新生成的输出目录但这不意味着你会丢失启动应用时所在目录的信息。Hydra 提供两个实用函数hydra.utils.get_original_cwd()返回应用启动时的原始工作目录hydra.utils.to_absolute_path(path)将相对路径解析为相对于原始工作目录的绝对路径。示例import os import hydra from hydra import utils hydra.main() def my_app(_cfg): print(Current working directory : {}.format(os.getcwd())) print(Original working directory : {}.format(utils.get_original_cwd())) print(to_absolute_path(foo) : {}.format(utils.to_absolute_path(foo))) print(to_absolute_path(/foo) : {}.format(utils.to_absolute_path(/foo)))运行结果$ python examples/tutorial/8_working_directory/original_cwd.py Current working directory : /Users/omry/dev/hydra/outputs/2019-10-23/10-53-03 Original working directory : /Users/omry/dev/hydra to_absolute_path(foo) : /Users/omry/dev/hydra/foo to_absolute_path(/foo) : /foo关键行为可以归纳为get_original_cwd()返回的是 Hydra 启动前的目录与当前工作目录无关to_absolute_path(foo)把相对路径拼接在原始工作目录之后to_absolute_path(/foo)对绝对路径不做任何处理原样返回。这意味着即使 Hydra 把进程切到了输出目录你依然可以用to_absolute_path稳定地定位到原始目录下的配置文件、数据文件等资源。源码级的实现印证上述两个函数并非黑盒其实现位于 hydra/utils.py可以直接在仓库中验证def get_original_cwd() - str: if not HydraConfig.initialized(): raise ValueError( get_original_cwd() must only be used after HydraConfig is initialized ) ret HydraConfig.get().runtime.cwd assert ret is not None and isinstance(ret, str) return ret def to_absolute_path(path: str) - str: p Path(path) if not HydraConfig.initialized(): base Path(os.getcwd()) else: base Path(get_original_cwd()) if p.is_absolute(): ret p else: ret base / p return str(ret)从源码可以看出两点实现事实get_original_cwd()依赖HydraConfig.runtime.cwd原始工作目录在 Hydra 初始化阶段被记录进运行时配置因此该函数只有在HydraConfig初始化之后调用才有效否则会抛出ValueError。应用代码位于hydra.main装饰的函数体内天然满足这一前提。to_absolute_path()的基准切换逻辑Hydra 初始化后以原始工作目录为基准拼接相对路径若尚未初始化则退化为基于当前os.getcwd()拼接。绝对路径则原样返回。这一设计保证了工具函数在任意上下文中的安全可用性。自定义工作目录模式工作目录的生成模式是 Hydra 配置的一部分可以通过覆盖hydra.run.dir来定制。常规做法是在应用的config.yaml中设置hydra: run: dir: ./outputs/${now:%Y-%m-%d}/${now:%H-%M-%S}仓库中 examples/configure_hydra/workdir 提供了一个可直接运行的示例应用其my_app.py在装饰函数内打印os.getcwd()配合 conf/config.yaml 中的目录配置即可观察自定义目录效果。更完整的自定义方案按 job 名分组、嵌入用户配置变量、multirun 的sweep.dir/sweep.subdir、hydra_override_dirname解析器按命令行参数生成子目录等可参考 website/docs/configure_hydra/workdir.md。版本演进提示需要特别说明的是本文所依据的 website/versioned_docs/version-0.11/tutorial/8_working_directory.md 属于Hydra 0.11 版本的教程快照。在 0.11 时代Hydra 默认会执行os.chdir切换进程工作目录到输出目录而从 Hydra 1.2 起见 website/docs/tutorials/basic/running_your_app/3_working_directory.md默认行为已变为不自动切换工作目录需要通过hydra.job.chdirTrue显式开启同时新增了通过hydra.output_subdir修改或禁用置为null.hydra子目录的能力。当前版本Hydra 1.x中输出目录依旧会为每次运行自动创建其中.hydra/config.yaml、.hydra/hydra.yaml、.hydra/overrides.yaml与my_app.log的产物结构保持不变应用可以通过HydraConfig.get().runtime.output_dir读取输出目录绝对路径get_original_cwd()与to_absolute_path()依然是访问原始目录的标准方式在hydra.job.chdirTrue场景下尤为常用。小结Hydra 的工作目录机制用一个简单的约定一次运行、一个带时间戳的目录同时解决了输出隔离与运行审计两大问题.hydra下的config.yaml、hydra.yaml、overrides.yaml完整记录了本次运行的全部配置与覆盖痕迹my_app.log统一承载应用日志而get_original_cwd()/to_absolute_path()保证了应用在切到输出目录后依然能够定位原始工作目录中的资源。理解这套机制是驾驭 Hydra 输出管理、multirun 扫描产物组织和实验复现的第一步。【免费下载链接】hydraHydra is a framework for elegantly configuring complex applications项目地址: https://gitcode.com/GitHub_Trending/hyd/hydra创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考