1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
|
{
"cells": [
{
"cell_type": "markdown",
"id": "453524a2-0d79-4512-8d97-0240ec1ea08e",
"metadata": {},
"source": [
"<img src=\"./images/DLI_Header.png\" width=400/>"
]
},
{
"cell_type": "markdown",
"id": "c57b540f-18e8-42c3-a688-c30103c5f462",
"metadata": {},
"source": [
"# Fundamentals of Accelerated Data Science # "
]
},
{
"cell_type": "markdown",
"id": "61aa05f5-febf-487c-bd59-d489efd98709",
"metadata": {},
"source": [
"## 07 - Triton ##\n",
"\n",
"**Table of Contents**\n",
"<br>\n",
"This notebook covers the process of deploying a model with Triton Inference Server and walks through the various tools available within Triton. This notebook covers the below sections: \n",
"1. [Background](#s1)\n",
"2. [Preparing the Model](#s1)\n",
" * [Load the Model](#s1)\n",
" * [Creating the Folder Structure](#s1)\n",
" * [Creating the Configuration File](#s1)\n",
"3. [Loading the Model in Triton](#s1)\n",
" * [Starting Triton](#s1)\n",
" * [Check Status of Triton Server](#s1)\n",
"4. [Testing Inference](#s1)\n",
" * [Triton Client](#s1)\n",
" * [Verifying Results for Local Model and Triton](#s1)\n",
"5. [Analyzing Performance](#s1)\n",
" * [Customizing Perf Analyzer](#s1)\n",
" * [Exercise #1 - Testing Perf Analyzer](#s1)\n",
"6. [Model Analyzer](#s1)"
]
},
{
"cell_type": "markdown",
"id": "d4d08487-8161-4d8c-b402-cdeab3fcbe2a",
"metadata": {},
"source": [
"# Background\n",
"NVIDIA offers a framework for deploying ML models called Triton. Triton will automatically handle all inference requests that comes to the server. Triton supports multiple backends including PyTorch, TensorFlow, Forest Inference Library (FIL), etc. In this notebook, we will focus on the FIL backend using the xgboost model that was trained previously. "
]
},
{
"cell_type": "markdown",
"id": "aa0a7d94-c0a9-4b86-92bb-fafffa1ed021",
"metadata": {},
"source": [
"## Preparing the Model\n",
"### Load the Model\n",
"Let's start with loading the previous XGBoost model."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "b6b2149c-3f83-46cd-a1eb-70db7067cf5b",
"metadata": {},
"outputs": [],
"source": [
"import xgboost as xgb\n",
"model = xgb.Booster({'nthread': 4}) # init model\n",
"model.load_model('xgboost_model.json') # load model data"
]
},
{
"cell_type": "markdown",
"id": "a7896106-8410-40c3-8b6d-e0bdb94f69c3",
"metadata": {},
"source": [
"### Creating the Folder Structure\n",
"In the previous notebook, we just saved the XGBoost model to the working directory. Triton expects the model to be in a particular structure: Model name should be the top level directory, and the version number should be next. This allows for multiple models and versions of those models to be hosted simulatenously. Let's create that folder structure and save the model!"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "28c42b97-2691-46d1-9b3a-7d19685d1d7f",
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"\n",
"# Create the model repository directory. The name of this directory is arbitrary.\n",
"REPO_PATH = os.path.abspath('models')\n",
"os.makedirs(REPO_PATH, exist_ok=True)\n",
"\n",
"# The name of the model directory determines the name of the model as reported by Triton\n",
"model_dir = os.path.join(REPO_PATH, \"virus_prediction\")\n",
"\n",
"# We can store multiple versions of the model in the same directory. In our case, we have just one version, so we will add a single directory, named '1'.\n",
"version_dir = os.path.join(model_dir, '1')\n",
"os.makedirs(version_dir, exist_ok=True)\n",
"\n",
"# The default filename for XGBoost models saved in json format is 'xgboost.json'.\n",
"# It is recommended that you use this filename to avoid having to specify a name in the configuration file.\n",
"model_file = os.path.join(version_dir, 'xgboost.json')\n",
"model.save_model(model_file)"
]
},
{
"cell_type": "markdown",
"id": "900e5837-4807-4fd4-af21-0973a4942f1b",
"metadata": {},
"source": [
"### Creating the Configuration File\n",
"Triton also requires a configuration file that provides details about the model and deployment. For this notebook, we will assume default parameters."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "61d898fb-a8d2-4d1c-a13f-2c4be6c18969",
"metadata": {},
"outputs": [],
"source": [
"# RAPIDS Forest Inference Library\n",
"# FIL returns class labels or probabilities\n",
"# mem / disk\n",
"config_text = f\"\"\"backend: \"fil\"\n",
"max_batch_size: 32768\n",
"input [ \n",
" {{ \n",
" name: \"input__0\"\n",
" data_type: TYPE_FP32\n",
" dims: [ 4 ] \n",
" }} \n",
"]\n",
"output [\n",
" {{\n",
" name: \"output__0\"\n",
" data_type: TYPE_FP32\n",
" dims: [ 1 ]\n",
" }}\n",
"]\n",
"instance_group [{{ kind: KIND_GPU }}]\n",
"parameters [\n",
" {{\n",
" key: \"model_type\"\n",
" value: {{ string_value: \"xgboost_json\" }}\n",
" }},\n",
" {{\n",
" key: \"output_class\" \n",
" value: {{ string_value: \"false\" }}\n",
" }},\n",
" {{\n",
" key: \"storage_type\"\n",
" value: {{ string_value: \"AUTO\" }}\n",
" }}\n",
"]\n",
"\n",
"dynamic_batching {{\n",
" max_queue_delay_microseconds: 100\n",
"}}\"\"\"\n",
"config_path = os.path.join(model_dir, 'config.pbtxt')\n",
"with open(config_path, 'w') as file_:\n",
" file_.write(config_text)"
]
},
{
"cell_type": "markdown",
"id": "f262d4d9-819a-4d28-bb26-7eb737c3387a",
"metadata": {},
"source": [
"Now the model is ready to be loaded in Triton! The model repository should look like this.\n",
"\n",
"```\n",
"model/\n",
"`-- virus_prediction\n",
" |-- 1\n",
" | `-- xgboost.json\n",
" `-- config.pbtxt\n",
"```\n"
]
},
{
"cell_type": "markdown",
"id": "b5876d7a-3416-4ac9-827a-53796a1f7f93",
"metadata": {},
"source": [
"## Loading the Model in Triton\n",
"Next, we will need to start the Triton server. For this course, the server has already been started, but we will briefly go the steps required."
]
},
{
"cell_type": "markdown",
"id": "709cf499-9faa-4746-9252-16f41fa548e6",
"metadata": {},
"source": [
"### Starting Triton\n",
"Triton is available as buildable source code or a pre-built docker image. For simplicity, we recommend that most users start with the docker images. This is how you would start the docker container in the console."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1283515c-c812-41c5-a100-e4dc5788781e",
"metadata": {},
"outputs": [],
"source": [
"#!docker run --gpus=1 --rm -p 8000:8000 -p 8001:8001 -p 8002:8002 -v /full/path/to/docs/examples/model_repository:/models nvcr.io/nvidia/tritonserver:<xx.yy>-py3 tritonserver --model-repository=/models"
]
},
{
"cell_type": "markdown",
"id": "2ded6e36-0a1d-488e-8b10-f482ced8ea07",
"metadata": {},
"source": [
"Wow! That's a lot of inputs. Let's break it down a little bit more.\n",
"\n",
"- **gpus=1** : Passes through the first GPU to the Triton Inference Server\n",
"- **rm** : Removes the container after completing execution\n",
"- **p 8000:8000** : Forwards the GTPCInferenceService Port\n",
"- **p 8001:8001** : Forwards the HTTPService Port\n",
"- **p 8002:8002** : Forwards the Metrics Port\n",
"- **v /full/path/to/docs/examples/model_repository:/models** : Mounts the path to the models folder on the host machine to the Triton Inference Server container\n",
"- **nvcr.io/nvidia/tritonserver:<xx.yy>-py3** : Name of the Triton Inference Server image. The version number will change depending on the latest release\n",
"- **tritonserver --model-repository=/models**: The command to run in the container. In this case, we start the Triton Inference Server and point to the models folder\n"
]
},
{
"cell_type": "markdown",
"id": "42967a82-fdfd-413e-8006-eb78a3ca805b",
"metadata": {},
"source": [
"As we mentioned before, the server has already been started for this lab. Let's check our connection to the server! We are using \"triton\" as the hostname because the default docker network will resolve \"triton\" to the ip address of the Triton Inference Server."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "ac240cdc-f0dc-45ad-9838-58066a85696a",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"* Trying 172.18.0.3:8000...\n",
"* Connected to triton (172.18.0.3) port 8000 (#0)\n",
"> GET /v2/health/ready HTTP/1.1\n",
"> Host: triton:8000\n",
"> User-Agent: curl/7.81.0\n",
"> Accept: */*\n",
"> \n",
"* Mark bundle as not supporting multiuse\n",
"< HTTP/1.1 200 OK\n",
"< Content-Length: 0\n",
"< Content-Type: text/plain\n",
"< \n",
"* Connection #0 to host triton left intact\n"
]
}
],
"source": [
"!curl -v triton:8000/v2/health/ready"
]
},
{
"cell_type": "markdown",
"id": "d92b9b35-51c6-4eba-a9c0-9a92d19e0a0b",
"metadata": {},
"source": [
"Now let's see if the model has been loaded!"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "d80b37c5-1242-489f-8463-387e657264a1",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[{\"name\":\"virus_prediction\",\"version\":\"1\",\"state\":\"READY\"}]"
]
}
],
"source": [
"!curl -X POST http://triton:8000/v2/repository/index"
]
},
{
"cell_type": "markdown",
"id": "06902d34-7763-4693-b919-f70ee4d60dfa",
"metadata": {},
"source": [
"If all went well, we should be able to see the model \"virus prediction\" show up as ready."
]
},
{
"cell_type": "markdown",
"id": "2429b1bf-9372-42a5-86ea-be07cabf30ed",
"metadata": {},
"source": [
"## Testing Inference"
]
},
{
"cell_type": "markdown",
"id": "0c2616f6-2de8-4e84-96d1-ad92b5f4b732",
"metadata": {},
"source": [
"### Triton Client\n",
"To test the deployment we will use the Triton Client library. Let's see how we can create an instance of the client. "
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "ec652ce4-a2d6-4b3a-8e2f-faac51da5487",
"metadata": {},
"outputs": [],
"source": [
"import time\n",
"import tritonclient.grpc as triton_grpc\n",
"from tritonclient import utils as triton_utils\n",
"HOST = \"triton\"\n",
"PORT = 8001\n",
"TIMEOUT = 60"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "22af3af5-1d15-406f-91cb-2208c938d7ca",
"metadata": {},
"outputs": [],
"source": [
"client = triton_grpc.InferenceServerClient(url=f'{HOST}:{PORT}')"
]
},
{
"cell_type": "markdown",
"id": "84c3a594-e377-47c9-b3e7-0da321138bf5",
"metadata": {},
"source": [
"Now let's make sure the Triton server is ready by sending a sample inference request. First let's load the training data. We will only load 32768 rows, as that's the max batch size we specified."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "b57396e8-bc06-43dd-bf4c-2e34b24f5962",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" infected\n",
"2463608 0.0\n",
"1172801 0.0\n",
"1384471 0.0\n",
"3971592 0.0\n",
"3828297 0.0\n",
"... ...\n",
"22018 0.0\n",
"503309 0.0\n",
"4751695 0.0\n",
"3003154 0.0\n",
"4605113 0.0\n",
"\n",
"[32768 rows x 1 columns]\n"
]
}
],
"source": [
"import cudf \n",
"import numpy as np\n",
"df = cudf.read_csv('./data/clean_uk_pop_full.csv', usecols=['age', 'sex', 'northing', 'easting', 'infected'], nrows=5000000)\n",
"df = df.sample(32768)\n",
"input_data = df.drop('infected', axis=1)\n",
"target = df[['infected']]\n",
"print(target)"
]
},
{
"cell_type": "markdown",
"id": "d24f3792-a541-4b9f-acdc-e72c64897804",
"metadata": {},
"source": [
"Now we convert it to a numpy array and force the type to be float32 (the same type we specified in the config file)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "1ab43811-f273-48cf-b473-ea3d4786cab4",
"metadata": {},
"outputs": [],
"source": [
"converted_df = input_data.to_numpy(dtype='float32')"
]
},
{
"cell_type": "markdown",
"id": "ed49f912-5e35-4fe8-b6fa-b91f025cc07e",
"metadata": {},
"source": [
"Since we limited our batch size to 32768, let's splice the array and attempt the inference."
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "77e90afc-9ea6-45ad-83bb-2ac7f154b3f8",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"CPU times: user 5.03 ms, sys: 347 μs, total: 5.38 ms\n",
"Wall time: 6.64 ms\n"
]
}
],
"source": [
"%%time\n",
"batched_data = converted_df[:32768]\n",
"# Prepare the input tensor\n",
"input_tensor = triton_grpc.InferInput(\"input__0\", batched_data.shape, 'FP32')\n",
"input_tensor.set_data_from_numpy(batched_data)\n",
"\n",
"# Prepare the output\n",
"output = triton_grpc.InferRequestedOutput(\"output__0\")\n",
"\n",
"# Send inference request\n",
"response = client.infer(\"virus_prediction\", [input_tensor], outputs=[output])\n",
"\n",
"# Get the output data\n",
"output_data = response.as_numpy(\"output__0\")"
]
},
{
"cell_type": "markdown",
"id": "923c2923-acc1-48cb-bc41-3adafbf7eca2",
"metadata": {},
"source": [
"Let's make sure the results we got were the same as with the local model."
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "f809c2db-11f9-48de-9913-3e032e14a553",
"metadata": {},
"outputs": [],
"source": [
"from sklearn.metrics import mean_squared_error, r2_score\n",
"from sklearn.metrics import roc_curve\n",
"from sklearn.metrics import auc\n",
"\n",
"xgb_data = xgb.DMatrix(input_data)\n",
"y_test = model.predict(xgb_data)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "52ada8b8-0f47-435b-90df-57c5056bfc26",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 500x500 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Check that we got the same accuracy as previously\n",
"#target = target.to_numpy()\n",
"import matplotlib.pyplot as plt\n",
"\n",
"false_pos_rate, true_pos_rate, thresholds = roc_curve(target.to_numpy(), y_test)\n",
"auc_result = auc(false_pos_rate, true_pos_rate)\n",
"\n",
"fig, ax = plt.subplots(figsize=(5, 5))\n",
"ax.plot(false_pos_rate, true_pos_rate, lw=3,\n",
" label='AUC = {:.2f}'.format(auc_result))\n",
"ax.plot([0, 1], [0, 1], 'k--', lw=2)\n",
"ax.set(\n",
" xlim=(0, 1),\n",
" ylim=(0, 1),\n",
" title=\"ROC Curve\",\n",
" xlabel=\"False Positive Rate\",\n",
" ylabel=\"True Positive Rate\",\n",
")\n",
"ax.legend(loc='lower right');\n",
"plt.show()\n"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "30562baa-f7c9-40d8-ab5d-40b3c642b666",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 500x500 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Check that we got the same accuracy as previously\n",
"#target = target.to_numpy()\n",
"import matplotlib.pyplot as plt\n",
"\n",
"false_pos_rate, true_pos_rate, thresholds = roc_curve(target.to_numpy(), output_data)\n",
"auc_result = auc(false_pos_rate, true_pos_rate)\n",
"\n",
"fig, ax = plt.subplots(figsize=(5, 5))\n",
"ax.plot(false_pos_rate, true_pos_rate, lw=3,\n",
" label='AUC = {:.2f}'.format(auc_result))\n",
"ax.plot([0, 1], [0, 1], 'k--', lw=2)\n",
"ax.set(\n",
" xlim=(0, 1),\n",
" ylim=(0, 1),\n",
" title=\"ROC Curve\",\n",
" xlabel=\"False Positive Rate\",\n",
" ylabel=\"True Positive Rate\",\n",
")\n",
"ax.legend(loc='lower right');\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "b00984cb-6e04-4951-a864-a67cc4a22b6f",
"metadata": {},
"source": [
"As we can see, our AUC score is the same between both inference options!"
]
},
{
"cell_type": "markdown",
"id": "a459c429-b902-4056-ad2e-05d53f82537c",
"metadata": {},
"source": [
"## Analyzing Performance"
]
},
{
"cell_type": "markdown",
"id": "e724bd09-057b-408a-896a-b48a7a4362d1",
"metadata": {},
"source": [
"Earlier, we tested a *relatively* small inference request. What if we want to see the max throughput of the model? Luckily, Triton offers a performance analysis tool that generates synthetic data to collect latency and throughput numbers. Let's try it out."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "15129aef-3d3f-4c65-b2ff-1d0b2599ffd7",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"*** Measurement Settings ***\n",
" Batch size: 1\n",
" Service Kind: TRITON\n",
" Using \"time_windows\" mode for stabilization\n",
" Stabilizing using average latency and throughput\n",
" Measurement window: 5000 msec\n",
" Using synchronous calls for inference\n",
"\n",
"Request concurrency: 1\n"
]
}
],
"source": [
"!perf_analyzer -m virus_prediction -u \"triton:8000\""
]
},
{
"cell_type": "markdown",
"id": "12fe9a4c-e5db-4474-bc9f-76e0f3485506",
"metadata": {},
"source": [
"That's a lot of information to take in. Let's break it down.\n",
"\n",
"**Measurement window**: Timeframe that measurements are taken in \n",
"\n",
"**Batch Size**: Number of inputs in each request\n",
"\n",
"\n",
"**Concurrency**: Number of simulatenous connections\n",
"**Latency**: Time taken to recieve results\n",
"**p50/90/95/99**: Different percentiles for latency\n",
"\n",
"Based on these results, we can see that our throughput is roughly ~2300 inferences per second with a single concurrent connection, and the average latency for each requst is 434 usec."
]
},
{
"cell_type": "markdown",
"id": "27e8c5c0-7f3e-41e3-881d-38f9d0aa5d3e",
"metadata": {},
"source": [
"# Customizing Perf Analyzer\n",
"The Performance Analyzer tool for Triton has many knobs that can be turned to analyze results. Let's enable GPU metric collection, and increase the batch size and concurrency range values!"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6353c5bb-ebd5-492e-ad62-90e8929849d4",
"metadata": {},
"outputs": [],
"source": [
"!perf_analyzer --collect-metrics -m virus_prediction -u \"triton:8000\" -b 8 --concurrency-range 2:8:2"
]
},
{
"cell_type": "markdown",
"id": "6d0340a9-da5a-400f-9127-b3f4fe1facad",
"metadata": {},
"source": [
"The results show that our model configuration gives a throughput of about ~156171 inferences per second. Notice how there are significant throughput gains as we increase the number of concurrent connections. With low concurrency values, Triton is idle during the time when the response is returned to the client and the next request is received at the server. Throughput increases when we increase concurrency values because Triton overlaps the processing of one request with the communication of the other. "
]
},
{
"cell_type": "markdown",
"id": "ea13ffda-b03d-435e-a01e-5f8ceaa076de",
"metadata": {},
"source": [
"# Exercise \n",
"Please take this time to experiment with the perf analyzer tool. A full list of parameters can be seen with the --help argument. Some parameters that we recommend trying out are listed below: \n",
"* -b <value> : batch size\n",
"* --concurrency-range <start:end:step> : range of concurrency values to test\n",
"* --collect-metrics : enable collection of GPU metrics"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e8bb02a7-92c1-4373-afb6-c4a507ddf20d",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"id": "e6ccd1e7-989b-49b5-8ece-0583e9890c66",
"metadata": {},
"source": [
"## Model Analyzer\n",
"Although it is out of scope for this course, we would like to introduce the Model Analyzer tool that is available as part of Triton. This tool searches through different parameter configurations to find optimal parameters that maximize inference throughput. With some minor processing, results can be viewed in a PDF format as well. An example of the output is shown below. More information about the Model Analyzer can be found [here](https://docs.nvidia.com/deeplearning/triton-inference-server/user-guide/docs/user_guide/model_analyzer.html). "
]
},
{
"cell_type": "markdown",
"id": "a0c0c90f-d8e6-4ce5-a9c9-197a46e1d8a2",
"metadata": {},
"source": [
""
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "91558f00-41d2-493d-8517-9468efcae64e",
"metadata": {},
"outputs": [],
"source": [
"import IPython\n",
"app = IPython.Application.instance()\n",
"app.kernel.do_shutdown(True)"
]
},
{
"cell_type": "markdown",
"id": "c7e473f9-9ccf-43c6-aa86-eda25150a5ca",
"metadata": {},
"source": [
"**Well Done!** Let's move to the [next notebook](3-08_k-means_dask.ipynb). "
]
},
{
"cell_type": "markdown",
"id": "832c59bf-517c-4703-9161-1f9997214e19",
"metadata": {},
"source": [
"<img src=\"./images/DLI_Header.png\" width=400/>"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.15"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
|