自定义完全指南:run/sweep 输出目录模式详解)
Hydra 工作目录Working Directory自定义完全指南run/sweep 输出目录模式详解【免费下载链接】hydraHydra is a framework for elegantly configuring complex applications项目地址: https://gitcode.com/GitHub_Trending/hyd/hydra导读Hydra 会自动为每次运行run和多运行multirun sweep创建输出目录用于存放日志文件与落盘的 YAML 配置。本文基于仓库文档website/versioned_docs/version-0.11/configure_hydra/workdir.md完整讲解如何通过hydra.run.dir、hydra.sweep.dir、hydra.sweep.subdir自定义输出目录模式并深入解析hydra.job.override_dirname与hydra_override_dirname解析器的底层实现。读完本文你将掌握按日期、任务名、用户配置变量、命令行覆盖参数等维度组织输出目录的全部实战写法并能在 bash 等 Shell 中正确转义通过 CLI 传入的目录模板。输出目录的核心机制Hydra 每次运行都会创建输出目录并将config.yaml、hydra.yaml、overrides.yaml三个文件写入其中。这一逻辑在 hydra/core/utils.py 的run_job()中体现运行前Path(str(output_dir)).mkdir(parentsTrue, exist_okTrue)创建目录见 hydra/core/utils.py#L151随后把任务配置、Hydra 配置与覆盖参数分别落盘hydra/core/utils.py#L164-L170。目录模式的配置入口如下配置项作用默认值hydra.run.dir单次运行非 multirun的输出目录outputs/${now:%Y-%m-%d}/${now:%H-%M-%S}hydra.sweep.dirmultirun 的整体 sweep 目录multirun/${now:%Y-%m-%d}/${now:%H-%M-%S}hydra.sweep.subdirsweep 目录下每个 job 的子目录${hydra.job.num}以上默认值定义在 hydra/conf/hydra/output/default.yaml单运行输出outputs/日期/时间multirun 输出multirun/日期/时间每个 job 按序号0、1、2…分目录。从源码调用链看基本启动器BasicLauncher.launch()读取hydra.sweep.dir作为 job 目录键、hydra.sweep.subdir作为子目录键传入run_job()见 hydra/_internal/core_plugins/basic_launcher.py#L74-L80run_job()先求值hydra.sweep.dir再延迟求值hydra.sweep.subdir并拼接到其后hydra/core/utils.py#L116-L122最后将绝对路径写入hydra.runtime.output_dirhydra/core/utils.py#L124-L126任务运行时即可通过hydra.runtime.output_dir访问实际输出目录。同理基本 sweeper 在启动 sweep 时也会先创建hydra.sweep.dir并保存multirun.yaml见 hydra/_internal/core_plugins/basic_sweeper.py#L162-L165。单次运行run输出目录模式按日期分组输出将输出目录按天分组每天内再按小时-分钟-秒细分hydra: run: dir: ./outputs/${now:%Y-%m-%d}/${now:%H-%M-%S}${now:...}是 Hydra 注册的now解析器接受strftime风格的时间格式在 hydra/core/utils.py#L365-L370 中注册实际调用datetime.now().strftime(pattern)并开启了use_cacheTrue同一配置树内只求值一次。按任务名分组输出在目录中包含任务名便于一眼定位是哪个应用产生的输出hydra: run: dir: outputs/${hydra.job.name}/${now:%Y-%m-%d_%H-%M-%S}${hydra.job.name}默认由 Hydra 自动填充通常为入口模块名也可在配置或 CLI 中显式指定见 hydra/conf/init.py#L47-L48 中JobConf.name的定义。目录中包含用户配置变量输出目录可以是任务配置的一部分——把配置变量的取值拼进路径hydra: run: dir: outputs/${now:%Y-%m-%d_%H-%M-%S}/opt:${optimizer.type}这里${optimizer.type}引用的是用户配置树中的optimizer.type字段。注意目录名中的冒号:在 Windows 上不被允许跨平台使用时建议替换为-或_等安全字符。由于目录名来自配置值请确保引用的配置字段取值不含路径分隔符。目录中包含任务的命令行覆盖参数利用hydra.job.override_dirname运行时变量将任务的覆盖参数拼入目录hydra: run: dir: output/${hydra.job.override_dirname}例如运行python train.py model.nb_layers3会生成类似output/model.nb_layers3的目录。override_dirname在 hydra/conf/init.py#L53-L54 中定义默认值为${hydra_override_dirname:}即委托给下面的hydra_override_dirname解析器注意该旧式变量名在源码中已标记为 Deprecated推荐直接使用解析器写法。多运行multirun sweep输出目录模式multirun 场景下hydra.sweep.dir定义所有 job 的公共父目录hydra.sweep.subdir定义每个 job 实例的子目录。文档默认配置为hydra: sweep: dir: multirun/${now:%Y-%m-%d}/${now:%H-%M-%S} subdir: ${hydra.job.num}对命令python my_app.py --multirun aa1,a2,a3执行后会生成如下目录结构hydra.job.num依次为 0、1、2my_app ├── 0 ├── 1 └── 2hydra.job.num由启动器在每个 job 启动前填充见 hydra/_internal/core_plugins/basic_launcher.py#L71-L73sweep_config.hydra.job.id idx、job.num idx。该值在每个 job 实例侧才可用因此subdir在run_job()中被延迟求值见 hydra/core/utils.py#L117-L122 的注释说明。run 目录的所有模式同样适用于 sweep例如按任务名分组、按 job 序号分子目录hydra: sweep: dir: ${hydra.job.name} subdir: ${hydra.job.num}生成结构为任务名/0、任务名/1、任务名/2。深入hydra_override_dirname解析器hydra_override_dirname解析器根据命令行覆盖参数生成目录名通常与hydra.sweep.subdir搭配使用。它对应的实现是hydra/core/utils.py中的hydra_override_dirname()hydra/core/utils.py#L288-L336在setup_globals()中注册hydra/core/utils.py#L353-L359。其工作流程可从源码归纳从配置树读取hydra.overrides.task即纯任务覆盖已过滤hydra.前缀的键见filter_overrides()hydra/core/utils.py#L92-L97用OverridesParser解析覆盖项跳过exclude_keys指定的键将剩余覆盖项排序后把替换为kv_sep、逐个解析内嵌插值最后用item_sep拼接成目录名。示例运行python my_app.py --multirun batch_size32 learning_rate0.1,0.01配合配置hydra: sweep: dir: multirun subdir: ${hydra_override_dirname:}生成的目录为multirun ├── batch_size32,learning_rate0.01 └── batch_size32,learning_rate0.1配置hydra.job.config.override_dirname解析器的默认参数键值分隔符kv_sep、条目分隔符item_sep、排除键列表exclude_keys可通过hydra.job.config.override_dirname全局配置hydra: job: config: # configuration for the ${hydra_override_dirname:} resolver override_dirname: kv_sep: item_sep: , exclude_keys: []参数说明默认值kv_sep键与值之间的分隔符item_sep多个覆盖项之间的分隔符,exclude_keys不参与目录名的覆盖键列表[]空列表这三个参数的默认值与类型校验均可在 hydra/conf/init.py#L74-L80dataclassOverrideDirnamekv_sep、item_sep,、exclude_keys空列表以及 hydra/core/utils.py#L214-L219OverrideDirnameOptions额外支持element_resolver中找到依据。_get_override_dirname_options()hydra/core/utils.py#L222-L272会对这些参数做严格的类型检查例如kv_sep/item_sep必须是字符串、exclude_keys必须是元素全为字符串的列表。一个典型场景是排除随机种子随机种子往往只影响结果复现、不体现实验差异混入目录名反而使目录爆炸。配置示例仓库示例应用 examples/configure_hydra/job_override_dirname/config.yaml 即采用此写法hydra: sweep: dir: multirun subdir: ${hydra_override_dirname:{exclude_keys: [seed]}}/seed${seed}运行python my_app.py --multirun batch_size32 learning_rate0.1,0.01 seed1,2会得到先按超参、再按 seed分层的目录结构multirun ├── batch_size32,learning_rate0.01 │ ├── seed1 │ └── seed2 └── batch_size32,learning_rate0.1 ├── seed1 └── seed2自定义分隔符在调用解析器时直接传参即可覆盖全局默认值hydra: sweep: subdir: ${hydra_override_dirname:{kv_sep: -, item_sep: _, exclude_keys: [seed]}}使用 element_resolver 定制目录元素如需更强控制element_resolver允许为目录名的每个元素指定一个已注册的 OmegaConf 解析器在元素拼接前逐个转换。解析器必须在 Hydra 启动前单独注册。例如把路径分隔符包括 Windows 的\替换为_from omegaconf import OmegaConf OmegaConf.register_resolver( pathsafe, lambda value: str(value).replace(/, _).replace(\\, _), )hydra: sweep: subdir: ${hydra_override_dirname:{item_sep: /, element_resolver: pathsafe}}从源码看element_resolver通过名字查表获取OmegaConf._get_resolver未知的解析器名会抛出ValueErrorhydra/core/utils.py#L303-L308每个元素在_resolve_override_dirname_item()完成插值解析后再交给该解析器处理hydra/core/utils.py#L329-L334。通过 CLI 自定义输出目录输出目录与普通配置一样可以通过 CLI 覆盖无需修改配置文件python train.py model.nb_layers3 hydra.run.dir3_layers这在与 multirun 组合时尤为强大——配合插值无需样板代码即可把每次实验写到独立目录python train.py --multirun model.nb_layers1,2,3,5 hydra.sweep.dirmultiruns/layers_effect hydra.sweep.subdir\$\{model.nb_layers}这里hydra.sweep.subdir的值是字面量\$\{model.nb_layers\}等价于 YAML 中的插值表达式${model.nb_layers}从而每个 job 根据自身的model.nb_layers取值建立子目录。bash 转义警告在 bash 等 Shell 中必须转义$符号写为\$否则 bash 会先尝试展开该变量而不是把它原样传给 Hydra。反斜杠转义后最终传给 Hydra 的才是\${model.nb_layers}对应的插值语义。这是该文档反复强调的易错点双引号包裹并不能豁免$的展开行为。运行与验证可以参照仓库示例应用快速验证上述模式。示例代码 examples/configure_hydra/job_override_dirname/my_app.py 中应用打印当前工作目录import os from omegaconf import DictConfig import hydra hydra.main(config_path., config_nameconfig) def my_app(_cfg: DictConfig) - None: print(fWorking dir {os.getcwd()}) if __name__ __main__: my_app()配合其配置 examples/configure_hydra/job_override_dirname/config.yaml 运行 multirun即可观察到按hydra_override_dirname生成的目录树。该示例也是文档在 website/docs/configure_hydra/workdir.md 中引用的官方示例应用可直接对照学习。小结输出目录三要素hydra.run.dir单运行、hydra.sweep.dirsweep 根目录、hydra.sweep.subdir每个 job 子目录默认值见 hydra/conf/hydra/output/default.yaml目录模板中可自由混用${now:...}、${hydra.job.*}与用户配置变量插值支持按日期、任务名、配置值、覆盖参数任意组合hydra_override_dirname:解析器由命令行覆盖自动生成目录名支持kv_sep、item_sep、exclude_keys、element_resolver四个参数其全局默认值通过hydra.job.config.override_dirname配置结构定义见 hydra/conf/init.py#L70-L82CLI 直接覆盖目录配置时可配合插值实现无样板的多实验组织但 bash 下务必转义$。【免费下载链接】hydraHydra is a framework for elegantly configuring complex applications项目地址: https://gitcode.com/GitHub_Trending/hyd/hydra创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考