Skip to content

Conversation

@justinchuby
Copy link
Member

@justinchuby justinchuby commented Oct 3, 2025

This PR introduces the tofile method on tensors (similarly named as the one on numpy arrays), which allows for faster write and lower memory usage on external data by bypassing tobytes().

Compatibility with existing TensorProtocols is maintained in the external data module by using tofile only when it is available in the class. The TorchTensor class in PyTorch exporter should be updated accordingly to leverage the new logic when saving.

Note that io time to disk is reduced by 40% below.

Note

TensorProtocol is not updated because we do isinstance() checks on external implementations (PyTorch). Adding the method in the protocol will cause isinstance check to fail on those implementations that have not added the tofile method.

Reference: https://github.com/microsoft/onnxscript/pull/2241/files/b2381658492510a9bcc8c0a8574db7368e33bceb

Before:

________________________________________________________
Executed in   48.08 secs    fish           external
   usr time   60.54 secs    0.00 millis   60.54 secs
   sys time   23.06 secs    1.22 millis   23.06 secs
image image

After:

________________________________________________________
Executed in   45.69 secs    fish           external
   usr time   60.68 secs  244.00 micros   60.68 secs
   sys time   22.22 secs  518.00 micros   22.22 secs
image image

Fix #207

Signed-off-by: Justin Chu <[email protected]>
Signed-off-by: Justin Chu <[email protected]>
Signed-off-by: Justin Chu <[email protected]>
Signed-off-by: Justin Chu <[email protected]>
Signed-off-by: Justin Chu <[email protected]>
@codecov
Copy link

codecov bot commented Oct 3, 2025

Codecov Report

❌ Patch coverage is 81.96721% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.92%. Comparing base (feb51e5) to head (e3df4c9).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
src/onnx_ir/_core.py 80.85% 7 Missing and 2 partials ⚠️
src/onnx_ir/external_data.py 66.66% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #210      +/-   ##
==========================================
+ Coverage   76.83%   76.92%   +0.08%     
==========================================
  Files          40       40              
  Lines        4922     4992      +70     
  Branches      980      996      +16     
==========================================
+ Hits         3782     3840      +58     
- Misses        856      864       +8     
- Partials      284      288       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Signed-off-by: Justin Chu <[email protected]>
Signed-off-by: Justin Chu <[email protected]>
Signed-off-by: Justin Chu <[email protected]>
Signed-off-by: Justin Chu <[email protected]>
@justinchuby justinchuby marked this pull request as ready for review October 4, 2025 00:44
@justinchuby justinchuby requested review from a team and titaiwangms as code owners October 4, 2025 00:44
@justinchuby justinchuby added this to the 0.1.11 milestone Oct 4, 2025
@justinchuby
Copy link
Member Author

cc @iksnagreb

@sonarqubecloud
Copy link

sonarqubecloud bot commented Oct 4, 2025

@justinchuby justinchuby changed the title Implement tofile on tensors Implement tofile on tensors to reduce data write time by 40% Oct 6, 2025
Signed-off-by: Justin Chu <[email protected]>
Signed-off-by: Justin Chu <[email protected]>
Signed-off-by: Justin Chu <[email protected]>
Signed-off-by: Justin Chu <[email protected]>
@justinchuby
Copy link
Member Author

@titaiwangms @gramalingam this is ready for review, thanks.

Signed-off-by: Justin Chu <[email protected]>
Signed-off-by: Justin Chu <[email protected]>
Signed-off-by: Justin Chu <[email protected]>
"""Return the bytes of the tensor."""
return self._evaluate().tobytes()

def tofile(self, file) -> None:
Copy link
Collaborator

Choose a reason for hiding this comment

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

I am wondering whether tofile() makes sense to LazyTensor. hmm

Copy link
Member Author

Choose a reason for hiding this comment

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

Can you say more?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I just thought it's not even real until it's evaluated. Intuitively, not very suitable with tofile(), which we want to write it to disk. But I guess in general expectation, we want all tensors have this method. It's understandable.

Copy link
Member Author

@justinchuby justinchuby Oct 10, 2025

Choose a reason for hiding this comment

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

It is actually useful: even when the tensor is lazily evaluated, we still want to avoid tobytes() making a copy of the tensor data before writing to file. The screenshots on the PR description are showing lazy tensors.

Signed-off-by: Justin Chu <[email protected]>
Signed-off-by: Justin Chu <[email protected]>
Signed-off-by: Justin Chu <[email protected]>
Signed-off-by: Justin Chu <[email protected]>
Signed-off-by: Justin Chu <[email protected]>
@justinchuby justinchuby merged commit 43ebf47 into main Oct 10, 2025
23 checks passed
@justinchuby justinchuby deleted the justinchu/write branch October 10, 2025 19:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create a tofile() method on Tensors that will avoid potential tobytes() call when serializing

3 participants