hydra-zen: Composable Hydra Configurations
hydra-zen is a Python library that simplifies the creation of reproducible, composable, and scalable configurations for machine learning and scientific workflows using Hydra. It provides a more Pythonic API to define Hydra configurations, enabling type-checking, autocompletion, and easier integration with existing Python code. The current version is 0.16.0, with releases occurring periodically, often driven by new features or compatibility updates.
Common errors
-
ModuleNotFoundError: No module named 'hydra_zen'
cause The `hydra-zen` package is not installed in the current Python environment.fixRun `pip install hydra-zen` to install the library. -
omegaconf.errors.MissingMandatoryValue: Missing mandatory value ${some_param}cause A parameter required by a `builds` configuration or a decorated function (either implicitly via `_target_` or explicitly defined) was not provided a default value in the config nor via Hydra's CLI.fixEnsure all parameters for the target function have defaults in the `builds` call or in the function signature. If running via Hydra CLI, provide missing parameters: `python your_app.py path.to.param=value`. -
TypeError: 'Config' object is not callable
cause Attempting to directly call a configuration object returned by `builds` or `make_config` as if it were the target function itself, instead of using `instantiate`.fixUse `instantiate(ConfigObject)` to create an instance of the target object. Configuration objects are not directly callable. -
NameError: name 'builds' is not defined
cause The `builds` (or `zen`, `instantiate`, etc.) symbol was not imported from `hydra_zen`.fixAdd the necessary import statement at the top of your script, e.g., `from hydra_zen import builds, zen, instantiate`.
Warnings
- breaking The `_target_wrapper_` behavior for partial instantiation was improved/changed in v0.15.0. If you relied on the exact previous behavior of custom target wrappers, this might subtly alter how partially constructed objects resolve.
- breaking Version 0.13.0 introduced Pydantic integration. While largely additive, this changed internal type representation and validation capabilities. Users with custom validation logic or deep introspection of config types might observe changes or new validation errors if Pydantic is enabled.
- gotcha `hydra-zen` is an abstraction layer over `hydra-core`. A solid understanding of Hydra's core concepts (e.g., `_target_`, `_recursive_`, config groups, CLI overrides) is crucial for effective use and debugging, as `hydra-zen` simplifies the API but does not eliminate the underlying complexities.
- gotcha Distinction between `zen.zen` decorator and `instantiate`: The `@zen` decorator creates a Hydra entry point for command-line execution, while `instantiate()` is for programmatic object creation from configs. Confusing these can lead to `MissingMandatoryValue` errors or difficulty running without the Hydra CLI.
Install
-
pip install hydra-zen
Imports
- zen
from hydra_zen import zen
- builds
from hydra_zen import builds
- make_config
from hydra_zen import make_config
- instantiate
from hydra_zen import instantiate
- store
from hydra_zen import store
Quickstart
from hydra_zen import builds, instantiate
from omegaconf import OmegaConf
def train_model(epochs: int, lr: float, model_name: str = "ResNet"): #_target_
"""Simulates a model training process."""
return f"Training {model_name} for {epochs} epochs with learning rate {lr}"
# Define a config for our function, setting default values
# Parameters not set here become mandatory CLI arguments or must have defaults in the function.
TrainConfig = builds(train_model, epochs=10, lr=0.01, model_name="AwesomeNet")
# Instantiate the configuration directly to run the target function
# This simulates `hydra.utils.instantiate` using hydra-zen's convenience API
result = instantiate(TrainConfig)
print(f"Direct instantiation: {result}")
# You can also override values programmatically
override_config = TrainConfig(epochs=20, lr=0.005, model_name="SuperNet")
result_override = instantiate(override_config)
print(f"Instantiation with overrides: {result_override}")
# Inspect the raw OmegaConf config object
print("\nGenerated config:\n" + OmegaConf.to_yaml(override_config))