Why yolort?¶
TorchVision coding style, easy to understand, easy to adapt at will.
Seamlessly load the official YOLOv5 trained checkpoints, ensuring consistency with the YOLOv5 structure.
Full unit testing.
Deployment-friendly, TensorRT / ONNX Runtime / LibTorch / ncnn multi-backend support.
Install yolort from PyPI¶
[1]:
%pip install -q yolort
Note: you may need to restart the kernel to use updated packages.
[2]:
from typing import List
import torch
from torch import nn, Tensor
Part of the code details¶
LetterBox is implemented using PyTorch native operators, via
torch.nn.functional.interpolateandtorch.nn.functional.padoperators.Easily exported to TorchScript and ONNX formats.
P5/P6-compatible PathAggregationNetwork implementation, which fully captures the symmetry in the PAN structure.
Minimalist implementation of PostProcess.
Compatible with YOLOv5 original model structure¶
[3]:
from yolort.v5 import attempt_download
from yolort.models._checkpoint import load_from_ultralytics
# yolov5s6.pt is downloaded from 'https://github.com/ultralytics/yolov5/releases/download/v6.1/yolov5s6.pt'
model_path = "yolov5s6.pt"
checkpoint_path = attempt_download(model_path)
version = "r6.0"
model_info = load_from_ultralytics(checkpoint_path, version=version)
Obtain Backbone¶
[4]:
from yolort.models.backbone_utils import darknet_pan_backbone
backbone_name = f"darknet_{model_info['size']}_{version.replace('.', '_')}"
depth_multiple = model_info["depth_multiple"]
width_multiple = model_info["width_multiple"]
use_p6 = model_info["use_p6"]
backbone = darknet_pan_backbone(backbone_name, depth_multiple, width_multiple, version=version, use_p6=use_p6)
Obtain full YOLOv5 model structure¶
[5]:
from yolort.models.box_head import YOLOHead
class YOLO(nn.Module):
def __init__(self, backbone: nn.Module, strides, num_anchors, num_classes: int):
super().__init__()
self.backbone = backbone
self.head = YOLOHead(backbone.out_channels, num_anchors, strides, num_classes)
def forward(self, samples: Tensor) -> List[Tensor]:
# get the features from the backbone
features = self.backbone(samples)
# compute the yolo heads outputs using the features
head_outputs = self.head(features)
return head_outputs
[6]:
strides = model_info["strides"]
num_anchors = len(model_info["anchor_grids"][0]) // 2
num_classes = model_info["num_classes"]
model = YOLO(backbone, strides, num_anchors, num_classes)
model.load_state_dict(model_info["state_dict"])
model = model.eval()
[7]:
inputs = torch.rand(1, 3, 640, 640)
outs = model(inputs)
Functional deployment support solutions¶
[8]:
fx_trace_model = torch.fx.symbolic_trace(model)
[9]:
jit_trace_model = torch.jit.script(model)
View this document as a notebook: https://github.com/zhiqwang/yolort/blob/main/notebooks/why-yolort.ipynb