autoconvert tensor rt engine from onnx to specific CUDA gpu

This commit is contained in:
Alex Bezdieniezhnykh
2025-04-24 16:30:21 +03:00
parent e798af470b
commit e9a44e368d
14 changed files with 25 additions and 44 deletions
+3 -3
View File
@@ -80,7 +80,7 @@ namespace Azaion.Annotator.Controls
FontWeights.Bold, FontWeights.Bold,
FontStretches.Normal); FontStretches.Normal);
FormattedText _fText; FormattedText _fText = null!;
private Brush _background = Brushes.Blue; private Brush _background = Brushes.Blue;
@@ -187,7 +187,7 @@ namespace Azaion.Annotator.Controls
IsChanged = true; IsChanged = true;
} }
string _text; string _text = null!;
public string Text public string Text
{ {
@@ -205,7 +205,7 @@ namespace Azaion.Annotator.Controls
} }
} }
Visual _child; Visual _child = null!;
public virtual Visual Child public virtual Visual Child
{ {
+1 -1
View File
@@ -33,7 +33,7 @@ public class Constants
AnnotationsDbFile = DEFAULT_ANNOTATIONS_DB_FILE AnnotationsDbFile = DEFAULT_ANNOTATIONS_DB_FILE
}; };
public static readonly List<DetectionClass> DefaultAnnotationClasses = private static readonly List<DetectionClass> DefaultAnnotationClasses =
[ [
new() { Id = 0, Name = "ArmorVehicle", ShortName = "Броня", Color = "#FF0000".ToColor() }, new() { Id = 0, Name = "ArmorVehicle", ShortName = "Броня", Color = "#FF0000".ToColor() },
new() { Id = 1, Name = "Truck", ShortName = "Вантаж.", Color = "#00FF00".ToColor() }, new() { Id = 1, Name = "Truck", ShortName = "Вантаж.", Color = "#00FF00".ToColor() },
@@ -10,7 +10,4 @@ public class ApiCredentials(string email, string password) : EventArgs
[Key(nameof(Password))] [Key(nameof(Password))]
public string Password { get; set; } = password; public string Password { get; set; } = password;
[Key(nameof(Folder))]
public string Folder { get; set; } = null!;
} }
@@ -70,7 +70,7 @@ public class AzaionApi(HttpClient client, ICache cache, ApiCredentials credentia
if (response.StatusCode == HttpStatusCode.Conflict) if (response.StatusCode == HttpStatusCode.Conflict)
{ {
var result = JsonConvert.DeserializeObject<BusinessExceptionDto>(content); var result = JsonConvert.DeserializeObject<BusinessExceptionDto>(content);
throw new Exception($"Failed: {response.StatusCode}! Error Code: {result.ErrorCode}. Message: {result.Message}"); throw new Exception($"Failed: {response.StatusCode}! Error Code: {result?.ErrorCode}. Message: {result?.Message}");
} }
throw new Exception($"Failed: {response.StatusCode}! Result: {content}"); throw new Exception($"Failed: {response.StatusCode}! Result: {content}");
} }
-2
View File
@@ -14,5 +14,3 @@ cdef class Annotation:
cdef format_time(self, ms) cdef format_time(self, ms)
cdef bytes serialize(self) cdef bytes serialize(self)
cdef to_str(self, class_names)
+2 -2
View File
@@ -32,12 +32,12 @@ cdef class Annotation:
d.annotation_name = self.name d.annotation_name = self.name
self.image = b'' self.image = b''
cdef to_str(self, class_names): def __str__(self):
if not self.detections: if not self.detections:
return f"{self.name}: No detections" return f"{self.name}: No detections"
detections_str = ", ".join( detections_str = ", ".join(
f"{class_names[d.cls]} {d.confidence * 100:.1f}% ({d.x:.2f}, {d.y:.2f})" f"class: {d.cls} {d.confidence * 100:.1f}% ({d.x:.2f}, {d.y:.2f})"
for d in self.detections for d in self.detections
) )
return f"{self.name}: {detections_str}" return f"{self.name}: {detections_str}"
+1 -1
View File
@@ -79,7 +79,7 @@ cdef class ApiClient:
try: try:
r = requests.post(url, headers=headers, files=files, allow_redirects=True) r = requests.post(url, headers=headers, files=files, allow_redirects=True)
r.raise_for_status() r.raise_for_status()
print(f"Upload success: {r.status_code}") print(f"Uploaded {filename} to {constants.API_URL}/{folder} successfully: {r.status_code}.")
except Exception as e: except Exception as e:
print(f"Upload fail: {e}") print(f"Upload fail: {e}")
-1
View File
@@ -10,7 +10,6 @@ cdef class Inference:
cdef object on_annotation cdef object on_annotation
cdef Annotation _previous_annotation cdef Annotation _previous_annotation
cdef AIRecognitionConfig ai_config cdef AIRecognitionConfig ai_config
cdef object class_names
cdef bint stop_signal cdef bint stop_signal
cdef str model_input cdef str model_input
+5 -9
View File
@@ -24,7 +24,6 @@ cdef class Inference:
self.model_width = 0 self.model_width = 0
self.model_height = 0 self.model_height = 0
self.engine = None self.engine = None
self.class_names = None
self.is_building_engine = False self.is_building_engine = False
cdef build_tensor_engine(self): cdef build_tensor_engine(self):
@@ -37,9 +36,11 @@ cdef class Inference:
models_dir = constants.MODELS_FOLDER models_dir = constants.MODELS_FOLDER
if not os.path.exists(os.path.join(<str> models_dir, f'{engine_filename}.big')): if not os.path.exists(os.path.join(<str> models_dir, f'{engine_filename}.big')):
self.is_building_engine = True self.is_building_engine = True
time.sleep(5) # prevent simultaneously loading dll and models
onnx_model = self.api_client.load_big_small_resource(constants.AI_ONNX_MODEL_FILE, models_dir, key) onnx_model = self.api_client.load_big_small_resource(constants.AI_ONNX_MODEL_FILE, models_dir, key)
model_bytes = TensorRTEngine.convert_from_onnx(onnx_model) model_bytes = TensorRTEngine.convert_from_onnx(onnx_model)
self.api_client.upload_big_small_resource(model_bytes, <str> engine_filename, models_dir, key) self.api_client.upload_big_small_resource(model_bytes, <str> engine_filename, models_dir, key)
print('uploaded ')
self.is_building_engine = False self.is_building_engine = False
@@ -62,7 +63,6 @@ cdef class Inference:
self.engine = OnnxEngine(model_bytes) self.engine = OnnxEngine(model_bytes)
self.model_height, self.model_width = self.engine.get_input_shape() self.model_height, self.model_width = self.engine.get_input_shape()
self.class_names = self.engine.get_class_names()
cdef preprocess(self, frames): cdef preprocess(self, frames):
blobs = [cv2.dnn.blobFromImage(frame, blobs = [cv2.dnn.blobFromImage(frame,
@@ -75,13 +75,11 @@ cdef class Inference:
return np.vstack(blobs) return np.vstack(blobs)
cdef postprocess(self, output, ai_config): cdef postprocess(self, output, ai_config):
print('enter postprocess')
cdef list[Detection] detections = [] cdef list[Detection] detections = []
cdef int ann_index cdef int ann_index
cdef float x1, y1, x2, y2, conf, cx, cy, w, h cdef float x1, y1, x2, y2, conf, cx, cy, w, h
cdef int class_id cdef int class_id
cdef list[list[Detection]] results = [] cdef list[list[Detection]] results = []
print('start try: code')
try: try:
for ann_index in range(len(output[0])): for ann_index in range(len(output[0])):
detections.clear() detections.clear()
@@ -163,7 +161,7 @@ cdef class Inference:
images.append(m) images.append(m)
# images first, it's faster # images first, it's faster
if len(images) > 0: if len(images) > 0:
for chunk in self.split_list_extend(images, self.engine.get_input_shape()): for chunk in self.split_list_extend(images, self.engine.get_batch_size()):
print(f'run inference on {" ".join(chunk)}...') print(f'run inference on {" ".join(chunk)}...')
self._process_images(cmd, ai_config, chunk) self._process_images(cmd, ai_config, chunk)
if len(videos) > 0: if len(videos) > 0:
@@ -189,7 +187,7 @@ cdef class Inference:
batch_frames.append(frame) batch_frames.append(frame)
batch_timestamps.append(int(v_input.get(cv2.CAP_PROP_POS_MSEC))) batch_timestamps.append(int(v_input.get(cv2.CAP_PROP_POS_MSEC)))
if len(batch_frames) == self.engine.get_input_shape(): if len(batch_frames) == self.engine.get_batch_size():
input_blob = self.preprocess(batch_frames) input_blob = self.preprocess(batch_frames)
outputs = self.engine.run(input_blob) outputs = self.engine.run(input_blob)
@@ -203,10 +201,9 @@ cdef class Inference:
annotation.image = image.tobytes() annotation.image = image.tobytes()
self._previous_annotation = annotation self._previous_annotation = annotation
print(annotation.to_str(self.class_names)) print(annotation)
self.on_annotation(cmd, annotation) self.on_annotation(cmd, annotation)
batch_frames.clear() batch_frames.clear()
batch_timestamps.clear() batch_timestamps.clear()
v_input.release() v_input.release()
@@ -231,7 +228,6 @@ cdef class Inference:
annotation = Annotation(image_paths[i], timestamps[i], detections) annotation = Annotation(image_paths[i], timestamps[i], detections)
_, image = cv2.imencode('.jpg', frames[i]) _, image = cv2.imencode('.jpg', frames[i])
annotation.image = image.tobytes() annotation.image = image.tobytes()
print(annotation.to_str(self.class_names))
self.on_annotation(cmd, annotation) self.on_annotation(cmd, annotation)
-3
View File
@@ -6,7 +6,6 @@ cdef class InferenceEngine:
cdef public int batch_size cdef public int batch_size
cdef tuple get_input_shape(self) cdef tuple get_input_shape(self)
cdef int get_batch_size(self) cdef int get_batch_size(self)
cdef get_class_names(self)
cpdef run(self, input_data) cpdef run(self, input_data)
cdef class OnnxEngine(InferenceEngine): cdef class OnnxEngine(InferenceEngine):
@@ -14,7 +13,6 @@ cdef class OnnxEngine(InferenceEngine):
cdef list model_inputs cdef list model_inputs
cdef str input_name cdef str input_name
cdef object input_shape cdef object input_shape
cdef object class_names
cdef class TensorRTEngine(InferenceEngine): cdef class TensorRTEngine(InferenceEngine):
cdef object stream cdef object stream
@@ -26,7 +24,6 @@ cdef class TensorRTEngine(InferenceEngine):
cdef object input_shape cdef object input_shape
cdef object output_shape cdef object output_shape
cdef object h_output cdef object h_output
cdef object class_names
@staticmethod @staticmethod
cdef bytes convert_from_onnx(bytes onnx_model) cdef bytes convert_from_onnx(bytes onnx_model)
+6 -12
View File
@@ -22,9 +22,6 @@ cdef class InferenceEngine:
cpdef run(self, input_data): cpdef run(self, input_data):
raise NotImplementedError("Subclass must implement run") raise NotImplementedError("Subclass must implement run")
cdef get_class_names(self):
raise NotImplementedError("Subclass must implement get_class_names")
cdef class OnnxEngine(InferenceEngine): cdef class OnnxEngine(InferenceEngine):
def __init__(self, model_bytes: bytes, batch_size: int = 1, **kwargs): def __init__(self, model_bytes: bytes, batch_size: int = 1, **kwargs):
@@ -39,7 +36,6 @@ cdef class OnnxEngine(InferenceEngine):
print(f'AI detection model input: {self.model_inputs} {self.input_shape}') print(f'AI detection model input: {self.model_inputs} {self.input_shape}')
model_meta = self.session.get_modelmeta() model_meta = self.session.get_modelmeta()
print("Metadata:", model_meta.custom_metadata_map) print("Metadata:", model_meta.custom_metadata_map)
self.class_names = eval(model_meta.custom_metadata_map["names"])
cdef tuple get_input_shape(self): cdef tuple get_input_shape(self):
shape = self.input_shape shape = self.input_shape
@@ -48,9 +44,6 @@ cdef class OnnxEngine(InferenceEngine):
cdef int get_batch_size(self): cdef int get_batch_size(self):
return self.batch_size return self.batch_size
cdef get_class_names(self):
return self.class_names
cpdef run(self, input_data): cpdef run(self, input_data):
return self.session.run(None, {self.input_name: input_data}) return self.session.run(None, {self.input_name: input_data})
@@ -69,10 +62,14 @@ cdef class TensorRTEngine(InferenceEngine):
raise RuntimeError(f"Failed to load TensorRT engine from bytes") raise RuntimeError(f"Failed to load TensorRT engine from bytes")
self.context = engine.create_execution_context() self.context = engine.create_execution_context()
# input # input
self.input_name = engine.get_tensor_name(0) self.input_name = engine.get_tensor_name(0)
engine_input_shape = engine.get_tensor_shape(self.input_name) engine_input_shape = engine.get_tensor_shape(self.input_name)
self.batch_size = self.input_shape[0] if self.input_shape[0] != -1 else batch_size if engine_input_shape[0] != -1:
self.batch_size = engine_input_shape[0]
else:
self.batch_size = batch_size
self.input_shape = [ self.input_shape = [
self.batch_size, self.batch_size,
@@ -154,7 +151,7 @@ cdef class TensorRTEngine(InferenceEngine):
if plan is None: if plan is None:
print('Conversion failed.') print('Conversion failed.')
return None return None
print('conversion done!')
return bytes(plan) return bytes(plan)
cdef tuple get_input_shape(self): cdef tuple get_input_shape(self):
@@ -163,9 +160,6 @@ cdef class TensorRTEngine(InferenceEngine):
cdef int get_batch_size(self): cdef int get_batch_size(self):
return self.batch_size return self.batch_size
cdef get_class_names(self):
return self.class_names
cpdef run(self, input_data): cpdef run(self, input_data):
try: try:
cuda.memcpy_htod_async(self.d_input, input_data, self.stream) cuda.memcpy_htod_async(self.d_input, input_data, self.stream)
+1 -1
View File
@@ -76,7 +76,7 @@ cdef class RemoteCommandHandler:
with self._context.socket(zmq.DEALER) as socket: with self._context.socket(zmq.DEALER) as socket:
socket.connect("inproc://backend") socket.connect("inproc://backend")
socket.send_multipart([client_id, data]) socket.send_multipart([client_id, data])
constants.log(<str>f'Sent {len(data)} bytes.', client_id) # constants.log(<str>f'Sent {len(data)} bytes.', client_id)
cdef stop(self): cdef stop(self):
self._shutdown_event.set() self._shutdown_event.set()
+1 -1
View File
@@ -94,7 +94,7 @@ public partial class App
_resourceLoader = new ResourceLoader(_inferenceClient); _resourceLoader = new ResourceLoader(_inferenceClient);
var login = new Login(); var login = new Login();
login.CredentialsEntered += async (_, credentials) => login.CredentialsEntered += (_, credentials) =>
{ {
_inferenceClient.Send(RemoteCommand.Create(CommandType.Login, credentials)); _inferenceClient.Send(RemoteCommand.Create(CommandType.Login, credentials));
_azaionApi = new AzaionApi(new HttpClient { BaseAddress = new Uri(SecurityConstants.API_URL) }, _cache, credentials, _hardwareService); _azaionApi = new AzaionApi(new HttpClient { BaseAddress = new Uri(SecurityConstants.API_URL) }, _cache, credentials, _hardwareService);
+4 -4
View File
@@ -50,9 +50,9 @@ public partial class MainSuite
Loaded += OnLoaded; Loaded += OnLoaded;
Closed += OnFormClosed; Closed += OnFormClosed;
SizeChanged += async (_, _) => await SaveUserSettings(); SizeChanged += (_, _) => SaveUserSettings();
LocationChanged += async (_, _) => await SaveUserSettings(); LocationChanged += (_, _) => SaveUserSettings();
StateChanged += async (_, _) => await SaveUserSettings(); StateChanged += (_, _) => SaveUserSettings();
Left = (SystemParameters.WorkArea.Width - Width) / 2; Left = (SystemParameters.WorkArea.Width - Width) / 2;
} }
@@ -130,7 +130,7 @@ public partial class MainSuite
} }
private async Task SaveUserSettings() private void SaveUserSettings()
{ {
ThrottleExt.Throttle(() => ThrottleExt.Throttle(() =>
{ {