A simple library for use with Hydra or OmegaConf configurations. The key feature is the _once_ keyword, which enables objects marked with it to be instantiated as singletons.
Sometimes, you want to ensure a subtree of your config is instantiated only once. Making unnecessary copies can waste resources or even break code.
Example:
dataset:
_target_: lightly.data.LightlyDataset
input_dir: data_dir
loader:
_target_: torch.utils.data.DataLoader
dataset: ${..dataset}
sampler:
_target_: torch.utils.data.RandomSampler
data_source: ${..dataset}Instantiating this config with Hydra will create three separate instances of dataset, which is undesirable because each one takes up memory. Even worse, calling instantiate a second time will create three more instances!
Hydra-Once introduces a new keyword, _once_, to the config. This ensures the subtree is instantiated only once.
dataset:
_target_: lightly.data.LightlyDataset
_once_: true # Only instantiate this tree once, reusing it as needed.
# Optionally, set _once_ to a string to manually specify a cache key
# _once_: dataset_unique_key
input_dir: data_dir
loader:
_target_: torch.utils.data.DataLoader
dataset: ${..dataset}
sampler:
_target_: torch.utils.data.RandomSampler
data_source: ${..dataset}Now, instantiate your config like so:
from hydra_once import instantiate
x = instantiate(cfg) # creates dataset just one time
y = instantiate(cfg) # creates dataset one more timeThis will create the dataset and loader, but only instantiate the dataset once. By default, the cache is ephemeral and destroyed at the end of the call to instantiate.
To use a persistent cache, set the cache argument to a dictionary you reuse, or to True to use a global cache:
from hydra_once import instantiate
cache = {} # or use True for a global cache
x = instantiate(cfg, cache=cache) # creates dataset one time
y = instantiate(cfg, cache=cache) # reuses dataset, but recreates loaderTo clear the global cache, use the clear function:
from hydra_once import clear
clear() # clears the global cacheNote:
It is best to use the default ephemeral cache or a dictionary you control. Using the global cache can lead to hard-to-debug issues, especially in multi-threaded code.
All Hydra instantiate tests pass without modification using this library. Just replace the Hydra instantiate function with the one from this library:
from hydra_once import instantiatepip install git+https://github.com/swamidass/hydra-onceThis is a Python-only library. The only dependencies are Hydra and OmegaConf.
Let me know if you want any further customization or additional sections! PRs welcome.