Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion deployment/Triton/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@
__pycache__
# Ignore Pipenv files
Pipfile
Pipfile.loc
Pipfile.lock
# Image Input Files
*.jpeg
*.gz
13 changes: 9 additions & 4 deletions deployment/Triton/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,22 @@ FROM nvcr.io/nvidia/tritonserver:21.04-py3

# create model directory in container
RUN mkdir -p /models/monai_covid/1
RUN mkdir -p /models/monai_covid/

RUN mkdir -p /models/mednist_class/1
# install project-specific dependencies
COPY requirements.txt .

RUN pip install -r requirements.txt
RUN rm requirements.txt

# copy contents of model project into model repo in container image
COPY models/monai_covid/config.pbtxt /models/monai_covid
COPY models/monai_covid/1/model.py /models/monai_covid/1
#COPY models/monai_covid/1/covid19_model.ts /models/monai_covid/1 #moved to google drive


# copy contents of model project into model repo in container image
COPY models/mednist_class/config.pbtxt /models/mednist_class
COPY models/mednist_class/1/model.py /models/mednist_class/1


ENTRYPOINT [ "tritonserver", "--model-repository=/models"]
#ENTRYPOINT [ "tritonserver", "--model-repository=/models", "--log-verbose=1"]
# ENTRYPOINT [ "tritonserver", "--model-repository=/models", "--log-verbose=1"]
21 changes: 19 additions & 2 deletions deployment/Triton/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ $ ./triton_build.sh
2. Run Triton Container Image in Background Terminal using provided shell script
The supplied script will start the demo container with Triton and expose the three ports to localhost needed for the application to send inference requests.
```
$ ./triton_run_local.sh
$ ./run_triton_local.sh
```
3. Install environment for client
The client environment should have Python 3 installed and should have the necessary packages installed.
Expand Down Expand Up @@ -171,7 +171,7 @@ filename = 'client/test_data/volume-covid19-A-0000.nii.gz'
```
- The client calls the Triton Service using the external port configured previously.
```python:
with httpclient.InferenceServerClient("localhost:8000") as client:
with httpclient.InferenceServerClient("localhost:7555") as client:
```
- The Triton inference response is returned :
```python:
Expand All @@ -182,6 +182,23 @@ response = client.infer(model_name,

result = response.get_response()
```
-------
## MedNIST Classification Example

- Added to this demo as alternate demo using the MedNIST dataset in a classification example.
- To run the MedNIST example use the same steps as shown in the [Quick Start](#quick-start) with the following changes at step 5.
5. Run the client program (for the MedNIST example)
The [client](./client/client_mednist.py) program will take an optional file input and perform classification on body parts using the MedNIST data set. A small subset of the database is included.
```
$ mkdir -p client/test_data/MedNist
$ python -u client/client_mednist.py client/test_data/MedNist
```
Alternatively, the user can just run the shell script provided the previous steps 1 -4 in the [Quick Start](#quick-start) were followed.
```
$ ./mednist_client_run.sh
```
The expected result is variety of classification results for body images and local inference times.

-------
## Usage
[See Triton Inference Server/python_backend documentation](https://github.com/triton-inference-server/python_backend#usage)
Expand Down
2 changes: 1 addition & 1 deletion deployment/Triton/client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def open_nifti_files(input_path):
print("No valid inputs provided")
sys.exit(1)

with httpclient.InferenceServerClient("localhost:8000") as client:
with httpclient.InferenceServerClient("localhost:7555") as client:
image_bytes = b''
for nifti_file in nifti_files:
with open(nifti_file, 'rb') as f:
Expand Down
123 changes: 123 additions & 0 deletions deployment/Triton/client/client_mednist.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Copyright 2020 - 2021 MONAI Consortium
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


# Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of NVIDIA CORPORATION nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from tritonclient.utils import *
import tritonclient.grpc as grpcclient
import tritonclient.http as httpclient

import argparse
import numpy as np
import os
import sys
import time
from uuid import uuid4
import glob

from monai.apps.utils import download_and_extract
from monai.transforms.utils import convert_to_numpy

MEDNIST_CLASSES = ["AbdomenCT", "BreastMRI", "CXR", "ChestCT", "Hand", "HeadCT"]



model_name = "mednist_class"
gdrive_path = "https://drive.google.com/uc?id=1HQk4i4vXKUX_aAYR4wcZQKd-qk5Lcm_W"
mednist_filename = "MedNIST_demo.tar.gz"
md5_check = "3f24a5833bb0455a7815c4e0ecc8a810"


def open_jpeg_files(input_path):
return sorted(glob.glob(os.path.join(input_path, "*.jpeg")))


if __name__ == "__main__":

parser = argparse.ArgumentParser(description='Triton CLI for MedNist classification inference from JPEG data')
parser.add_argument(
'input',
type=str,
help="Path to JPEG file or directory containing JPEG files to send for MedNist classification"
)
args = parser.parse_args()

jpeg_files = []
extract_dir = "./client/test_data/MedNist"
tar_save_path = os.path.join(extract_dir, mednist_filename)
if os.path.isdir(args.input): # check for directory existence
# Grab files from Google Drive and place in directory
download_and_extract(gdrive_path, tar_save_path, output_dir=extract_dir, hash_val=md5_check, hash_type="md5")
jpeg_files = open_jpeg_files(args.input)

elif os.path.isfile(args.input):
jpeg_files = [args.input]

if not jpeg_files:
print("No valid inputs provided")
sys.exit(1)

with httpclient.InferenceServerClient("localhost:7555") as client:
image_bytes = b''
for jpeg_file in jpeg_files:
with open(jpeg_file, 'rb') as f:
image_bytes = f.read()

input0_data = np.array([[image_bytes]], dtype=np.bytes_)

inputs = [
httpclient.InferInput("INPUT0", input0_data.shape, np_to_triton_dtype(input0_data.dtype)),
]

inputs[0].set_data_from_numpy(input0_data)

outputs = [
httpclient.InferRequestedOutput("OUTPUT0"),
]

inference_start_time = time.time() * 1000
response = client.infer(model_name,
inputs,
request_id=str(uuid4().hex),
outputs=outputs,)
inference_time = time.time() * 1000 - inference_start_time

result = response.get_response()
print("Classification result for `{}`: {}. (Inference time: {:6.0f} ms)".format(
jpeg_file,
response.as_numpy("OUTPUT0").astype(str)[0],
inference_time,
))
12 changes: 10 additions & 2 deletions deployment/Triton/client_run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,13 @@
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

python -u client/client.py client/test_data
# if no argument provided use default `client/test_data` name
if [ $# -eq 0 ]
then
echo "No arguments supplied defaulting 'client/test_data'"
input_name="client/test_data"
else
# otherwise use the first argument as the operator image
input_name=$1
fi
python -u client/client.py $input_name
58 changes: 58 additions & 0 deletions deployment/Triton/mednist_client_run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/bin/bash
# Copyright 2020 - 2021 MONAI Consortium
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


# Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of NVIDIA CORPORATION nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# if no argument provided use default `client/test_data` name
if [ $# -eq 0 ]
then
echo "No arguments supplied defaulting './client/test_data/MedNist/demo'"
input_name="./client/test_data/MedNist"
# check if the output directory exists
if [ -d $input_name ]
then
echo "Directory $PWD/client/test_data/MedNist exists."
else
echo "Error: Directory $PWD/client/test_data/MedNist does not exist.
Please create the directory to save data to disk from the Clara operator."
exit 1
fi
else
# otherwise use the first argument as the operator image
input_name=$1
fi
python -u client/client_mednist.py $input_name

Loading