Skip to content

add predict_fn_or_cls as a bundle - #246

Merged
ivan-khomyakov-sc merged 13 commits into
hmi-releasefrom
ivan_k/upload_class_bundle
Mar 12, 2022
Merged

add predict_fn_or_cls as a bundle#246
ivan-khomyakov-sc merged 13 commits into
hmi-releasefrom
ivan_k/upload_class_bundle

Conversation

@ivan-khomyakov-sc

@ivan-khomyakov-sc ivan-khomyakov-sc commented Mar 4, 2022

Copy link
Copy Markdown

@ivan-khomyakov-sc
ivan-khomyakov-sc requested review from seanshi-scale, syandroo and yixu34 and removed request for seanshi-scale and syandroo March 4, 2022 17:48
Comment thread nucleus/deploy/client.py
Comment thread nucleus/deploy/client.py Outdated
Comment thread nucleus/deploy/client.py
@@ -103,6 +107,7 @@ def create_model_bundle(
model: Typically a trained Neural Network, e.g. a Pytorch module
load_model_fn: Function that when run, loads a model, e.g. a Pytorch module
load_predict_fn: Function that when called with model, returns a function that carries out inference

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the original type annotation of load_predict_fn was a Callable: Callable[[DeployModel_T], Callable[[Any], Any]]. In that case, maybe we don't need to create a new predict_fn_or_cls field, since load_predict_fn was already forwards compatible with the way you've specified the Bundle class with a __call__ method?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They have different usage:
a. predict_fn_or_cls

foo("woo") # returns inference result;
client.upload_bundle(predict_fn_or_cls=foo)

b. load_predict_fn

foo("woo") # returns inference result;

# incorrect:
client.upload_bundle(load_predict_fn=foo)

# correct:
def load_predict_fn(model):
    def predict(args):
          return foo(args)
    return predict

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean predict_fn_or_cls is a function/class that you can use directly in the service. load_predict_fn on the other hand is a factory that produces a callable object.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see, the absence or presence of the load prefix can serve as a distinction as to whether or not it's directly used or not 👌🏻

Comment thread nucleus/deploy/client.py Outdated
"""
Grabs a s3 signed url and uploads a model bundle to Scale Deploy.
A model bundle consists of a "load_predict_fn" and exactly one of "model" or "load_model_fn", such that
A model bundle consists of a "predict_fn_or_cls" or "load_predict_fn" and exactly one of "model" or "load_model_fn", such that

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the allowed combinations are {predict_fn_or_cls}, {load_predict_fn + model}, {load_predict_fn + load_model_fn}, I'm not sure if it's completely clear from reading this. Maybe something like "A model bundle consists of {predict_fn_or_cls}, {load_predict_fn + model}, or {load_predict_fn + load_model_fn}.".

Comment thread nucleus/deploy/client.py Outdated
if sum(check_args) != 1:
raise ValueError(
"Exactly one of model and load_model_fn should be non-None"
"Exactly one of `model` or `load_model_fn` or `predict_fn_or_cls` should be non-None"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we check that load_predict_fn doesn't get passed if a user passes predict_fn_or_cls?

Comment thread nucleus/deploy/client.py
load_predict_fn: Optional[
Callable[[DeployModel_T], Callable[[Any], Any]]
] = None,
predict_fn_or_cls: Optional[Callable[[Any], Any]] = None,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall I think this is fine for now, but we might as well start deprecating load_predict_fn later.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I guess same comment as https://github.com/scaleapi/models/pull/2684/files#r820019055, basically.

Comment thread nucleus/deploy/client.py Outdated
)
else:
bundle = dict(
bundle_func_2 = dict(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just call both of these bundle_func? These branches are mutually exclusive, so even Python's funky dynamic scoping rules wouldn't be an issue.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I did it for typing check that a linter performs. It complains that a variable bundle has different types in different branches, i.e dict/func/class_obj
I will play with the Optional[Dict...]

@ivan-khomyakov-sc
ivan-khomyakov-sc merged commit 2fec150 into hmi-release Mar 12, 2022
@ivan-khomyakov-sc
ivan-khomyakov-sc deleted the ivan_k/upload_class_bundle branch March 12, 2022 14:52
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.

3 participants