-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New feature: hydra_zen.builds_decorator
#93
Comments
I like this idea and have been trying to think of ways to make
Maybe we could simply document this as a recipe for library authors to use, but they are ultimately responsible for opting-in/maintaining it. Like, I can definitely imagine |
Good point. I just remember we were talking about so thought I'd document our discussion at least :) |
Yep! I think it is good to document our thoughts on these sorts of things. It can be also helpful for us to reference these issues if users request similar features later. |
@jgbos what do you think about this approach from functools import partial
def as_builds(target):
return partial(builds, target, populate_full_signature=True)
RandomCrop = as_builds(transforms.RandomCrop)
RandomHorizontalFlip = as_builds(transforms.RandomHorizontalFlip)
ColorJitter = as_builds(transforms.ColorJitter)
RandomRotation = as_builds(transforms.RandomRotation)
ToTensor = as_builds(transforms.ToTensor)
Normalize = as_builds(transforms.Normalize)
Compose = as_builds(transforms.Compose)
Cifar10TrainTransformsConf = Compose(
transforms=[
RandomCrop(size=32, padding=4),
RandomHorizontalFlip(),
ColorJitter(brightness=0.25, contrast=0.25, saturation=0.25),
RandomRotation(degrees=2),
ToTensor(),
Normalize(
mean=[0.4914, 0.4822, 0.4465],
std=[0.2023, 0.1994, 0.2010],
),
],
) A really cool thing about this is that you can just copy-and-paste your code from your jupyter notebook, and the code that was building your transform is now building a conf for that same transform! >>> instantiate(Cifar10TrainTransformsConf)
Compose(
RandomCrop(size=(32, 32), padding=4)
RandomHorizontalFlip(p=0.5)
ColorJitter(brightness=[0.75, 1.25], contrast=[0.75, 1.25], saturation=[0.75, 1.25], hue=None)
RandomRotation(degrees=[-2.0, 2.0], interpolation=nearest, expand=False, fill=0)
ToTensor()
Normalize(mean=[0.4914, 0.4822, 0.4465], std=[0.2023, 0.1994, 0.201])
) Obviously all of the Some cool things about this: our runtime validation ends up being really useful and intuitive here: >>> Normalize(average=2)
TypeError: Building: Normalize ..
The following unexpected keyword argument(s) was specified for torchvision.transforms.transforms.Normalize via `builds`: average |
I guess I'm not sure how this really helps (other than the validation). Are you saying that since a project is going to use |
Yep, I am thinking that end-users could do something like this in Although it would be super slick if we could do something like: from torchvisions import transforms
# some magic where we auto-apply `as_builds` to everything in `transforms.__all__` and then
# return a corresponding namespace that exposes the config counterparts
cfg = hydrate(transforms)
cfg.Normalize # is actually partial(builds, transforms.Normalize) and in this way, the library maintainers don't have to do anything at all to make it easy to configure their stuff. |
👍 to I like that. I always hate that tab completion for imports would have |
The biggest blocker for this is getting static tooling to play nice. Right now, I can't think of any way to get Closing this for the time being. Hopefully #129 gets most of the job done. |
@rsokl What about a runtime check in the decorator - does that sufficiently handle the collision downside? def builds_decorator(f):
if hasattr(f, 'config'):
raise RuntimeError(f'{f.__name__}.config already exists, refusing to override with decorator')
f.config = builds(f, populate_full_signature=True)
return f Maybe you would also need to wrap |
@rsokl @jgbos regarding |
@addisonklinke That runtime check looks good to me. We could also name the attribute something like For now, I don't envision adding
You might be interested in my crude prototype for
We are familiar with hydra-torch, but thanks for pointing us to it! We had considered using it prior to our creating hydra-zen. One issue with an approach like hydra-torch is that the notion of spinning up a similar codebase for other third-party libraries simply is too cumbersome and requires too much repetition. Additionally, for some torch objects -- especially optimizers -- we often want to leverage partial instantiation, which isn't immediately possible with hydra-torch's configs. |
I have built out my own, and so far I really like how it's working out. I've been trying to think of an appropriate term for what it enables, and I think the closest is "object oriented packaging". I've written the decorator in such a way that my config groups mirror the hierarchy of the application's Python package. This makes it very intuitive to decide where certain class definitions should live and a new user could also understand the package quickly by reading the CLI Portions of the design have turned out to be more complex than I thought, and it would be great to discuss some more concrete details with you or any of the other Hydra-Zen authors. I'm actually presenting my tech stack at a MLOps.Community meetup and will focus heavily on the configuration system I built to power an experimentation-friendly PyTorch Lightning application with Hydra-Zen. If you all are interested, please hop in their Slack workspace and shoot me a DM - I'll get you added to the Google Meet invite. Anyone else reading this issue thread is also welcome to join
Thanks for the pointer! I'll continue on that PR thread
I also find it a little too complex to require a new |
This sounds great! I'd love to see what this design looks like. Perhaps you could point me to the code, or we could arrange a video call sometime so that we can chat about it. Ultimately, I am quite interested in facilitating this sort of design for library authors who want to create "Hydra-aware" code. |
Great looking forward to discussing further at the meetup! |
We had a discussion on Teams about possibly adding a
builds_decorator
of the form:Then we can automatically build configs for a function or class. For example, to get the config for the following function,
simply access the
config
attribute,The text was updated successfully, but these errors were encountered: