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

[WebNN EP] Support Einsum op #19558

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

peishenyan
Copy link
Contributor

Adds support for einsum via WebNN matmul, transpose, reshape, reducesum, identity and element-wise binary ops.

Copy link
Contributor

@Honry Honry left a comment

Choose a reason for hiding this comment

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

Thanks @peishenyan, some comments.

@peishenyan
Copy link
Contributor Author

Thanks @Honry , comments addressed.
@fdwr , @guschmue , PTAL, thanks!

@peishenyan
Copy link
Contributor Author

peishenyan commented Feb 26, 2024

Hi, all. Last week, I implemented Einsum based on the DML execution provider's implementation, which only support a few conditions. However, Einsum('bhwc,hkc->bhwk', A, B) cannot be handled in ``Segment Anything Encoder''.

Now, according to Einsum Formula in ML Operator Formulas, I implement pair-wise operand processing for handling two inputs and kept the previously implemented single operand processing (Identity, Transpose and ReduceSum.)

@peishenyan
Copy link
Contributor Author

Since WebNN does not support Triangular op so far and Diagonal depends on triangular, WebNN will fallback when the Einsum op is used for Diagonal operation.

One more thing, in Segment Anything Encoder model, the output shape of Einsum is not defined, which is the input of some Unsqueeze operation, while WebNN does not support dynamic shape. We need additional work to solve this problem in another work branch.

@peishenyan
Copy link
Contributor Author

I will leave for about one week for my research paper submission. Responses may be delayed.

@Honry
Copy link
Contributor

Honry commented Feb 27, 2024

Thanks @peishenyan!

@guschmue, @fdwr, PTAL thanks!

One more thing, in Segment Anything Encoder model, the output shape of Einsum is not defined, which is the input of some Unsqueeze operation, while WebNN does not support dynamic shape. We need additional work to solve this problem in another work branch.

@guschmue, @fdwr, the output shape of Einsum is not provided in the ONNX graph even it is a static shape model. You know its output shape could only be calculated via its equation expression and input shape.

So my question is, is that possible to calculate and add its output shape info to the graph during ORT Web graph optimization?

@fdwr
Copy link
Contributor

fdwr commented Feb 27, 2024

So my question is, is that possible to calculate and add its output shape info to the graph during ORT Web graph optimization?

Are you saying that ORT is not doing shape inference properly for EinSum? The DML EP (which also needs constant shapes before DML CompileGraph is called) registers its own shape inference function for EinSum here

// Generate output dimensions from corresponding input tensor labels.
// e.g. Given ij,jk->ij with [2,3] and [3,5], the output is [2,5].
std::vector<uint32_t> outputDimensions;
auto outputLabelIndices = m_components.back().GetLabels(m_labelIndices);
for (auto labelIndex : outputLabelIndices)
{
outputDimensions.push_back(labelSizes[labelIndex]);
}
return { EdgeShapes(outputDimensions) };
, which (if you've already parsed the components) isn't too long/complicated.

Since WebNN does not support Triangular op so far and Diagonal depends on triangular, WebNN will fallback when the Einsum op is used for Diagonal operation.

👍 Lisha is working on it (and I drew some whiteboard diagrams on decomposing it for DML feature level 4). It should be available soon.

... my research paper submission

Thanks for creating this - hope your research paper goes well.

@Honry
Copy link
Contributor

Honry commented Feb 27, 2024

Are you saying that ORT is not doing shape inference properly for EinSum?

Right, ORT doesn't do shape inference for EinSum, we couldn't get the input shape of EinSum node's following nodes from the graph, e.g. in following snapshot, we couldn't get the Usqueeze node's input shape. Thus this op will be fallback to wasm as we do dynamic input shape check at https://github.com/microsoft/onnxruntime/blob/main/onnxruntime/core/providers/webnn/builders/helper.cc#L73.

image

The DML EP (which also needs constant shapes before DML CompileGraph is called) registers its own shape inference function for EinSum here

Interesting, how and when does DML EP register the shape info to the graph?

@guschmue guschmue added the ep:WebNN WebNN execution provider label Feb 27, 2024
Copy link
Contributor

@fdwr fdwr left a comment

Choose a reason for hiding this comment

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

Thanks Peishen. I'm still trying to figure out PairwiseOperandProcess (some more comments/visuals/examples could help, especially future generations), but I reviewed the rest of it.

@peishenyan
Copy link
Contributor Author

Hi @fdwr , I have addressed most of the comments, but the code is not ready for final review now.
As @Honry said before, the output shape of Einsum is not provided in the ONNX graph. We found that we could use onnx shape inference to achieve almost all output shapes except the output shape of Einsum. Since there was only Rank Inference function for Einsum instead of Shape Inference, we implemented Shape Infernce for Einusm in onnx/onnx#6010 to address this problem, which is still waiting for review and merge.
Furthermore, I am working on supporting parsing ellipsis in equation and diagnoal now~

@peishenyan
Copy link
Contributor Author

Hi @Honry @fdwr , I have addressed all the comments and we decide to implement the extended features (diagonal and ellipsis parsing) in the future, which will not be included in this PR. This PR is ready for review. PTAL. Thanks

@tianleiwu
Copy link
Contributor

/azp run Windows ARM64 QNN CI Pipeline,Windows x64 QNN CI Pipeline,Windows CPU CI Pipeline,Windows GPU CI Pipeline,Windows GPU TensorRT CI Pipeline,ONNX Runtime Web CI Pipeline,Linux CPU CI Pipeline,Linux CPU Minimal Build E2E CI Pipeline,Linux GPU CI Pipeline,Linux GPU TensorRT CI Pipeline

@tianleiwu
Copy link
Contributor

/azp run Linux OpenVINO CI Pipeline,Linux QNN CI Pipeline,MacOS CI Pipeline,orttraining-amd-gpu-ci-pipeline,orttraining-linux-ci-pipeline,orttraining-linux-gpu-ci-pipeline,orttraining-ortmodule-distributed,onnxruntime-binary-size-checks-ci-pipeline,Big Models

Copy link

Azure Pipelines successfully started running 9 pipeline(s).

Copy link

Azure Pipelines successfully started running 10 pipeline(s).

@tianleiwu
Copy link
Contributor

Any test can cover the op in WebNN EP?

@Honry
Copy link
Contributor

Honry commented Apr 6, 2024

Any test can cover the op in WebNN EP?

@tianleiwu, good point!

@peishenyan has ever tested the following unit tests, but which are all fp64 data type that currently is not supported by WebNN. Is that possible to change the data type to fp32?
https://github.com/microsoft/onnxruntime/blob/main/js/web/test/suite-test-list.jsonc#L1731-L1735

Copy link
Contributor

@fdwr fdwr left a comment

Choose a reason for hiding this comment

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

TY Peishen. Some more thoughts. I'll make a few trivial edits directly (little typos), and for the renaming, we can go ahead and submit as-is if you can follow up in a small CR to make some of the local variable names cleaner.


std::vector<uint32_t> sequence_o(output_indices.size());
std::iota(sequence_o.begin(), sequence_o.end(), 0);
if (v != sequence_o) {
Copy link
Contributor

@fdwr fdwr Jun 21, 2024

Choose a reason for hiding this comment

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

  if (output_permutation != sequence_o) {

We should use a clearer name than just "v". Does output_permutation make sense here? With the exception of really common cases (like i for loop counters and x,y,z for coordinates), single letter variable names are best avoided. Similarly s and t are unclear what they stand for?

@fdwr
Copy link
Contributor

fdwr commented Jun 21, 2024

/azp run Windows ARM64 QNN CI Pipeline,Windows x64 QNN CI Pipeline,Windows CPU CI Pipeline,Windows GPU CI Pipeline,Windows GPU TensorRT CI Pipeline,ONNX Runtime Web CI Pipeline,Linux CPU CI Pipeline,Linux CPU Minimal Build E2E CI Pipeline,Linux GPU CI Pipeline,Linux GPU TensorRT CI Pipeline

@fdwr
Copy link
Contributor

fdwr commented Jun 21, 2024

/azp run Linux OpenVINO CI Pipeline,Linux QNN CI Pipeline,MacOS CI Pipeline,orttraining-amd-gpu-ci-pipeline,orttraining-linux-ci-pipeline,orttraining-linux-gpu-ci-pipeline,orttraining-ortmodule-distributed,onnxruntime-binary-size-checks-ci-pipeline,Big Models

Copy link

Azure Pipelines successfully started running 10 pipeline(s).

Copy link

Azure Pipelines successfully started running 9 pipeline(s).

@fdwr
Copy link
Contributor

fdwr commented Jun 21, 2024

/azp run Linux Android Emulator QNN CI Pipeline

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@fdwr
Copy link
Contributor

fdwr commented Jun 25, 2024

/azp run Windows ARM64 QNN CI Pipeline,Windows x64 QNN CI Pipeline,Windows CPU CI Pipeline,Windows GPU CI Pipeline,Windows GPU TensorRT CI Pipeline,ONNX Runtime Web CI Pipeline,Linux CPU CI Pipeline,Linux CPU Minimal Build E2E CI Pipeline,Linux GPU CI Pipeline,Linux GPU TensorRT CI Pipeline

@fdwr
Copy link
Contributor

fdwr commented Jun 25, 2024

/azp run Linux OpenVINO CI Pipeline,Linux QNN CI Pipeline,MacOS CI Pipeline,orttraining-amd-gpu-ci-pipeline,orttraining-linux-ci-pipeline,orttraining-linux-gpu-ci-pipeline,orttraining-ortmodule-distributed,onnxruntime-binary-size-checks-ci-pipeline,Big Models

Copy link

Azure Pipelines successfully started running 10 pipeline(s).

Copy link

Azure Pipelines successfully started running 9 pipeline(s).

@fdwr
Copy link
Contributor

fdwr commented Jun 25, 2024

/azp run Linux Android Emulator QNN CI Pipeline

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@peishenyan
Copy link
Contributor Author

Hi @fdwr, long time no see. Really appreciate your help. I will address the comments today~
BTW, I remember a few months ago when I ran ORT WebNN EP without onnx shape inference, it aborted because the output could not be registered (no output shape). I'm not sure if this branch can be merged before onnx 1.17 is ready, and I will confirm this today.

@peishenyan
Copy link
Contributor Author

Hi all, I have addressed the comments in the latest commit.
However, without onnx v1.17 the ORT with WebNN EP will crash because the output of einsum op is not registered correctly. This branch should not be merged until onnx v1.17 is ready. Thanks.

@fdwr
Copy link
Contributor

fdwr commented Jun 25, 2024

This branch should not be merged until onnx v1.17 is ready.

Thanks for confirmation. Ok, will defer merging. So then for any models that need the shape inference logic (like the Segment Anything encoder https://github.com/microsoft/webnn-developer-preview/blob/main/demos/segment-anything/index.js#L739), we'll need a custom build of ORT and copy the .wasm files onto the server.

@fdwr
Copy link
Contributor

fdwr commented Oct 3, 2024

Relevant! #21897

Address comments

register einsum op

add logs for einsum

Fully implement Einsum op for WebNN EP

Address comments

address comments

fix bugs

fix bugs

add some comments and fix einsum_type error

lint and apply the fixes

address comments

add TODO and fix identity case

remove useless code

fix permutation error

Apply suggestions from code review

Typos and minor declaration.

address comments

add datatype check and modify IsOpSupported check

add diagonal and fix some bugs
@Honry
Copy link
Contributor

Honry commented Oct 11, 2024

#22376 this is landed!

@fdwr, Peishen has resolved the conflict and applied latest OpSupportLimits feature, pls. take another look, thanks!

@tianleiwu
Copy link
Contributor

/azp run Windows ARM64 QNN CI Pipeline,Windows x64 QNN CI Pipeline,Windows CPU CI Pipeline,Windows GPU CUDA CI Pipeline,Windows GPU DML CI Pipeline,Windows GPU Doc Gen CI Pipeline,Windows GPU TensorRT CI Pipeline,ONNX Runtime Web CI Pipeline,Linux CPU CI Pipeline,Linux CPU Minimal Build E2E CI Pipeline

@tianleiwu
Copy link
Contributor

/azp run Linux GPU CI Pipeline,Linux GPU TensorRT CI Pipeline,Linux OpenVINO CI Pipeline,Linux QNN CI Pipeline,MacOS CI Pipeline,orttraining-amd-gpu-ci-pipeline,orttraining-linux-ci-pipeline,orttraining-linux-gpu-ci-pipeline,orttraining-ortmodule-distributed,onnxruntime-binary-size-checks-ci-pipeline

@tianleiwu
Copy link
Contributor

/azp run Big Models,Linux Android Emulator QNN CI Pipeline,Android CI Pipeline,iOS CI Pipeline,ONNX Runtime React Native CI Pipeline

Copy link

Azure Pipelines successfully started running 5 pipeline(s).

Copy link

Azure Pipelines successfully started running 8 pipeline(s).

Copy link

Azure Pipelines successfully started running 10 pipeline(s).

@peishenyan
Copy link
Contributor Author

Hi @fdwr, do you have any other comment? Could we merge this branch?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ep:WebNN WebNN execution provider
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants