-
Notifications
You must be signed in to change notification settings - Fork 666
Add IOBinding support to ONNX Runtime module #421
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
Merged
Merged
Changes from 6 commits
Commits
Show all changes
53 commits
Select commit
Hold shift + click to select a range
7b058e5
Create IOBinding helper and Type helper
JingyaHuang a82f2ab
fix style
JingyaHuang 9ff48be
Apply IOBinding helper to causallm model
JingyaHuang a0ae729
remove useless
JingyaHuang ee7afd5
Update docstring
JingyaHuang c280fa2
Add use_io_binding args
JingyaHuang adfbc6a
Fix case
JingyaHuang bef7f4d
Fix doctring
JingyaHuang dd7db8f
Fix docstring
JingyaHuang cd06b9a
Fix case
JingyaHuang 92ff5de
Improve class description
JingyaHuang a4f70c5
Improve class description
JingyaHuang ec60023
Complete comment
JingyaHuang da6fe5a
Fix use_io_binding value define bug
JingyaHuang 0729d0b
Fix typos
JingyaHuang 9446274
np to numpy
JingyaHuang 80e9c1a
Replace asserts with error raise
JingyaHuang 4ddfcdb
Add io binding return type
JingyaHuang 0c8813c
Add is_onnxruntime_training_available in utils
JingyaHuang a07b6a8
Apply io binding to encoders
JingyaHuang f08479f
Also for custom tasks
JingyaHuang 8c7d82e
Improve use_io_binding args
JingyaHuang e97769b
Apply io binding for seq2seq
JingyaHuang a5e599b
seq2seq io binding bug fix
JingyaHuang 7dcaff8
nits
JingyaHuang 78a5106
remove zip when outputs are fixed
JingyaHuang cd999d4
Check cupy availability
JingyaHuang 2ec100f
Move io binding preparation to causal model
JingyaHuang 369c441
move io binding preparation for other ort models
JingyaHuang 2424e33
Move io binding to ort seq2seq model
JingyaHuang 3918234
Bind output tensors directly for causal lm
JingyaHuang c2e9d5d
Remove useless in IO helper
JingyaHuang a3ac26c
Fix test name
JingyaHuang fffcccc
Direct binding for multi-choice/im-cls/custom
JingyaHuang b218758
Direct binding for all other ort models
JingyaHuang 6c38d46
Remove IO binding for ORTModelForCustomModels
JingyaHuang c774f38
Remove unused import
JingyaHuang ede2895
Merge main
JingyaHuang 5236a15
IO binding added for seq2seq model
JingyaHuang 9f5a2a3
modify for comments
JingyaHuang fb1680d
Revert dependencies for anothet PR
JingyaHuang 07f3248
Add IO binding tests for Encoder/Decoder
JingyaHuang b90ae76
Add config for passing seq2seq modeling tests
JingyaHuang aadd037
Improve seq2seq buffer size
JingyaHuang e98ee95
Add test for seq2seq
JingyaHuang 855bad5
Add tests for generation
JingyaHuang 56bf6c6
Merge branch 'main' into add-ort-iobinding
JingyaHuang cc51dc6
Fix doc
JingyaHuang 095268b
Add comments
JingyaHuang 479be02
Merge branch 'add-ort-iobinding' of https://github.com/huggingface/op…
JingyaHuang c0eea41
Add warning for TensorRT
JingyaHuang a6021a6
Merge main branch
JingyaHuang 505ed8c
Test: allclose -> equal
JingyaHuang File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| # Copyright 2022 The HuggingFace Team. All rights reserved. | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
| from .io_binding_helper import IOBindingHelper, TypeHelper |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,170 @@ | ||
| # Copyright 2022 The HuggingFace Team. All rights reserved. | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| import logging | ||
| import traceback | ||
| from typing import Dict | ||
|
|
||
| import numpy as np | ||
| import torch | ||
|
|
||
| import onnxruntime as ort | ||
| import pkg_resources | ||
| from onnxruntime import InferenceSession | ||
| from onnxruntime.capi.onnxruntime_inference_collection import OrtValue | ||
| from onnxruntime.transformers.io_binding_helper import TypeHelper as ORTTypeHelper | ||
|
|
||
|
|
||
| # adapted from https://github.com/microsoft/onnxruntime/blob/93e0a151177ad8222c2c95f814342bfa27f0a64d/onnxruntime/python/tools/transformers/io_binding_helper.py#L12 | ||
| class TypeHelper(ORTTypeHelper): | ||
| """ | ||
| TypeHelper helps get data type information of the ONNX runtime inference session and offers the mapping from | ||
|
JingyaHuang marked this conversation as resolved.
Outdated
|
||
| OrtValues data type to the data type of other data structures(numpy, torch tensor...). | ||
|
JingyaHuang marked this conversation as resolved.
Outdated
|
||
| """ | ||
|
|
||
| # TODO: Current DLPack doesn't support boolean tensor, use uint8 as workaround, remove after it is supported. | ||
| @staticmethod | ||
| def ort_type_to_numpy_type(ort_type: str): | ||
| ort_type_to_numpy_type_map = { | ||
| "tensor(int64)": np.int64, | ||
| "tensor(int32)": np.int32, | ||
| "tensor(int8)": np.int8, | ||
| "tensor(float)": np.float32, | ||
| "tensor(float16)": np.float16, | ||
| "tensor(bool)": np.uint8, | ||
| } | ||
|
JingyaHuang marked this conversation as resolved.
|
||
| if ort_type not in ort_type_to_numpy_type_map: | ||
| raise ValueError(f"{ort_type} not found in map") | ||
|
JingyaHuang marked this conversation as resolved.
Outdated
|
||
| return ort_type_to_numpy_type_map[ort_type] | ||
|
|
||
| @staticmethod | ||
| def ort_type_to_torch_type(ort_type: str): | ||
| ort_type_to_torch_type_map = { | ||
| "tensor(int64)": torch.int64, | ||
| "tensor(int32)": torch.int32, | ||
| "tensor(int8)": torch.int8, | ||
| "tensor(float)": torch.float32, | ||
| "tensor(float16)": torch.float16, | ||
| "tensor(bool)": torch.bool, | ||
| } | ||
|
JingyaHuang marked this conversation as resolved.
|
||
| if ort_type not in ort_type_to_torch_type_map: | ||
| raise ValueError(f"{ort_type} not found in map") | ||
|
JingyaHuang marked this conversation as resolved.
Outdated
|
||
| return ort_type_to_torch_type_map[ort_type] | ||
|
|
||
|
|
||
| # adapted from https://github.com/microsoft/onnxruntime/blob/1ab11a111ce0717bfbfaca964d04a017cb9b1752/onnxruntime/python/tools/transformers/io_binding_helper.py#L97 | ||
|
JingyaHuang marked this conversation as resolved.
Outdated
|
||
| class IOBindingHelper: | ||
|
JingyaHuang marked this conversation as resolved.
Outdated
|
||
| """ | ||
| IOBindingHelper is a class that helps ORTModels to create buffers for inputs and outputs of an ONNX runtime | ||
|
JingyaHuang marked this conversation as resolved.
Outdated
|
||
| inference session when using devices like GPU for acceleration. It helps reduce memory copy between the host | ||
| and device. | ||
| """ | ||
|
|
||
| def __init__(self, model: ort.InferenceSession, config, device, **kwargs): | ||
| self.model = model | ||
| self.config = config | ||
| self.device = device | ||
| # create {name:idx} dict for model outputs | ||
|
JingyaHuang marked this conversation as resolved.
Outdated
|
||
| self.model_inputs = {output_key.name: idx for idx, output_key in enumerate(model.get_inputs())} | ||
| self.model_outputs = {output_key.name: idx for idx, output_key in enumerate(model.get_outputs())} | ||
| self.model_input_names = list(self.model_inputs.keys()) | ||
| self.model_output_names = list(self.model_outputs.keys()) | ||
|
|
||
| def prepare_io_binding(self, **kwargs): | ||
|
JingyaHuang marked this conversation as resolved.
Outdated
|
||
| """Returnas IO binding object for a session.""" | ||
|
JingyaHuang marked this conversation as resolved.
Outdated
|
||
|
|
||
| name_to_np_type = TypeHelper.get_io_numpy_type_map(self.model) | ||
|
|
||
| # Bind inputs and outputs to onnxruntime session | ||
| io_binding = self.model.io_binding() | ||
|
|
||
| # Bind inputs | ||
| for input_name in self.model_input_names: | ||
| onnx_input = kwargs.pop(input_name) | ||
|
|
||
| assert onnx_input.is_contiguous() | ||
|
JingyaHuang marked this conversation as resolved.
Outdated
|
||
| io_binding.bind_input( | ||
| input_name, | ||
| onnx_input.device.type, | ||
| self.device.index, | ||
| name_to_np_type[input_name], | ||
| list(onnx_input.size()), | ||
| onnx_input.data_ptr(), | ||
| ) | ||
|
|
||
| # Bind outputs | ||
| for name in self.model_output_names: | ||
| io_binding.bind_output(name, self.device.type, device_id=self.device.index) | ||
|
|
||
| return io_binding | ||
|
|
||
| @staticmethod | ||
| def to_pytorch(ort_value: OrtValue) -> torch.Tensor: | ||
| """Converts tensors held by OrtValues to torch tensor.""" | ||
| env = {pkg.key for pkg in pkg_resources.working_set} | ||
| if "onnxruntime-training" in env: | ||
|
JingyaHuang marked this conversation as resolved.
Outdated
|
||
| return IOBindingHelper.to_pytorch_via_dlpack(ort_value) | ||
| else: | ||
| try: | ||
| return IOBindingHelper.to_pytorch_via_cupy(ort_value) | ||
| except Exception as e: | ||
| logging.error(traceback.format_exc()) | ||
| logging.info("Unable to access output memory in CUDA, will offload to CPU") | ||
| return IOBindingHelper.to_pytorch_via_np(ort_value) | ||
|
|
||
| @staticmethod | ||
| def to_pytorch_via_np(ort_value: OrtValue) -> torch.Tensor: | ||
|
JingyaHuang marked this conversation as resolved.
Outdated
|
||
| ort_device = ort_value.device_name().lower() | ||
| return torch.tensor(ort_value.numpy()).to(ort_device) | ||
|
JingyaHuang marked this conversation as resolved.
Outdated
|
||
|
|
||
| @staticmethod | ||
| def to_pytorch_via_cupy(ort_value: OrtValue) -> torch.Tensor: | ||
| ort_device = ort_value.device_name().lower() | ||
| assert ort_device == "cuda", f"Convert via CuPy only when device is CUDA, got: {ort_device}" | ||
|
JingyaHuang marked this conversation as resolved.
Outdated
|
||
|
|
||
| ort_type = ort_value.data_type() | ||
| np_type = TypeHelper.ort_type_to_numpy_type(ort_type) | ||
|
JingyaHuang marked this conversation as resolved.
Outdated
|
||
|
|
||
| # Access CUDA memory via CuPy | ||
| import cupy as cp | ||
|
JingyaHuang marked this conversation as resolved.
Outdated
|
||
|
|
||
| memory = cp.cuda.UnownedMemory(ort_value.data_ptr(), 0, None) | ||
| memory_ptr = cp.cuda.MemoryPointer(memory, 0) | ||
| cp_array = cp.ndarray(shape=ort_value.shape(), memptr=memory_ptr, dtype=np_type) | ||
| torch_tensor = torch.from_dlpack(cp_array.toDlpack()) | ||
|
|
||
| # If is boolean, the dtype will be uint8 and need to be convert back to bool. | ||
| if "bool" in ort_type: | ||
| torch_tensor = torch_tensor.to(torch.bool) | ||
|
|
||
| torch_tensor = torch_tensor.clone() | ||
|
|
||
| return torch_tensor | ||
|
|
||
| @staticmethod | ||
| # only `onnxruntime-training` supports dlpack for OrtValue | ||
|
JingyaHuang marked this conversation as resolved.
Outdated
|
||
| def to_pytorch_via_dlpack(ort_value: OrtValue) -> torch.Tensor: | ||
| from torch._C import _from_dlpack | ||
|
|
||
| torch_tensor = ort_value.to_dlpacks(_from_dlpack) | ||
| return torch_tensor | ||
|
|
||
| @staticmethod | ||
| def get_device_index(device): | ||
| if isinstance(device, str): | ||
| # could be 'cuda:0', 'cuda:1', or 'cpu'. with cpu, set index=0 | ||
| device = torch.device(device) | ||
| elif isinstance(device, int): | ||
| return device | ||
| return 0 if device.index is None else device.index | ||
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
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.
Uh oh!
There was an error while loading. Please reload this page.