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.interpolate
andtorch.nn.functional.pad
operators.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