henry000 commited on
Commit
200b5c1
Β·
1 Parent(s): 9cc9e5d

πŸ› [Fix] a bug in deploying TensorRT model

Browse files
yolo/config/model/v9-c.yaml CHANGED
@@ -1,6 +1,6 @@
1
  anchor:
2
  reg_max: 16
3
- anchors: [8, 16, 32]
4
 
5
  model:
6
  backbone:
 
1
  anchor:
2
  reg_max: 16
3
+ strides: [8, 16, 32]
4
 
5
  model:
6
  backbone:
yolo/lazy.py CHANGED
@@ -25,7 +25,7 @@ def main(cfg: Config):
25
  model = FastModelLoader(cfg).load_model()
26
  else:
27
  model = create_model(cfg.model, class_num=cfg.class_num, weight_path=cfg.weight)
28
- model = model.to(device)
29
 
30
  vec2box = Vec2Box(model, cfg.image_size, device)
31
 
 
25
  model = FastModelLoader(cfg).load_model()
26
  else:
27
  model = create_model(cfg.model, class_num=cfg.class_num, weight_path=cfg.weight)
28
+ model = model.to(device)
29
 
30
  vec2box = Vec2Box(model, cfg.image_size, device)
31
 
yolo/model/module.py CHANGED
@@ -105,7 +105,7 @@ class Anchor2Vec(nn.Module):
105
  def forward(self, anchor_x: Tensor) -> Tensor:
106
  anchor_x = rearrange(anchor_x, "B (P R) h w -> B R P h w", P=4)
107
  vector_x = anchor_x.softmax(dim=1)
108
- vector_x = self.anc2vec(vector_x).squeeze(1)
109
  return anchor_x, vector_x
110
 
111
 
 
105
  def forward(self, anchor_x: Tensor) -> Tensor:
106
  anchor_x = rearrange(anchor_x, "B (P R) h w -> B R P h w", P=4)
107
  vector_x = anchor_x.softmax(dim=1)
108
+ vector_x = self.anc2vec(vector_x)[:, 0]
109
  return anchor_x, vector_x
110
 
111
 
yolo/model/yolo.py CHANGED
@@ -26,13 +26,15 @@ class YOLO(nn.Module):
26
  self.layer_map = get_layer_map() # Get the map Dict[str: Module]
27
  self.model: List[YOLOLayer] = nn.ModuleList()
28
  self.build_model(model_cfg.model)
 
29
 
30
  def build_model(self, model_arch: Dict[str, List[Dict[str, Dict[str, Dict]]]]):
31
  self.layer_index = {}
32
  output_dim, layer_idx = [3], 1
33
  logger.info(f"🚜 Building YOLO")
34
  for arch_name in model_arch:
35
- logger.info(f" πŸ—οΈ Building {arch_name}")
 
36
  for layer_idx, layer_spec in enumerate(model_arch[arch_name], start=layer_idx):
37
  layer_type, layer_info = next(iter(layer_spec.items()))
38
  layer_args = layer_info.get("args", {})
@@ -45,7 +47,6 @@ class YOLO(nn.Module):
45
  layer_args["in_channels"] = output_dim[source]
46
  if "Detection" in layer_type:
47
  layer_args["in_channels"] = [output_dim[idx] for idx in source]
48
- if "Detection" in layer_type or "Anchor2Box" in layer_type:
49
  layer_args["num_classes"] = self.num_classes
50
 
51
  # create layers
@@ -134,6 +135,7 @@ def create_model(model_cfg: ModelConfig, weight_path: Optional[str], class_num:
134
  if os.path.exists(weight_path):
135
  # TODO: fix map_location
136
  model.model.load_state_dict(torch.load(weight_path), strict=False)
137
- logger.info("βœ… Success load model weight")
138
-
 
139
  return model
 
26
  self.layer_map = get_layer_map() # Get the map Dict[str: Module]
27
  self.model: List[YOLOLayer] = nn.ModuleList()
28
  self.build_model(model_cfg.model)
29
+ self.strides = getattr(model_cfg.anchor, "strides", None)
30
 
31
  def build_model(self, model_arch: Dict[str, List[Dict[str, Dict[str, Dict]]]]):
32
  self.layer_index = {}
33
  output_dim, layer_idx = [3], 1
34
  logger.info(f"🚜 Building YOLO")
35
  for arch_name in model_arch:
36
+ if model_arch[arch_name]:
37
+ logger.info(f" πŸ—οΈ Building {arch_name}")
38
  for layer_idx, layer_spec in enumerate(model_arch[arch_name], start=layer_idx):
39
  layer_type, layer_info = next(iter(layer_spec.items()))
40
  layer_args = layer_info.get("args", {})
 
47
  layer_args["in_channels"] = output_dim[source]
48
  if "Detection" in layer_type:
49
  layer_args["in_channels"] = [output_dim[idx] for idx in source]
 
50
  layer_args["num_classes"] = self.num_classes
51
 
52
  # create layers
 
135
  if os.path.exists(weight_path):
136
  # TODO: fix map_location
137
  model.model.load_state_dict(torch.load(weight_path), strict=False)
138
+ logger.info("βœ… Success load model & weight")
139
+ else:
140
+ logger.info("βœ… Success load model")
141
  return model
yolo/tools/drawer.py CHANGED
@@ -13,7 +13,7 @@ def draw_bboxes(
13
  img: Union[Image.Image, torch.Tensor],
14
  bboxes: List[List[Union[int, float]]],
15
  *,
16
- idx2label: Optional[list],
17
  ):
18
  """
19
  Draw bounding boxes on an image.
@@ -47,7 +47,7 @@ def draw_bboxes(
47
  draw.rounded_rectangle(bbox, outline=(*color_map, 200), radius=5, width=2)
48
  draw.rounded_rectangle(bbox, fill=(*color_map, 100), radius=5)
49
 
50
- class_text = str(idx2label[int(class_id)] if idx2label else class_id)
51
  label_text = f"{class_text}" + (f" {conf[0]: .0%}" if conf else "")
52
 
53
  text_bbox = font.getbbox(label_text)
 
13
  img: Union[Image.Image, torch.Tensor],
14
  bboxes: List[List[Union[int, float]]],
15
  *,
16
+ idx2label: Optional[list] = None,
17
  ):
18
  """
19
  Draw bounding boxes on an image.
 
47
  draw.rounded_rectangle(bbox, outline=(*color_map, 200), radius=5, width=2)
48
  draw.rounded_rectangle(bbox, fill=(*color_map, 100), radius=5)
49
 
50
+ class_text = str(idx2label[int(class_id)] if idx2label else int(class_id))
51
  label_text = f"{class_text}" + (f" {conf[0]: .0%}" if conf else "")
52
 
53
  text_bbox = font.getbbox(label_text)
yolo/utils/bounding_box_utils.py CHANGED
@@ -9,6 +9,7 @@ from torch import Tensor
9
  from torchvision.ops import batched_nms
10
 
11
  from yolo.config.config import MatcherConfig, ModelConfig, NMSConfig
 
12
 
13
 
14
  def calculate_iou(bbox1, bbox2, metrics="iou") -> Tensor:
@@ -264,8 +265,8 @@ class BoxMatcher:
264
 
265
 
266
  class Vec2Box:
267
- def __init__(self, model, image_size, device, anchors: list = None):
268
- if anchors is None:
269
  logger.info("🧸 Found no anchor, Make a dummy test for auto-anchor size")
270
  dummy_input = torch.zeros(1, 3, *image_size).to(device)
271
  dummy_output = model(dummy_input)
@@ -274,7 +275,8 @@ class Vec2Box:
274
  _, _, *anchor_num = predict_head[2].shape
275
  anchors_num.append(anchor_num)
276
  else:
277
- anchors_num = [[image_size[0] / anchor, image_size[0] / anchor] for anchor in anchors]
 
278
  anchor_grid, scaler = generate_anchors(image_size, anchors_num)
279
  self.anchor_grid, self.scaler = anchor_grid.to(device), scaler.to(device)
280
  self.anchor_norm = (anchor_grid / scaler[:, None])[None].to(device)
 
9
  from torchvision.ops import batched_nms
10
 
11
  from yolo.config.config import MatcherConfig, ModelConfig, NMSConfig
12
+ from yolo.model.yolo import YOLO
13
 
14
 
15
  def calculate_iou(bbox1, bbox2, metrics="iou") -> Tensor:
 
265
 
266
 
267
  class Vec2Box:
268
+ def __init__(self, model: YOLO, image_size, device):
269
+ if model.strides is None:
270
  logger.info("🧸 Found no anchor, Make a dummy test for auto-anchor size")
271
  dummy_input = torch.zeros(1, 3, *image_size).to(device)
272
  dummy_output = model(dummy_input)
 
275
  _, _, *anchor_num = predict_head[2].shape
276
  anchors_num.append(anchor_num)
277
  else:
278
+ logger.info(f"🈢 Found anchor {model.strides}")
279
+ anchors_num = [[image_size[0] // stride, image_size[0] // stride] for stride in model.strides]
280
  anchor_grid, scaler = generate_anchors(image_size, anchors_num)
281
  self.anchor_grid, self.scaler = anchor_grid.to(device), scaler.to(device)
282
  self.anchor_norm = (anchor_grid / scaler[:, None])[None].to(device)
yolo/utils/deploy_utils.py CHANGED
@@ -30,9 +30,7 @@ class FastModelLoader:
30
  return self._load_trt_model()
31
  elif self.compiler == "deploy":
32
  self.cfg.model.model.auxiliary = {}
33
- return create_model(
34
- self.cfg.model, class_num=self.cfg.class_num, weight_path=self.cfg.weight, device=self.device
35
- )
36
 
37
  def _load_onnx_model(self):
38
  from onnxruntime import InferenceSession
@@ -91,9 +89,9 @@ class FastModelLoader:
91
  from torch2trt import torch2trt
92
 
93
  model = create_model(self.cfg.model, class_num=self.cfg.class_num, weight_path=self.cfg.weight).eval()
94
- dummy_input = torch.ones((1, 3, *self.cfg.image_size))
95
  logger.info(f"♻️ Creating TensorRT model")
96
- model_trt = torch2trt(model, [dummy_input])
97
  torch.save(model_trt.state_dict(), self.model_path)
98
  logger.info(f"πŸ“₯ TensorRT model saved to {self.model_path}")
99
  return model_trt
 
30
  return self._load_trt_model()
31
  elif self.compiler == "deploy":
32
  self.cfg.model.model.auxiliary = {}
33
+ return create_model(self.cfg.model, class_num=self.cfg.class_num, weight_path=self.cfg.weight)
 
 
34
 
35
  def _load_onnx_model(self):
36
  from onnxruntime import InferenceSession
 
89
  from torch2trt import torch2trt
90
 
91
  model = create_model(self.cfg.model, class_num=self.cfg.class_num, weight_path=self.cfg.weight).eval()
92
+ dummy_input = torch.ones((1, 3, *self.cfg.image_size)).cuda()
93
  logger.info(f"♻️ Creating TensorRT model")
94
+ model_trt = torch2trt(model.cuda(), [dummy_input])
95
  torch.save(model_trt.state_dict(), self.model_path)
96
  logger.info(f"πŸ“₯ TensorRT model saved to {self.model_path}")
97
  return model_trt