Fix OnnxDiscrepancyCheck crash on BF16 models — format_data cannot convert bfloat16 to NumPy#2585
Open
tadani3 wants to merge 3 commits into
Open
Fix OnnxDiscrepancyCheck crash on BF16 models — format_data cannot convert bfloat16 to NumPy#2585tadani3 wants to merge 3 commits into
tadani3 wants to merge 3 commits into
Conversation
added 2 commits
July 23, 2026 18:52
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes a crash in Olive’s ONNX input-feed formatting path when inputs are torch.bfloat16, by upcasting BF16 tensors to FP32 before converting to NumPy, then letting the existing NumPy dtype cast produce the desired ONNX input dtype.
Changes:
- Updated
olive.common.utils.format_datato upcasttorch.bfloat16tensors totorch.float32prior to calling.cpu().numpy(). - Added unit tests to cover BF16 regression behavior and ensure non-BF16 inputs remain byte-identical.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
olive/common/utils.py |
Adds a BF16-safe tensor→NumPy conversion path to prevent .numpy() from raising on BF16 tensors. |
test/common/test_format_data.py |
Adds coverage for BF16 inputs and regression tests for byte-identical behavior on other dtypes. |
Comment on lines
308
to
312
| return { | ||
| k: np.ascontiguousarray( | ||
| data[k].cpu().numpy() if isinstance(data[k], torch.Tensor) else data[k], | ||
| dtype=name_to_type[k], | ||
| ) | ||
| k: np.ascontiguousarray(_to_numpy(data[k]), dtype=name_to_type[k]) | ||
| for k in data | ||
| if k in input_names | ||
| } |
xiaoyu-work
reviewed
Jul 24, 2026
| @@ -0,0 +1,67 @@ | |||
| # ------------------------------------------------------------------------- | |||
Collaborator
There was a problem hiding this comment.
can you rename this file to test_utils.py?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Describe your changes
Summary
Fix
OnnxDiscrepancyCheck(and any other consumer offormat_data) crashing onBF16 models with
TypeError: Got unsupported ScalarType BFloat16.Background / previous logic
olive/common/utils.py::format_databuilds the ONNX input feed by callingtorch.Tensor.numpy()directly on each input tensor and then value-casting to thetarget ONNX dtype:
NumPy has no native bfloat16 dtype, so
torch.Tensor.numpy()raises for atorch.bfloat16tensor before the trailingdtype=name_to_type[k]cast can run.For a BF16 model,
OnnxDiscrepancyCheck._prepare_dataloadergenerates dummy inputs atthe ONNX graph's input dtypes, so float inputs (e.g.
past_key_values.*.key/value)arrive as
torch.bfloat16and trip this path. The identical flow with FP16 succeeds,which is the key signal that this is an input-feed-only gap.
BF16 is already handled correctly everywhere else in the pass:
discrepancy_check.py::_onnx_output_to_torchreinterprets ORT'suint16output backto
torch.bfloat16.discrepancy_check.py::_onnx_dtype_to_torchmapsonnx.TensorProto.BFLOAT16 → torch.bfloat16.common/utils.py::tensor_data_to_dtypealready includestorch.bfloat16.So
format_datawas the sole remaining gap.Change
format_datanow upcaststorch.bfloat16tensors tofloat32before.numpy(), thenlets the existing
np.ascontiguousarray(..., dtype=name_to_type[k])value-cast emit thecorrect target dtype (bf16 via
ml_dtypes, or fp16/fp32):Why fp32 (not a
uint16bit-reinterpret like the output side): the trailingdtype=is a value-preserving cast, so it needs an array whose values are correct. bf16 → fp32
is lossless (bf16 shares fp32's 8 exponent bits and has only 7 mantissa bits), so casting
back to bf16 returns the identical value. A
uint16.view()reinterpret would feedinteger bit-patterns into the value-cast and corrupt the data.
FP16/FP32/int and numpy-array inputs are untouched (no upcast branch taken), so their
feeds stay byte-identical.
Files changed
olive/common/utils.py—format_data: upcast bf16 → fp32 before.numpy().test/common/test_format_data.py— new unit tests.Checklist before requesting a review
lintrunner -aRelease note
Fixed a crash (
TypeError: Got unsupported ScalarType BFloat16) when running the ONNXdiscrepancy check / evaluation input feed on BF16 models.
(Optional) Issue link