From 5d277f8de2cb844185592cd7007ff4b10e6aadb7 Mon Sep 17 00:00:00 2001 From: mmelqin Date: Tue, 19 Oct 2021 22:41:56 -0700 Subject: [PATCH 1/6] add doc on build and run Deploy app on AArch64 Signed-off-by: mmelqin --- examples/apps/deply_app_on_aarch64_interim.md | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 examples/apps/deply_app_on_aarch64_interim.md diff --git a/examples/apps/deply_app_on_aarch64_interim.md b/examples/apps/deply_app_on_aarch64_interim.md new file mode 100644 index 00000000..b0aae01b --- /dev/null +++ b/examples/apps/deply_app_on_aarch64_interim.md @@ -0,0 +1,114 @@ +# Containerizing MONAI Deploy Application for ARMv8 AArch64 (Interim Solution) + +This article describes how to containerize a MONAI Deploy application targeting ARMv8 AArch64, without using the MONAI Deploy App SDK Packager or Runner as they do not yet support ARMv8 AArch64. A Docker image will be generated, though not in the form of the **MONAI Application Package**. + +## Overview of Solution + +The [MONAI Application Packager (Packager)](https://docs.monai.io/projects/monai-deploy-app-sdk/en/latest/developing_with_sdk/packaging_app.html) is a utility for building an application developed with the MONAI Deploy App SDK into a structured MONAI Application Package (**MAP**). The MAP produced by the Packager is a deployable and reusable docker image that can be launched by applicatons that can parse and understand MAP format, e.g. the [MONAI Application Runner (MAR)](https://docs.monai.io/projects/monai-deploy-app-sdk/en/latest/developing_with_sdk/executing_packaged_app_locally.html). + +The Packager and MAR, however, do not support AArch64 in APP SDK release v0.1, due to the following reasons, +- The Packager limits the use of base Docker images to those targeting x86 on Ubuntu only +- The Packager injects an binary executable that only supports x86 in the generated MAP, and sets it as the Docker entry point +- The MAR runs the MAP Docker with the aforementioned entry point + +An interim solution is therefore provided to containerize and deploy a MONAI Deploy application for AArch64, +- Make use of an trusted AArch64 compatible base image, e.g. [nvcr.io/nvidia/clara-agx:21.05-1.7-py3](https://ngc.nvidia.com/catalog/containers/nvidia:clara-agx:agx-pytorch) which is based on Ubuntu 18.04.5 LTS and already has PyTorch 1.7 +- Use custom Docker file to explicitly install dependencies with a `requirements` file and setting the application's main function as the entry point +- Build the application docker with the aforementioned `Dockerfile` and `requirements` file on a AArch64 host computer. [Docker Buildx](https://docs.docker.com/buildx/working-with-buildx/) can also be used to build multi-platform images, though it is not used in this example +- On the AArch64 host machine, use `docker run` command or a script to launch the application docker + +## Steps +### Create the MONAI Deploy Application +For general guidance on how to build an deploy application using MONAI Deploy App SDK, and test it on x86 with the Packager and Runner, plesae refer [Developing with SDK](https://docs.monai.io/projects/monai-deploy-app-sdk/en/latest/developing_with_sdk/index.html). + +For the specific example on building and running a segmentation application on x86, e.g. the Spleen segmentation application, please see [Creating a Segmentation App](https://docs.monai.io/projects/monai-deploy-app-sdk/en/latest/getting_started/tutorials/03_segmentation_app.html). + +In the following sections, the Spleen UNETR Multi-organ Segmentation application will be used as an example. + +### Create the requirements file +Without using the MONAI DEDeploy App ASK Packager to automatically detect the dependencies of an application, one has to explicitly create the `requierments.txt` file to be used in the `Dockerfile`. Create the `requirements.txt` file in the application's folder with content shown below, +```bash +monai>=0.6.0 +monai-deploy-app-sdk>=0.1.0 +nibabel +numpy>=1.17 +pydicom>=1.4.2 +torch>=1.5 +``` +Note: The base image to be used already has torch 1.7 and numpy 19.5 pre-installed. + +### Crete the Custom Dockerfile +Create the `Dockerfile` in the application folder with content shown below, + +```bash +ARG CONTAINER_REGISTRY=nvcr.io/nvidia/clara-agx +ARG AGX_PT_TAG=21.05-1.7-py3 +FROM ${CONTAINER_REGISTRY}/agx-pytorch:${AGX_PT_TAG} + +# This is the name of the folder containing the application files. +ENV MY_APP_NAME="ai_unetr_seg_app" + +USER root + +RUN pip3 install --no-cache-dir --upgrade setuptools==57.4.0 wheel==0.37.0 + +WORKDIR /opt/$MY_APP_NAME + +COPY ./$MY_APP_NAME/requirements.txt ./ +RUN pip3 install --no-cache-dir -r requirements.txt + +# Copy the application source code. +COPY ./$MY_APP_NAME ./ +ENTRYPOINT python3 ./__main__.py -i /input -m /model/model.ts -o /output +``` +Note that +- The application files are copied to `/opt/unetr_seg_app` in this example +- The input DICOM instances are in folder `/input` +- The Torch Script model file `model.ts` is in `/model` +- The applicaton output will be in `/output` + +### Build the Docker Image targeting AArch64 +Copy the application folder including the `requirements.txt` and `Dockerfile` to the working directory, e.g. `my_apps`, on a AArch64 host machine, and ensure Docker is already installed. The application folder structure looks like below, +```bash +my_apps + └─ ai_unetr_seg_app + ├── app.py + ├── Dockerfile + ├── __init__.py + ├── __main__.py + ├── requirements.txt + └── unetr_seg_operator.py +``` + +In working directory `my_apps`, build the Dcoker image, named `ai_unetr_seg_app` with the default tag `default`with the following command, +```bash +docker build -t ai_unetr_seg_app -f ai_unetr_seg_app/Dockerfile . +``` +### Run the Application Docker Locally +On launching the application docker, input DICOM instances as well model file `model.ts` must be available, and the output folder may be a mounted NFS file share hosted on a remote machine. +A sample shell script is provided below, +``` +# Root of the datasets folder, change as needed +OUTPUT_ROOT="/mnt/nfs_clientshare" +DATASETS_FOLDER="datasets" + +# App specific parameters, change as needed and ensure contents are present. +APP_DATASET_FOLDER="unetr_dataset" +INPUT_FOLDER="/media/m2/monai_apps/input" +MODEL_FOLDER="/media/m2/monai_apps/models/unetr" +DOCKER_IMAGE="ai_unetr_seg_app" + +APP_DATASET_PATH=${OUTPUT_ROOT}/${DATASETS_FOLDER}/${APP_DATASET_FOLDER} +echo "Set to save rendering dataset to: ${APP_DATASET_PATH} ..." +docker run -t --rm --shm-size=1G\ + -v ${INPUT_FOLDER}:/input \ + -v ${MODEL_FOLDER}:/model \ + -v ${APP_DATASET_PATH}:/output \ + ${DOCKER_IMAGE} +echo "${DOCKER_IMAGE} completed." +echo +echo "Rendering dataset files are saved in the folder, ${APP_DATASET_PATH}:" +ls ${APP_DATASET_PATH +``` + +Once application docker terminates, check the application output in the folder shown in the console log. From 895540b605a357607f7ac9f8d5248c4389a45ef9 Mon Sep 17 00:00:00 2001 From: mmelqin Date: Wed, 20 Oct 2021 00:00:29 -0700 Subject: [PATCH 2/6] Correct typos Signed-off-by: mmelqin --- examples/apps/deply_app_on_aarch64_interim.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/apps/deply_app_on_aarch64_interim.md b/examples/apps/deply_app_on_aarch64_interim.md index b0aae01b..2f13f742 100644 --- a/examples/apps/deply_app_on_aarch64_interim.md +++ b/examples/apps/deply_app_on_aarch64_interim.md @@ -19,11 +19,11 @@ An interim solution is therefore provided to containerize and deploy a MONAI Dep ## Steps ### Create the MONAI Deploy Application -For general guidance on how to build an deploy application using MONAI Deploy App SDK, and test it on x86 with the Packager and Runner, plesae refer [Developing with SDK](https://docs.monai.io/projects/monai-deploy-app-sdk/en/latest/developing_with_sdk/index.html). +For general guidance on how to build a deploy application using MONAI Deploy App SDK, and test it on x86 with the Packager and Runner, please refer to [Developing with SDK](https://docs.monai.io/projects/monai-deploy-app-sdk/en/latest/developing_with_sdk/index.html). -For the specific example on building and running a segmentation application on x86, e.g. the Spleen segmentation application, please see [Creating a Segmentation App](https://docs.monai.io/projects/monai-deploy-app-sdk/en/latest/getting_started/tutorials/03_segmentation_app.html). +For the specific example on building and running a segmentation application, e.g. the Spleen segmentation application, please see [Creating a Segmentation App](https://docs.monai.io/projects/monai-deploy-app-sdk/en/latest/getting_started/tutorials/03_segmentation_app.html). -In the following sections, the Spleen UNETR Multi-organ Segmentation application will be used as an example. +In the following sections, the UNETR Multi-organ Segmentation application will be used as an example. ### Create the requirements file Without using the MONAI DEDeploy App ASK Packager to automatically detect the dependencies of an application, one has to explicitly create the `requierments.txt` file to be used in the `Dockerfile`. Create the `requirements.txt` file in the application's folder with content shown below, From 809ca9522009d4b5847aa9a733ecf5745659a796 Mon Sep 17 00:00:00 2001 From: Ming M Qin <38891913+MMelQin@users.noreply.github.com> Date: Wed, 20 Oct 2021 11:07:31 -0700 Subject: [PATCH 3/6] Update examples/apps/deply_app_on_aarch64_interim.md Co-authored-by: Gigon Bae Signed-off-by: mmelqin --- examples/apps/deply_app_on_aarch64_interim.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/apps/deply_app_on_aarch64_interim.md b/examples/apps/deply_app_on_aarch64_interim.md index 2f13f742..374b521d 100644 --- a/examples/apps/deply_app_on_aarch64_interim.md +++ b/examples/apps/deply_app_on_aarch64_interim.md @@ -26,7 +26,7 @@ For the specific example on building and running a segmentation application, e.g In the following sections, the UNETR Multi-organ Segmentation application will be used as an example. ### Create the requirements file -Without using the MONAI DEDeploy App ASK Packager to automatically detect the dependencies of an application, one has to explicitly create the `requierments.txt` file to be used in the `Dockerfile`. Create the `requirements.txt` file in the application's folder with content shown below, +Without using the MONAI Deploy App SDK Packager to automatically detect the dependencies of an application, one has to explicitly create the `requierments.txt` file to be used in the `Dockerfile`. Create the `requirements.txt` file in the application's folder with the content shown below, ```bash monai>=0.6.0 monai-deploy-app-sdk>=0.1.0 From 63b963f04d3257b65533b6e8551ab42acce67e62 Mon Sep 17 00:00:00 2001 From: Ming M Qin <38891913+MMelQin@users.noreply.github.com> Date: Wed, 20 Oct 2021 11:07:42 -0700 Subject: [PATCH 4/6] Update examples/apps/deply_app_on_aarch64_interim.md Co-authored-by: Gigon Bae Signed-off-by: mmelqin --- examples/apps/deply_app_on_aarch64_interim.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/apps/deply_app_on_aarch64_interim.md b/examples/apps/deply_app_on_aarch64_interim.md index 374b521d..424623fb 100644 --- a/examples/apps/deply_app_on_aarch64_interim.md +++ b/examples/apps/deply_app_on_aarch64_interim.md @@ -100,7 +100,7 @@ DOCKER_IMAGE="ai_unetr_seg_app" APP_DATASET_PATH=${OUTPUT_ROOT}/${DATASETS_FOLDER}/${APP_DATASET_FOLDER} echo "Set to save rendering dataset to: ${APP_DATASET_PATH} ..." -docker run -t --rm --shm-size=1G\ +docker run -t --rm --shm-size=1G \ -v ${INPUT_FOLDER}:/input \ -v ${MODEL_FOLDER}:/model \ -v ${APP_DATASET_PATH}:/output \ From 513a306f489632c52260c28d599beaea57712380 Mon Sep 17 00:00:00 2001 From: Ming M Qin <38891913+MMelQin@users.noreply.github.com> Date: Wed, 20 Oct 2021 11:07:58 -0700 Subject: [PATCH 5/6] Update examples/apps/deply_app_on_aarch64_interim.md Co-authored-by: Gigon Bae Signed-off-by: mmelqin --- examples/apps/deply_app_on_aarch64_interim.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/apps/deply_app_on_aarch64_interim.md b/examples/apps/deply_app_on_aarch64_interim.md index 424623fb..f69cd412 100644 --- a/examples/apps/deply_app_on_aarch64_interim.md +++ b/examples/apps/deply_app_on_aarch64_interim.md @@ -108,7 +108,7 @@ docker run -t --rm --shm-size=1G \ echo "${DOCKER_IMAGE} completed." echo echo "Rendering dataset files are saved in the folder, ${APP_DATASET_PATH}:" -ls ${APP_DATASET_PATH +ls ${APP_DATASET_PATH} ``` Once application docker terminates, check the application output in the folder shown in the console log. From bcd70bd79530e39861ba54d2d2689d86816a6b82 Mon Sep 17 00:00:00 2001 From: mmelqin Date: Wed, 20 Oct 2021 12:06:54 -0700 Subject: [PATCH 6/6] Updated adfter resolving merge conflict Signed-off-by: mmelqin --- examples/apps/deply_app_on_aarch64_interim.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/apps/deply_app_on_aarch64_interim.md b/examples/apps/deply_app_on_aarch64_interim.md index f69cd412..ab9f2f84 100644 --- a/examples/apps/deply_app_on_aarch64_interim.md +++ b/examples/apps/deply_app_on_aarch64_interim.md @@ -38,7 +38,7 @@ torch>=1.5 Note: The base image to be used already has torch 1.7 and numpy 19.5 pre-installed. ### Crete the Custom Dockerfile -Create the `Dockerfile` in the application folder with content shown below, +Create the `Dockerfile` in the application folder with the content shown below, ```bash ARG CONTAINER_REGISTRY=nvcr.io/nvidia/clara-agx @@ -59,7 +59,7 @@ RUN pip3 install --no-cache-dir -r requirements.txt # Copy the application source code. COPY ./$MY_APP_NAME ./ -ENTRYPOINT python3 ./__main__.py -i /input -m /model/model.ts -o /output +ENTRYPOINT python3 -u ./app.py -i /input -m /model/model.ts -o /output ``` Note that - The application files are copied to `/opt/unetr_seg_app` in this example @@ -111,4 +111,4 @@ echo "Rendering dataset files are saved in the folder, ${APP_DATASET_PATH}:" ls ${APP_DATASET_PATH} ``` -Once application docker terminates, check the application output in the folder shown in the console log. +Once application docker terminates, check the application output in the folder shown in the console log. \ No newline at end of file