Skip to content

Commit 8aa4f99

Browse files
committed
Update features: done infer triton pipeline, return box and save output. Update readme: benchmarks, cmd ex...
1 parent 7491b62 commit 8aa4f99

12 files changed

+78
-59
lines changed

LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright (c) 2021, Kim Nguyen
1+
Copyright (c) 2021, Kim Nguyen, NVIDIA CORPORATION
22
All rights reserved.
33

44
Redistribution and use in source and binary forms, with or without

README.md

+19-5
Original file line numberDiff line numberDiff line change
@@ -73,20 +73,34 @@ I0714 00:37:55.312507 1 http_server.cc:2906] Started Metrics Service at 0.0.0.0:
7373
```
7474
Run infer by cmd:
7575
```
76-
$ python infer_triton.py -m='detec_trt' -x=1 --input='./images/image_1.jpg' -i='grpc' -u='localhost:8001'
77-
78-
$ python infer_triton.py -m='detec_onnx' -x=1 --input='./images/image_1.jpg'
76+
$ python infer_triton.py -m='detec_trt' -x=1 --test_folder='./images' -i='grpc' -u='localhost:8001'
77+
Request 1, batch size 1s/sample.jpg
78+
elapsed time : 0.9521937370300293s
7979
```
80+
#### Performance benchmarks: single image (sample.jpg), time in seconds
81+
- Triton server: (gRPC-HTTP): <br>
82+
83+
| Model format| gRPC (s)| HTTP (s) |
84+
|-------------|---------|----------|
85+
| TensoRT | 0.946 | 0.952 |
86+
| Torchscript | 1.244 | 1.098 |
87+
| ONNX | 1.052 | 1.060 |
88+
89+
- Classic Pytorch: 1.319s
8090

8191
#### Arguments
8292
* `-m`: name of model with format
8393
* `-x`: version of model
84-
* `--input`: input image/folder
94+
* `--test_folder`: input image/folder
8595
* `-i`: protocol (HTTP/gRPC)
8696
* `-u`: URL of corresponding protocol (HTTP-8000, gRPC-8001)
8797
* ... (Details in ./infer_triton.py)
8898

89-
99+
#### Notes:
100+
- Error below is caused by wrong dynamic input shapes, check if the input image shape is valid to dynamic shapes in config.
101+
```
102+
inference failed: [StatusCode.INTERNAL] request specifies invalid shape for input 'input' for detec_trt_0_gpu0. Error details: model expected the shape of dimension 2 to be between 256 and 1200 but received 1216
103+
```
90104
b. Classic Pytorch (.pth) inference:
91105
```
92106
$ python test.py --trained_model=[weightfile] --test_folder=[folder path to test images]

README_Triton.md

+16-13
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ There are multiple method to infer the detec pipeline, devided into 2 main types
5858
If you run the pipeline using single model format, run as below, no need environment installation as Triton server.
5959
```
6060
$ cd inference
61-
Run infer_pipeline.py with target method (pth/onnx/tensorrt) and suitable arguments of that method. Use single format, for ex pth format:
62-
$ python infer_pipeline.py --method='pth' --input='./images/image_1.jpg'
61+
Run infer_triton.py with target method (pth/onnx/tensorrt) and suitable arguments of that method. Use single format, for ex pth format:
62+
$ python infer_triton.py -m='detec_pt' -x=1 --test_folder='./images'
6363
```
6464
## I. Setup environment and tools
6565
First, update your PIP:
@@ -225,12 +225,12 @@ Convert source model into target formats and copy into Triton's Model Repository
225225
## III. Run the server and client to infer (included in .sh script):
226226
Run server in container and client in cmd
227227
```
228-
$ sudo docker run --gpus all --rm -p8000:8000 -p8001:8001 -p8002:8002 -v <full_path_to/data/model_repository>:/models nvcr.io/nvidia/tritonserver:<xx.yy>-py3 tritonserver --model-repository=/models
228+
$ sudo docker run --gpus all --rm -p8000:8000 -p8001:8001 -p8002:8002 -v <full_path_to/model_repository>:/models nvcr.io/nvidia/tritonserver:<xx.yy>-py3 tritonserver --model-repository=/models
229229

230-
For example, run on server with full path "/home/maverick911/repo/Triton-server-CRAFT-pytorch
231-
/data/model_repository":
232-
$ sudo docker run --gpus all --rm -p8000:8000 -p8001:8001 -p8002:8002 -v /home/maverick911/repo/Triton-server-CRAFT-pytorch
233-
/data/model_repository:/models nvcr.io/nvidia/tritonserver:21.05-py3 tritonserver --model-repository=/models
230+
For example, run on server with full path "/home/maverick911/repo/triton-server-CRAFT-pytorch
231+
/model_repository":
232+
$ sudo docker run --gpus all --rm -p8000:8000 -p8001:8001 -p8002:8002 -v /home/maverick911/repo/triton-server-CRAFT-pytorch
233+
/model_repository:/models nvcr.io/nvidia/tritonserver:21.05-py3 tritonserver --model-repository=/models
234234

235235
+----------------------+---------+--------+
236236
| Model | Version | Status |
@@ -244,18 +244,21 @@ I0611 04:10:23.080860 1 http_server.c9:2906] Started Metrics Service at 0.0.0.0:
244244
```
245245
2. Infer by client in cmd (this repo), with method (triton), model name (<model_type>_\<format>), version (not required). For ex:
246246
```
247-
$ cd Triton-server-CRAFT-pytorch/
248-
$ python infer_pipeline.py --method='triton' -m='detec_onnx' -x=1 --input='./images/image_1.jpg'
249-
247+
$ cd triton-server-CRAFT-pytorch/
248+
$ python infer_triton.py -m='detec_trt' -x=1 --test_folder='./images'
249+
Request 1, batch size 1s/sample.jpg
250+
elapsed time : 0.9521937370300293s
250251
```
251252
```
252-
$ python infer_pipeline.py --method='triton' -m='detec_trt' -x=1 --input='./images/image_1.jpg'
253+
$ python infer_triton.py -m='detec_pt' -x=1 --test_folder='./images' -i='grpc' -u='localhost:8001'
254+
Request 1, batch size 1s/sample.jpg
255+
elapsed time : 1.244419813156128s
253256
```
254257
-------
255258
Run server in container and client sdk in container:
256259
1. Start the server side:
257260
```
258-
$ sudo docker run --gpus all --rm -p8000:8000 -p8001:8001 -p8002:8002 -v /home/maverick911/repo/Triton-server-CRAFT-pytorch/model_repository:/models nvcr.io/nvidia/tritonserver:21.05-py3 tritonserver --model-repository=/models
261+
$ sudo docker run --gpus all --rm -p8000:8000 -p8001:8001 -p8002:8002 -v /home/maverick911/repo/triton-server-CRAFT-pytorch/model_repository:/models nvcr.io/nvidia/tritonserver:21.05-py3 tritonserver --model-repository=/models
259262

260263
+----------------------+---------+--------+
261264
| Model | Version | Status |
@@ -271,4 +274,4 @@ I0611 04:10:23.080860 1 http_server.c9:2906] Started Metrics Service at 0.0.0.0:
271274
```
272275
$ sudo docker run -it --rm --net=host -v <full_path/to/repo>:/workspace/client nvcr.io/nvidia/tritonserver:<xx.yy>-py3-sdk
273276
```
274-
3. Use infer_pipeline.py as example above to run.
277+
3. Use infer_triton.py as example above to run.

figures/craft_example.gif

-850 KB
Binary file not shown.

file_utils.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import numpy as np
44
import cv2
55
import imgproc
6+
from icecream import ic
67

78
# borrowed from https://github.com/lengstrom/fast-style-transfer/blob/master/src/utils.py
89
def get_files(img_dir):
@@ -30,7 +31,7 @@ def list_files(in_path):
3031
# gt_files.sort()
3132
return img_files, mask_files, gt_files
3233

33-
def saveResult(method='triton', img_file, img, boxes, dirname='./result/', verticals=None, texts=None):
34+
def saveResult(img_file, img, boxes, dirname='./result/', verticals=None, texts=None, method='triton'):
3435
""" save text detection result one by one
3536
Args:
3637
img_file (str): image file name
@@ -46,8 +47,9 @@ def saveResult(method='triton', img_file, img, boxes, dirname='./result/', verti
4647
filename, file_ext = os.path.splitext(os.path.basename(img_file))
4748

4849
# result directory
49-
res_file = dirname + "res_" + filename + '.txt' if method!='triton' else '_triton.txt'
50-
res_img_file = dirname + "res_" + filename + '.jpg' if method!='triton' else '_triton.txt'
50+
tmp_name = dirname + "res_" + filename
51+
res_file = tmp_name + '.txt' if method!='triton' else tmp_name + '_triton.txt'
52+
res_img_file = tmp_name + '.jpg' if method!='triton' else tmp_name + '_triton.jpg'
5153

5254
if not os.path.isdir(dirname):
5355
os.mkdir(dirname)

images/sample.jpg

2.61 MB
Loading

images/sample_img.jpg

-7.42 MB
Binary file not shown.

infer_triton.py

+23-20
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
"""
44
_____________________________________________________________________________
55
6-
This file main inference pipeline to Triton
6+
This file contains main inference pipeline to Triton
77
_____________________________________________________________________________
88
"""
9-
9+
from icecream import ic
1010
import sys
1111
import os
1212
import time
@@ -30,23 +30,21 @@
3030

3131
from collections import OrderedDict
3232

33-
import tritonclient as triton
33+
import triton_utils as triton
3434

3535
def str2bool(v):
3636
return v.lower() in ("yes", "y", "true", "t", "1")
3737

38-
parser = argparse.ArgumentParser(description='CRAFT Text Detection')
38+
parser = argparse.ArgumentParser(description='Triton inference pipeline for CRAFT Text Detection')
3939
parser.add_argument('--text_threshold', default=0.7, type=float, help='text confidence threshold')
4040
parser.add_argument('--low_text', default=0.4, type=float, help='text low-bound score')
4141
parser.add_argument('--link_threshold', default=0.4, type=float, help='link confidence threshold')
4242
parser.add_argument('--cuda', default=True, type=str2bool, help='Use cuda for inference')
43-
parser.add_argument('--canvas_size', default=1280, type=int, help='image size for inference')
43+
parser.add_argument('--canvas_size', default=1100, type=int, help='image size for inference')
4444
parser.add_argument('--mag_ratio', default=1.5, type=float, help='image magnification ratio')
4545
parser.add_argument('--poly', default=False, action='store_true', help='enable polygon type')
4646
parser.add_argument('--show_time', default=False, action='store_true', help='show processing time')
47-
parser.add_argument('--test_folder', default='/data/', type=str, help='folder path to input images')
48-
parser.add_argument('--refine', default=False, action='store_true', help='enable link refiner')
49-
parser.add_argument('--refiner_model', default='weights/craft_refiner_CTW1500.pth', type=str, help='pretrained refiner model')
47+
parser.add_argument('--test_folder', default='images/', type=str, help='folder path to input images')
5048

5149
# triton server
5250
parser.add_argument('-v',
@@ -110,7 +108,7 @@ def str2bool(v):
110108
if not os.path.isdir(result_folder):
111109
os.mkdir(result_folder)
112110

113-
def test_net(args, net, image, text_threshold, link_threshold, low_text, cuda, poly):
111+
def test_net(args, image, text_threshold, link_threshold, low_text, cuda, poly):
114112
t0 = time.time()
115113

116114
# resize
@@ -120,13 +118,13 @@ def test_net(args, net, image, text_threshold, link_threshold, low_text, cuda, p
120118
# preprocessing
121119
x = imgproc.normalizeMeanVariance(img_resized)
122120
x = torch.from_numpy(x).permute(2, 0, 1) # [h, w, c] to [c, h, w]
123-
x = Variable(x.unsqueeze(0)) # [c, h, w] to [b, c, h, w]
124-
if cuda:
125-
x = x.cuda()
121+
# x = Variable(x.unsqueeze(0)) # [c, h, w] to [b, c, h, w]
122+
# if cuda:
123+
# x = x.cuda()
126124

127125
# send request to triton server
128-
y, feature = triton.triton_requester(args, x)
129-
126+
y = triton.triton_requester(args, x)
127+
130128
# make score and link map
131129
score_text = y[0,:,:,0].cpu().data.numpy()
132130
score_link = y[0,:,:,1].cpu().data.numpy()
@@ -158,19 +156,24 @@ def test_net(args, net, image, text_threshold, link_threshold, low_text, cuda, p
158156

159157

160158
if __name__ == '__main__':
161-
159+
t = time.time()
162160
# load data
163161
for k, image_path in enumerate(image_list):
164162
print("Test image {:d}/{:d}: {:s}".format(k+1, len(image_list), image_path), end='\r')
165163
image = imgproc.loadImage(image_path)
166164

167-
bboxes, polys, score_text = test_net(args, net, image, args.text_threshold, args.link_threshold, args.low_text, args.cuda, args.poly, refine_net)
165+
bboxes, polys, score_text = test_net(args, image, args.text_threshold, args.link_threshold, args.low_text, args.cuda, args.poly)
168166

169167
# save score text
170-
filename, file_ext = os.path.splitext(os.path.basename(image_path))
171-
mask_file = result_folder + "/res_" + filename + '_mask_triton.jpg'
172-
cv2.imwrite(mask_file, score_text)
168+
# filename, file_ext = os.path.splitext(os.path.basename(image_path))
169+
# mask_file = result_folder + "/res_" + filename + '_mask_triton.jpg'
170+
# cv2.imwrite(mask_file, score_text)
173171

174-
file_utils.saveResult(method='triton', image_path, image[:,:,::-1], polys, dirname=result_folder)
172+
file_utils.saveResult(image_path, image[:,:,::-1], polys, dirname=result_folder, method='triton')
175173

176174
print("elapsed time : {}s".format(time.time() - t))
175+
176+
# Example cmd:
177+
# python infer_triton.py -m='detec_trt' -x=1 --test_folder='./images' -i='grpc' -u='localhost:8001'
178+
# python infer_triton.py -m='detec_onnx' -x=1 --test_folder='./images'
179+
# python infer_triton.py -m='detec_pt' -x=1 --test_folder='./images'

requirements.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ onnxruntime-gpu
1414
nvidia-pyindex
1515
onnx_graphsurgeon
1616

17-
#tritonclient[all]
17+
tritonclient[all]

result/sampletxt.txt

-14
This file was deleted.

test.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22
Copyright (c) 2019-present NAVER Corp.
33
MIT License
44
"""
5+
"""
6+
_____________________________________________________________________________
57
8+
This file contains classic Pytorch pth inference from forked repo
9+
_____________________________________________________________________________
10+
"""
611
# -*- coding: utf-8 -*-
712
import sys
813
import os
@@ -166,7 +171,7 @@ def test_net(net, image, text_threshold, link_threshold, low_text, cuda, poly, r
166171
mask_file = result_folder + "/res_" + filename + '_mask.jpg'
167172
cv2.imwrite(mask_file, score_text)
168173

169-
file_utils.saveResult(method='pth', image_path, image[:,:,::-1], polys, dirname=result_folder)
174+
file_utils.saveResult(image_path, image[:,:,::-1], polys, dirname=result_folder, method='pth')
170175

171176
print("Done, elapsed time : {}s. Check at folder result/".format(time.time() - t))
172177

tritonclient.py triton_utils.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
#!/usr/bin/env python3
22
# -*- coding: utf-8 -*-
3+
"""
4+
_____________________________________________________________________________
35
6+
This file contains functions for Triton inference pipeline
7+
_____________________________________________________________________________
8+
"""
49
# Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved.
510
#
611
# Redistribution and use in source and binary forms, with or without
@@ -26,7 +31,7 @@
2631
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2732
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2833
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29-
34+
from icecream import ic
3035
import sys
3136
import torch
3237
import numpy as np
@@ -313,6 +318,7 @@ def triton_requester(FLAGS, img_resized):
313318
else:
314319
this_id = response.get_response()["id"]
315320
print("Request {}, batch size {}".format(this_id, FLAGS.batch_size))
321+
316322
tmp = postprocess(response, output_name, FLAGS.batch_size, max_batch_size > 0)
317323
y = torch.from_numpy(tmp)
318324
return y

0 commit comments

Comments
 (0)