Skip to content

Commit 63b309e

Browse files
authored
Nuance PIN MONAI Integration Example App (#328)
1 parent 66d6283 commit 63b309e

File tree

12 files changed

+908
-0
lines changed

12 files changed

+908
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,6 @@ output
137137
# Sphinx temporary files
138138
docs/notebooks
139139
_autosummary
140+
141+
# model files
142+
*.ts

integrations/nuance_pin/.dockerignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Dockerfile*
2+
docker-compose.yml
3+
README.md
4+
README*

integrations/nuance_pin/Dockerfile

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
FROM nvcr.io/nvidia/pytorch:21.07-py3 AS application
2+
3+
ARG PARTNER_NAME
4+
ARG SERVICE_NAME
5+
ARG VERSION
6+
ARG MONAI_APP_MODULE
7+
ARG MODEL_PATH
8+
ARG EXTRA_PYTHON_PACKAGES
9+
10+
ENV TZ=Etc/UTC
11+
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
12+
13+
# python3-gdcm or python-gdcm is required for decompression
14+
RUN apt-get -y update && \
15+
apt-get -y install --no-install-recommends python3-distutils python3-gdcm && \
16+
# apt-get -y install python3.7 && \
17+
apt-get autoclean && \
18+
apt-get clean && \
19+
rm -rf /var/lib/apt/lists/*
20+
21+
ENV DEBUG=YES
22+
ENV KEEP_FILES=YES
23+
24+
# make sure all messages reach the console
25+
ENV PYTHONUNBUFFERED=1
26+
27+
# copy MONAI app files
28+
COPY . /app/.
29+
WORKDIR /app
30+
31+
# copy model file to model folder
32+
RUN wget -q https://github.com/Project-MONAI/model-zoo/releases/download/hosting_storage_v1/lung_nodule_ct_detection_v0.2.0.zip && \
33+
unzip lung_nodule_ct_detection_v0.2.0.zip -d /tmp/ && \
34+
cp /tmp/lung_nodule_ct_detection/models/model.ts model/. && \
35+
rm -rf /tmp/lung_nodule_ct_detection && \
36+
rm lung_nodule_ct_detection_v0.2.0.zip
37+
38+
# non-root aiserviceuser in group aiserviceuser with UserID and GroupID as 20225
39+
RUN groupadd -g 20225 -r aiserviceuser && useradd -u 20225 -r -g aiserviceuser aiserviceuser && chown -R aiserviceuser:aiserviceuser /app && \
40+
chown -R aiserviceuser:aiserviceuser /var
41+
USER aiserviceuser:aiserviceuser
42+
43+
ENV VIRTUAL_ENV=.venv
44+
RUN python3 -m venv $VIRTUAL_ENV
45+
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
46+
47+
RUN python -m pip install --upgrade pip && \
48+
python -m pip install --upgrade --no-cache-dir ${EXTRA_PYTHON_PACKAGES} -r requirements.txt && \
49+
python -m pip install --upgrade --no-cache-dir lib/ai_service-*-py3-none-any.whl && \
50+
pip install --upgrade numpy && \
51+
rm -rf lib && \
52+
rm requirements.txt
53+
54+
ENV AI_PARTNER_NAME ${PARTNER_NAME}
55+
ENV AI_SVC_NAME ${SERVICE_NAME}
56+
ENV AI_SVC_VERSION ${VERSION}
57+
ENV AI_MODEL_PATH ${MODEL_PATH}
58+
ENV MONAI_APP_CLASSPATH ${MONAI_APP_MODULE}
59+
60+
ENV PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python
61+
CMD ["python", "app_wrapper.py"]

integrations/nuance_pin/README.md

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
# Running MONAI Apps in Nuance PIN
2+
3+
MONAI Deploy Apps can be deployed as Nuance PIN applications with minimal effort and near-zero coding.
4+
5+
This folder includes an example MONAI app, AI-based Lung Nodule Segmentation, which is wrapped by the Nuance PIN API.
6+
The Nuance PIN wrapper code allows MONAI app developer to deploy their existing MONAI apps in Nuance
7+
with minimal code changes.
8+
9+
## Prerequisites
10+
11+
Before setting up and running the example MONAI spleen segmentation app to run as a Nuance PIN App, the user will need to install/download the following libraries.
12+
It is optional to use a GPU for the example app, however, it is recommended that a GPU is used for inference as it is very computationally intensive.
13+
14+
Minimum software requirements:
15+
- [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
16+
- [NVIDIA Docker](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#pre-requisites)
17+
- [Docker Compose](https://docs.docker.com/compose/install/)
18+
- [Nuance PIN SDK](https://www.nuance.com/healthcare/diagnostics-solutions/precision-imaging-network.html)
19+
20+
> **Note**: Nuance PIN SDK does not require host installation to make the example app work. We will explore options in the [Quickstart](#quickstart) section
21+
22+
## Quickstart
23+
24+
If you are reading this guide on the MONAI Github repo, you will need to clone the MONAI repo and change the directory to the Nuance PIN integration path.
25+
```bash
26+
git clone https://github.com/Project-MONAI/monai-deploy-app-sdk.git
27+
cd integrations/nuance_pin
28+
```
29+
30+
In this folder you will see the following directory structure
31+
```bash
32+
nuance_pin
33+
├── app # directory with MONAI app code
34+
├── lib # directory where we will place Nuance PIN wheels
35+
├── model # directory where we will place the model used by our MONAI app
36+
├── app_wrapper.py # Nuance PIN wrapper code
37+
├── docker-compose.yml # docker compose runtime script
38+
├── Dockerfile # container image build script
39+
├── README.md # this README
40+
└── requirements.txt # libraries required for the example integration to work
41+
```
42+
43+
When building the base container image the [Lung Nodule Detection model](https://github.com/Project-MONAI/model-zoo/releases/download/hosting_storage_v1/lung_nodule_ct_detection_v0.2.0.zip), available from the [MONAI model zoo](https://github.com/Project-MONAI/model-zoo/releases/tag/hosting_storage_v1) will automatically download in the `model` folder. Should the developer choose a different location of their own within the `nuance_pin` subtree for their model, then an update to `MODEL_PATH` variable in `docker-compose.yml` is required.
44+
45+
### Downloading Data for Spleen Segmentation
46+
47+
To download the test data you may follow the instructions in the [Lund Nodule Detection Documentation](https://github.com/Project-MONAI/model-zoo/tree/dev/models/lung_nodule_ct_detection#data).
48+
49+
### Download Nuance PIN SDK
50+
51+
Place the Nuance PIN `ai_service` wheel in the `nuance_pin/lib` folder. This can be obtained in the link provided in step 3 of of the [prerequisites](#prerequisites).
52+
53+
### Running the Example App in the Container
54+
55+
Now we are ready to build and start the container that runs our MONAI app as a Nuance service.
56+
```bash
57+
docker-compose up --build
58+
```
59+
60+
If the build is successful the a service will start on `localhost:5000`. We can verify the service is running
61+
by issuing a "live" request such as
62+
```bash
63+
curl -v http://localhost:5000/aiservice/2/live && echo ""
64+
```
65+
The issued command should return the developer, app, and version of the deployed example app.
66+
67+
Now we can run the example app with the example spleen data as the payload using Nuance PIN AI Service Test
68+
(`AiSvcTest`) utility obtained with the Nuance PIN SDK.
69+
```bash
70+
# create a virtual environment and activate it
71+
python3 -m venv /opt/venv
72+
. /opt/venv/bin/activate
73+
74+
# install AiSvcTest
75+
pip install AiSvcTest-<version>-py3-none-any.whl
76+
77+
# create an output directory for the inference results
78+
mkdir -p ~/Downloads/dcm/out
79+
80+
# run AiSvcTest with spleen dicom payload
81+
python -m AiSvcTest -i ~/Downloads/dcm -o ~/Downloads/dcm/out -s http://localhost:5000 -V 2 -k
82+
```
83+
84+
### Running the Example App on the Host
85+
86+
Alternatively the user may choose to run the Nuance PIn service directly on the host. For this we must install the following:
87+
- Nuance PIN AI Service libraries
88+
- Libraries in the `requirements.txt`
89+
90+
```bash
91+
# create a virtual environment and activate it
92+
python3 -m venv /opt/venv
93+
. /opt/venv/bin/activate
94+
95+
# install Nuance Ai Service
96+
pip install ai_service-<version>-py3-none-any.whl
97+
98+
# install requirements
99+
pip install -r requirements.txt
100+
101+
# download the lung nodule detection model
102+
wget -q https://github.com/Project-MONAI/model-zoo/releases/download/hosting_storage_v1/lung_nodule_ct_detection_v0.2.0.zip && \
103+
unzip lung_nodule_ct_detection_v0.2.0.zip -d /tmp/ && \
104+
cp /tmp/lung_nodule_ct_detection/models/model.ts model/. && \
105+
rm -rf /tmp/lung_nodule_ct_detection && \
106+
rm lung_nodule_ct_detection_v0.2.0.zip
107+
108+
# run the service
109+
export AI_PARTNER_NAME=NVIDIA
110+
export AI_SVC_NAME=ai_spleen_seg_app
111+
export AI_SVC_VERSION=0.1.0
112+
export AI_MODEL_PATH=model/model.ts
113+
export MONAI_APP_CLASSPATH=app.spleen_seg.AISpleenSegApp
114+
export PYTHONPATH=$PYTHONPATH:.
115+
python app_wrapper.py
116+
```
117+
118+
Now we can issue a "live" request to check whether the service is running
119+
```bash
120+
curl -v http://localhost:5000/aiservice/2/live && echo ""
121+
```
122+
As we did in the last section, we can now run the example app with the example spleen data as the payload using Nuance PIN AI Service Test
123+
(`AiSvcTest`) utility obtained with the Nuance PIN SDK.
124+
```bash
125+
. /opt/venv/bin/activate
126+
127+
# install AiSvcTest
128+
pip install AiSvcTest-<version>-py3-none-any.whl
129+
130+
# create an output directory for the inference results
131+
mkdir -p ~/Downloads/dcm/out
132+
133+
# run AiSvcTest with spleen dicom payload
134+
python -m AiSvcTest -i ~/Downloads/dcm -o ~/Downloads/dcm/out -s http://localhost:5000 -V 2 -k
135+
```
136+
137+
### Bring Your Own MONAI App
138+
139+
This example integration may be modified to fit any existing MONAI app, however, there may be caveats.
140+
141+
Nuance PIN requires all artifacts present in the output folder to be also added into the `resultManifest.json` output file
142+
to consider the run successful. To see what this means in practical terms, check the `resultManifest.json` output from the
143+
example app we ran the in previous sections. You will notice an entry in `resultManifest.json` that corresponds to the DICOM
144+
SEG output generated by the underlying MONAI app
145+
```json
146+
"study": {
147+
"uid": "1.2.826.0.1.3680043.2.1125.1.67295333199898911264201812221946213",
148+
"artifacts": [],
149+
"series": [
150+
{
151+
"uid": "1.2.826.0.1.3680043.2.1125.1.67295333199898911264201812221946213",
152+
"artifacts": [
153+
{
154+
"documentType": "application/dicom",
155+
"groupCode": "default",
156+
"name": "dicom_seg-DICOMSEG.dcm",
157+
"trackingUids": []
158+
}
159+
]
160+
}
161+
]
162+
},
163+
```
164+
This entry is generated by `app_wrapper.py`, which takes care of adding any DICOM present in the output folder in the `resultManifest.json`
165+
to ensure that existing MONAI apps complete successfully when deployed in Nuance. In general, however, the developer may need to tailor some
166+
of the code in `app_wrapper.py` to provide more insight to Nuance's network, such as adding findings, conclusions, etc. and generating more insight
167+
using SNOMED codes. All of this is handled within the Nuance PIN SDK libraries - for more information please consult Nuance PIN [documentation](https://www.nuance.com/healthcare/diagnostics-solutions/precision-imaging-network.html).
168+
169+
In simpler cases, the developer will need to place their code and model under `nuance_pin`. Placing the model under `model` is optional as the model may be placed
170+
anywhere where the code under `app` can access it, however, considerations must be taken when needing to deploy the model inside a container image. The MONAI app code
171+
is placed in `app` and structured as a small Python project.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Copyright 2021-2022 MONAI Consortium
2+
# Licensed under the Apache License, Version 2.0 (the "License");
3+
# you may not use this file except in compliance with the License.
4+
# You may obtain a copy of the License at
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
# Unless required by applicable law or agreed to in writing, software
7+
# distributed under the License is distributed on an "AS IS" BASIS,
8+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
# See the License for the specific language governing permissions and
10+
# limitations under the License.

0 commit comments

Comments
 (0)