【Python】Hydra 用法详解
Hydra官方文档
Hydra(Python配置管理工具)
1. 引言
在机器学习、深度学习和软件开发中,管理复杂的配置是一个常见的挑战。Hydra
是一个强大的 Python 库,允许开发者轻松地管理和组织配置文件,支持动态参数覆盖、多层次配置和可组合配置等特性。
2. 安装 Hydra
Hydra
可以通过 pip
直接安装:
pip install hydra-core
安装完成后,你可以使用 hydra
进行配置管理。
3. 基础用法
3.1 目录结构
Hydra 的核心思想是 使用 YAML 文件管理配置。推荐的项目结构如下:
project/
│── config.yaml # 主配置文件
│── config/ # 额外的子配置
│ │── database.yaml
│ │── model.yaml
│── main.py # 入口文件
3.2 编写主配置文件
创建 config.yaml
:
database:
user: root
password: 123456
host: localhost
port: 3306
model:
name: resnet50
learning_rate: 0.001
batch_size: 32
3.3 读取配置文件
在 main.py
中使用 Hydra
读取配置:
import hydra
from omegaconf import DictConfig
@hydra.main(version_base=None, config_path=".", config_name="config")
def main(cfg: DictConfig):
print(cfg.database.user) # 访问 database 配置
print(cfg.model.name) # 访问 model 配置
if __name__ == "__main__":
main()
运行 python main.py
,输出:
root
resnet50
4. 运行时修改配置
Hydra 允许在 命令行 运行时修改配置,适用于实验调参。
4.1 直接覆盖参数
在运行时,使用 键值对格式 修改参数:
python main.py database.user=admin model.learning_rate=0.01
输出:
Database user: admin
Model: resnet50, Learning rate: 0.01
4.2 添加新参数
Hydra 允许动态增加新参数:
python main.py +new_param=value
在 Python 代码中:
print(cfg.new_param) # 输出 value
5. 运行时传入配置文件
有时,我们希望在运行时 传入不同的配置文件,比如:
config.yaml
(默认配置)config_exp1.yaml
(实验 1 配置)config_exp2.yaml
(实验 2 配置)
5.1 创建多个 YAML 配置
config_exp1.yaml
:
database:
user: exp_user
password: exp_pass
model:
name: vgg16
learning_rate: 0.005
5.2 运行时选择配置文件
使用 hydra.run.dir
指定运行时目录:
python main.py --config-name=config_exp1
输出:
Database user: exp_user
Model: vgg16, Learning rate: 0.005
6. 多文件配置(分模块管理)
在复杂项目中,通常希望将 配置拆分 成多个文件。
Hydra 提供 defaults
机制,使多个 YAML 组合成 主配置。
6.1 目录结构
project/
│── config.yaml # 主配置文件
│── database/ # 子配置目录
│ │── database.yaml
│── model
│ │── model.yaml
│── main.py # 入口文件
6.2 创建子配置文件
database.yaml
user: root
password: 123456
host: localhost
port: 3306
model.yaml
name: resnet50
learning_rate: 0.001
batch_size: 32
6.3 在主配置 config.yaml
引入子配置
defaults:
- database: database
- model: model
解析时, database
和 model
都会解析成一个键,对应的值为他们文件的yaml组成的配置内容。(就是说两个文件的配置不会在全局,而是在单独的键里面)
6.4 代码中访问配置
@hydra.main(version_base=None, config_path="config", config_name="config")
def main(cfg: DictConfig):
print(cfg.database.user)
print(cfg.model.name)
if __name__ == "__main__":
main()
运行:
python main.py
输出:
root
resnet50
总结:
defaults
机制支持 多个 YAML 组合- 让配置文件 更加模块化,易维护
7. 组合多个配置(实验管理)
Hydra 允许 动态切换子配置,适用于 实验管理。
假设 config/experiment/
目录存放不同实验的配置:
config/
│── experiment/
│ │── exp1.yaml
│ │── exp2.yaml
exp1.yaml
model:
learning_rate: 0.005
exp2.yaml
model:
learning_rate: 0.01
7.1 运行不同实验
python main.py +experiment=exp1
代码自动加载 config/experiment/exp1.yaml
,使 model.learning_rate = 0.005
。
8. 运行时工作目录
Hydra 默认改变运行目录,每次运行会创建 outputs/YYYY-MM-DD_HH-MM-SS/
目录。
如果想 保持当前目录:
python main.py hydra.run.dir=.
9. 实例化自定义模型
假设我们的项目结构如下:
project_root/
│── config/
│ ├── model/
│ │ ├── model_modified.yaml # 模型的配置文件
│── model/
│ ├── __init__.py # 使 model/ 成为 Python 包
│ ├── model.py # 定义 Model 类
│── main.py # 运行实例化的代码
Step 1:编写 model.py
首先,我们在 model/model.py
中定义一个简单的 Model
类:
# model/model.py
class Model:
def __init__(self, input_dim: int, hidden_dim: int, output_dim: int):
self.input_dim = input_dim
self.hidden_dim = hidden_dim
self.output_dim = output_dim
def __repr__(self):
return f"Model(input_dim={self.input_dim}, hidden_dim={self.hidden_dim}, output_dim={self.output_dim})"
这个 Model
类有三个参数 input_dim
、hidden_dim
和 output_dim
,它们将在实例化时被赋值。
Step 2:编写 Hydra 配置文件 (model_modified.yaml
)
在 config/model/model_modified.yaml
中,我们使用 _target_
指定 Model
类的路径,并提供初始化参数:
# config/model/model_modified.yaml
_target_: model.model.Model
input_dim: 128
hidden_dim: 256
output_dim: 10
注意:参数不能写多,如果出现了类中没有的参数会报错
_target_
:指定Model
类的完整 Python 路径,即model/model.py
文件中的Model
类。- 下面的
input_dim
、hidden_dim
、output_dim
是Model
类的__init__
方法需要的参数。
Step 3:使用 instantiate
进行实例化
在 main.py
中,我们可以使用 hydra.utils.instantiate
方法来动态创建 Model
对象:
# main.py
import hydra
from omegaconf import OmegaConf
from hydra.utils import instantiate
# 加载 YAML 配置
cfg = OmegaConf.load("config/model/model_modified.yaml")
# 通过 instantiate 实例化 Model
model = instantiate(cfg)
print(model) # 输出:Model(input_dim=128, hidden_dim=256, output_dim=10)
Step 4:运行代码
执行 main.py
后,Hydra 会:
- 解析
model_modified.yaml
,读取_target_
并找到model.model.Model
。 - 使用
input_dim=128, hidden_dim=256, output_dim=10
调用Model
的__init__
方法。 - 返回实例化后的
Model
对象。
运行结果:
Model(input_dim=128, hidden_dim=256, output_dim=10)