NVIDIA / TensorRT

NVIDIA® TensorRT™ is an SDK for high-performance deep learning inference on NVIDIA GPUs. This repository contains the open source components of TensorRT.
https://developer.nvidia.com/tensorrt
Apache License 2.0
10.5k stars 2.1k forks source link

AttributeError: 'tensorrt_bindings.tensorrt.ICudaEngine' object has no attribute 'get_binding_index' #4007

Open ryou128hr opened 1 month ago

ryou128hr commented 1 month ago

TensorRT 10.2.0

def process_with_ai_engine(frame_rgb, engine):

  print("Processing frame with AI engine...")
 input_name = 'input'
 output_name = 'output'

# Create execution context
context = engine.create_execution_context()

# Get input and output binding indices
input_binding_index = engine.get_binding_index(input_name)
output_binding_index = engine.get_binding_index(output_name)

# Allocate device memory
d_input = cuda.mem_alloc(frame_rgb.nelement() * frame_rgb.element_size())
d_output = cuda.mem_alloc(frame_rgb.nelement() * frame_rgb.element_size())

# Set input shape
context.set_binding_shape(input_binding_index, frame_rgb.shape)

# Transfer input data to device
cuda.memcpy_htod(d_input, frame_rgb.cpu().numpy().tobytes())

# Execute model
bindings = [int(d_input), int(d_output)]
context.execute_v2(bindings)

# Transfer predictions back
output = torch.empty_like(frame_rgb)
cuda.memcpy_dtoh(output.data_ptr(), d_output)

return output

↓ Traceback (most recent call last): File "C:\Users\ryou\AppData\Local\Programs\Python\Python311\Lib\tkinter__init.py", line 1948, in call__ return self.func(*args) ^^^^^^^^^^^^^^^^ File "C:\Smooth Video\video_degradation_app\main.py", line 133, in process_and_play_video_ffstream frame_rgb = process_with_ai_engine(frame_rgb, engine) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Smooth Video\video_degradation_app\main.py", line 72, in process_with_ai_engine input_binding_index = engine.get_binding_index(input_name) ^^^^^^^^^^^^^^^^^^^^^^^^ AttributeError: 'tensorrt_bindings.tensorrt.ICudaEngine' object has no attribute 'get_binding_index'

I don't understand this.

lix19937 commented 1 month ago

ref https://github.com/NVIDIA/TensorRT/issues/3954#issuecomment-2180401230

ryou128hr commented 1 month ago

TensorRT 10.2.0

why

import os import tkinter as tk from tkinter import filedialog, messagebox import torch from ffstream.ffstream import FFStream import tensorrt as trt import pycuda.driver as cuda import pycuda.autoinit import numpy as np import cv2

TRT_LOGGER = trt.Logger(trt.Logger.WARNING)

def build_engine(onnx_file_path, engine_file_path): print("Starting to build the engine...") with trt.Builder(TRT_LOGGER) as builder, \ builder.create_network(1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)) as network, \ trt.OnnxParser(network, TRT_LOGGER) as parser: config = builder.create_builder_config() config.set_memory_pool_limit(trt.MemoryPoolType.WORKSPACE, 1 << 30) # 1GB config.set_flag(trt.BuilderFlag.FP16)

    print("Parsing ONNX file...")
    with open(onnx_file_path, 'rb') as model:
        if not parser.parse(model.read()):
            print('Failed to parse the ONNX file.')
            for error in range(parser.num_errors):
                print(parser.get_error(error))
            return None

    print("Creating optimization profile...")
    profile = builder.create_optimization_profile()
    input_name = network.get_input(0).name
    profile.set_shape(input_name, min=(1, 3, 64, 64), opt=(1, 3, 1080, 1920), max=(1, 3, 2160, 3840))
    config.add_optimization_profile(profile)

    print("Building the engine...")
    engine_bytes = builder.build_serialized_network(network, config)
    if engine_bytes is None:
        print('Failed to create engine')
        sys.exit(1)

    print("Deserializing the engine...")
    with trt.Runtime(TRT_LOGGER) as runtime:
        engine = runtime.deserialize_cuda_engine(engine_bytes)

    print("Engine built successfully.")
    save_engine(engine, engine_file_path)
    return engine

def save_engine(engine, file_path): with open(file_path, 'wb') as f: f.write(engine.serialize())

def load_engine(runtime, file_path): with open(file_path, 'rb') as f: engine_data = f.read() return runtime.deserialize_cuda_engine(engine_data)

def allocate_buffers(engine, context, input_shape): inputs = [] outputs = [] bindings = [] stream = cuda.Stream()

for i in range(engine.num_io_tensors):
    tensor_name = engine.get_tensor_name(i)
    if engine.get_tensor_mode(tensor_name) == trt.TensorIOMode.INPUT:
        context.set_input_shape(tensor_name, input_shape)
    shape = context.get_tensor_shape(tensor_name)
    size = trt.volume(shape)
    dtype = trt.nptype(engine.get_tensor_dtype(tensor_name))
    host_mem = cuda.pagelocked_empty(size, dtype)
    device_mem = cuda.mem_alloc(host_mem.nbytes)
    bindings.append(int(device_mem))
    if engine.get_tensor_mode(tensor_name) == trt.TensorIOMode.INPUT:
        inputs.append({'host': host_mem, 'device': device_mem, 'shape': shape})
    else:
        outputs.append({'host': host_mem, 'device': device_mem, 'shape': shape})

return inputs, outputs, bindings, stream

def do_inference(context, bindings, inputs, outputs, stream): [cuda.memcpy_htod_async(inp['device'], inp['host'], stream) for inp in inputs] context.execute_v2(bindings=bindings) [cuda.memcpy_dtoh_async(out['host'], out['device'], stream) for out in outputs] stream.synchronize() return [out['host'] for out in outputs]

def process_with_ai_engine(frame_rgb, engine, context, inputs, outputs, bindings, stream): print("Processing frame with AI engine...") frame_rgb_np = frame_rgb.cpu().numpy().ravel() input_shape = inputs[0]['shape'] print(f"Input tensor shape: {input_shape}, Frame shape: {frame_rgb_np.shape}") if frame_rgb_np.size != np.prod(input_shape): raise ValueError(f"Size mismatch: input tensor has {np.prod(input_shape)} elements but frame has {frame_rgb_np.size} elements.") np.copyto(inputs[0]['host'], frame_rgb_np) output = do_inference(context, bindings, inputs, outputs, stream) output_shape = outputs[0]['shape'] output_tensor = torch.from_numpy(output[0]).view(*output_shape).cuda() return output_tensor

def select_video(): file_path = filedialog.askopenfilename(filetypes=[("Video files", ".mp4;.avi;.mov;.mkv;.m2ts;.h264")]) if file_path: video_path.set(file_path)

def select_model(): file_path = filedialog.askopenfilename(filetypes=[("ONNX files", "*.onnx")]) if file_path: model_path.set(file_path)

def process_and_play_video_ffstream(): video_path_str = video_path.get() model_path_str = model_path.get() engine_file_path = "model.engine"

if not video_path_str or not model_path_str:
    messagebox.showerror("Error", "Please select both video file and model file")
    return

device = torch.device('cuda')

if not os.path.exists(engine_file_path):
    engine = build_engine(model_path_str, engine_file_path)
else:
    with trt.Runtime(TRT_LOGGER) as runtime:
        engine = load_engine(runtime, engine_file_path)

context = engine.create_execution_context()
input_shape = (1, 3, 1080, 1920)  # ここで正しい入力シェイプを設定
inputs, outputs, bindings, stream = allocate_buffers(engine, context, input_shape)

ff = FFStream(video_path_str, None, crf=20, pix_fmt='yuv420p', copy_audio_stream=False, device=device)

while True:
    frame_rgb = ff.get_rgb()
    if frame_rgb is None:
        break
    frame_rgb = process_with_ai_engine(frame_rgb, engine, context, inputs, outputs, bindings, stream)

    # Print the shape of the frame for debugging
    print(f"Processed frame shape: {frame_rgb.shape}")

    # Adjust the shape for visualization
    frame_rgb = frame_rgb.squeeze(0)  # Remove batch dimension if necessary

    img = frame_rgb.cpu().numpy().transpose(1, 2, 0)
    img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
    cv2.imshow('Video', img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

ff.close()
cv2.destroyAllWindows()

app = tk.Tk() app.title("Video Processing App")

video_path = tk.StringVar() model_path = tk.StringVar()

tk.Label(app, text="Select Video File:").grid(row=0, column=0, padx=10, pady=10) tk.Entry(app, textvariable=video_path, width=50).grid(row=0, column=1, padx=10, pady=10) tk.Button(app, text="Browse", command=select_video).grid(row=0, column=2, padx=10, pady=10)

tk.Label(app, text="Select ONNX Model File:").grid(row=1, column=0, padx=10, pady=10) tk.Entry(app, textvariable=model_path, width=50).grid(row=1, column=1, padx=10, pady=10) tk.Button(app, text="Browse", command=select_model).grid(row=1, column=2, padx=10, pady=10)

tk.Button(app, text="Process and Play Video", command=process_and_play_video_ffstream).grid(row=2, columnspan=3, padx=10, pady=20)

app.mainloop()

This is the 2xCompact model. It's black.

ryou128hr commented 1 month ago

This is real-time playback.