From 010f0113a4d52004ade6e852085c9aeddc29f007 Mon Sep 17 00:00:00 2001 From: David Gardner <96306125+dagardner-nv@users.noreply.github.com> Date: Tue, 28 Jun 2022 11:54:13 -0700 Subject: [PATCH] Documentation fixes (#147) Documentation updates to: * Reflect Python module re-org, and config changes to Git LFS * Fixes from Adam Wood * Remove usage of third-party psutils lib (no longer in Conda env and not strictly needed) * Remove instructions for building patched cudf * Update pipeline images for examples Fixes #92 Authors: - David Gardner (https://github.com/dagardner-nv) - Michael Demoret (https://github.com/mdemoret-nv) Approvers: - Michael Demoret (https://github.com/mdemoret-nv) - https://github.com/bsuryadevara - Devin Robison (https://github.com/drobison00) URL: https://github.com/nv-morpheus/Morpheus/pull/147 --- CONTRIBUTING.md | 114 +++++++++- README.md | 205 +++--------------- docs/source/basics/overview.rst | 1 + .../guides/1_simple_python_stage.md | 4 +- .../guides/2_real_world_phishing.md | 16 +- .../guides/3_simple_cpp_stage.md | 4 +- .../guides/4_source_cpp_stage.md | 7 +- docs/source/extra_info/troubleshooting.md | 2 +- docs/source/index.rst | 112 +--------- docs/source/morpheus_quickstart_guide.md | 79 ++++--- examples/abp_nvsmi_detection/README.md | 19 +- examples/abp_nvsmi_detection/pipeline.png | Bin 18630 -> 15682 bytes examples/abp_pcap_detection/README.md | 2 +- .../abp_pcap_preprocessing.py | 3 + .../img/abp_pcap_detection.png | Bin 14406 -> 19396 bytes examples/log_parsing/README.md | 13 +- examples/nlp_si_detection/README.md | 2 +- examples/nlp_si_detection/pipeline.png | Bin 22768 -> 17114 bytes morpheus.code-workspace | 8 +- scripts/validation/val-run-pipeline.sh | 10 +- 20 files changed, 254 insertions(+), 347 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 361996cdfb..38dfd1d488 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -134,7 +134,7 @@ This workflow utilizes a docker container to set up most dependencies ensuring a (morpheus) user@host:/workspace# conda list | grep python python 3.8.13 py3.8.13_dbg_morpheus local ``` - 1. Note: This does not build any Morpheus or Neo code and defers building the code until the entire repo can be mounted into a running container. This allows for faster incremental builds during development. + 1. Note: This does not build any Morpheus or SRF code and defers building the code until the entire repo can be mounted into a running container. This allows for faster incremental builds during development. 2. Run the development container ```bash ./docker/run_container_dev.sh @@ -148,6 +148,9 @@ This workflow utilizes a docker container to set up most dependencies ensuring a Then once the container is started you will need to install some extra packages to enable launching docker containers: ```bash ./docker/install_docker.sh + + # Install utils for checking output + apt install -y jq bc ``` 3. Compile Morpheus @@ -234,6 +237,115 @@ Note: These instructions assume the user is using `mamba` instead of `conda` sin ``` At this point, Morpheus can be fully used. Any changes to Python code will not require a rebuild. Changes to C++ code will require calling `./scripts/compile.sh`. Installing Morpheus is only required once per virtual environment. +### Quick Launch Kafka Cluster + +Launching a full production Kafka cluster is outside the scope of this project. However, if a quick cluster is needed for testing or development, one can be quickly launched via Docker Compose. The following commands outline that process. See [this](https://medium.com/big-data-engineering/hello-kafka-world-the-complete-guide-to-kafka-with-docker-and-python-f788e2588cfc) guide for more in-depth information: + +1. Install `docker-compose` if not already installed: + + ```bash + conda install -c conda-forge docker-compose + ``` +2. Clone the `kafka-docker` repo from the Morpheus repo root: + + ```bash + git clone https://github.com/wurstmeister/kafka-docker.git + ``` +3. Change directory to `kafka-docker`: + + ```bash + cd kafka-docker + ``` +4. Export the IP address of your Docker `bridge` network: + + ```bash + export KAFKA_ADVERTISED_HOST_NAME=$(docker network inspect bridge | jq -r '.[0].IPAM.Config[0].Gateway') + ``` +5. Update the `kafka-docker/docker-compose.yml` so the environment variable `KAFKA_ADVERTISED_HOST_NAME` matches the previous step. For example, the line should look like: + + ```yml + environment: + KAFKA_ADVERTISED_HOST_NAME: 172.17.0.1 + ``` + Which should match the value of `$KAFKA_ADVERTISED_HOST_NAME` from the previous step: + + ```bash + $ echo $KAFKA_ADVERTISED_HOST_NAME + "172.17.0.1" + ``` +6. Launch kafka with 3 instances: + + ```bash + docker-compose up -d --scale kafka=3 + ``` + In practice, 3 instances has been shown to work well. Use as many instances as required. Keep in mind each instance takes about 1 Gb of memory. +7. Create the topic: + + ```bash + ./start-kafka-shell.sh $KAFKA_ADVERTISED_HOST_NAME + $KAFKA_HOME/bin/kafka-topics.sh --create --topic=$MY_INPUT_TOPIC_NAME --bootstrap-server `broker-list.sh` + ``` + Replace `` with the input name of your choice. If you are using `to-kafka`, ensure your output topic is also created. + +8. Generate input messages + 1. In order for Morpheus to read from Kafka, messages need to be published to the cluster. For debugging/testing purposes, the following container can be used: + + ```bash + # Download from https://netq-shared.s3-us-west-2.amazonaws.com/kafka-producer.tar.gz + wget https://netq-shared.s3-us-west-2.amazonaws.com/kafka-producer.tar.gz + # Load container + docker load --input kafka-producer.tar.gz + # Run the producer container + docker run --rm -it -e KAFKA_BROKER_SERVERS=$(broker-list.sh) -e INPUT_FILE_NAME=$MY_INPUT_FILE -e TOPIC_NAME=$MY_INPUT_TOPIC_NAME --mount src="$PWD,target=/app/data/,type=bind" kafka-producer:1 + ``` + In order for this to work, your input file must be accessible from `$PWD`. + 2. You can view the messages with: + + ```bash + ./start-kafka-shell.sh $KAFKA_ADVERTISED_HOST_NAME + $KAFKA_HOME/bin/kafka-console-consumer.sh --topic=$MY_TOPIC --bootstrap-server `broker-list.sh` + ``` + +### Launching Triton Server + +Many of the validation tests and example workflows require a Triton server to function. To launch Triton server, use the following command: + +```bash +docker run --rm -ti --gpus=all -p8000:8000 -p8001:8001 -p8002:8002 -v $PWD/models:/models \ + nvcr.io/nvidia/tritonserver:21.12-py3 \ + tritonserver --model-repository=/models/triton-model-repo \ + --exit-on-error=false \ + --model-control-mode=explicit \ + --load-model abp-nvsmi-xgb \ + --load-model sid-minibert-onnx \ + --load-model phishing-bert-onnx +``` +This will launch Triton using port 8001 for the GRPC server. This needs to match the Morpheus configuration. + +### Pipeline Validation + +To verify that all pipelines are working correctly, validation scripts have been added at `${MORPHEUS_ROOT}/scripts/validation`. There are scripts for each of the main workflows: Anomalous Behavior Profiling (ABP), Humans-as-Machines-Machines-as-Humans (HAMMAH), Phishing Detection (Phishing), and Sensitive Information Detection (SID). + +To run all of the validation workflow scripts, use the following commands: + +```bash +# Run validation scripts +./scripts/validation/val-run-all.sh +``` + +At the end of each workflow, a section will print the different inference workloads that were run and the validation error percentage for each. For example: + +```bash +===ERRORS=== +PyTorch :3/314 (0.96 %) +Triton(ONNX):Skipped +Triton(TRT) :Skipped +TensorRT :Skipped +Complete! +``` + +This indicates that only 3 out of 314 rows did not match the validation dataset. If you see errors similar to `:/ ( %)` or very high percentages, then the workflow did not complete sucessfully. + ### Troubleshooting the Build Due to the large number of dependencies, it's common to run into build issues. The follow are some common issues, tips, and suggestions: diff --git a/README.md b/README.md index 9a4bdb00c4..23d51e68c7 100644 --- a/README.md +++ b/README.md @@ -7,18 +7,27 @@ NVIDIA Morpheus is an open AI application framework that provides cybersecurity ## Documentation Full documentation (including a quick start guide, a developer/user guide, and API documentation) is available online at [https://docs.nvidia.com/morpheus/](https://docs.nvidia.com/morpheus/). -## Getting Started with Morpheus -The instructions below provide guidelines on how to get started with the pre-built Docker container, build the Morpheus Docker container yourself, or build Morpheus from source. +## Getting Started with Morpheus +There are three ways to get started with Morpheus: +- Using pre-built Docker containers +- Building the Morpheus Docker container +- Building Morpheus from source + +The pre-built Docker containers are the easiest way to get started with the latest release of Morpheus. Instructions on how to download and run these containers, including the necessary data and models, can be found on NGC [here](https://catalog.ngc.nvidia.com/orgs/nvidia/teams/morpheus/collections/morpheus_). + +More advanced users, or those who are interested in using the latest pre-release features, will need to build the Morpheus container or build from source. Step-by-step instructions for these users can be found in the following section. ### Prerequisites +The following sections must be followed prior to building the Morpheus container or building Morpheus from source. +#### Requirements - Pascal architecture or better - NVIDIA driver `450.80.02` or higher - [Docker](https://docs.docker.com/get-docker/) - [The NVIDIA container toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#docker) - [Git LFS](https://git-lfs.github.com/) -#### Ensure Git LFS is Installed +#### Git LFS The large model and data files in this repo are stored using [Git Large File Storage (LFS)](https://git-lfs.github.com/). These files will be required for running the training/validation scripts and example pipelines for the Morpheus pre-trained models. @@ -27,7 +36,7 @@ If `Git LFS` is not installed before cloning the repository, the large files wil git lfs install ``` -### Clone the Repository +#### Clone the Repository ```bash MORPHEUS_ROOT=$(pwd)/morpheus @@ -41,170 +50,45 @@ cd $MORPHEUS_ROOT git lfs pull ``` -#### Using the Pre-built `runtime` Docker Image - -Pre-built Morpheus Docker images can be downloaded from NGC. See [here](docs/source/morpheus_quickstart_guide.md#set-up-ngc-api-key-and-install-ngc-registry-cli) for details on accessing NGC. The `runtime` image includes Morpheus pre-built and its dependencies: +### Build Morpheus Container -```bash -docker pull nvcr.io/nvidia/morpheus/morpheus:-runtime -``` -where `` refers to the build of Morpheus you want. For example, if you want release 22.04, use the command: - -```bash -docker pull nvcr.io/nvidia/morpheus/morpheus:22.04-runtime -``` - -You can then run the pre-built `runtime` container using the provided script: - -```bash -DOCKER_IMAGE_TAG=-runtime ./docker/run_container_release.sh -``` -Again replacing `` with the appropriate release number. For v22.04, it becomes: - -```bash -DOCKER_IMAGE_TAG=22.04-runtime ./docker/run_container_release.sh -``` - -#### Manually Build the `runtime` Docker Image - -The Morpheus `runtime` image can also be built manually. This allows you to use a Morpheus build from the development branch or another branch/tag. -To manually build the `runtime` image, run the following from the repo's root: - -#### Build Locally (Outside a Container) - -To build Morpheus outside a container, all the necessary dependencies will need to be installed locally or in a virtual environment. Due to the increased complexity of installing outside of a container, this section has been moved to [`CONTRIBUTING.md`](CONTRIBUTING.md). Please see the "Build in a Conda Environment" section for more information. - -Note: Once `morpheus` CLI is installed, shell command completion can be installed with: +To assist in building the Morpheus container, several scripts have been provided in the `./docker` directory. To build the "release" container, run the following: ```bash ./docker/build_container_release.sh ``` -This will create an image named `nvcr.io/nvidia/morpheus/morpheus:latest`. -Run the manually built `runtime` container: +This will create an image named `nvcr.io/nvidia/morpheus/morpheus:${MORPHEUS_VERSION}-runtime` where `$MORPHEUS_VERSION` is replaced by the output of `git describe --tags --abbrev=0`. + +To run the built "release" container, use the following: ```bash ./docker/run_container_release.sh ``` -You can specify the specific image version by passing the script the `DOCKER_IMAGE_TAG` variable: + +You can specify different Docker images and tags by passing the script the `DOCKER_IMAGE_TAG`, and `DOCKER_IMAGE_TAG` variables respectively. For example, to run version `v22.06.00a` use the following: ```bash -DOCKER_IMAGE_TAG= ./docker/run_container_release.sh +DOCKER_IMAGE_TAG="v22.06.00a-runtime" ./docker/run_container_release.sh ``` -#### Build from Source +### Build from Source -Build instructions for developers and contributors can be found in [CONTRIBUTING.md](./CONTRIBUTING.md). +It's possible to build from source outside of a container. However, due to the large number of dependencies, this can be complex and is only necessary for developers. Instructions for developers and contributors can be found in [CONTRIBUTING.md](./CONTRIBUTING.md). ## Running Morpheus -Depending on your configuration, it may be necessary to start additional services that Morpheus will interact with before launching the pipeline. See the following list of stages that require additional services: - - - `from-kafka`/`to-kafka` - - Requires a running Kafka cluster - - See the Quick Launch Kafka section. - - `inf-triton` - - Requires a running Triton server - - See the Launching Triton Server section. - -### Quick Launch Kafka Cluster - -Launching a full production Kafka cluster is outside the scope of this project. However, if a quick cluster is needed for testing or development, one can be quickly launched via Docker Compose. The following commands outline that process. See [this](https://medium.com/big-data-engineering/hello-kafka-world-the-complete-guide-to-kafka-with-docker-and-python-f788e2588cfc) guide for more in-depth information: - -1. Install `docker-compose` if not already installed: - - ```bash - conda install -c conda-forge docker-compose - ``` -2. Clone the `kafka-docker` repo from the Morpheus repo root: - - ```bash - git clone https://github.com/wurstmeister/kafka-docker.git - ``` -3. Change directory to `kafka-docker`: - - ```bash - cd kafka-docker - ``` -4. Export the IP address of your Docker `bridge` network: - - ```bash - export KAFKA_ADVERTISED_HOST_NAME=$(docker network inspect bridge | jq -r '.[0].IPAM.Config[0].Gateway') - ``` -5. Update the `kafka-docker/docker-compose.yml` so the environment variable `KAFKA_ADVERTISED_HOST_NAME` matches the previous step. For example, the line should look like: - - ```yml - environment: - KAFKA_ADVERTISED_HOST_NAME: 172.17.0.1 - ``` - Which should match the value of `$KAFKA_ADVERTISED_HOST_NAME` from the previous step: - - ```bash - $ echo $KAFKA_ADVERTISED_HOST_NAME - "172.17.0.1" - ``` -6. Launch kafka with 3 instances: - - ```bash - docker-compose up -d --scale kafka=3 - ``` - In practice, 3 instances has been shown to work well. Use as many instances as required. Keep in mind each instance takes about 1 Gb of memory. -7. Create the topic: - - ```bash - ./start-kafka-shell.sh $KAFKA_ADVERTISED_HOST_NAME - $KAFKA_HOME/bin/kafka-topics.sh --create --topic=$MY_INPUT_TOPIC_NAME --bootstrap-server `broker-list.sh` - ``` - Replace `` with the input name of your choice. If you are using `to-kafka`, ensure your output topic is also created. - -8. Generate input messages - 1. In order for Morpheus to read from Kafka, messages need to be published to the cluster. For debugging/testing purposes, the following container can be used: - - ```bash - # Download from https://netq-shared.s3-us-west-2.amazonaws.com/kafka-producer.tar.gz - wget https://netq-shared.s3-us-west-2.amazonaws.com/kafka-producer.tar.gz - # Load container - docker load --input kafka-producer.tar.gz - # Run the producer container - docker run --rm -it -e KAFKA_BROKER_SERVERS=$(broker-list.sh) -e INPUT_FILE_NAME=$MY_INPUT_FILE -e TOPIC_NAME=$MY_INPUT_TOPIC_NAME --mount src="$PWD,target=/app/data/,type=bind" kafka-producer:1 - ``` - In order for this to work, your input file must be accessible from `$PWD`. - 2. You can view the messages with: - - ```bash - ./start-kafka-shell.sh $KAFKA_ADVERTISED_HOST_NAME - $KAFKA_HOME/bin/kafka-console-consumer.sh --topic=$MY_TOPIC --bootstrap-server `broker-list.sh` - ``` - -### Launching Triton Server - -To launch Triton server, use the following command: - -```bash -docker run --rm -ti --gpus=all -p8000:8000 -p8001:8001 -p8002:8002 -v $PWD/models:/models \ - nvcr.io/nvidia/tritonserver:21.12-py3 \ - tritonserver --model-repository=/models/triton-model-repo \ - --exit-on-error=false \ - --model-control-mode=explicit \ - --load-model abp-nvsmi-xgb \ - --load-model sid-minibert-onnx \ - --load-model phishing-bert-onnx -``` -This will launch Triton using port 8001 for the GRPC server. This needs to match the Morpheus configuration. - -## Configuration +To run Morpheus, users will need to choose from the Morpheus Command Line Interface (CLI) or Python interface. Which interface to use depends on the user's needs, amount of customization, and operating environment. More information on each interface can be found below. -The Morpheus pipeline can be configured in two ways: -1. Manual configuration via Python script. -2. Using the provided CLI (i.e., `morpheus`). +### Morpheus Python Interface -### Starting the Pipeline (via Manual Python Config) +The Morpheus python interface allows users to configure their pipelines using a python script file. This is ideal for users who are working in a Jupyter notebook, users who need complex initialization logic or users who have customized stages. Documentation on using the Morpheus python interface can be found at [`docs/source/developer_guide/guides.rst`](./docs/source/developer_guide/guides.rst). -See the `./examples` directory for examples on how to configure a pipeline via Python. +For full example pipelines using the python interface, see the `./examples` directory. -### Starting the Pipeline (via CLI) +### Morpheus Command Line Interface (CLI) -The provided CLI (`morpheus`) is capable of running the included tools as well as any linear pipeline. Instructions for using the CLI can be queried with: +The CLI allows users to completely configure a Morpheus pipeline directly from a terminal. This is ideal for users who do not need customized stages and for users configuring a pipeline in Kubernetes. The Morpheus CLI can be invoked using the `morpheus` command and is capable of running linear pipelines as well as additional tools. Instructions for using the CLI can be queried directly in the terminal using `morpheus --help`: ```bash $ morpheus @@ -226,6 +110,7 @@ Commands: run Run one of the available pipelines tools Run a utility tool ``` + Each command in the CLI has its own help information. Use `morpheus [command] [...sub-command] --help` to get instructions for each command and sub command. For example: ```bash @@ -253,6 +138,8 @@ Options: False] ``` +Several examples on using the Morpheus CLI can be found at [`docs/source/basics/examples.rst`](./docs/source/basics/examples.rst). + #### CLI Stage Configuration When configuring a pipeline via the CLI, you start with the command `morpheus run pipeline` and then list the stages in order from start to finish. The order that the commands are placed in will be the order that data flows from start to end. The output of each stage will be linked to the input of the next. For example, to build a simple pipeline that reads from Kafka, deserializes messages, serializes them, and then writes to a file, use the following: @@ -392,33 +279,5 @@ Commands: ``` Note: The available commands for different types of pipelines are not the same. This means that the same stage, when used in different pipelines, may have different options. Please check the CLI help for the most up-to-date information during development. - -## Pipeline Validation - -To verify that all pipelines are working correctly, validation scripts have been added at `${MORPHEUS_ROOT}/scripts/validation`. There are scripts for each of the main workflows: Anomalous Behavior Profiling (ABP), Humans-as-Machines-Machines-as-Humans (HAMMAH), Phishing Detection (Phishing), and Sensitive Information Detection (SID). - -To run all of the validation workflow scripts, use the following commands: - -```bash -# Install utils for checking output -apt update && apt install -y jq bc - -# Run validation scripts -./scripts/validation/val-run-all.sh -``` - -At the end of each workflow, a section will print the different inference workloads that were run and the validation error percentage for each. For example: - -```bash -===ERRORS=== -PyTorch :3/314 (0.96 %) -Triton(ONNX):Skipped -Triton(TRT) :Skipped -TensorRT :Skipped -Complete! -``` - -This indicates that only 3 out of 314 rows did not match the validation dataset. If you see errors similar to `:/ ( %)` or very high percentages, then the workflow did not complete sucessfully. - ## Contributing Please see our [guide for contributing to Morpheus](./CONTRIBUTING.md). diff --git a/docs/source/basics/overview.rst b/docs/source/basics/overview.rst index 285918d8e1..2b37501030 100644 --- a/docs/source/basics/overview.rst +++ b/docs/source/basics/overview.rst @@ -74,6 +74,7 @@ installed. Morpheus comes with a tool to assist with this: $ morpheus tools autocomplete install bash completion installed in ~/.bash_completion + $ source ~/.bash_completion After autocomplete has been installed, ``[TAB]`` can be used to show all commands, options and arguments when building pipelines via the CLI: diff --git a/docs/source/developer_guide/guides/1_simple_python_stage.md b/docs/source/developer_guide/guides/1_simple_python_stage.md index 0eadb0f9dd..92e3385278 100644 --- a/docs/source/developer_guide/guides/1_simple_python_stage.md +++ b/docs/source/developer_guide/guides/1_simple_python_stage.md @@ -162,7 +162,7 @@ The output should look like this: ====Registering Pipeline Complete!==== ====Starting Pipeline==== ====Building Pipeline==== -Added source: +Added source: └─> morpheus.MessageMeta Added stage: └─ morpheus.MessageMeta -> morpheus.MessageMeta @@ -194,7 +194,7 @@ def run_pipeline(): configure_logging(log_level=logging.DEBUG) root_dir = os.environ['MORPHEUS_ROOT'] - input_file = os.path.join(root_dir, 'examples/data/email.jsonlines') + input_file = os.path.join(root_dir, 'examples/data/email_with_addresses.jsonlines') config = Config() diff --git a/docs/source/developer_guide/guides/2_real_world_phishing.md b/docs/source/developer_guide/guides/2_real_world_phishing.md index 194e5a6c23..06ddbe9fcd 100644 --- a/docs/source/developer_guide/guides/2_real_world_phishing.md +++ b/docs/source/developer_guide/guides/2_real_world_phishing.md @@ -176,6 +176,10 @@ Let's ask Triton for some information about the `phishing-bert-onnx` model which ```shell curl "localhost:8000/v2/models/phishing-bert-onnx/config" +``` + +Output: +``` {"name":"phishing-bert-onnx","versions":["1"],"platform":"onnxruntime_onnx","inputs":[{"name":"input_ids","datatype":"INT64","shape":[-1,128]},{"name":"attention_mask","datatype":"INT64","shape":[-1,128]}],"outputs":[{"name":"output","datatype":"FP32","shape":[-1,2]}]} ``` @@ -185,6 +189,8 @@ From this information, we can see that the expected shape of the model inputs is Let's set up the paths for our input and output files. For simplicity, we assume that the `MORPHEUS_ROOT` environment variable is set to the root of the Morpheus project repository. In a production deployment, it may be more prudent to replace our usage of environment variables with command-line flags or a dedicated configuration management library. ```python +import os + import morpheus root_dir = os.environ['MORPHEUS_ROOT'] @@ -203,14 +209,14 @@ To start, we will need to instantiate and set a few members of the `Config` clas config = Config() config.mode = PipelineModes.NLP -config.num_threads = psutil.cpu_count() +config.num_threads = os.cpu_count() config.feature_length = 128 with open(labels_file) as fh: config.class_labels = [x.strip() for x in fh] ``` -First we set our pipeline mode to NLP. Next, we use the third-party [psutils](https://psutil.readthedocs.io/en/stable/) library to set the `num_threads` property to match the number of cores in our system. +First we set our pipeline mode to NLP. Next, we set the `num_threads` property to match the number of cores in our system. The `feature_length` property needs to match the length of the model inputs, which we got from Triton in the previous section using the model's `/config` endpoint. @@ -284,8 +290,6 @@ To explicitly set the output format we could specify the `file_type` argument to import logging import os -import psutil - import morpheus from morpheus.config import Config from morpheus.config import PipelineModes @@ -300,7 +304,7 @@ from morpheus.stages.preprocess.deserialize_stage import DeserializeStage from morpheus.stages.preprocess.preprocess_nlp_stage import PreprocessNLPStage from morpheus.utils.logging import configure_logging -from recipient_feature_stage import RecipientFeaturesStage +from recipient_features_stage import RecipientFeaturesStage def run_pipeline(): # Enable the default logger @@ -321,7 +325,7 @@ def run_pipeline(): config.mode = PipelineModes.NLP # Set the thread count to match our cpu count - config.num_threads = psutil.cpu_count() + config.num_threads = os.cpu_count() config.feature_length = 128 with open(labels_file) as fh: diff --git a/docs/source/developer_guide/guides/3_simple_cpp_stage.md b/docs/source/developer_guide/guides/3_simple_cpp_stage.md index 2bca67a363..5d51483ea7 100644 --- a/docs/source/developer_guide/guides/3_simple_cpp_stage.md +++ b/docs/source/developer_guide/guides/3_simple_cpp_stage.md @@ -28,9 +28,9 @@ CppConfig.set_should_use_cpp(False) If a stage does not have a C++ implementation, Morpheus will fall back to the Python implementation without any additional configuration and operate in a hybrid execution mode. -In addition to C++ accelerated stage implementations, Morpheus also provides a C++ implementation for message primitives. When C++ execution is enabled, constructing one of the Python message classes defined in the `morpheus.pipeline.messages` module will return a Python object with bindings to the underlying C++ implementation. +In addition to C++ accelerated stage implementations, Morpheus also provides a C++ implementation for message primitives. When C++ execution is enabled, constructing one of the Python message classes defined under `morpheus.messages` will return a Python object with bindings to the underlying C++ implementation. -Since we are defining our pipelines in Python, it becomes the responsibility of the Python implementation to build a C++ accelerated node. This happens in the `_build_source` and `_build_single` methods. Ultimately it is the decision of a Python stage to build a Python node or a C++ node. It is perfectly acceptable to build a Python node when `morpheus.config.CppConfig.get_should_use_cpp()` is configured to `True`. It is not acceptable, however, to build a C++ node when `morpheus.config.CppConfig.get_should_use_cpp() == False`. The reason is the C++ implementations of Morpheus' messages can be consumed by Python and C++ stage implementations alike. However when `morpheus.config.CppConfig.get_should_use_cpp() == False`, the Python implementations will be used which cannot be consumed by the C++ implementations of stages. +Since we are defining our pipelines in Python, it becomes the responsibility of the Python implementation to build a C++ accelerated node. This happens in the `_build_source` and `_build_single` methods. Ultimately it is the decision of a Python stage to build a Python node or a C++ node. It is perfectly acceptable to build a Python node when `morpheus.config.CppConfig.get_should_use_cpp()` is configured to `True`. It is not acceptable, however, to build a C++ node when `morpheus.config.CppConfig.get_should_use_cpp() == False`. The reason is the C++ implementations of Morpheus' messages can be consumed by Python and C++ stage implementations alike. However when `morpheus.config.CppConfig.get_should_use_cpp() == False`, the Python implementations of each message type will be used which cannot be consumed by the C++ implementations of stages. Python stages which have a C++ implementation must advertise this functionality by overriding the `supports_cpp_node` method: diff --git a/docs/source/developer_guide/guides/4_source_cpp_stage.md b/docs/source/developer_guide/guides/4_source_cpp_stage.md index 7a2f55178f..aca1d0cafc 100644 --- a/docs/source/developer_guide/guides/4_source_cpp_stage.md +++ b/docs/source/developer_guide/guides/4_source_cpp_stage.md @@ -482,6 +482,11 @@ PYBIND11_MODULE(morpheus_rabbit, m) ## Python Changes +As in the previous example we need to add an import of the `CppConfig` object. +```python +from morpheus.config import CppConfig +``` + Previously, our stage connected to the RabbitMQ server in the constructor. This is no longer advantageous to us when C++ execution is enabled. Instead, we will record our constructor arguments and move the connection code to a new `connect` method. Our new constructor and `connect` methods are updated to: ```python @@ -526,7 +531,7 @@ def connect(self): ``` -Lastly, our `_build_source` method needs to be updated to build a C++ node when `morpheus.config.CppConfig` is configured to `True` by using the `self._build_cpp_node()` method. +Lastly, our `_build_source` method needs to be updated to build a C++ node when `morpheus.config.CppConfig.get_should_use_cpp()` is configured to `True` by using the `self._build_cpp_node()` method. ```python def _build_source(self, builder: srf.Builder) -> StreamPair: diff --git a/docs/source/extra_info/troubleshooting.md b/docs/source/extra_info/troubleshooting.md index bf142f5baf..e29d6330c6 100644 --- a/docs/source/extra_info/troubleshooting.md +++ b/docs/source/extra_info/troubleshooting.md @@ -31,7 +31,7 @@ rm -rf ${MORPHEUS_ROOT}/build ``` **Debugging Python Code** -To debug issues in python code, several launch Visual Studio Code launch configurations have been included in the repo. These launch configurations can be found in `${MORPHEUS_ROOT}/morpheus.code-workspace`. To launch the debugging environment, ensure that Visual Studio Code has opened the morpheus workspace file (File->Open Workspace from File...). Once the workspace has been loaded, the launch configurations should be available in the debugging tab. +To debug issues in python code, several Visual Studio Code launch configurations have been included in the repo. These launch configurations can be found in `${MORPHEUS_ROOT}/morpheus.code-workspace`. To launch the debugging environment, ensure that Visual Studio Code has opened the morpheus workspace file (File->Open Workspace from File...). Once the workspace has been loaded, the launch configurations should be available in the debugging tab. **Debugging C++ Code** diff --git a/docs/source/index.rst b/docs/source/index.rst index 030678af20..cbf14e51e1 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -41,7 +41,7 @@ Features * Real-Time Telemetry * Morpheus can receive rich, real-time network telemetry from every NVIDIA® BlueField® DPU-accelerated server in the data center without impacting performance. Integrating the framework into a third-party cybersecurity offering - brings the world’s best AI computing to communication networks. + brings the world's best AI computing to communication networks. * DPU-Connected * The NVIDIA BlueField Data Processing Unit (DPU) can be used as a telemetry agent for receiving critical data center communications into Morpheus. As an optional addition to Morpheus, BlueField DPU also extends static @@ -58,7 +58,7 @@ The best way to get started with Morpheus will vary depending on the goal of the Using NGC Container ^^^^^^^^^^^^^^^^^^^ -Accessing Morpheus by pulling the pre-built NGC container is best suited for users who do not need any customization and +Accessing Morpheus by pulling the pre-built `NGC container `_ is best suited for users who do not need any customization and are only interested in running Morpheus via the CLI. The pre-built container does not require checking out the source code and is best suited for users who are new to Morpheus and don't require any customization. @@ -77,7 +77,7 @@ Launch an interactive container to start using Morpheus: .. code-block:: console - $ ./docker/run_container_release.sh + $ docker run --rm -ti --net=host --gpus=all nvcr.io/nvidia/morpheus/morpheus:22.06-runtime bash (morpheus) root@958a683a8a26:/workspace# morpheus --help Usage: morpheus [OPTIONS] COMMAND [ARGS]...Options: --debug / --no-debug [default: False] @@ -100,112 +100,6 @@ Launch an interactive container to start using Morpheus: See :doc:`basics/overview` for more information on using the CLI. -Building Local Image -^^^^^^^^^^^^^^^^^^^^ - -Building the image locally is best suited for users who prefer working within a -Docker container, want to avoid installing many dependencies or have a moderate -amount of customization. This method requires pulling the source code and -manually building the container and does not require the user to setup a Conda -environment and install dependencies. Users can use either the CLI or Python -interface. - -Prerequisites -""""""""""""" - * `Docker `__ - * `The NVIDIA container toolkit `__ - -To get started, first clone the Morpheus repo: - -.. code-block:: bash - - # Make sure to recurse the submodules - git clone https://github.com/NVIDIA/Morpheus.git - # Change directory to the repo root - cd morpheus - -.. note:: - - Cloning the repo may take a while to download large data objects and models. - -To build the container: - -.. code-block:: bash - - ./docker/build_container_dev.sh - -To run the development container: - -.. code-block:: bash - - ./docker/run_container_dev.sh - -From this point, follow the previous getting started section for running the CLI. - -.. _outside-of-a-container: - -Outside of a Container -^^^^^^^^^^^^^^^^^^^^^^ - -.. warning:: - - This is not the preferred way to use Morpheus. Morpheus requires a large - amount of dependencies and this method should only be used by advanced and - experienced users only. - -Running Morpheus outside of a container requires the most setup, but offers the -most flexibility and customization. Users of this method will need the source -code and will be required to install several dependencies in a Conda virtual -environment. - -Prerequisites -""""""""""""" - * `Conda `__ - * `Mamba `__ - * Once ``conda`` is installed, ``mamba`` can be instaled with ``conda install -n base -c conda-forge mamba`` (Make sure to only install into the base environment) - * `CUDA `__ - * While CUDA can be installed with Conda, it requires installing the matching CUDA SDK outside of the Conda environment. - -To get started, first clone the Morpheus repo: - -.. code-block:: bash - - # Make sure to recurse the submodules - git clone https://github.com/NVIDIA/Morpheus.git - # Change directory to the repo root - cd morpheus - -.. note:: - - Cloning the repo may take a while to download large data objects and models. - -Next, create a Conda environment and install the necessary dependencies. - -.. code-block:: bash - - conda create -n morpheus -c conda-forge python=${PYTHON_VER} - conda activate morpheus - conda install -c conda-forge python=${PYTHON_VER} - - # Build and install the cuDF conda package - ./docker/build_conda_packages.sh libcudf cudf - mamba install -c file:///${MORPHEUS_ROOT}/.conda-bld -c nvidia -c rapidsai -c conda-forge libcudf cudf - - # Install the remaining Morpheus dependencies - mamba env update -n morpheus -f ./docker/conda/environments/cuda${CUDA_VER}_dev.yml - -Where ``$PYTHON_VER``, ``$CUDA_VER``, and ``$RAPIDS_VER`` represent the desired Python version, CUDA version and, RAPIDS -version, respectively. Finally, build Morpheus: - -.. code-block:: bash - - ./scripts/compile.sh - - pip install . - # Or for a debug/editable installation - pip install -e . - -See :doc:`basics/overview` for more information on using the CLI. .. toctree:: :maxdepth: 20 diff --git a/docs/source/morpheus_quickstart_guide.md b/docs/source/morpheus_quickstart_guide.md index 8d7e641a75..dbe891dc4c 100644 --- a/docs/source/morpheus_quickstart_guide.md +++ b/docs/source/morpheus_quickstart_guide.md @@ -1,3 +1,20 @@ + + # Morpheus Quickstart Guide ## Table of Contents @@ -13,8 +30,8 @@ - [Install Morpheus AI Engine](#install-morpheus-ai-engine) - [Install Morpheus SDK Client](#install-morpheus-sdk-client) - [Morpheus SDK Client in Sleep Mode](#morpheus-sdk-client-in-sleep-mode) - - [Models for MLFlow Plugin Deployment](#models-for-mlflow-plugin-deployment) - - [Install Morpheus MLFlow Triton Plugin](#install-morpheus-mlflow-triton-plugin) + - [Models for MLflow Plugin Deployment](#models-for-mlflow-plugin-deployment) + - [Install Morpheus MLflow Triton Plugin](#install-morpheus-mlflow-triton-plugin) - [Model Deployment](#model-deployment) - [Verify Model Deployment](#verify-model-deployment) - [Create Kafka Topics](#create-kafka-topics) @@ -71,8 +88,8 @@ This quick start guide provides the necessary instructions to set up the minimum - Set up of the NVIDIA Cloud Native Core Stack - Set up Morpheus AI Engine - Set up Morpheus SDK Client -- Models for MLFlow Triton Plugin Deployments -- Set up Morpheus MLFlow Triton Plugin +- Models for MLflow Triton Plugin Deployments +- Set up Morpheus MLflow Triton Plugin - Deploy models to Triton inference server - Create Kafka topics - Run example workloads @@ -85,7 +102,7 @@ Morpheus makes it easy to build and scale cybersecurity applications that harnes NVIDIA Morpheus enables organizations to attack the issue of cybersecurity head on. Rather than continuously chasing the cybersecurity problem, Morpheus provides the ability to propel you ahead of the breach and address the cybersecurity issue. With the world in a "discover and respond" state, where companies are finding breaches much too late, in a way that is way behind the curve, NVIDIA’s Morpheus cybersecurity AI framework enables any organization to warp to the present and begin to defend itself in real time. -The Morpheus Developer Kit allows developers to quickly and easily set up example pipelines to run inference on different sample models provided from NVIDIA and experiment with the features and capabilities available within the Morpheus framework to address their cybersecurity and information security use cases. +The Morpheus Developer Kit allows developers to quickly and easily set up example pipelines to run inference on different sample models provided by NVIDIA and experiment with the features and capabilities available within the Morpheus framework to address their cybersecurity and information security use cases. ### Features @@ -107,7 +124,7 @@ The Morpheus Developer Kit allows developers to quickly and easily set up exampl - **AI Cybersecurity Capabilities** - Deploy your own models using common deep learning frameworks. Or get a jump-start in building applications to identify leaked sensitive information, detect malware or fraud, do network mapping, flag user behavior changes, or and identify errors via logs by using one of NVIDIA’s pre-trained and tested models. + Deploy your own models using common deep learning frameworks. Or get a jump-start in building applications to identify leaked sensitive information, detect malware or fraud, do network mapping, flag user behavior changes, and identify errors via logs by using one of NVIDIA’s pre-trained and tested models. ## Setup @@ -115,7 +132,7 @@ The Morpheus Developer Kit allows developers to quickly and easily set up exampl 1. Refer to [Appendix A](#appendix-a) for Cloud (AWS) or On-Prem (Ubuntu) 2. Registration in the NGC Public Catalog -Continue with the setup steps below once the host system is installed and configured and satisfies all prerequisites. +Continue with the setup steps below once the host system is installed, configured, and satisfies all prerequisites. ### Set up NGC API Key and Install NGC Registry CLI @@ -134,8 +151,8 @@ Next, install and configure the NGC Registry CLI on your system using the linked Next, create a namespace and an environment variable for the namespace to organize the Kubernetes cluster deployed via the Cloud Native Core Stack and logically separate Morpheus related deployments from other projects using the following command: ```bash -$ kubectl create namespace $ export NAMESPACE="" +$ kubectl create namespace ${NAMESPACE} ``` ### Install Morpheus AI Engine @@ -157,7 +174,7 @@ $ helm install --set ngc.apiKey="$API_KEY" \ morpheus-ai-engine ``` -After the installation, You can verify that the Kubernetes pods are running successfully using the following command: +After the installation, you can verify that the Kubernetes pods are running successfully using the following command: ```bash $ kubectl -n $NAMESPACE get all @@ -193,16 +210,6 @@ Run the following command to pull the Morpheus SDK Client chart on to your insta $ helm fetch https://helm.ngc.nvidia.com/nvidia/morpheus/charts/morpheus-sdk-client-22.06.tgz --username='$oauthtoken' --password=$API_KEY --untar ``` -**Note**: For reference, the Morpheus SDK Client install pipeline command template is provided. Let's take a closer look at this when running [example workflows](#example-workflows), but for now, let's proceed to the next step. - -```bash -$ helm install --set ngc.apiKey="$API_KEY" \ - --set sdk.args="" \ - --namespace $NAMESPACE \ - \ - morpheus-sdk-client -``` - #### Morpheus SDK Client in Sleep Mode Install the Morpheus SDK client pod in sleep mode to copy its sample datasets and models from the container to a shared location that other pods can access. If no `sdk.args` is supplied, the default value `/bin/sleep infinity` from the chart is used in the following command. @@ -225,18 +232,17 @@ Output: pod/sdk-cli-helper 1/1 Running 0 41s ``` -### Models for MLFlow Plugin Deployment +### Models for MLflow Plugin Deployment -Connect to the **sdk-cli-helper** and copy models to `/common`, which is mapped to `/opt/morpheus/common` on the host and where MLFlow will have access to model files. +Connect to the **sdk-cli-helper** container and copy the models to `/common`, which is mapped to `/opt/morpheus/common` on the host and where MLflow will have access to model files. ```bash $ kubectl -n $NAMESPACE exec sdk-cli-helper -- cp -RL /workspace/models /common ``` -### Install Morpheus MLFlow Triton Plugin +### Install Morpheus MLflow Triton Plugin -The Morpheus MLFlow Triton Plugin is used to deploy, update, and remove models from the Morpheus AI Engine. MLFlow server UI can be accessed using NodePort 30500 -Follow the below steps to install Morpheus MlFLow Triton Plugin: +The Morpheus MLflow Triton Plugin is used to deploy, update, and remove models from the Morpheus AI Engine. The MLflow server UI can be accessed using NodePort 30500. Follow the below steps to install the Morpheus MLflow Triton Plugin: ```bash $ helm fetch https://helm.ngc.nvidia.com/nvidia/morpheus/charts/morpheus-mlflow-22.06.tgz --username='$oauthtoken' --password=$API_KEY --untar @@ -254,7 +260,7 @@ $ helm install --set ngc.apiKey="$API_KEY" \ Error: Service "mlflow" is invalid: spec.ports[0].nodePort: Invalid value: 30500: provided port is already allocated ``` -After the installation, you can verify that the MLFlow pod is running successfully using the following command: +After the installation, you can verify that the MLflow pod is running successfully using the following command: ```bash $ kubectl -n $NAMESPACE get all | grep pod/mlflow @@ -266,7 +272,7 @@ pod/mlflow-6d98 1/1 Running 0 39s ``` ### Model Deployment -Attach to the MLFLow pod to publish models to MLFlow server and then deploy it onto Morpheus AI Engine: +Attach to the MLfLow pod to publish models to the MLflow server and then deploy it onto Morpheus AI Engine: ```bash $ kubectl -n $NAMESPACE exec -it deploy/mlflow -- bash @@ -278,8 +284,8 @@ $ kubectl -n $NAMESPACE exec -it deploy/mlflow -- bash `Important`: When (mlflow) is present, commands are directly within the container. -Let's have a look at how to use the MLFlow Triton plugin before we start deploying models. -Publish models to MLFlow server: +First let's have a look at the syntax of the commands we will be using to communicate with the MLflow Triton plugin before we start deploying models. +Publish models to MLflow server looks like: ```bash (mlflow) root@mlflow-6d98:/mlflow# python publish_model_to_mlflow.py \ @@ -314,7 +320,7 @@ Delete deployed models from Morpheus AI Engine: --name / ``` -Now that we've figured out how to deploy models let's move on to the next step. Now it's time to deploy the relevant models, which have already been copied to `/opt/morpheus/common/models` which are bound to `/common/models` within the MLFlow pod. +Now that we've figured out how to deploy models let's move on to the next step. Now it's time to deploy the relevant models, which have already been copied to `/opt/morpheus/common/models` which are bound to `/common/models` within the MLflow pod. ```bash (mlflow) root@mlflow-6d98:/mlflow# ls -lrt /common/models @@ -469,6 +475,17 @@ Refer to the Using Morpheus SDK Client to Run Pipelines section of the Appendix - Replace **** with the name you want. +For reference, the Morpheus SDK Client install pipeline command template is provided. Let's take a closer look at this when running [example workflows](#example-workflows), but for now, let's proceed to the next step. + +```bash +$ helm install --set ngc.apiKey="$API_KEY" \ + --set sdk.args="" \ + --namespace $NAMESPACE \ + \ + morpheus-sdk-client +``` + + ### Run AutoEncoder Digital Fingerprinting Pipeline The following AutoEncoder pipeline example shows how to train and validate the AutoEncoder model and write the inference results to a specified location. Digital fingerprinting has also been referred to as **HAMMAH (Human as Machine <> Machine as Human)**. These use cases are currently implemented to detect user behavior changes that indicate a change from a human to a machine or a machine to a human. The model is an ensemble of an autoencoder and fast fourier transform reconstruction. @@ -652,7 +669,7 @@ $ helm install --set ngc.apiKey="$API_KEY" \ When the pipeline runs successfully, an output file *sid-minibert-onnx-output.jsonlines* will appear in the output directory. -Pipeline example to read messages from an input Kafka topic, run inference using a *sid-minibert-onnx* model, and write the results of the inference to an output Kafka topic: +Pipeline example to read messages from an input Kafka topic, run inference using a *sid-minibert-onnx* model, and write the results of the inference to an output Kafka topic: ```bash $ helm install --set ngc.apiKey="$API_KEY" \ @@ -1104,7 +1121,7 @@ This section lists solutions to problems you might encounter with Morpheus or fr #### Common Problems - Models Unloaded After Reboot - - When the pod is restarted, K8s will not automatically load the models. Since models are deployed to *ai-engine* in explicit mode using MLFlow, we'd have to manually deploy them again using the [Model Deployment](#model-deployment) process. + - When the pod is restarted, K8s will not automatically load the models. Since models are deployed to *ai-engine* in explicit mode using MLflow, we'd have to manually deploy them again using the [Model Deployment](#model-deployment) process. - AI Engine CPU Only Mode - After a server restart, the ai-engine pod on k8s can start up before the gpu operator infrastructure is available, making it "think" there is no driver installed (i.e., CPU -only mode). - Improve Pipeline Message Processing Rate diff --git a/examples/abp_nvsmi_detection/README.md b/examples/abp_nvsmi_detection/README.md index 9c590d867e..06277587e8 100644 --- a/examples/abp_nvsmi_detection/README.md +++ b/examples/abp_nvsmi_detection/README.md @@ -46,7 +46,7 @@ $ nvidia-smi dmon Each line in the output represents the GPU metrics at a single point in time. As the tool progresses the GPU begins to be utilized and you can see the SM% and Mem% increase as memory is loaded into the GPU and computations are performed. The model we will be using can ingest this information and determine whether or not the GPU is mining cryptocurriences without needing additional information from the host machine. -In this example we will be using the `examples/data/nvsmi.jsonlines` dataset that is known to contain mining behavior profiles. The dataset is in the `.jsonlines` format which means each new line represents an new JSON object. In order to parse this data, it must be ingested, split by lines into individual JSON objects, and parsed into cuDF dataframes. This will all be handled by Morpheus. +In this example we will be using the `examples/data/nvsmi.jsonlines` dataset that is known to contain mining behavior profiles. The dataset is in the `.jsonlines` format which means each new line represents a new JSON object. In order to parse this data, it must be ingested, split by lines into individual JSON objects, and parsed into cuDF dataframes. This will all be handled by Morpheus. ## Pipeline Architecture @@ -93,8 +93,9 @@ With the Morpheus CLI, an entire pipeline can be configured and run without writ The following command line is the entire command to build and launch the pipeline. Each new line represents a new stage. The comment above each stage gives information about why the stage was added and configured this way (you can copy/paste the entire command with comments). +From the Morpheus repo root directory run: ```bash -export MORPHEUS_ROOT=../.. +export MORPHEUS_ROOT=$(pwd) # Launch Morpheus printing debug messages morpheus --log_level=DEBUG \ `# Run a pipeline with 8 threads and a model batch size of 32 (Must be equal or less than Triton config)` \ @@ -102,13 +103,13 @@ morpheus --log_level=DEBUG \ `# Specify a NLP pipeline with 256 sequence length (Must match Triton config)` \ pipeline-fil \ `# 1st Stage: Read from file` \ - from-file --filename=$MORPHEUS_ROOT/examples/data/nvsmi.jsonlines \ + from-file --filename=examples/data/nvsmi.jsonlines \ `# 2nd Stage: Deserialize from JSON strings to objects` \ deserialize \ `# 3rd Stage: Preprocessing converts the input data into BERT tokens` \ preprocess \ `# 4th Stage: Send messages to Triton for inference. Specify the model loaded in Setup` \ - inf-triton --model_name=abp-nvsmi-xgb --server_url=localhost:8001 \ + inf-triton --model_name=abp-nvsmi-xgb --server_url=localhost:8000 \ `# 5th Stage: Monitor stage prints throughput information to the console` \ monitor --description "Inference Rate" --smoothing=0.001 --unit inf \ `# 6th Stage: Add results from inference to the messages` \ @@ -177,14 +178,15 @@ CPP Enabled: True ====Registering Pipeline==== ====Registering Pipeline Complete!==== ====Starting Pipeline==== +====Pipeline Started==== ====Building Pipeline==== -Added source: +Added source: └─> morpheus.MessageMeta Added stage: └─ morpheus.MessageMeta -> morpheus.MultiMessage Added stage: └─ morpheus.MultiMessage -> morpheus.MultiInferenceFILMessage -Added stage: +Added stage: └─ morpheus.MultiInferenceFILMessage -> morpheus.MultiResponseProbsMessage Added stage: └─ morpheus.MultiResponseProbsMessage -> morpheus.MultiResponseProbsMessage @@ -195,9 +197,8 @@ Added stage: └─ morpheus.MessageMeta -> morpheus.MessageMeta ====Building Pipeline Complete!==== -Starting! Time: 1650991285.1247575 -====Pipeline Started==== -Inference Rate[Complete]: 1242inf [00:00, 6823.28inf/s] +Starting! Time: 1656353254.9919598 +Inference Rate[Complete]: 1242inf [00:00, 1863.04inf/s] ====Pipeline Complete==== ``` diff --git a/examples/abp_nvsmi_detection/pipeline.png b/examples/abp_nvsmi_detection/pipeline.png index f612fd6d597b9eb302b62ad99e31df431544ca60..4a19fe83b3325322dea6ea4852616808a80534e5 100644 GIT binary patch literal 15682 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 Qirl!8yxOg7xj&!(5A|v|LI3~& literal 18630 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 diff --git a/examples/abp_pcap_detection/README.md b/examples/abp_pcap_detection/README.md index 4f43f77b0a..0d76950e3b 100644 --- a/examples/abp_pcap_detection/README.md +++ b/examples/abp_pcap_detection/README.md @@ -83,7 +83,7 @@ Options: --help Show this message and exit. ``` -To launch the configured Morpheus pipeline with the sample data that is provided at `/examples/data`, run the following: +To launch the configured Morpheus pipeline with the sample data that is provided at `/examples/data`, from the `examples/abp_pcap_detection` directory run the following: ```bash python run.py \ diff --git a/examples/abp_pcap_detection/abp_pcap_preprocessing.py b/examples/abp_pcap_detection/abp_pcap_preprocessing.py index 741ddb24c4..0194ede15d 100644 --- a/examples/abp_pcap_detection/abp_pcap_preprocessing.py +++ b/examples/abp_pcap_detection/abp_pcap_preprocessing.py @@ -59,6 +59,9 @@ def __init__(self, c: Config): def name(self) -> str: return "preprocess-anomaly" + def supports_cpp_node(self): + return False + @staticmethod def pre_process_batch(x: MultiMessage, fea_len: int, fea_cols: typing.List[str]) -> MultiInferenceFILMessage: flags_bin_series = cudf.Series(x.get_meta("flags").to_pandas().apply(lambda x: format(int(x), "05b"))) diff --git a/examples/abp_pcap_detection/img/abp_pcap_detection.png b/examples/abp_pcap_detection/img/abp_pcap_detection.png index 70f2cb9fd6665228737a4bc0a2bec476ddc21bac..9fae49950d7e3d1dc403ad7bdabee682e388db2d 100644 GIT binary patch literal 19396 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 literal 14406 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 Y--OuZ{XY&^A$x*RyLuu2+>Lwx10nMT!~g&Q diff --git a/examples/log_parsing/README.md b/examples/log_parsing/README.md index c22d7a4dae..61484e5158 100644 --- a/examples/log_parsing/README.md +++ b/examples/log_parsing/README.md @@ -36,9 +36,20 @@ cd ${MORPHEUS_ROOT}/models docker run --gpus=1 --rm -p8000:8000 -p8001:8001 -p8002:8002 -v $PWD:/models nvcr.io/nvidia/tritonserver:22.02-py3 tritonserver --model-repository=/models/triton-model-repo --model-control-mode=explicit --load-model log-parsing-onnx ``` +##### Verify Model Deployment +Once Triton server finishes starting up, it will display the status of all loaded models. Successful deployment of the model will show the following: + +``` ++------------------+---------+--------+ +| Model | Version | Status | ++------------------+---------+--------+ +| log-parsing-onnx | 1 | READY | ++------------------+---------+--------+ +``` + ### Run Log Parsing Pipeline -Run the following in your Morpheus container to start the log parsing pipeline: +Run the following from the root of the Morpheus repo to start the log parsing pipeline: ``` python ./examples/log_parsing/run.py \ diff --git a/examples/nlp_si_detection/README.md b/examples/nlp_si_detection/README.md index 294932319d..8fc7263e7c 100644 --- a/examples/nlp_si_detection/README.md +++ b/examples/nlp_si_detection/README.md @@ -57,7 +57,7 @@ The dataset that this workflow was designed to process is PCAP, or Packet Captur } ``` -In this example, we will be using a simulated PCAP dataset that is known to contain SI from each of the 10 categories the model was trained for. The dataset is located at `examples/data/pcap_dump.jsonlines`. The dataset is in the `.jsonlines` format which means each new line represents an new JSON object. In order to parse this data, it must be ingested, split by lines into individual JSON objects, and parsed. This will all be handled by Morpheus. +In this example, we will be using a simulated PCAP dataset that is known to contain SI from each of the 10 categories the model was trained for. The dataset is located at `examples/data/pcap_dump.jsonlines`. The dataset is in the `.jsonlines` format which means each new line represents a new JSON object. In order to parse this data, it must be ingested, split by lines into individual JSON objects, and parsed. This will all be handled by Morpheus. ## Pipeline Architecture diff --git a/examples/nlp_si_detection/pipeline.png b/examples/nlp_si_detection/pipeline.png index 0f9c44f9176185d61718d61ee279ec506c4ed445..6de012072084afb371d4cd5a573f4b321640d16f 100644 GIT binary patch literal 17114 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 D^Zom% literal 22768 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 diff --git a/morpheus.code-workspace b/morpheus.code-workspace index a4ee3e30c2..11a0f9db2c 100644 --- a/morpheus.code-workspace +++ b/morpheus.code-workspace @@ -84,7 +84,7 @@ // "from-kafka", "deserialize", "preprocess", - "--vocab_hash_file=./data/bert-base-uncased-hash.txt", + "--vocab_hash_file=./morpheus/data/bert-base-uncased-hash.txt", "--truncation=True", "--do_lower_case=True", "--add_special_tokens=False", @@ -247,7 +247,7 @@ "--model_max_batch_size=32", // "--use_cpp=False", "pipeline-nlp", - "--labels_file=data/labels_phishing.txt", + "--labels_file=morpheus/data/labels_phishing.txt", "--model_seq_length=128", "from-file", "--filename=models/datasets/validation-data/phishing-email-validation-data.jsonlines", @@ -256,7 +256,7 @@ // "from-kafka", "deserialize", "preprocess", - "--vocab_hash_file=./data/bert-base-uncased-hash.txt", + "--vocab_hash_file=./morpheus/data/bert-base-uncased-hash.txt", "--truncation=True", // "--stride=", "--do_lower_case=True", @@ -353,7 +353,7 @@ // "from-kafka", "deserialize", "preprocess", - "--vocab_hash_file=./data/bert-base-uncased-hash.txt", + "--vocab_hash_file=./morpheus/data/bert-base-uncased-hash.txt", "--truncation=True", "--do_lower_case=True", "--add_special_tokens=False", diff --git a/scripts/validation/val-run-pipeline.sh b/scripts/validation/val-run-pipeline.sh index 38d53329a7..8849b847dc 100755 --- a/scripts/validation/val-run-pipeline.sh +++ b/scripts/validation/val-run-pipeline.sh @@ -1,5 +1,5 @@ #!/bin/bash -# SPDX-FileCopyrightText: Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-FileCopyrightText: Copyright (c) 2021-2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -41,7 +41,7 @@ function run_pipeline_sid_minibert(){ pipeline-nlp --model_seq_length=256 \ from-file --filename=${INPUT_FILE} \ deserialize \ - preprocess --vocab_hash_file=${MORPHEUS_ROOT}/data/bert-base-uncased-hash.txt --truncation=True --do_lower_case=True --add_special_tokens=False \ + preprocess --vocab_hash_file=${MORPHEUS_ROOT}/morpheus/data/bert-base-uncased-hash.txt --truncation=True --do_lower_case=True --add_special_tokens=False \ ${INFERENCE_STAGE} \ monitor --description "Inference Rate" --smoothing=0.001 --unit inf \ add-class --prefix="si_" \ @@ -62,7 +62,7 @@ function run_pipeline_sid_bert(){ pipeline-nlp --model_seq_length=256 \ from-file --filename=${INPUT_FILE} \ deserialize \ - preprocess --vocab_hash_file=${MORPHEUS_ROOT}/data/bert-base-cased-hash.txt --truncation=True --do_lower_case=False --add_special_tokens=False \ + preprocess --vocab_hash_file=${MORPHEUS_ROOT}/morpheus/data/bert-base-cased-hash.txt --truncation=True --do_lower_case=False --add_special_tokens=False \ ${INFERENCE_STAGE} \ monitor --description "Inference Rate" --smoothing=0.001 --unit inf \ add-class --prefix="si_" \ @@ -101,10 +101,10 @@ function run_pipeline_phishing_email(){ VAL_OUTPUT=$5 morpheus --log_level=DEBUG run --num_threads=1 --pipeline_batch_size=1024 --model_max_batch_size=32 --use_cpp=${USE_CPP} \ - pipeline-nlp --model_seq_length=128 --labels_file=${MORPHEUS_ROOT}/data/labels_phishing.txt \ + pipeline-nlp --model_seq_length=128 --labels_file=${MORPHEUS_ROOT}/morpheus/data/labels_phishing.txt \ from-file --filename=${INPUT_FILE} \ deserialize \ - preprocess --vocab_hash_file=${MORPHEUS_ROOT}/data/bert-base-uncased-hash.txt --truncation=True --do_lower_case=True --add_special_tokens=False \ + preprocess --vocab_hash_file=${MORPHEUS_ROOT}/morpheus/data/bert-base-uncased-hash.txt --truncation=True --do_lower_case=True --add_special_tokens=False \ ${INFERENCE_STAGE} \ monitor --description "Inference Rate" --smoothing=0.001 --unit inf \ add-class --label=pred --threshold=0.7 \