Skip to content

Commit

Permalink
add yolov7 support
Browse files Browse the repository at this point in the history
  • Loading branch information
dujw committed Jul 16, 2022
1 parent 61c494f commit 6420525
Show file tree
Hide file tree
Showing 19 changed files with 203 additions and 51 deletions.
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ lean_tensor_rt := /datav/lean/TensorRT-8.2.3.0-cuda11.4-cudnn8.2
lean_cudnn := /datav/lean/cudnn8.2.4.15-cuda11.4
lean_opencv := /datav/lean/opencv-4.2.0
lean_cuda := /datav/lean/cuda-11.2
use_python := false
use_python := true
python_root := /datav/software/anaconda3

# python_root指向的lib目录下有个libpython3.9.so,因此这里写python3.9
Expand Down Expand Up @@ -201,6 +201,9 @@ pycenternet : pytrtc
pyyolov5 : pytrtc
@cd example-python && python test_yolov5.py

pyyolov7 : pytrtc
@cd example-python && python test_yolov7.py

pyyolox : pytrtc
@cd example-python && python test_yolox.py

Expand Down
67 changes: 67 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,73 @@ make yolo -j32
</details>


<details>
<summary>YoloV7 Support</summary>
1. Download yolov7 and pth

```bash
# from cdn
# or wget https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7.pt

wget https://cdn.githubjs.cf/WongKinYiu/yolov7/releases/download/v0.1/yolov7.pt
git clone git@github.com:WongKinYiu/yolov7.git
```

2. Modify the code for dynamic batchsize
```python
# line 45 forward function in yolov7/models/yolo.py
# bs, _, ny, nx = x[i].shape # x(bs,255,20,20) to x(bs,3,20,20,85)
# x[i] = x[i].view(bs, self.na, self.no, ny, nx).permute(0, 1, 3, 4, 2).contiguous()
# modified into:

bs, _, ny, nx = map(int, x[i].shape) # x(bs,255,20,20) to x(bs,3,20,20,85)
bs = -1
x[i] = x[i].view(bs, self.na, self.no, ny, nx).permute(0, 1, 3, 4, 2).contiguous()

# line 52 in yolov7/models/yolo.py
# y = x[i].sigmoid()
# y[..., 0:2] = (y[..., 0:2] * 2. - 0.5 + self.grid[i]) * self.stride[i] # xy
# y[..., 2:4] = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i] # wh
# z.append(y.view(bs, -1, self.no))
# modified into:
y = x[i].sigmoid()
xy = (y[..., 0:2] * 2. - 0.5 + self.grid[i]) * self.stride[i] # xy
wh = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i].view(1, -1, 1, 1, 2) # wh
classif = y[..., 4:]
y = torch.cat([xy, wh, classif], dim=-1)
z.append(y.view(bs, self.na * ny * nx, self.no))

# line 57 in yolov7/models/yolo.py
# return x if self.training else (torch.cat(z, 1), x)
# modified into:
return x if self.training else torch.cat(z, 1)


# line 52 in yolov7/models/export.py
# output_names=['classes', 'boxes'] if y is None else ['output'],
# dynamic_axes={'images': {0: 'batch', 2: 'height', 3: 'width'}, # size(1,3,640,640)
# 'output': {0: 'batch', 2: 'y', 3: 'x'}} if opt.dynamic else None)
# modified into:
output_names=['classes', 'boxes'] if y is None else ['output'],
dynamic_axes={'images': {0: 'batch'}, # size(1,3,640,640)
'output': {0: 'batch'}} if opt.dynamic else None)

```
3. Export to onnx model
```bash
cd yolov7
python models/export.py --dynamic --grid --weight=yolov7.pt
```
4. Copy the model and execute it
```bash
cp yolov7/yolov7.onnx tensorRT_cpp/workspace/
cd tensorRT_cpp
make yolo -j32
```

</details>


<details>
<summary>YoloX Support</summary>

Expand Down
62 changes: 62 additions & 0 deletions example-python/test_yolov7.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import os
import cv2
import numpy as np
import pytrt as tp

# change current workspace
os.chdir("../workspace/")

# 如果执行出错,请删掉 ~/.pytrt 的缓存模型
# rm -rf ~/.pytrt,重新下载
device_id = 7
engine_file = "yolov7.fp32.trtmodel"
if not os.path.exists(engine_file):
tp.compile_onnx_to_file(5, tp.onnx_hub("yolov7"), engine_file, device_id=device_id)

yolo = tp.Yolo(engine_file, type=tp.YoloType.V5, device_id=device_id)
image = cv2.imread("inference/car.jpg")
bboxes = yolo.commit(image).get()
print(f"{len(bboxes)} objects")
print(bboxes)

for box in bboxes:
left, top, right, bottom = map(int, [box.left, box.top, box.right, box.bottom])
cv2.rectangle(image, (left, top), (right, bottom), tp.random_color(box.class_label), 5)

os.makedirs("single_inference", exist_ok=True)
saveto = "single_inference/yolov5.car.jpg"
print(f"Save to {saveto}")

cv2.imwrite(saveto, image)


try:
import torch

image = cv2.imread("inference/car.jpg")
device = 0

gpu_image = torch.from_numpy(image).to(device)
bboxes = yolo.commit_gpu(
pimage = gpu_image.data_ptr(),
width = image.shape[1],
height = image.shape[0],
device_id = device,
imtype = tp.ImageType.GPUBGR,
stream = torch.cuda.current_stream().cuda_stream
).get()
print(f"{len(bboxes)} objects")
print(bboxes)

for box in bboxes:
left, top, right, bottom = map(int, [box.left, box.top, box.right, box.bottom])
cv2.rectangle(image, (left, top), (right, bottom), tp.random_color(box.class_label), 5)

os.makedirs("single_inference", exist_ok=True)
saveto = "single_inference/yolov7-gpuptr.car.jpg"
print(f"Save to {saveto}")

cv2.imwrite(saveto, image)

except Exception as e:
print("GPUPtr test failed.", e)
4 changes: 2 additions & 2 deletions example-restful_server/src/infer/simple_yolo.cu
Original file line number Diff line number Diff line change
Expand Up @@ -1813,7 +1813,7 @@ namespace SimpleYolo{

virtual bool startup(const string& file, Type type, int gpuid, float confidence_threshold, float nms_threshold){

if(type == Type::V5){
if(type == Type::V5 || type == Type::V3 || type == Type::V7){
normalize_ = Norm::alpha_beta(1 / 255.0f, 0.0f, ChannelType::SwapRB);
}else if(type == Type::X){
//float mean[] = {0.485, 0.456, 0.406};
Expand Down Expand Up @@ -1993,7 +1993,7 @@ namespace SimpleYolo{
void image_to_tensor(const cv::Mat& image, shared_ptr<Tensor>& tensor, Type type, int ibatch){

Norm normalize;
if(type == Type::V5){
if(type == Type::V5 || type == Type::V3 || type == Type::V7){
normalize = Norm::alpha_beta(1 / 255.0f, 0.0f, ChannelType::SwapRB);
}else if(type == Type::X){
//float mean[] = {0.485, 0.456, 0.406};
Expand Down
12 changes: 8 additions & 4 deletions example-simple_yolo/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@ cu_mk := $(cu_objs:.cuo=.cumk)
# tensorRT下载GA版本(通用版、稳定版),EA(尝鲜版本)不要
# 3. cuda10.2,也可以是11.x看搭配(请自行下载安装)

lean_tensor_rt := /data/sxai/lean/TensorRT-8.0.1.6-cuda10.2-cudnn8.2
lean_cudnn := /data/sxai/lean/cudnn8.2.2.26
lean_opencv := /data/sxai/lean/opencv4.2.0
lean_cuda := /data/sxai/lean/cuda-10.2
# lean_tensor_rt := /data/sxai/lean/TensorRT-8.0.1.6-cuda10.2-cudnn8.2
# lean_cudnn := /data/sxai/lean/cudnn8.2.2.26
# lean_opencv := /data/sxai/lean/opencv4.2.0
# lean_cuda := /data/sxai/lean/cuda-10.2
lean_tensor_rt := /datav/lean/TensorRT-8.2.3.0-cuda11.4-cudnn8.2
lean_cudnn := /datav/lean/cudnn8.2.4.15-cuda11.4
lean_opencv := /datav/lean/opencv-4.2.0
lean_cuda := /datav/lean/cuda-11.2

# lean_tensor_rt := /data/sxai/lean/TensorRT-7.0.0.11
# lean_cudnn := /data/sxai/lean/cudnn7.6.5.32-cuda10.2
Expand Down
55 changes: 28 additions & 27 deletions example-simple_yolo/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ static double timestamp_now_float() {

bool requires_model(const string& name) {

auto onnx_file = cv::format("%s_dynamic.onnx", name.c_str());
auto onnx_file = cv::format("%s.onnx", name.c_str());
if (!exists(onnx_file)) {
printf("Auto download %s\n", onnx_file.c_str());
system(cv::format("wget http://zifuture.com:1556/fs/25.shared/%s", onnx_file.c_str()).c_str());
Expand Down Expand Up @@ -189,8 +189,8 @@ static void test(SimpleYolo::Type type, SimpleYolo::Mode mode, const string& mod
if(!requires_model(name))
return;

string onnx_file = cv::format("%s_dynamic.onnx", name);
string model_file = cv::format("%s_dynamic.%s.trtmodel", name, mode_name);
string onnx_file = cv::format("%s.onnx", name);
string model_file = cv::format("%s.%s.trtmodel", name, mode_name);
int test_batch_size = 16;

if(!exists(model_file)){
Expand All @@ -211,11 +211,11 @@ void direct_test(){
printf("TRTVersion: %s\n", SimpleYolo::trt_version());

int device_id = 0;
string model = "yolox_s";
string model = "yolox_s_dynamic";
auto type = SimpleYolo::Type::X;
auto mode = SimpleYolo::Mode::FP32;
string onnx_file = cv::format("%s_dynamic.onnx", model.c_str());
string model_file = cv::format("%s_dynamic.%s.trtmodel", model.c_str(), SimpleYolo::mode_string(mode));
string onnx_file = cv::format("%s.onnx", model.c_str());
string model_file = cv::format("%s.%s.trtmodel", model.c_str(), SimpleYolo::mode_string(mode));
SimpleYolo::set_device(device_id);

if(!requires_model(model)){
Expand Down Expand Up @@ -257,27 +257,28 @@ void direct_test(){
int main(){

//direct_test();
test(SimpleYolo::Type::V5, SimpleYolo::Mode::FP32, "yolov5s");
//test(SimpleYolo::Type::X, SimpleYolo::Mode::INT8, "yolox_s");
test(SimpleYolo::Type::V7, SimpleYolo::Mode::FP32, "yolov7");
//test(SimpleYolo::Type::V5, SimpleYolo::Mode::FP32, "yolov5s_dynamic");
//test(SimpleYolo::Type::X, SimpleYolo::Mode::INT8, "yolox_s_dynamic");

//test(SimpleYolo::Type::X, SimpleYolo::Mode::FP32, "yolox_s");
// test(SimpleYolo::Type::X, SimpleYolo::Mode::FP32, "yolox_x");
// test(SimpleYolo::Type::X, SimpleYolo::Mode::FP32, "yolox_l");
// test(SimpleYolo::Type::X, SimpleYolo::Mode::FP32, "yolox_m");
// test(SimpleYolo::Type::X, SimpleYolo::Mode::FP32, "yolox_s");
// test(SimpleYolo::Type::X, SimpleYolo::Mode::FP16, "yolox_x");
// test(SimpleYolo::Type::X, SimpleYolo::Mode::FP16, "yolox_l");
// test(SimpleYolo::Type::X, SimpleYolo::Mode::FP16, "yolox_m");
// test(SimpleYolo::Type::X, SimpleYolo::Mode::FP16, "yolox_s");

// test(SimpleYolo::Type::V5, SimpleYolo::Mode::FP32, "yolov5x");
// test(SimpleYolo::Type::V5, SimpleYolo::Mode::FP32, "yolov5l");
// test(SimpleYolo::Type::V5, SimpleYolo::Mode::FP32, "yolov5m");
// test(SimpleYolo::Type::V5, SimpleYolo::Mode::FP32, "yolov5s");

// test(SimpleYolo::Type::V5, SimpleYolo::Mode::FP16, "yolov5x");
// test(SimpleYolo::Type::V5, SimpleYolo::Mode::FP16, "yolov5l");
// test(SimpleYolo::Type::V5, SimpleYolo::Mode::FP16, "yolov5m");
// test(SimpleYolo::Type::V5, SimpleYolo::Mode::FP16, "yolov5s");
//test(SimpleYolo::Type::X, SimpleYolo::Mode::FP32, "yolox_s_dynamic");
// test(SimpleYolo::Type::X, SimpleYolo::Mode::FP32, "yolox_x_dynamic");
// test(SimpleYolo::Type::X, SimpleYolo::Mode::FP32, "yolox_l_dynamic");
// test(SimpleYolo::Type::X, SimpleYolo::Mode::FP32, "yolox_m_dynamic");
// test(SimpleYolo::Type::X, SimpleYolo::Mode::FP32, "yolox_s_dynamic");
// test(SimpleYolo::Type::X, SimpleYolo::Mode::FP16, "yolox_x_dynamic");
// test(SimpleYolo::Type::X, SimpleYolo::Mode::FP16, "yolox_l_dynamic");
// test(SimpleYolo::Type::X, SimpleYolo::Mode::FP16, "yolox_m_dynamic");
// test(SimpleYolo::Type::X, SimpleYolo::Mode::FP16, "yolox_s_dynamic");

// test(SimpleYolo::Type::V5, SimpleYolo::Mode::FP32, "yolov5x_dynamic");
// test(SimpleYolo::Type::V5, SimpleYolo::Mode::FP32, "yolov5l_dynamic");
// test(SimpleYolo::Type::V5, SimpleYolo::Mode::FP32, "yolov5m_dynamic");
// test(SimpleYolo::Type::V5, SimpleYolo::Mode::FP32, "yolov5s_dynamic");

// test(SimpleYolo::Type::V5, SimpleYolo::Mode::FP16, "yolov5x_dynamic");
// test(SimpleYolo::Type::V5, SimpleYolo::Mode::FP16, "yolov5l_dynamic");
// test(SimpleYolo::Type::V5, SimpleYolo::Mode::FP16, "yolov5m_dynamic");
// test(SimpleYolo::Type::V5, SimpleYolo::Mode::FP16, "yolov5s_dynamic");
return 0;
}
6 changes: 4 additions & 2 deletions example-simple_yolo/src/simple_yolo.cu
Original file line number Diff line number Diff line change
Expand Up @@ -1771,6 +1771,8 @@ namespace SimpleYolo{
const char* type_name(Type type){
switch(type){
case Type::V5: return "YoloV5";
case Type::V3: return "YoloV3";
case Type::V7: return "YoloV7";
case Type::X: return "YoloX";
default: return "Unknow";
}
Expand Down Expand Up @@ -1814,7 +1816,7 @@ namespace SimpleYolo{

virtual bool startup(const string& file, Type type, int gpuid, float confidence_threshold, float nms_threshold){

if(type == Type::V5){
if(type == Type::V5 || type == Type::V3 || type == Type::V7){
normalize_ = Norm::alpha_beta(1 / 255.0f, 0.0f, ChannelType::SwapRB);
}else if(type == Type::X){
//float mean[] = {0.485, 0.456, 0.406};
Expand Down Expand Up @@ -1994,7 +1996,7 @@ namespace SimpleYolo{
void image_to_tensor(const cv::Mat& image, shared_ptr<Tensor>& tensor, Type type, int ibatch){

Norm normalize;
if(type == Type::V5){
if(type == Type::V5 || type == Type::V3 || type == Type::V7){
normalize = Norm::alpha_beta(1 / 255.0f, 0.0f, ChannelType::SwapRB);
}else if(type == Type::X){
//float mean[] = {0.485, 0.456, 0.406};
Expand Down
4 changes: 3 additions & 1 deletion example-simple_yolo/src/simple_yolo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ namespace SimpleYolo{

enum class Type : int{
V5 = 0,
X = 1
X = 1,
V3 = 2,
V7 = 3
};

enum class Mode : int {
Expand Down
2 changes: 1 addition & 1 deletion src/application/app_high_performance/yolo_high_perf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ namespace YoloHighPerf{
public:
virtual bool startup(const string& file, Type type, int gpuid, float confidence_threshold, float nms_threshold){

if(type == Type::V5){
if(type == Type::V5 || type == Type::V3 || type == Type::V7){
normalize_ = CUDAKernel::Norm::alpha_beta(1 / 255.0f, 0.0f, CUDAKernel::ChannelType::Invert);
}else if(type == Type::X){
//float mean[] = {0.485, 0.456, 0.406};
Expand Down
4 changes: 3 additions & 1 deletion src/application/app_high_performance/yolo_high_perf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ namespace YoloHighPerf{

enum class Type : int{
V5 = 0,
X = 1
X = 1,
V3 = 2,
V7 = 3
};

struct Box{
Expand Down
1 change: 1 addition & 0 deletions src/application/app_python/interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,7 @@ PYBIND11_MODULE(libpytrtc, m) {
py::enum_<YoloGPUPtr::Type>(m, "YoloType")
.value("V5", YoloGPUPtr::Type::V5)
.value("V3", YoloGPUPtr::Type::V3)
.value("V7", YoloGPUPtr::Type::V7)
.value("X", YoloGPUPtr::Type::X);

py::enum_<YoloGPUPtr::NMSMethod>(m, "NMSMethod")
Expand Down
3 changes: 2 additions & 1 deletion src/application/app_yolo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,8 @@ void multi_gpu_test(){

int app_yolo(){

test(Yolo::Type::V5, TRT::Mode::FP32, "yolov5s");
test(Yolo::Type::V7, TRT::Mode::FP32, "yolov7");
//test(Yolo::Type::V5, TRT::Mode::FP32, "yolov5s");
//test(Yolo::Type::V3, TRT::Mode::FP32, "yolov3");

// multi_gpu_test();
Expand Down
6 changes: 4 additions & 2 deletions src/application/app_yolo/yolo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ namespace Yolo{
const char* type_name(Type type){
switch(type){
case Type::V5: return "YoloV5";
case Type::V3: return "YoloV3";
case Type::V7: return "YoloV7";
case Type::X: return "YoloX";
default: return "Unknow";
}
Expand Down Expand Up @@ -165,7 +167,7 @@ namespace Yolo{
NMSMethod nms_method, int max_objects,
bool use_multi_preprocess_stream
){
if(type == Type::V5){
if(type == Type::V5 || type == Type::V3 || type == Type::V7){
normalize_ = CUDAKernel::Norm::alpha_beta(1 / 255.0f, 0.0f, CUDAKernel::ChannelType::Invert);
}else if(type == Type::X){
//float mean[] = {0.485, 0.456, 0.406};
Expand Down Expand Up @@ -400,7 +402,7 @@ namespace Yolo{
void image_to_tensor(const cv::Mat& image, shared_ptr<TRT::Tensor>& tensor, Type type, int ibatch){

CUDAKernel::Norm normalize;
if(type == Type::V5){
if(type == Type::V5 || type == Type::V3 || type == Type::V7){
normalize = CUDAKernel::Norm::alpha_beta(1 / 255.0f, 0.0f, CUDAKernel::ChannelType::Invert);
}else if(type == Type::X){
//float mean[] = {0.485, 0.456, 0.406};
Expand Down
3 changes: 2 additions & 1 deletion src/application/app_yolo/yolo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ namespace Yolo{
enum class Type : int{
V5 = 0,
X = 1,
V3 = V5
V3 = 2,
V7 = 3
};

enum class NMSMethod : int{
Expand Down
Loading

0 comments on commit 6420525

Please sign in to comment.