Skip to content
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

Experiments with Decorators #16

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

FelixBenning
Copy link

@FelixBenning FelixBenning commented May 5, 2023

Since that seminar on Thursday I wondered whether it would be possible to make model building much easier using decorators.

So right now if you have a function my_model, you have to create the umbridge class yourself

def my_model(params):
      # implementation

class MyModel(umbridge.Model):
       def __call__(self, params):
               return my_model(params)
               

I experimented a little with decorators, and it is fairly easy to remove this boilerplate with a decorator. Then the code above is replaced by:

@umbridge.autoUM()
def my_model(params):
      # implementation

I attached the code (I also experimented with the filestructure, so this looks like more than it is). It would also be possible to provide a default implementation for gradient, apply_jacobian and apply_hessian using autodiff libraries like jax.

I also think that you can probably use function introspection to avoid having the user manually implement supports_evaluate, etc. i.e. you would check if the function is implemented and return true or false depending on that.

For the transfer of data, I still think that Arrow might be a good fit (See also https://stackoverflow.com/a/75025713/6662425 and https://arrow.apache.org/docs/python/ipc.html).
It is trivial and often zero copy to translate the arrow format to numpy and similar other transformations are implemented.

get_input_sizes and get_output_sizes feel wrong. They seems to me like they should either be derived from the call signature (Python has type hints now after all) or not be enforced. If you used arrows format, then you would have (possibly named) data columns of arbitrary length. The column names could be the schema you enforce. The column length on the other hand could be flexible. Python, Julia, etc. all have variable length vectors and that includes C++ (std::vector) and many models can probably work for different input lengths. If they want to enforce a length, they could do so by themselves (using custom input validation). But if you enforce a length by default, then models which do not need to enforce this length (as they work in arbitrary dimension for example) are forced to pick a fixed dimension.

Talking about typing: Most of the code in the serve_models is just parsing the parameters from the JSON response and then validate those parameters. There are python api packages, which use the parameters in the function signature of the routes to parse the JSON automatically. They can also use type hints to do validation. That makes those routes much cleaner. The first package that did this was FastAPI I think. But it has only one maintainer who is unable to trust others with more priviledges, so people got a bit fed up with it and started the Litestar project, which has a much bigger pool of developers. If you are not married to aiohttp I could rewrite that code. (Performance should be on par, litestar advertises with faster performance than FastAPI and fastAPI is only slightly slower than aiohttp e.g. http://klen.github.io/py-frameworks-bench/)

I am itching to try these things, but I feel like I should probably wait whether or not you are interested in these changes.

@FelixBenning FelixBenning marked this pull request as draft May 5, 2023 17:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant