inference-models 0.18.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- inference_models/__init__.py +36 -0
- inference_models/configuration.py +72 -0
- inference_models/constants.py +2 -0
- inference_models/entities.py +5 -0
- inference_models/errors.py +137 -0
- inference_models/logger.py +52 -0
- inference_models/model_pipelines/__init__.py +0 -0
- inference_models/model_pipelines/auto_loaders/__init__.py +0 -0
- inference_models/model_pipelines/auto_loaders/core.py +120 -0
- inference_models/model_pipelines/auto_loaders/pipelines_registry.py +36 -0
- inference_models/model_pipelines/face_and_gaze_detection/__init__.py +0 -0
- inference_models/model_pipelines/face_and_gaze_detection/mediapipe_l2cs.py +200 -0
- inference_models/models/__init__.py +0 -0
- inference_models/models/auto_loaders/__init__.py +0 -0
- inference_models/models/auto_loaders/access_manager.py +168 -0
- inference_models/models/auto_loaders/auto_negotiation.py +1329 -0
- inference_models/models/auto_loaders/auto_resolution_cache.py +129 -0
- inference_models/models/auto_loaders/constants.py +7 -0
- inference_models/models/auto_loaders/core.py +1341 -0
- inference_models/models/auto_loaders/dependency_models.py +52 -0
- inference_models/models/auto_loaders/entities.py +57 -0
- inference_models/models/auto_loaders/models_registry.py +497 -0
- inference_models/models/auto_loaders/presentation_utils.py +333 -0
- inference_models/models/auto_loaders/ranking.py +413 -0
- inference_models/models/auto_loaders/utils.py +31 -0
- inference_models/models/base/__init__.py +0 -0
- inference_models/models/base/classification.py +123 -0
- inference_models/models/base/depth_estimation.py +62 -0
- inference_models/models/base/documents_parsing.py +111 -0
- inference_models/models/base/embeddings.py +66 -0
- inference_models/models/base/instance_segmentation.py +87 -0
- inference_models/models/base/keypoints_detection.py +93 -0
- inference_models/models/base/object_detection.py +143 -0
- inference_models/models/base/semantic_segmentation.py +74 -0
- inference_models/models/base/types.py +5 -0
- inference_models/models/clip/__init__.py +0 -0
- inference_models/models/clip/clip_onnx.py +148 -0
- inference_models/models/clip/clip_pytorch.py +104 -0
- inference_models/models/clip/preprocessing.py +162 -0
- inference_models/models/common/__init__.py +0 -0
- inference_models/models/common/cuda.py +30 -0
- inference_models/models/common/model_packages.py +25 -0
- inference_models/models/common/onnx.py +379 -0
- inference_models/models/common/roboflow/__init__.py +0 -0
- inference_models/models/common/roboflow/model_packages.py +361 -0
- inference_models/models/common/roboflow/post_processing.py +436 -0
- inference_models/models/common/roboflow/pre_processing.py +1332 -0
- inference_models/models/common/torch.py +20 -0
- inference_models/models/common/trt.py +266 -0
- inference_models/models/deep_lab_v3_plus/__init__.py +0 -0
- inference_models/models/deep_lab_v3_plus/deep_lab_v3_plus_segmentation_onnx.py +282 -0
- inference_models/models/deep_lab_v3_plus/deep_lab_v3_plus_segmentation_torch.py +264 -0
- inference_models/models/deep_lab_v3_plus/deep_lab_v3_plus_segmentation_trt.py +313 -0
- inference_models/models/depth_anything_v2/__init__.py +0 -0
- inference_models/models/depth_anything_v2/depth_anything_v2_hf.py +77 -0
- inference_models/models/dinov3/__init__.py +0 -0
- inference_models/models/dinov3/dinov3_classification_onnx.py +348 -0
- inference_models/models/dinov3/dinov3_classification_torch.py +323 -0
- inference_models/models/doctr/__init__.py +0 -0
- inference_models/models/doctr/doctr_torch.py +304 -0
- inference_models/models/easy_ocr/__init__.py +0 -0
- inference_models/models/easy_ocr/easy_ocr_torch.py +222 -0
- inference_models/models/florence2/__init__.py +0 -0
- inference_models/models/florence2/florence2_hf.py +897 -0
- inference_models/models/grounding_dino/__init__.py +0 -0
- inference_models/models/grounding_dino/grounding_dino_torch.py +227 -0
- inference_models/models/l2cs/__init__.py +0 -0
- inference_models/models/l2cs/l2cs_onnx.py +216 -0
- inference_models/models/mediapipe_face_detection/__init__.py +0 -0
- inference_models/models/mediapipe_face_detection/face_detection.py +203 -0
- inference_models/models/moondream2/__init__.py +0 -0
- inference_models/models/moondream2/moondream2_hf.py +281 -0
- inference_models/models/owlv2/__init__.py +0 -0
- inference_models/models/owlv2/cache.py +182 -0
- inference_models/models/owlv2/entities.py +112 -0
- inference_models/models/owlv2/owlv2_hf.py +695 -0
- inference_models/models/owlv2/reference_dataset.py +291 -0
- inference_models/models/paligemma/__init__.py +0 -0
- inference_models/models/paligemma/paligemma_hf.py +209 -0
- inference_models/models/perception_encoder/__init__.py +0 -0
- inference_models/models/perception_encoder/perception_encoder_pytorch.py +197 -0
- inference_models/models/perception_encoder/vision_encoder/__init__.py +0 -0
- inference_models/models/perception_encoder/vision_encoder/config.py +160 -0
- inference_models/models/perception_encoder/vision_encoder/pe.py +742 -0
- inference_models/models/perception_encoder/vision_encoder/rope.py +344 -0
- inference_models/models/perception_encoder/vision_encoder/tokenizer.py +342 -0
- inference_models/models/perception_encoder/vision_encoder/transforms.py +33 -0
- inference_models/models/qwen25vl/__init__.py +1 -0
- inference_models/models/qwen25vl/qwen25vl_hf.py +285 -0
- inference_models/models/resnet/__init__.py +0 -0
- inference_models/models/resnet/resnet_classification_onnx.py +330 -0
- inference_models/models/resnet/resnet_classification_torch.py +305 -0
- inference_models/models/resnet/resnet_classification_trt.py +369 -0
- inference_models/models/rfdetr/__init__.py +0 -0
- inference_models/models/rfdetr/backbone_builder.py +101 -0
- inference_models/models/rfdetr/class_remapping.py +41 -0
- inference_models/models/rfdetr/common.py +115 -0
- inference_models/models/rfdetr/default_labels.py +108 -0
- inference_models/models/rfdetr/dinov2_with_windowed_attn.py +1330 -0
- inference_models/models/rfdetr/misc.py +26 -0
- inference_models/models/rfdetr/ms_deform_attn.py +180 -0
- inference_models/models/rfdetr/ms_deform_attn_func.py +60 -0
- inference_models/models/rfdetr/position_encoding.py +166 -0
- inference_models/models/rfdetr/post_processor.py +83 -0
- inference_models/models/rfdetr/projector.py +373 -0
- inference_models/models/rfdetr/rfdetr_backbone_pytorch.py +394 -0
- inference_models/models/rfdetr/rfdetr_base_pytorch.py +807 -0
- inference_models/models/rfdetr/rfdetr_instance_segmentation_onnx.py +206 -0
- inference_models/models/rfdetr/rfdetr_instance_segmentation_pytorch.py +373 -0
- inference_models/models/rfdetr/rfdetr_instance_segmentation_trt.py +227 -0
- inference_models/models/rfdetr/rfdetr_object_detection_onnx.py +244 -0
- inference_models/models/rfdetr/rfdetr_object_detection_pytorch.py +470 -0
- inference_models/models/rfdetr/rfdetr_object_detection_trt.py +270 -0
- inference_models/models/rfdetr/segmentation_head.py +273 -0
- inference_models/models/rfdetr/transformer.py +767 -0
- inference_models/models/roboflow_instant/__init__.py +0 -0
- inference_models/models/roboflow_instant/roboflow_instant_hf.py +141 -0
- inference_models/models/sam/__init__.py +0 -0
- inference_models/models/sam/cache.py +147 -0
- inference_models/models/sam/entities.py +25 -0
- inference_models/models/sam/sam_torch.py +675 -0
- inference_models/models/sam2/__init__.py +0 -0
- inference_models/models/sam2/cache.py +162 -0
- inference_models/models/sam2/entities.py +43 -0
- inference_models/models/sam2/sam2_torch.py +905 -0
- inference_models/models/sam2_rt/__init__.py +0 -0
- inference_models/models/sam2_rt/sam2_pytorch.py +119 -0
- inference_models/models/smolvlm/__init__.py +0 -0
- inference_models/models/smolvlm/smolvlm_hf.py +245 -0
- inference_models/models/trocr/__init__.py +0 -0
- inference_models/models/trocr/trocr_hf.py +53 -0
- inference_models/models/vit/__init__.py +0 -0
- inference_models/models/vit/vit_classification_huggingface.py +319 -0
- inference_models/models/vit/vit_classification_onnx.py +326 -0
- inference_models/models/vit/vit_classification_trt.py +365 -0
- inference_models/models/yolact/__init__.py +1 -0
- inference_models/models/yolact/yolact_instance_segmentation_onnx.py +336 -0
- inference_models/models/yolact/yolact_instance_segmentation_trt.py +361 -0
- inference_models/models/yolo_world/__init__.py +1 -0
- inference_models/models/yolonas/__init__.py +0 -0
- inference_models/models/yolonas/nms.py +44 -0
- inference_models/models/yolonas/yolonas_object_detection_onnx.py +204 -0
- inference_models/models/yolonas/yolonas_object_detection_trt.py +230 -0
- inference_models/models/yolov10/__init__.py +0 -0
- inference_models/models/yolov10/yolov10_object_detection_onnx.py +187 -0
- inference_models/models/yolov10/yolov10_object_detection_trt.py +215 -0
- inference_models/models/yolov11/__init__.py +0 -0
- inference_models/models/yolov11/yolov11_onnx.py +28 -0
- inference_models/models/yolov11/yolov11_torch_script.py +25 -0
- inference_models/models/yolov11/yolov11_trt.py +21 -0
- inference_models/models/yolov12/__init__.py +0 -0
- inference_models/models/yolov12/yolov12_onnx.py +7 -0
- inference_models/models/yolov12/yolov12_torch_script.py +7 -0
- inference_models/models/yolov12/yolov12_trt.py +7 -0
- inference_models/models/yolov5/__init__.py +0 -0
- inference_models/models/yolov5/nms.py +99 -0
- inference_models/models/yolov5/yolov5_instance_segmentation_onnx.py +225 -0
- inference_models/models/yolov5/yolov5_instance_segmentation_trt.py +255 -0
- inference_models/models/yolov5/yolov5_object_detection_onnx.py +192 -0
- inference_models/models/yolov5/yolov5_object_detection_trt.py +218 -0
- inference_models/models/yolov7/__init__.py +0 -0
- inference_models/models/yolov7/yolov7_instance_segmentation_onnx.py +226 -0
- inference_models/models/yolov7/yolov7_instance_segmentation_trt.py +253 -0
- inference_models/models/yolov8/__init__.py +0 -0
- inference_models/models/yolov8/yolov8_classification_onnx.py +181 -0
- inference_models/models/yolov8/yolov8_instance_segmentation_onnx.py +239 -0
- inference_models/models/yolov8/yolov8_instance_segmentation_torch_script.py +201 -0
- inference_models/models/yolov8/yolov8_instance_segmentation_trt.py +268 -0
- inference_models/models/yolov8/yolov8_key_points_detection_onnx.py +263 -0
- inference_models/models/yolov8/yolov8_key_points_detection_torch_script.py +218 -0
- inference_models/models/yolov8/yolov8_key_points_detection_trt.py +287 -0
- inference_models/models/yolov8/yolov8_object_detection_onnx.py +213 -0
- inference_models/models/yolov8/yolov8_object_detection_torch_script.py +166 -0
- inference_models/models/yolov8/yolov8_object_detection_trt.py +231 -0
- inference_models/models/yolov9/__init__.py +0 -0
- inference_models/models/yolov9/yolov9_onnx.py +7 -0
- inference_models/models/yolov9/yolov9_torch_script.py +7 -0
- inference_models/models/yolov9/yolov9_trt.py +7 -0
- inference_models/runtime_introspection/__init__.py +0 -0
- inference_models/runtime_introspection/core.py +410 -0
- inference_models/utils/__init__.py +0 -0
- inference_models/utils/download.py +608 -0
- inference_models/utils/environment.py +28 -0
- inference_models/utils/file_system.py +51 -0
- inference_models/utils/hashing.py +7 -0
- inference_models/utils/imports.py +48 -0
- inference_models/utils/onnx_introspection.py +17 -0
- inference_models/weights_providers/__init__.py +0 -0
- inference_models/weights_providers/core.py +20 -0
- inference_models/weights_providers/entities.py +159 -0
- inference_models/weights_providers/roboflow.py +601 -0
- inference_models-0.18.3.dist-info/METADATA +466 -0
- inference_models-0.18.3.dist-info/RECORD +195 -0
- inference_models-0.18.3.dist-info/WHEEL +5 -0
- inference_models-0.18.3.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
from threading import Lock
|
|
2
|
+
from typing import List, Optional, Tuple, Union
|
|
3
|
+
|
|
4
|
+
import numpy as np
|
|
5
|
+
import torch
|
|
6
|
+
import torchvision
|
|
7
|
+
|
|
8
|
+
from inference_models import InstanceDetections, InstanceSegmentationModel
|
|
9
|
+
from inference_models.configuration import DEFAULT_DEVICE
|
|
10
|
+
from inference_models.entities import ColorFormat
|
|
11
|
+
from inference_models.errors import (
|
|
12
|
+
CorruptedModelPackageError,
|
|
13
|
+
MissingDependencyError,
|
|
14
|
+
ModelRuntimeError,
|
|
15
|
+
)
|
|
16
|
+
from inference_models.models.common.cuda import (
|
|
17
|
+
use_cuda_context,
|
|
18
|
+
use_primary_cuda_context,
|
|
19
|
+
)
|
|
20
|
+
from inference_models.models.common.model_packages import get_model_package_contents
|
|
21
|
+
from inference_models.models.common.roboflow.model_packages import (
|
|
22
|
+
InferenceConfig,
|
|
23
|
+
PreProcessingMetadata,
|
|
24
|
+
ResizeMode,
|
|
25
|
+
TRTConfig,
|
|
26
|
+
parse_class_names_file,
|
|
27
|
+
parse_inference_config,
|
|
28
|
+
parse_trt_config,
|
|
29
|
+
)
|
|
30
|
+
from inference_models.models.common.roboflow.post_processing import (
|
|
31
|
+
align_instance_segmentation_results,
|
|
32
|
+
crop_masks_to_boxes,
|
|
33
|
+
)
|
|
34
|
+
from inference_models.models.common.roboflow.pre_processing import (
|
|
35
|
+
pre_process_network_input,
|
|
36
|
+
)
|
|
37
|
+
from inference_models.models.common.trt import (
|
|
38
|
+
get_engine_inputs_and_outputs,
|
|
39
|
+
infer_from_trt_engine,
|
|
40
|
+
load_model,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
try:
|
|
44
|
+
import tensorrt as trt
|
|
45
|
+
except ImportError as import_error:
|
|
46
|
+
raise MissingDependencyError(
|
|
47
|
+
message=f"Could not import YOLOv8 model with TRT backend - this error means that some additional dependencies "
|
|
48
|
+
f"are not installed in the environment. If you run the `inference-models` library directly in your Python "
|
|
49
|
+
f"program, make sure the following extras of the package are installed: `trt10` - installation can only "
|
|
50
|
+
f"succeed for Linux and Windows machines with Cuda 12 installed. Jetson devices, should have TRT 10.x "
|
|
51
|
+
f"installed for all builds with Jetpack 6. "
|
|
52
|
+
f"If you see this error using Roboflow infrastructure, make sure the service you use does support the model. "
|
|
53
|
+
f"You can also contact Roboflow to get support.",
|
|
54
|
+
help_url="https://todo",
|
|
55
|
+
) from import_error
|
|
56
|
+
|
|
57
|
+
try:
|
|
58
|
+
import pycuda.driver as cuda
|
|
59
|
+
except ImportError as import_error:
|
|
60
|
+
raise MissingDependencyError(
|
|
61
|
+
message="TODO", help_url="https://todo"
|
|
62
|
+
) from import_error
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class YOLOACTForInstanceSegmentationTRT(
|
|
66
|
+
InstanceSegmentationModel[
|
|
67
|
+
torch.Tensor,
|
|
68
|
+
PreProcessingMetadata,
|
|
69
|
+
Tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor],
|
|
70
|
+
]
|
|
71
|
+
):
|
|
72
|
+
|
|
73
|
+
@classmethod
|
|
74
|
+
def from_pretrained(
|
|
75
|
+
cls,
|
|
76
|
+
model_name_or_path: str,
|
|
77
|
+
device: torch.device = DEFAULT_DEVICE,
|
|
78
|
+
engine_host_code_allowed: bool = False,
|
|
79
|
+
**kwargs,
|
|
80
|
+
) -> "YOLOACTForInstanceSegmentationTRT":
|
|
81
|
+
if device.type != "cuda":
|
|
82
|
+
raise ModelRuntimeError(
|
|
83
|
+
message=f"TRT engine only runs on CUDA device - {device} device detected.",
|
|
84
|
+
help_url="https://todo",
|
|
85
|
+
)
|
|
86
|
+
model_package_content = get_model_package_contents(
|
|
87
|
+
model_package_dir=model_name_or_path,
|
|
88
|
+
elements=[
|
|
89
|
+
"class_names.txt",
|
|
90
|
+
"inference_config.json",
|
|
91
|
+
"trt_config.json",
|
|
92
|
+
"engine.plan",
|
|
93
|
+
],
|
|
94
|
+
)
|
|
95
|
+
class_names = parse_class_names_file(
|
|
96
|
+
class_names_path=model_package_content["class_names.txt"]
|
|
97
|
+
)
|
|
98
|
+
inference_config = parse_inference_config(
|
|
99
|
+
config_path=model_package_content["inference_config.json"],
|
|
100
|
+
allowed_resize_modes={
|
|
101
|
+
ResizeMode.STRETCH_TO,
|
|
102
|
+
ResizeMode.LETTERBOX,
|
|
103
|
+
ResizeMode.CENTER_CROP,
|
|
104
|
+
ResizeMode.LETTERBOX_REFLECT_EDGES,
|
|
105
|
+
},
|
|
106
|
+
)
|
|
107
|
+
trt_config = parse_trt_config(
|
|
108
|
+
config_path=model_package_content["trt_config.json"]
|
|
109
|
+
)
|
|
110
|
+
cuda.init()
|
|
111
|
+
cuda_device = cuda.Device(device.index or 0)
|
|
112
|
+
with use_primary_cuda_context(cuda_device=cuda_device) as cuda_context:
|
|
113
|
+
engine = load_model(
|
|
114
|
+
model_path=model_package_content["engine.plan"],
|
|
115
|
+
engine_host_code_allowed=engine_host_code_allowed,
|
|
116
|
+
)
|
|
117
|
+
execution_context = engine.create_execution_context()
|
|
118
|
+
inputs, outputs = get_engine_inputs_and_outputs(engine=engine)
|
|
119
|
+
if len(inputs) != 1:
|
|
120
|
+
raise CorruptedModelPackageError(
|
|
121
|
+
message=f"Implementation assume single model input, found: {len(inputs)}.",
|
|
122
|
+
help_url="https://todo",
|
|
123
|
+
)
|
|
124
|
+
if len(outputs) != 5:
|
|
125
|
+
raise CorruptedModelPackageError(
|
|
126
|
+
message=f"Implementation assume 5 model outputs, found: {len(outputs)}.",
|
|
127
|
+
help_url="https://todo",
|
|
128
|
+
)
|
|
129
|
+
return cls(
|
|
130
|
+
engine=engine,
|
|
131
|
+
input_name=inputs[0],
|
|
132
|
+
output_name=outputs[0],
|
|
133
|
+
class_names=class_names,
|
|
134
|
+
inference_config=inference_config,
|
|
135
|
+
trt_config=trt_config,
|
|
136
|
+
device=device,
|
|
137
|
+
cuda_context=cuda_context,
|
|
138
|
+
execution_context=execution_context,
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
def __init__(
|
|
142
|
+
self,
|
|
143
|
+
engine: trt.ICudaEngine,
|
|
144
|
+
input_name: str,
|
|
145
|
+
output_name: str,
|
|
146
|
+
class_names: List[str],
|
|
147
|
+
inference_config: InferenceConfig,
|
|
148
|
+
trt_config: TRTConfig,
|
|
149
|
+
device: torch.device,
|
|
150
|
+
cuda_context: cuda.Context,
|
|
151
|
+
execution_context: trt.IExecutionContext,
|
|
152
|
+
):
|
|
153
|
+
self._engine = engine
|
|
154
|
+
self._input_name = input_name
|
|
155
|
+
self._output_names = [output_name]
|
|
156
|
+
self._class_names = class_names
|
|
157
|
+
self._inference_config = inference_config
|
|
158
|
+
self._trt_config = trt_config
|
|
159
|
+
self._device = device
|
|
160
|
+
self._cuda_context = cuda_context
|
|
161
|
+
self._execution_context = execution_context
|
|
162
|
+
self._lock = Lock()
|
|
163
|
+
|
|
164
|
+
@property
|
|
165
|
+
def class_names(self) -> List[str]:
|
|
166
|
+
return self._class_names
|
|
167
|
+
|
|
168
|
+
def pre_process(
|
|
169
|
+
self,
|
|
170
|
+
images: Union[torch.Tensor, List[torch.Tensor], np.ndarray, List[np.ndarray]],
|
|
171
|
+
input_color_format: Optional[ColorFormat] = None,
|
|
172
|
+
**kwargs,
|
|
173
|
+
) -> Tuple[torch.Tensor, List[PreProcessingMetadata]]:
|
|
174
|
+
return pre_process_network_input(
|
|
175
|
+
images=images,
|
|
176
|
+
image_pre_processing=self._inference_config.image_pre_processing,
|
|
177
|
+
network_input=self._inference_config.network_input,
|
|
178
|
+
target_device=self._device,
|
|
179
|
+
input_color_format=input_color_format,
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
def forward(
|
|
183
|
+
self, pre_processed_images: torch.Tensor, **kwargs
|
|
184
|
+
) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]:
|
|
185
|
+
with self._lock:
|
|
186
|
+
with use_cuda_context(context=self._cuda_context):
|
|
187
|
+
(
|
|
188
|
+
all_loc_data,
|
|
189
|
+
all_conf_data,
|
|
190
|
+
all_mask_data,
|
|
191
|
+
all_prior_data,
|
|
192
|
+
all_proto_data,
|
|
193
|
+
) = ([], [], [], [], [])
|
|
194
|
+
for image in pre_processed_images:
|
|
195
|
+
loc_data, conf_data, mask_data, prior_data, proto_data = (
|
|
196
|
+
infer_from_trt_engine(
|
|
197
|
+
pre_processed_images=image.unsqueeze(0).contiguous(),
|
|
198
|
+
trt_config=self._trt_config,
|
|
199
|
+
engine=self._engine,
|
|
200
|
+
context=self._execution_context,
|
|
201
|
+
device=self._device,
|
|
202
|
+
input_name=self._input_name,
|
|
203
|
+
outputs=self._output_names,
|
|
204
|
+
)
|
|
205
|
+
)
|
|
206
|
+
all_loc_data.append(loc_data)
|
|
207
|
+
all_conf_data.append(conf_data)
|
|
208
|
+
all_mask_data.append(mask_data)
|
|
209
|
+
all_prior_data.append(prior_data)
|
|
210
|
+
all_proto_data.append(proto_data)
|
|
211
|
+
return (
|
|
212
|
+
torch.cat(all_loc_data, dim=0),
|
|
213
|
+
torch.cat(all_conf_data, dim=0),
|
|
214
|
+
torch.cat(all_mask_data, dim=0),
|
|
215
|
+
torch.stack(all_prior_data, dim=0),
|
|
216
|
+
torch.cat(all_proto_data, dim=0),
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
def post_process(
|
|
220
|
+
self,
|
|
221
|
+
model_results: Tuple[
|
|
222
|
+
torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor
|
|
223
|
+
],
|
|
224
|
+
pre_processing_meta: List[PreProcessingMetadata],
|
|
225
|
+
conf_thresh: float = 0.25,
|
|
226
|
+
iou_thresh: float = 0.45,
|
|
227
|
+
max_detections: int = 100,
|
|
228
|
+
class_agnostic: bool = False,
|
|
229
|
+
**kwargs,
|
|
230
|
+
) -> List[InstanceDetections]:
|
|
231
|
+
all_loc_data, all_conf_data, all_mask_data, all_prior_data, all_proto_data = (
|
|
232
|
+
model_results
|
|
233
|
+
)
|
|
234
|
+
batch_size = all_loc_data.shape[0]
|
|
235
|
+
num_priors = all_loc_data.shape[1]
|
|
236
|
+
boxes = torch.zeros((batch_size, num_priors, 4), device=self._device)
|
|
237
|
+
for batch_element_id, (
|
|
238
|
+
batch_element_loc_data,
|
|
239
|
+
batch_element_priors,
|
|
240
|
+
image_prep_meta,
|
|
241
|
+
) in enumerate(zip(all_loc_data, all_prior_data, pre_processing_meta)):
|
|
242
|
+
image_boxes = decode_predicted_bboxes(
|
|
243
|
+
loc_data=batch_element_loc_data,
|
|
244
|
+
priors=batch_element_priors,
|
|
245
|
+
)
|
|
246
|
+
inference_height, inference_width = (
|
|
247
|
+
image_prep_meta.inference_size.height,
|
|
248
|
+
image_prep_meta.inference_size.width,
|
|
249
|
+
)
|
|
250
|
+
scale = torch.tensor(
|
|
251
|
+
[inference_width, inference_height, inference_width, inference_height],
|
|
252
|
+
device=self._device,
|
|
253
|
+
)
|
|
254
|
+
image_boxes = image_boxes.mul_(scale)
|
|
255
|
+
boxes[batch_element_id, :, :] = image_boxes
|
|
256
|
+
all_conf_data = all_conf_data[:, :, 1:] # remove background class
|
|
257
|
+
instances = torch.cat([boxes, all_conf_data, all_mask_data], dim=2)
|
|
258
|
+
nms_results = run_nms_for_instance_segmentation(
|
|
259
|
+
output=instances,
|
|
260
|
+
conf_thresh=conf_thresh,
|
|
261
|
+
iou_thresh=iou_thresh,
|
|
262
|
+
max_detections=max_detections,
|
|
263
|
+
class_agnostic=class_agnostic,
|
|
264
|
+
)
|
|
265
|
+
final_results = []
|
|
266
|
+
for image_bboxes, image_protos, image_meta in zip(
|
|
267
|
+
nms_results, all_proto_data, pre_processing_meta
|
|
268
|
+
):
|
|
269
|
+
pre_processed_masks = image_protos @ image_bboxes[:, 6:].T
|
|
270
|
+
pre_processed_masks = 1 / (1 + torch.exp(-pre_processed_masks))
|
|
271
|
+
pre_processed_masks = torch.permute(pre_processed_masks, (2, 0, 1))
|
|
272
|
+
cropped_masks = crop_masks_to_boxes(
|
|
273
|
+
image_bboxes[:, :4], pre_processed_masks
|
|
274
|
+
)
|
|
275
|
+
padding = (
|
|
276
|
+
image_meta.pad_left,
|
|
277
|
+
image_meta.pad_top,
|
|
278
|
+
image_meta.pad_right,
|
|
279
|
+
image_meta.pad_bottom,
|
|
280
|
+
)
|
|
281
|
+
aligned_boxes, aligned_masks = align_instance_segmentation_results(
|
|
282
|
+
image_bboxes=image_bboxes,
|
|
283
|
+
masks=cropped_masks,
|
|
284
|
+
padding=padding,
|
|
285
|
+
scale_height=image_meta.scale_height,
|
|
286
|
+
scale_width=image_meta.scale_width,
|
|
287
|
+
original_size=image_meta.original_size,
|
|
288
|
+
size_after_pre_processing=image_meta.size_after_pre_processing,
|
|
289
|
+
inference_size=image_meta.inference_size,
|
|
290
|
+
static_crop_offset=image_meta.static_crop_offset,
|
|
291
|
+
binarization_threshold=0.5,
|
|
292
|
+
)
|
|
293
|
+
final_results.append(
|
|
294
|
+
InstanceDetections(
|
|
295
|
+
xyxy=aligned_boxes[:, :4].round().int(),
|
|
296
|
+
class_id=aligned_boxes[:, 5].int(),
|
|
297
|
+
confidence=aligned_boxes[:, 4],
|
|
298
|
+
mask=aligned_masks,
|
|
299
|
+
)
|
|
300
|
+
)
|
|
301
|
+
return final_results
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
def decode_predicted_bboxes(
|
|
305
|
+
loc_data: torch.Tensor, priors: torch.Tensor
|
|
306
|
+
) -> torch.Tensor:
|
|
307
|
+
variances = torch.tensor([0.1, 0.2], device=loc_data.device)
|
|
308
|
+
boxes = torch.cat(
|
|
309
|
+
[
|
|
310
|
+
priors[:, :2] + loc_data[:, :2] * variances[0] * priors[:, 2:],
|
|
311
|
+
priors[:, 2:] * torch.exp(loc_data[:, 2:] * variances[1]),
|
|
312
|
+
],
|
|
313
|
+
dim=1,
|
|
314
|
+
)
|
|
315
|
+
boxes[:, :2] -= boxes[:, 2:] / 2
|
|
316
|
+
boxes[:, 2:] += boxes[:, :2]
|
|
317
|
+
return boxes
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
def run_nms_for_instance_segmentation(
|
|
321
|
+
output: torch.Tensor,
|
|
322
|
+
conf_thresh: float = 0.25,
|
|
323
|
+
iou_thresh: float = 0.45,
|
|
324
|
+
max_detections: int = 100,
|
|
325
|
+
class_agnostic: bool = False,
|
|
326
|
+
) -> List[torch.Tensor]:
|
|
327
|
+
bs = output.shape[0]
|
|
328
|
+
boxes = output[:, :, :4] # (N, 19248, 4)
|
|
329
|
+
scores = output[:, :, 4:-32] # (N, 19248, num_classes)
|
|
330
|
+
masks = output[:, :, -32:]
|
|
331
|
+
results = []
|
|
332
|
+
for b in range(bs):
|
|
333
|
+
bboxes = boxes[b] # (19248, 4)
|
|
334
|
+
class_scores = scores[b] # (19248, 80)
|
|
335
|
+
box_masks = masks[b]
|
|
336
|
+
class_conf, class_ids = class_scores.max(1) # (8400,), (8400,)
|
|
337
|
+
mask = class_conf > conf_thresh
|
|
338
|
+
if mask.sum() == 0:
|
|
339
|
+
results.append(torch.zeros((0, 38), device=output.device))
|
|
340
|
+
continue
|
|
341
|
+
bboxes = bboxes[mask]
|
|
342
|
+
class_conf = class_conf[mask]
|
|
343
|
+
class_ids = class_ids[mask]
|
|
344
|
+
box_masks = box_masks[mask]
|
|
345
|
+
# Class-agnostic NMS -> use dummy class ids
|
|
346
|
+
nms_class_ids = torch.zeros_like(class_ids) if class_agnostic else class_ids
|
|
347
|
+
keep = torchvision.ops.batched_nms(
|
|
348
|
+
bboxes, class_conf, nms_class_ids, iou_thresh
|
|
349
|
+
)
|
|
350
|
+
keep = keep[:max_detections]
|
|
351
|
+
detections = torch.cat(
|
|
352
|
+
[
|
|
353
|
+
bboxes[keep],
|
|
354
|
+
class_conf[keep].unsqueeze(1),
|
|
355
|
+
class_ids[keep].unsqueeze(1).float(),
|
|
356
|
+
box_masks[keep],
|
|
357
|
+
],
|
|
358
|
+
dim=1,
|
|
359
|
+
) # [x1, y1, x2, y2, conf, cls]
|
|
360
|
+
results.append(detections)
|
|
361
|
+
return results
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# TODO: implement in the future - clarify caching in new inference first
|
|
File without changes
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from typing import List
|
|
2
|
+
|
|
3
|
+
import torch
|
|
4
|
+
import torchvision
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def run_yolonas_nms_for_object_detection(
|
|
8
|
+
output: torch.Tensor,
|
|
9
|
+
conf_thresh: float = 0.25,
|
|
10
|
+
iou_thresh: float = 0.45,
|
|
11
|
+
max_detections: int = 100,
|
|
12
|
+
class_agnostic: bool = False,
|
|
13
|
+
) -> List[torch.Tensor]:
|
|
14
|
+
bs = output.shape[0]
|
|
15
|
+
boxes = output[:, :, :4]
|
|
16
|
+
scores = output[:, :, 4:]
|
|
17
|
+
results = []
|
|
18
|
+
for b in range(bs):
|
|
19
|
+
# Combine transpose & max for efficiency
|
|
20
|
+
class_scores = scores[b] # (8400, cls_num)
|
|
21
|
+
class_conf, class_ids = torch.max(class_scores, dim=-1)
|
|
22
|
+
mask = class_conf > conf_thresh
|
|
23
|
+
if not torch.any(mask):
|
|
24
|
+
results.append(torch.zeros((0, 6), device=output.device))
|
|
25
|
+
continue
|
|
26
|
+
bboxes = boxes[b][mask]
|
|
27
|
+
class_conf = class_conf[mask]
|
|
28
|
+
class_ids = class_ids[mask]
|
|
29
|
+
nms_class_ids = torch.zeros_like(class_ids) if class_agnostic else class_ids
|
|
30
|
+
keep = torchvision.ops.batched_nms(
|
|
31
|
+
bboxes, class_conf, nms_class_ids, iou_thresh
|
|
32
|
+
)
|
|
33
|
+
if keep.numel() > max_detections:
|
|
34
|
+
keep = keep[:max_detections]
|
|
35
|
+
detections = torch.cat(
|
|
36
|
+
(
|
|
37
|
+
bboxes[keep],
|
|
38
|
+
class_conf[keep, None], # unsqueeze(1) is replaced with None
|
|
39
|
+
class_ids[keep, None].float(),
|
|
40
|
+
),
|
|
41
|
+
1,
|
|
42
|
+
) # [x1, y1, x2, y2, conf, cls]
|
|
43
|
+
results.append(detections)
|
|
44
|
+
return results
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
from threading import Lock
|
|
2
|
+
from typing import List, Optional, Tuple, Union
|
|
3
|
+
|
|
4
|
+
import numpy as np
|
|
5
|
+
import torch
|
|
6
|
+
|
|
7
|
+
from inference_models import Detections, ObjectDetectionModel
|
|
8
|
+
from inference_models.configuration import DEFAULT_DEVICE
|
|
9
|
+
from inference_models.entities import ColorFormat
|
|
10
|
+
from inference_models.errors import (
|
|
11
|
+
CorruptedModelPackageError,
|
|
12
|
+
EnvironmentConfigurationError,
|
|
13
|
+
MissingDependencyError,
|
|
14
|
+
)
|
|
15
|
+
from inference_models.models.common.model_packages import get_model_package_contents
|
|
16
|
+
from inference_models.models.common.onnx import (
|
|
17
|
+
run_session_with_batch_size_limit,
|
|
18
|
+
set_execution_provider_defaults,
|
|
19
|
+
)
|
|
20
|
+
from inference_models.models.common.roboflow.model_packages import (
|
|
21
|
+
InferenceConfig,
|
|
22
|
+
PreProcessingMetadata,
|
|
23
|
+
ResizeMode,
|
|
24
|
+
parse_class_names_file,
|
|
25
|
+
parse_inference_config,
|
|
26
|
+
)
|
|
27
|
+
from inference_models.models.common.roboflow.post_processing import rescale_detections
|
|
28
|
+
from inference_models.models.common.roboflow.pre_processing import (
|
|
29
|
+
pre_process_network_input,
|
|
30
|
+
)
|
|
31
|
+
from inference_models.models.yolonas.nms import run_yolonas_nms_for_object_detection
|
|
32
|
+
from inference_models.utils.onnx_introspection import (
|
|
33
|
+
get_selected_onnx_execution_providers,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
try:
|
|
37
|
+
import onnxruntime
|
|
38
|
+
except ImportError as import_error:
|
|
39
|
+
raise MissingDependencyError(
|
|
40
|
+
message=f"Could not import Yolo NAS model with ONNX backend - this error means that some additional dependencies "
|
|
41
|
+
f"are not installed in the environment. If you run the `inference-models` library directly in your Python "
|
|
42
|
+
f"program, make sure the following extras of the package are installed: \n"
|
|
43
|
+
f"\t* `onnx-cpu` - when you wish to use library with CPU support only\n"
|
|
44
|
+
f"\t* `onnx-cu12` - for running on GPU with Cuda 12 installed\n"
|
|
45
|
+
f"\t* `onnx-cu118` - for running on GPU with Cuda 11.8 installed\n"
|
|
46
|
+
f"\t* `onnx-jp6-cu126` - for running on Jetson with Jetpack 6\n"
|
|
47
|
+
f"If you see this error using Roboflow infrastructure, make sure the service you use does support the model. "
|
|
48
|
+
f"You can also contact Roboflow to get support.",
|
|
49
|
+
help_url="https://todo",
|
|
50
|
+
) from import_error
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class YOLONasForObjectDetectionOnnx(
|
|
54
|
+
ObjectDetectionModel[torch.Tensor, PreProcessingMetadata, torch.Tensor]
|
|
55
|
+
):
|
|
56
|
+
|
|
57
|
+
@classmethod
|
|
58
|
+
def from_pretrained(
|
|
59
|
+
cls,
|
|
60
|
+
model_name_or_path: str,
|
|
61
|
+
onnx_execution_providers: Optional[List[Union[str, tuple]]] = None,
|
|
62
|
+
default_onnx_trt_options: bool = True,
|
|
63
|
+
device: torch.device = DEFAULT_DEVICE,
|
|
64
|
+
**kwargs,
|
|
65
|
+
) -> "YOLONasForObjectDetectionOnnx":
|
|
66
|
+
if onnx_execution_providers is None:
|
|
67
|
+
onnx_execution_providers = get_selected_onnx_execution_providers()
|
|
68
|
+
if not onnx_execution_providers:
|
|
69
|
+
raise EnvironmentConfigurationError(
|
|
70
|
+
message=f"Could not initialize model - selected backend is ONNX which requires execution provider to "
|
|
71
|
+
f"be specified - explicitly in `from_pretrained(...)` method or via env variable "
|
|
72
|
+
f"`ONNXRUNTIME_EXECUTION_PROVIDERS`. If you run model locally - adjust your setup, otherwise "
|
|
73
|
+
f"contact the platform support.",
|
|
74
|
+
help_url="https://todo",
|
|
75
|
+
)
|
|
76
|
+
onnx_execution_providers = set_execution_provider_defaults(
|
|
77
|
+
providers=onnx_execution_providers,
|
|
78
|
+
model_package_path=model_name_or_path,
|
|
79
|
+
device=device,
|
|
80
|
+
default_onnx_trt_options=default_onnx_trt_options,
|
|
81
|
+
)
|
|
82
|
+
model_package_content = get_model_package_contents(
|
|
83
|
+
model_package_dir=model_name_or_path,
|
|
84
|
+
elements=[
|
|
85
|
+
"class_names.txt",
|
|
86
|
+
"inference_config.json",
|
|
87
|
+
"weights.onnx",
|
|
88
|
+
],
|
|
89
|
+
)
|
|
90
|
+
class_names = parse_class_names_file(
|
|
91
|
+
class_names_path=model_package_content["class_names.txt"]
|
|
92
|
+
)
|
|
93
|
+
inference_config = parse_inference_config(
|
|
94
|
+
config_path=model_package_content["inference_config.json"],
|
|
95
|
+
allowed_resize_modes={
|
|
96
|
+
ResizeMode.STRETCH_TO,
|
|
97
|
+
ResizeMode.LETTERBOX,
|
|
98
|
+
ResizeMode.CENTER_CROP,
|
|
99
|
+
ResizeMode.LETTERBOX_REFLECT_EDGES,
|
|
100
|
+
},
|
|
101
|
+
)
|
|
102
|
+
if inference_config.post_processing.type != "nms":
|
|
103
|
+
raise CorruptedModelPackageError(
|
|
104
|
+
message="Expected NMS to be the post-processing",
|
|
105
|
+
help_url="https://todo",
|
|
106
|
+
)
|
|
107
|
+
if inference_config.post_processing.fused is True:
|
|
108
|
+
raise CorruptedModelPackageError(
|
|
109
|
+
message="Model implementation does not support fused NMS",
|
|
110
|
+
help_url="https://todo",
|
|
111
|
+
)
|
|
112
|
+
session = onnxruntime.InferenceSession(
|
|
113
|
+
path_or_bytes=model_package_content["weights.onnx"],
|
|
114
|
+
providers=onnx_execution_providers,
|
|
115
|
+
)
|
|
116
|
+
input_batch_size = session.get_inputs()[0].shape[0]
|
|
117
|
+
if isinstance(input_batch_size, str):
|
|
118
|
+
input_batch_size = None
|
|
119
|
+
input_name = session.get_inputs()[0].name
|
|
120
|
+
return cls(
|
|
121
|
+
session=session,
|
|
122
|
+
input_name=input_name,
|
|
123
|
+
class_names=class_names,
|
|
124
|
+
inference_config=inference_config,
|
|
125
|
+
device=device,
|
|
126
|
+
input_batch_size=input_batch_size,
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
def __init__(
|
|
130
|
+
self,
|
|
131
|
+
session: onnxruntime.InferenceSession,
|
|
132
|
+
input_name: str,
|
|
133
|
+
inference_config: InferenceConfig,
|
|
134
|
+
class_names: List[str],
|
|
135
|
+
device: torch.device,
|
|
136
|
+
input_batch_size: Optional[int],
|
|
137
|
+
):
|
|
138
|
+
self._session = session
|
|
139
|
+
self._input_name = input_name
|
|
140
|
+
self._inference_config = inference_config
|
|
141
|
+
self._class_names = class_names
|
|
142
|
+
self._device = device
|
|
143
|
+
self._input_batch_size = input_batch_size
|
|
144
|
+
self._session_thread_lock = Lock()
|
|
145
|
+
|
|
146
|
+
@property
|
|
147
|
+
def class_names(self) -> List[str]:
|
|
148
|
+
return self._class_names
|
|
149
|
+
|
|
150
|
+
def pre_process(
|
|
151
|
+
self,
|
|
152
|
+
images: Union[torch.Tensor, List[torch.Tensor], np.ndarray, List[np.ndarray]],
|
|
153
|
+
input_color_format: Optional[ColorFormat] = None,
|
|
154
|
+
**kwargs,
|
|
155
|
+
) -> Tuple[torch.Tensor, List[PreProcessingMetadata]]:
|
|
156
|
+
return pre_process_network_input(
|
|
157
|
+
images=images,
|
|
158
|
+
image_pre_processing=self._inference_config.image_pre_processing,
|
|
159
|
+
network_input=self._inference_config.network_input,
|
|
160
|
+
target_device=self._device,
|
|
161
|
+
input_color_format=input_color_format,
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
def forward(self, pre_processed_images: torch.Tensor, **kwargs) -> torch.Tensor:
|
|
165
|
+
with self._session_thread_lock:
|
|
166
|
+
boxes, class_confs = run_session_with_batch_size_limit(
|
|
167
|
+
session=self._session,
|
|
168
|
+
inputs={self._input_name: pre_processed_images},
|
|
169
|
+
min_batch_size=self._input_batch_size,
|
|
170
|
+
max_batch_size=self._input_batch_size,
|
|
171
|
+
)
|
|
172
|
+
return torch.cat([boxes, class_confs], dim=-1)
|
|
173
|
+
|
|
174
|
+
def post_process(
|
|
175
|
+
self,
|
|
176
|
+
model_results: torch.Tensor,
|
|
177
|
+
pre_processing_meta: List[PreProcessingMetadata],
|
|
178
|
+
conf_thresh: float = 0.25,
|
|
179
|
+
iou_thresh: float = 0.45,
|
|
180
|
+
max_detections: int = 100,
|
|
181
|
+
class_agnostic: bool = False,
|
|
182
|
+
**kwargs,
|
|
183
|
+
) -> List[Detections]:
|
|
184
|
+
nms_results = run_yolonas_nms_for_object_detection(
|
|
185
|
+
output=model_results,
|
|
186
|
+
conf_thresh=conf_thresh,
|
|
187
|
+
iou_thresh=iou_thresh,
|
|
188
|
+
max_detections=max_detections,
|
|
189
|
+
class_agnostic=class_agnostic,
|
|
190
|
+
)
|
|
191
|
+
rescaled_results = rescale_detections(
|
|
192
|
+
detections=nms_results,
|
|
193
|
+
images_metadata=pre_processing_meta,
|
|
194
|
+
)
|
|
195
|
+
results = []
|
|
196
|
+
for result in rescaled_results:
|
|
197
|
+
results.append(
|
|
198
|
+
Detections(
|
|
199
|
+
xyxy=result[:, :4].round().int(),
|
|
200
|
+
class_id=result[:, 5].int(),
|
|
201
|
+
confidence=result[:, 4],
|
|
202
|
+
)
|
|
203
|
+
)
|
|
204
|
+
return results
|