dnn test: move layer norm tests into conformance tests#24544
dnn test: move layer norm tests into conformance tests#24544asmorkalov merged 5 commits intoopencv:4.xfrom
Conversation
| if (op_type == "LayerNormalization") { | ||
| net.mutable_output()->DeleteSubrange(1, 2); | ||
| } | ||
| } |
There was a problem hiding this comment.
Isn't the problem in the test ONNX models? Shall they be exported in eval() mode?
There was a problem hiding this comment.
No. They are generated by the ONNX official. You can find most of them in https://github.com/onnx/onnx/tree/main/onnx/backend/test/data/node.
These models and tests are added via #21088.
Also related issue to check ONNX operator coverage: #21078.
There was a problem hiding this comment.
I checked all ONNX operators with optional outputs. Turns out there are only BatchNormalization, Dropout, LayerNormalization and MaxPool which have optional outputs for training. All except LayerNormalization have conformance models set for training mode and eval mode. Some of them have training outputs, some dont, so we can still use those without training outputs for conformance tests. But this is not the case with LayerNormalization. All LayerNormalization conformance models have training outputs. Blame ONNX for that.
Seems like this patch is meaningful only for LayerNormalization. What do you think?
There was a problem hiding this comment.
As tests passed and layers' outputs do not depend in train/eval phase on which they were exported to ONNX, I'm fine.
The only concern is that changes made in the unrelated graph fusion method. Can this be moved to parseLayerNorm from onnx_importer.cpp?
There was a problem hiding this comment.
Can this be moved to parseLayerNorm from onnx_importer.cpp?
AFAIK, it is not feasible because for conformance tests like I present above their ouputs are attached to graph outputs, and we cannot modify graph proto inside parseLayerNorm.
The only concern is that changes made in the unrelated graph fusion method.
I put conditions to ensure node_size == 1, op_type == "LayerNormalization" and node_output_size > 1. I think it should be safe for basically all models, since they have more than one node even after fusion.
There was a problem hiding this comment.
@fengyuentau, please try this:
--- a/modules/dnn/src/onnx/onnx_graph_simplifier.cpp
+++ b/modules/dnn/src/onnx/onnx_graph_simplifier.cpp
@@ -1184,18 +1184,6 @@ void simplifySubgraphs(opencv_onnx::GraphProto& net)
subgraphs.push_back(makePtr<NormalizeSubgraph5>());
simplifySubgraphs(Ptr<ImportGraphWrapper>(new ONNXGraphWrapper(net)), subgraphs);
-
- // remove training outputs for conformance tests
- if (net.node().size() == 1) {
- const auto &node = net.node(0);
- const auto &op_type = node.op_type();
- if (op_type == "LayerNormalization") {
- if (net.output_size() > 1) {
- int num = net.output_size() - 1;
- net.mutable_output()->DeleteSubrange(1, num);
- }
- }
- }
}
Mat getMatFromTensor(const opencv_onnx::TensorProto& tensor_proto)
diff --git a/modules/dnn/src/onnx/onnx_importer.cpp b/modules/dnn/src/onnx/onnx_importer.cpp
index 28dd4d9b77..80f57c4156 100644
--- a/modules/dnn/src/onnx/onnx_importer.cpp
+++ b/modules/dnn/src/onnx/onnx_importer.cpp
@@ -3187,6 +3187,17 @@ void ONNXImporter::parseLayerNorm(LayerParams& layerParams, const opencv_onnx::N
// Remove additional outputs (Mean, InvStdDev)
if (node_proto.output_size() > 1)
{
+ for (size_t i = 1; i < node_proto.output_size(); ++i)
+ {
+ for (int j = graph_proto.output_size() - 1; j >= 0; --j)
+ {
+ if (graph_proto.output(j).name() == node_proto.output(i))
+ {
+ graph_proto.mutable_output()->DeleteSubrange(j, 1);
+ break;
+ }
+ }
+ }
auto outputName = node_proto.output(0);
opencv_onnx::NodeProto node_proto_ = node_proto;
node_proto_.clear_output();There was a problem hiding this comment.
I did not know graph_proto is available inside each parseXXX. Thanks, it works.
dnn: add openvino, opencl and cuda backends for layer normalization layer #24552 Merge after #24544. Todo: - [x] openvino - [x] opencl - [x] cuda ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake
dnn test: move layer norm tests into conformance tests opencv#24544 Merge with opencv/opencv_extra#1122 ## Motivation Some ONNX operators, such as `LayerNormalization`, `BatchNormalization` and so on, produce outputs for training (mean, stdev). So they have reference outputs of conformance tests for those training outputs as well. However, when it comes to inference, we do not need and produce those outputs for training here in dnn. Hence, output size does not match if we use dnn to infer those conformance models. This has become the barrier if we want to test these operators using their conformance tests. <!-- | Operator | Inference needed | Outputs (required - total) | Optional outputs for training? | | ----------------------- | ----------------------------------- | -------------------------- | ------------------------------ | | BatchNormalization | Yes | 1 - 3 | Yes | | Dropout | Maybe, can be eliminated via fusion | 1 - 2 | Yes | | GRU | Yes | 0 - 2 | No | | LSTM | Yes | 0 - 3 | No | | LayerNormalization | Yes | 1 - 3 | Yes | | MaxPool | Yes | 1 - 2 | Yes | | RNN | Yes | 0 - 2 | No | | SoftmaxCrossEntropyLoss | No | 1 - 2 | -- | --> **I checked all ONNX operators with optional outputs. Turns out there are only `BatchNormalization`, `Dropout`, `LayerNormalization` and `MaxPool` has optional outputs for training. All except `LayerNormalization` have models set for training mode and eval mode. Blame ONNX for that.** ## Solution In this pull request, we remove graph outputs if the graph looks like the following: ``` [X] [Scale] [Bias] [X] [Scale] [Bias] \ | / this patch \ | / LayerNormalization -----------> LayerNormalization / | \ | [Y] [Mean] [Stdev] [Y] ``` We can update conformance tests and turn on some cases as well if extending to more layers. Notes: 1. This workaround does not solve expanded function operators if they are fused into a single operator, such as `$onnx/onnx/backend/test/data/node/test_layer_normalization_2d_axis1_expanded`, but they can be run without fusion. Note that either dnn or onnxruntime does not fuse those expanded function operators. ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake
dnn: add openvino, opencl and cuda backends for layer normalization layer opencv#24552 Merge after opencv#24544. Todo: - [x] openvino - [x] opencl - [x] cuda ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake
dnn test: move layer norm tests into conformance tests opencv#24544 Merge with opencv/opencv_extra#1122 ## Motivation Some ONNX operators, such as `LayerNormalization`, `BatchNormalization` and so on, produce outputs for training (mean, stdev). So they have reference outputs of conformance tests for those training outputs as well. However, when it comes to inference, we do not need and produce those outputs for training here in dnn. Hence, output size does not match if we use dnn to infer those conformance models. This has become the barrier if we want to test these operators using their conformance tests. <!-- | Operator | Inference needed | Outputs (required - total) | Optional outputs for training? | | ----------------------- | ----------------------------------- | -------------------------- | ------------------------------ | | BatchNormalization | Yes | 1 - 3 | Yes | | Dropout | Maybe, can be eliminated via fusion | 1 - 2 | Yes | | GRU | Yes | 0 - 2 | No | | LSTM | Yes | 0 - 3 | No | | LayerNormalization | Yes | 1 - 3 | Yes | | MaxPool | Yes | 1 - 2 | Yes | | RNN | Yes | 0 - 2 | No | | SoftmaxCrossEntropyLoss | No | 1 - 2 | -- | --> **I checked all ONNX operators with optional outputs. Turns out there are only `BatchNormalization`, `Dropout`, `LayerNormalization` and `MaxPool` has optional outputs for training. All except `LayerNormalization` have models set for training mode and eval mode. Blame ONNX for that.** ## Solution In this pull request, we remove graph outputs if the graph looks like the following: ``` [X] [Scale] [Bias] [X] [Scale] [Bias] \ | / this patch \ | / LayerNormalization -----------> LayerNormalization / | \ | [Y] [Mean] [Stdev] [Y] ``` We can update conformance tests and turn on some cases as well if extending to more layers. Notes: 1. This workaround does not solve expanded function operators if they are fused into a single operator, such as `$onnx/onnx/backend/test/data/node/test_layer_normalization_2d_axis1_expanded`, but they can be run without fusion. Note that either dnn or onnxruntime does not fuse those expanded function operators. ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake
dnn: add openvino, opencl and cuda backends for layer normalization layer opencv#24552 Merge after opencv#24544. Todo: - [x] openvino - [x] opencl - [x] cuda ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake
Merge with opencv/opencv_extra#1122
Motivation
Some ONNX operators, such as
LayerNormalization,BatchNormalizationand so on, produce outputs for training (mean, stdev). So they have reference outputs of conformance tests for those training outputs as well. However, when it comes to inference, we do not need and produce those outputs for training here in dnn. Hence, output size does not match if we use dnn to infer those conformance models. This has become the barrier if we want to test these operators using their conformance tests.I checked all ONNX operators with optional outputs. Turns out there are only
BatchNormalization,Dropout,LayerNormalizationandMaxPoolhas optional outputs for training. All exceptLayerNormalizationhave models set for training mode and eval mode. Blame ONNX for that.Solution
In this pull request, we remove graph outputs if the graph looks like the following:
We can update conformance tests and turn on some cases as well if extending to more layers.
Notes:
$onnx/onnx/backend/test/data/node/test_layer_normalization_2d_axis1_expanded, but they can be run without fusion. Note that either dnn or onnxruntime does not fuse those expanded function operators.Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
Patch to opencv_extra has the same branch name.