-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
Support set schema inference function in python #5940
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: opluss <[email protected]>
We're spending a considerable amount of code on passing proto objects between C++ and Python. However, the repository seems well-prepared for this feature. |
Signed-off-by: opluss <[email protected]>
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #5940 +/- ##
==========================================
+ Coverage 56.95% 57.10% +0.14%
==========================================
Files 506 506
Lines 30467 30989 +522
Branches 4592 4601 +9
==========================================
+ Hits 17353 17696 +343
- Misses 12285 12467 +182
+ Partials 829 826 -3 ☔ View full report in Codecov by Sentry. |
Signed-off-by: oPluss <[email protected]>
add check in `InferenceContext` py wrapper Signed-off-by: opluss <[email protected]>
Signed-off-by: oPluss <[email protected]>
Signed-off-by: opluss <[email protected]>
Signed-off-by: opluss <[email protected]>
Hi @justinchuby , In this PR, we can implement shape inference on the Python side, similar to how it's done on the C++ side. If you have any suggestions for this implementation, I'm open to making adjustments accordingly. |
Thank you! Is it ready to be reviewed? |
Yes, I have removed the 'WIP' prefix from the title. Please feel free to leave any comments. :D |
) | ||
|
||
assert ctx.get_num_inputs() == 2 | ||
in0 = ctx.get_input_type(0) |
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.
My concern with this is it goes through serialization to access the type information. It is not really efficient. I would change the API so that it does not return a TypeProto but the type and the shape as regular python objects.
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 I agree with Xavier, but I am a bit confused also. I see the method implementation serializes proto values to string and returns them. We could just return a pointer to the C++ Proto object (wrapped as a Python object). Is that your suggestion Xavier?
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.
Should we closely mimic the C++ API design interface, or should we integrate Python's native types for interactions? Utilizing the proto pointer for interactions may require additional codes to bind them to Python (If there is another way please correct me), or we need to include some third-party library.
out.tensor_type.shape.dim.add().dim_value = N | ||
out.tensor_type.shape.dim.add().dim_value = La * Lb | ||
out.tensor_type.shape.dim.add().dim_value = out_len[i] | ||
ctx.set_output_type(i, out) |
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 comment here, we should avoid serialization with something like set_output_type_and_shape(in0_type, (N, La*Lb, out_lin[i])
. The type is created on C++ side, there is no serialization and it would be more efficient.
It would be a nice feature to have. |
@@ -114,6 +116,9 @@ PYBIND11_MODULE(onnx_cpp2py_export, onnx_cpp2py_export) { | |||
#endif // ONNX_ML | |||
); | |||
|
|||
// Avoid Segmentation fault if we not free the python function in Custom Schema | |||
onnx_cpp2py_export.add_object("_cleanup", py::capsule([] { OpSchemaRegistry::OpSchemaDeregisterAll(); })); |
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.
Can you clarify when this gets invoked?
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 the segfault is caused by:
The python object (the inference function in custom schema) need destroyed before the python interpreter is destroyed. The static container within the schema factory is destroyed after main function and before the interpreter. Therefore, we need to manually destroy the Python object.
About '_cleanup' : https://pybind11.readthedocs.io/en/stable/advanced/misc.html#module-destructors
Thanks for creating the PR! It would be great to add this functionality. My comments above. |
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.
Forgive my mistake, I didn't know that the response need to be commit manually. My reply is always in pending status.
@@ -114,6 +116,9 @@ PYBIND11_MODULE(onnx_cpp2py_export, onnx_cpp2py_export) { | |||
#endif // ONNX_ML | |||
); | |||
|
|||
// Avoid Segmentation fault if we not free the python function in Custom Schema | |||
onnx_cpp2py_export.add_object("_cleanup", py::capsule([] { OpSchemaRegistry::OpSchemaDeregisterAll(); })); |
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.
Perhaps a more graceful approach would be to collect the schemas registered from Python and deregister them during cleanup. However, I'm not sure if it's worth the effort. In most cases, invoking cleanup implies that Python is exiting.
) | ||
|
||
assert ctx.get_num_inputs() == 2 | ||
in0 = ctx.get_input_type(0) |
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.
Should we closely mimic the C++ API design interface, or should we integrate Python's native types for interactions? Utilizing the proto pointer for interactions may require additional codes to bind them to Python (If there is another way please correct me), or we need to include some third-party library.
@@ -114,6 +116,9 @@ PYBIND11_MODULE(onnx_cpp2py_export, onnx_cpp2py_export) { | |||
#endif // ONNX_ML | |||
); | |||
|
|||
// Avoid Segmentation fault if we not free the python function in Custom Schema | |||
onnx_cpp2py_export.add_object("_cleanup", py::capsule([] { OpSchemaRegistry::OpSchemaDeregisterAll(); })); |
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 the segfault is caused by:
The python object (the inference function in custom schema) need destroyed before the python interpreter is destroyed. The static container within the schema factory is destroyed after main function and before the interpreter. Therefore, we need to manually destroy the Python object.
About '_cleanup' : https://pybind11.readthedocs.io/en/stable/advanced/misc.html#module-destructors
I would do this in a different way. I think we should export in python all functions doing shape inference for every operator. We should have a python version of the algorithm doing shape inference. That way, adding new shape inference function would be easier and we could do local shape inference. This feature is needed when building a model. Shapes can be used to write efficient sequences of onnx operators. |
Hi Xavier, After thinking about it for a while, please correct me if my understanding is wrong. Implementing a Python version of shape inference may not eliminate the need to pass ONNX protos between C++ and Python. In the current architecture, if we want to obtain any proto in the shape inference function, we need to export Best Regards. |
Signed-off-by: opluss <[email protected]>
Description
Support set schema inference callback function for custion OpSchema before register in python.
example:
Note
Depends on #5906
Motivation and Context
Follow up of #5019