Hydra Config Management
Master Hydra for config management in this Applied AI engineering lesson — hands-on steps, troubleshooting, and what to study next.
Focus: hydra config management
You've just finished tuning your AI model's hyperparameters, only to realize the learning rate that worked yesterday breaks today's run. Or you've been asked to reproduce a teammate's experiment, but their config lives in a forgotten Jupyter notebook cell. This is the pain Hydra solves: configuration that's scattered, unversioned, and impossible to override cleanly. In the world of Applied AI engineering, where experiments are the product, Hydra for config management turns your configuration into a first-class, composable artifact you can version, override, and share with confidence.
The problem this lesson solves
Configuration is the silent killer of reproducibility. In AI projects, you're not just tracking code — you're tracking datasets, model architectures, training hyperparameters, and evaluation settings. When these live in disparate files, CLI arguments, or hard-coded constants, you face three daily battles:
- Reproducibility: A teammate runs your script and gets different results because their default config differs from yours.
- Experiment management: To try a new learning rate, you edit a file, run, and hope you remember what changed.
- Composition: A real project has multiple configs — data, model, training, and deployment — that must work together without becoming a tangled web.
Pro tip: The pain isn't unique to AI. Any application with more than a handful of settings suffers. Hydra's design, though, is especially tuned for the experiment-heavy workflow of machine learning.
Traditional approaches fail because they don't treat config as data with structure and hierarchy. Hydra solves this by giving you a structured, hierarchical, and overridable configuration system that integrates directly with Python.
Core concept / mental model
Think of Hydra as the command-line for configuration: your .yaml files define the defaults, but every single value can be overridden from the command line, without editing a file. This is the mental model that separates Hydra from a plain config.py or a .env file.
Here's the core idea: you define your config as a set of configuration groups (e.g., db, model, train), each with a default YAML file. At runtime, Hydra composes all the defaults, applies any overrides you specify, and hands you a single DictConfig object that your code reads.
Key terms to know:
- Config groups: Folders under a
conf/directory, each representing a category of settings (e.g.,conf/model/,conf/data/). - Defaults list: In a primary config file (e.g.,
conf/config.yaml), you list which groups and which specific YAML file within each group to use. - Overrides: Command-line arguments like
model.lr=0.001that temporarily change a value. - Multi-run: One command can launch multiple runs with different overrides — critical for hyperparameter sweeps.
A hierarchical config is like a nested dictionary wrapped in porcelain. Hydra flattens the YAML hierarchy into dotted paths (model.lr) that are obvious and tab-completable.
How it works step by step
Here's the flow of a typical Hydra-powered script:
- Structure your project with a
conf/directory: -conf/config.yaml— the root config, where you define the defaults list. -conf/data/— YAML files for different datasets (e.g.,cifar10.yaml,imagenet.yaml). -conf/model/— YAML files for different architectures (e.g.,cnn.yaml,transformer.yaml). - Define the root config with a
defaultslist that points to your chosen files. - Decorate your entry point with
@hydra.main(version_base=None, config_path='conf')— Hydra takes over the CLI parsing and provides the composedDictConfigto yourmainfunction. - Use the config object in your code to read values, just like a dictionary.
- Override at runtime by appending
model.lr=0.0001to the command line — no file edits needed.
Make sure the conf directory is inside the directory where you run the command — or pass config_path accordingly.
Hands-on walkthrough
Let's build a small, runnable example that demonstrates the essentials. We'll create a simple training script that uses Hydra to manage its config.
First, create the directory structure:
mkdir -p conf/data conf/model
Create conf/config.yaml:
# Root config
defaults:
- data: cifar10
- model: cnn
- override db: postgres # example of overriding a default group
# Global settings
train:
epochs: 10
batch_size: 32
lr: 0.01
# db settings are in conf/db/
Create conf/data/cifar10.yaml:
name: cifar10
num_classes: 10
Create conf/model/cnn.yaml:
arch: resnet18
pretrained: true
Now, create a train.py script:
import hydra
from omegaconf import DictConfig, OmegaConf
@hydra.main(version_base=None, config_path="conf")
def train(cfg: DictConfig):
"""Main training entry point."""
print("Config:")
print(OmegaConf.to_yaml(cfg))
# Access values naturally
print(f"Training {cfg.model.arch} on {cfg.data.name} for {cfg.train.epochs} epochs")
# ... actual training code would go here
if __name__ == "__main__":
train()
Run it:
python train.py
Expected output (truncated):
Config:
data:
name: cifar10
num_classes: 10
model:
arch: resnet18
pretrained: true
train:
epochs: 10
batch_size: 32
lr: 0.01
Training resnet18 on cifar10 for 10 epochs
Now let's override a value on the command line:
python train.py model.arch=vit data.name=imagenet train.lr=0.001
Output shows the new config:
model:
arch: vit
pretrained: true
train:
lr: 0.001
This is the power of Hydra — you can change config without touching a single YAML file.
Compare options / when to choose what
| Approach | Pros | Cons | Best For |
|---|---|---|---|
| Hydra | Hierarchy, overrides, multi-run, plugin ecosystem | Adds a dependency, YAML overhead | Complex AI projects with many config groups |
| Plain YAML + argparse | Simple, no extra deps | Manual merging, no defaults hierarchy | Small scripts with few params |
| dotenv/.env | Environment-based, 12-factor friendly | Not structured, limited to strings | App deployment config, secrets |
| pydantic settings | Type-safe, validates | No built-in CLI overrides | If you need validation and env vars |
For experiment-heavy AI workflows, Hydra's ability to compose and override is a game-changer. If your config is just 5 variables, Hydra might be overkill — stick with argparse. But as soon as you have multiple datasets, models, and training regimes, Hydra pays off.
Pro tip: Hydra plugs into
optunaorray.tunefor automatic hyperparameter sweeps — a natural synergy for AI engineering.
Troubleshooting & edge cases
Error: Config not found
Error: Override 'config.yaml' not found
Fix: Ensure the config_path argument points to the correct folder, and that the root config is named config.yaml.
Error: Missing required group
If your defaults list references a group that doesn't exist, Hydra will fail with a clear message. Ensure the folder and YAML file names match exactly.
Overriding nested values
Use dot notation: model.lr=0.1. If the key doesn't exist in the defaults, Hydra will add it — but that's often an oversight. Add + prefix to force addition if needed.
Empty defaults with _self_
In recent Hydra versions, the defaults list is processed before the root config body. If you want your root config to have precedence, add - _self_ at the top of the defaults list.
Overriding entire groups
To pick a different config file in a group, use ~model to remove the default, or +model=transformer to add one. But the cleanest way is to specify group choices directly: model=transformer where transformer.yaml exists.
KeyboardInterrupt / multi-run results
When using --multirun, Hydra creates a new working directory for each run, so be mindful of file paths in your code — use cfg.datasets.root if your config has it.
What you learned & what's next
You've learned how to use Hydra for config management: restructuring your project with a conf/ directory, composing defaults from groups, overriding values from the command line, and reading the final config in Python. You now understand the mental model of config-as-data and can apply it to keep your AI experiments reproducible and flexible.
Next step: Connect this to the broader Applied AI engineering track — Hydra's ability to define experiment variants sets the stage for automated hyperparameter sweeps and reproducible evaluation harnesses. You'll likely learn about experiment trackers (like MLflow) or structured output next — check the track outline.
Keep this pattern in your toolbox: whenever you find yourself editing config files by hand, remember that Hydra is designed to make that unnecessary.
Practice recap
Mini exercise: Extend the example above by adding a conf/train/ group with two YAML files — fast.yaml (5 epochs) and slow.yaml (50 epochs). Run python train.py train=fast and python train.py train=slow, and verify the epochs value changes. Then try python train.py --multirun train.lr=0.01,0.001 and observe the output directory structure.
Common mistakes
- Forgetting to add
- _self_to the defaults list when you want the root config to take precedence over group defaults. - Using
hydra.mainwithout passingconfig_path— it defaults toconfbut only if the app runs from the same directory. - Trying to override a missing key without the
+prefix — Hydra treats it as an error, not as a new key. - Relying on YAML file paths relative to the current directory in multi-run mode — Hydra changes the working directory, breaking relative paths.
Variations
- Hydra with OmegaConf: Use OmegaConf's dot-list access (
cfg.model.arch) for typed access and runtime composition. - Hydra + dataclasses: Define your config as
@dataclassobjects usinghydra.utils.instantiatefor type-safe config with code generation. - Hydra with Optuna: Use
hydra.maininside Optuna's objective function to sweep hyperparameters without leaving the Hydra config world.
Real-world use cases
- A research team defines per-dataset and per-model YAML configs, then runs a 1000-run hyperparameter sweep with
--multirunto find the best learning rate. - A production ML service loads the same Hydra config from a Git tag, ensuring the deployed model matches the exact settings used at training time.
- A MLOps pipeline uses Hydra configs to parameterize data preprocessing, model selection, and evaluation steps, making each pipeline run fully reproducible.
Key takeaways
- Hydra makes configuration hierarchical, composable, and overridable from the command line, solving the reproducibility problem.
- Structure your project with
conf/folders and a rootconfig.yamlwith adefaultslist. - Decorate your
mainwith@hydra.main(version_base=None, config_path='conf')to get a composedDictConfig. - Override any config value at runtime using dotted paths, e.g.,
model.lr=0.001— no file edits needed. - Use
--multirunfor hyperparameter sweeps and explore integrations with Optuna/Ray Tune for automation. - Prefer Hydra when your project has multiple config groups; plain argparse suffices for tiny configs.
Keep learning
Related tutorials, quizzes, and articles for this topic.
Discussion
Questions, corrections, and tips help everyone reading this page.
0 comments
Add a comment
No comments yet — start the thread.