-
Notifications
You must be signed in to change notification settings - Fork 265
feat: Decorators - part 2 #607
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
Conversation
moved the exception to the errors file.
made some fixes to code
linting changes.
|
||
2. Create a Python class that inherits from `PytorchClassifierAbstractUDF`. | ||
|
||
* The `PytorchClassifierAbstractUDF` is a parent class that defines and implements standard methods for model inference. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we introducing PytorchClassifierAbstractUDF
upfront? How about we break it into using AbstractUDF
etc.? And it is not a classification job so we should also change it in the system.
We had a bad design earlier, let us carefully fix most of it now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to do this in this PR or a different one?
Create a new PR with only the documentation. Thanks! |
We need more descriptive documentation.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How many overhead will this bring? Are we doing the input and output check on every forward call?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes we will be checking it on every forward call.
I don't think there will be a lot of overhead as we are using the library functions and just doing basic shape and type checking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we can have some numbers, that will be great. Do you know why we are not considering a more static type checking?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of checking on every forward
call, we could optimistically assume that once the first forward
works, the remaining forward
calls will be on similar data shape etc. Just a boolean variable for the first check (self.check) might be sufficient for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can have it as input from the user (check_inputs
). And default to always doing it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added this parameter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added some comments, mostly looks good to me. Thanks @IshSiva !
eva/udfs/decorators/decorators.py
Outdated
# the first object in the forward function is self so we start from the second object | ||
input_signature.validate_object(args[i + 1], True) | ||
) | ||
except UDFIODefinitionError as e: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's better to use the assert style syntax that we have adopted in other parts of the code recently. @gaurav274 what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since converting the shape or data type might throw an exception I am using the try-except
try: | ||
object = self.check_array_and_convert_type(object) | ||
except Exception as e: | ||
if input_flag: | ||
msg = "Data type mismatch of Input parameter. " | ||
else: | ||
msg = "Data type mismatch of Output parameter." | ||
raise UDFIODefinitionError(msg) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moving to assert syntax will mostly cleanup code by avoiding try and except everywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The assert statement can have the appropriate message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same response as before, the shape conversions might throw an error if its not possible, hence used try-except
object = self.check_array_and_convert_shape(object) | ||
except Exception as e: | ||
if input_flag: | ||
msg = "Shape mismatch of Input parameter. " | ||
else: | ||
msg = "Shape mismatch of Output parameter." | ||
raise UDFIODefinitionError(msg) | ||
|
||
return object |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above.
@@ -41,6 +44,46 @@ def __init__( | |||
array_dimensions=dimensions, | |||
) | |||
|
|||
def check_array_and_convert_shape(self, input_object): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to be converting data on our own? Or should that be an additional flag? For example user specifies that all data should be converted to this the given IOSignature format. We assert if it isn't possible
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel that it is redundant to add another flag given that we have check_input and check_output flags.
def check_array_and_convert_shape(self, input_object): | ||
try: | ||
return torch.reshape(input_object, self.array_dimensions) | ||
|
||
except Exception as e: | ||
raise UDFIODefinitionError( | ||
"The input object cannot be reshaped to %s. Error is %s" | ||
% (self.array_dimensions, str(e)) | ||
) | ||
|
||
def check_array_and_convert_type(self, input_object): | ||
|
||
if not isinstance(input_object, torch.Tensor): | ||
if isinstance(input_object, list): | ||
input_object = torch.Tensor(input_object) | ||
elif isinstance(input_object, np.ndarray): | ||
input_object = torch.from_numpy(input_object) | ||
else: | ||
raise UDFIODefinitionError( | ||
"Unknown data type. Only input types List and Tensor can be converted to Numpy array" | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above.
@suryatejreddy Please help review this. |
@IshSiva mentioned that we could close this PR and revert the @gaurav274 @xzdandy Does that sound good? |
Sounds good, We will redesign in #1017 . |
This PR has the code to perform type checking and shape checking in the decorators. It also has the documentation for using decorators in the EVA UDFs.