I want to package the repo and provide a cmd-line entry point for all the separate tasks managed by hydra. Let me explain with an example. I have multiple tasks that are all powered by hydra. Each task has 3 possible operations. Let's look at only 2 for simplicity- training and inference I can run them like this
python train.py args.epochs=2 ... # edit default params via hyda
python infer.py ...
Now I want to package this repo and create a cli interface that can access all these tasks and support the same ease of use as hydra. Something like this
yolov5 train --args.epochs=2 # should be same as python detect/train.py --args.epochs=2 ..
yolov5 infer --args.conf=0.2
Up until now, I would use fire CLI to create console entry points. But combining fire with hydra doesn't work. If I try to initialize fire with a function decorated by hydra main, it expects cfg as manual cmd-line input rather than hydra reading the default config.
# train.py
@hydra.main(...):
def run(cfg):
...
fire.Fire({
'classify/train': yolov5.train.run,
}) # Throws error that cfg must be passed
Another way that I can think of is directly adding console entry points to the hydra.main()
decorated function. But that would really populate the global cli space.
So, is there a clean and simple way of supporting this use case? Ideally, I'd like to use only hydra to manage this but open to combining other tools if absolutely necessary.
Hydra doesn't support a standalone "command" argument.
The general pattern is to add an action
or mode
config option which enumerate the supported tasks.
@hydra.main(...)
def main(cfg):
if cfg.action == "train":
...
elif cfg.action == "test":
...
You can populate entry points as you suggested. You can see an example here. (Page has a link to a working example)
You can get closer to the user experience you are describing using use a script or a shell alias to convert something like my_app mode
to my_app action=mode
to make the user experience similar to what you are trying to achieve.