diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 000000000..b4d509648
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,19 @@
+# Ignore git objects
+.git/
+.gitignore
+.gitlab-ci.yml
+.gitmodules
+
+# Ignore temperory volumes
+deploy/compose/volumes
+
+# creating a docker image
+.dockerignore
+
+# Ignore any virtual environment configuration files
+.env*
+.venv/
+env/
+# Ignore python bytecode files
+*.pyc
+__pycache__/
diff --git a/.gitignore b/.gitignore
index 241cbc4f0..7094b42f7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,3 +24,7 @@ docs/_*
docs/notebooks
docs/experimental
docs/tools
+
+# Developing examples
+RetrievalAugmentedGeneration/examples/simple_rag_api_catalog/
+deploy/compose/simple-rag-api-catalog.yaml
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 22aece8e7..4f67ebf67 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -9,3 +9,17 @@ repos:
args:
- --license-filepath
- RetrievalAugmentedGeneration/LICENSE.md
+- repo: https://github.com/psf/black
+ rev: 19.10b0
+ hooks:
+ - id: black
+ args: ["--skip-string-normalization", "--line-length=119"]
+ additional_dependencies: ['click==8.0.4']
+- repo: https://github.com/pycqa/isort
+ rev: 5.12.0
+ hooks:
+ - id: isort
+ name: isort (python)
+ args: ["--multi-line=3", "--trailing-comma", "--force-grid-wrap=0", "--use-parenthese", "--line-width=119", "--ws"]
+
+
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ad637060c..6112a8840 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,38 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [0.7.0] - 2024-06-18
+
+This release switches all examples to use cloud hosted GPU accelerated LLM and embedding models from [Nvidia API Catalog](https://build.nvidia.com) as default. It also deprecates support to deploy on-prem models using NeMo Inference Framework Container and adds support to deploy accelerated generative AI models across the cloud, data center, and workstation using [latest Nvidia NIM-LLM](https://docs.nvidia.com/nim/large-language-models/latest/introduction.html).
+
+### Added
+- Added model [auto download and caching support for `nemo-retriever-embedding-microservice` and `nemo-retriever-reranking-microservice`](./deploy/compose/docker-compose-nim-ms.yaml). Updated steps to deploy the services can be found [here](https://nvidia.github.io/GenerativeAIExamples/latest/nim-llms.html).
+- [Multimodal RAG Example enhancements](https://nvidia.github.io/GenerativeAIExamples/latest/multimodal-data.html)
+ - Moved to the [PDF Plumber library](https://pypi.org/project/pdfplumber/) for parsing text and images.
+ - Added `pgvector` vector DB support.
+ - Added support to ingest files with .pptx extension
+ - Improved accuracy of image parsing by using [tesseract-ocr](https://pypi.org/project/tesseract-ocr/)
+- Added a [new notebook showcasing RAG usecase using accelerated NIM based on-prem deployed models](./notebooks/08_RAG_Langchain_with_Local_NIM.ipynb)
+- Added a [new experimental example](./experimental/rag-developer-chatbot/) showcasing how to create a developer-focused RAG chatbot using RAPIDS cuDF source code and API documentation.
+- Added a [new experimental example](./experimental/event-driven-rag-cve-analysis/) demonstrating how NVIDIA Morpheus, NIMs, and RAG pipelines can be integrated to create LLM-based agent pipelines.
+
+### Changed
+- All examples now use llama3 models from [Nvidia API Catalog](https://build.nvidia.com/search?term=llama3) as default. Summary of updated examples and the model it uses is available [here](https://nvidia.github.io/GenerativeAIExamples/latest/index.html#developer-rag-examples).
+- Switched default embedding model of all examples to [Snowflake arctic-embed-I model](https://build.nvidia.com/snowflake/arctic-embed-l)
+- Added more verbose logs and support to configure [log level for chain server using LOG_LEVEL enviroment variable](https://nvidia.github.io/GenerativeAIExamples/latest/configuration.html#chain-server).
+- Bumped up version of `langchain-nvidia-ai-endpoints`, `sentence-transformers` package and `milvus` containers
+- Updated base containers to use ubuntu 22.04 image `nvcr.io/nvidia/base/ubuntu:22.04_20240212`
+- Added `llama-index-readers-file` as dependency to avoid runtime package installation within chain server.
+
+
+### Deprecated
+- Deprecated support of on-prem LLM model deployment using [NeMo Inference Framework Container](https://github.com/NVIDIA/GenerativeAIExamples/blob/v0.6.0/deploy/compose/rag-app-text-chatbot.yaml#L2). Developers can use [Nvidia NIM-LLM to deploy TensorRT optimized models on-prem and plug them in with existing examples](https://nvidia.github.io/GenerativeAIExamples/latest/nim-llms.html).
+- Deprecated [kubernetes operator support](https://github.com/NVIDIA/GenerativeAIExamples/tree/v0.6.0/deploy/k8s-operator/kube-trailblazer).
+- `nvolveqa_40k` embedding model was deprecated from [Nvidia API Catalog](https://build.nvidia.com). Updated all [notebooks](./notebooks/) and [experimental artifacts](./experimental/) to use [Nvidia embed-qa-4 model](https://build.nvidia.com/nvidia/embed-qa-4) instead.
+- Removed [notebooks numbered 00-04](https://github.com/NVIDIA/GenerativeAIExamples/tree/v0.6.0/notebooks), which used on-prem LLM model deployment using deprecated [NeMo Inference Framework Container](https://github.com/NVIDIA/GenerativeAIExamples/blob/v0.6.0/deploy/compose/rag-app-text-chatbot.yaml#L2).
+
+
## [0.6.0] - 2024-05-07
### Added
diff --git a/README.md b/README.md
index aebece7c9..70fc8dbdf 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@ State-of-the-art Generative AI examples that are easy to deploy, test, and exten
## NVIDIA NGC
-Generative AI Examples can use models and GPUs from the [NVIDIA NGC: AI Development Catalog](https://catalog.ngc.nvidia.com).
+Generative AI Examples can use models and GPUs from the [NVIDIA API Catalog](https://catalog.ngc.nvidia.com).
Sign up for a [free NGC developer account](https://ngc.nvidia.com/signin) to access:
@@ -27,20 +27,18 @@ The examples demonstrate how to combine NVIDIA GPU acceleration with popular LLM
The examples are easy to deploy with [Docker Compose](https://docs.docker.com/compose/).
Examples support local and remote inference endpoints.
-If you have a GPU, you can inference locally with [TensorRT-LLM](https://github.com/NVIDIA/TensorRT-LLM).
+If you have a GPU, you can inference locally with an [NVIDIA NIM for LLMs](https://catalog.ngc.nvidia.com/orgs/nvidia/teams/nim/containers/nim_llm).
If you don't have a GPU, you can inference and embed remotely with [NVIDIA API Catalog endpoints](https://build.nvidia.com/explore/discover).
| Model | Embedding | Framework | Description | Multi-GPU | TRT-LLM | NVIDIA Endpoints | Triton | Vector Database |
| ---------------------------------- | ---------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | ------- | ---------------- | ------ | ------------------ |
-| mixtral_8x7b | ai-embed-qa-4 | LangChain | NVIDIA API Catalog endpoints chat bot [[code](./RetrievalAugmentedGeneration/examples/nvidia_api_catalog/), [docs](https://nvidia.github.io/GenerativeAIExamples/latest/api-catalog.html)] | No | No | Yes | Yes | Milvus or pgvector |
-| llama-2 | UAE-Large-V1 | LlamaIndex | Canonical QA Chatbot [[code](./RetrievalAugmentedGeneration/examples/developer_rag/), [docs](https://nvidia.github.io/GenerativeAIExamples/latest/local-gpu.html)] | [Yes](https://nvidia.github.io/GenerativeAIExamples/latest/multi-gpu.html) | Yes | No | Yes | Milvus or pgvector |
-| llama-2 | all-MiniLM-L6-v2 | LlamaIndex | Chat bot, GeForce, Windows [[repo](https://github.com/NVIDIA/trt-llm-rag-windows/tree/release/1.0)] | No | Yes | No | No | FAISS |
-| llama-2 | ai-embed-qa-4 | LangChain | Chat bot with query decomposition agent [[code](./RetrievalAugmentedGeneration/examples/query_decomposition_rag/), [docs](https://nvidia.github.io/GenerativeAIExamples/latest/query-decomposition.html)] | No | No | Yes | Yes | Milvus or pgvector |
-| mixtral_8x7b | ai-embed-qa-4 | LangChain | Minimilastic example: RAG with NVIDIA AI Foundation Models [[code](./examples/5_mins_rag_no_gpu/), [README](./examples/README.md#rag-in-5-minutes-example)] | No | No | Yes | Yes | FAISS |
-| mixtral_8x7b
Deplot
Neva-22b | ai-embed-qa-4 | Custom | Chat bot with multimodal data [[code](./RetrievalAugmentedGeneration/examples/multimodal_rag/), [docs](https://nvidia.github.io/GenerativeAIExamples/latest/multimodal-data.html)] | No | No | Yes | No | Milvus or pvgector |
-| llama-2 | UAE-Large-V1 | LlamaIndex | Chat bot with quantized LLM model [[docs](https://nvidia.github.io/GenerativeAIExamples/latest/quantized-llm-model.html)] | Yes | Yes | No | Yes | Milvus or pgvector |
+| llama3-70b | snowflake-arctic-embed-l | LangChain | NVIDIA API Catalog endpoints chat bot [[code](./RetrievalAugmentedGeneration/examples/nvidia_api_catalog/), [docs](https://nvidia.github.io/GenerativeAIExamples/latest/api-catalog.html)] | No | No | Yes | Yes | Milvus or pgvector |
+| llama3-8b | snowflake-arctic-embed-l | LlamaIndex | Canonical QA Chatbot [[code](./RetrievalAugmentedGeneration/examples/developer_rag/), [docs](https://nvidia.github.io/GenerativeAIExamples/latest/api-catalog.html#using-the-llamaindex-data-framework)] | [Yes](https://nvidia.github.io/GenerativeAIExamples/latest/multi-gpu.html) | Yes | No | Yes | Milvus or pgvector |
+| llama3-70b | snowflake-arctic-embed-l | LangChain | Chat bot with query decomposition agent [[code](./RetrievalAugmentedGeneration/examples/query_decomposition_rag/), [docs](https://nvidia.github.io/GenerativeAIExamples/latest/query-decomposition.html)] | No | No | Yes | Yes | Milvus or pgvector |
+| llama3-70b | ai-embed-qa-4 | LangChain | Minimilastic example: RAG with NVIDIA AI Foundation Models [[code](./examples/5_mins_rag_no_gpu/), [README](./examples/README.md#rag-in-5-minutes-example)] | No | No | Yes | Yes | FAISS |
+| llama3-8b
Deplot
Neva-22b | snowflake-arctic-embed-l | Custom | Chat bot with multimodal data [[code](./RetrievalAugmentedGeneration/examples/multimodal_rag/), [docs](https://nvidia.github.io/GenerativeAIExamples/latest/multimodal-data.html)] | No | No | Yes | No | Milvus or pvgector |
| llama3-70b | none | PandasAI | Chat bot with structured data [[code](./RetrievalAugmentedGeneration/examples/structured_data_rag/), [docs](https://nvidia.github.io/GenerativeAIExamples/latest/structured-data.html)] | No | No | Yes | No | none |
-| llama-2 | ai-embed-qa-4 | LangChain | Chat bot with multi-turn conversation [[code](./RetrievalAugmentedGeneration/examples/multi_turn_rag/), [docs](https://nvidia.github.io/GenerativeAIExamples/latest/multi-turn.html)] | No | No | Yes | No | Milvus or pgvector |
+| llama3-8b | snowflake-arctic-embed-l | LangChain | Chat bot with multi-turn conversation [[code](./RetrievalAugmentedGeneration/examples/multi_turn_rag/), [docs](https://nvidia.github.io/GenerativeAIExamples/latest/multi-turn.html)] | No | No | Yes | No | Milvus or pgvector |
### Enterprise RAG Examples
@@ -48,13 +46,13 @@ The enterprise RAG examples run as microservices distributed across multiple VMs
These examples show how to orchestrate RAG pipelines with [Kubernetes](https://kubernetes.io/) and deployed with [Helm](https://helm.sh/).
Enterprise RAG examples include a [Kubernetes operator](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/) for LLM lifecycle management.
-It is compatible with the [NVIDIA GPU operator](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/gpu-operator) that automates GPU discovery and lifecycle management in a Kubernetes cluster.
+It is compatible with the [NVIDIA GPU Operator](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/gpu-operator) that automates GPU discovery and lifecycle management in a Kubernetes cluster.
Enterprise RAG examples also support local and remote inference with [TensorRT-LLM](https://github.com/NVIDIA/TensorRT-LLM) and [NVIDIA API Catalog endpoints](https://build.nvidia.com/explore/discover).
| Model | Embedding | Framework | Description | Multi-GPU | Multi-node | TRT-LLM | NVIDIA Endpoints | Triton | Vector Database |
| ------- | ----------- | ---------- | -------------------------------------------------------------------------- | --------- | ---------- | ------- | ---------------- | ------ | --------------- |
-| llama-2 | NV-Embed-QA | LlamaIndex | Chat bot, Kubernetes deployment [[README](./docs/developer-llm-operator/)] | No | No | Yes | No | Yes | Milvus |
+| llama-3 | nv-embed-qa-4 | LlamaIndex | Chat bot, Kubernetes deployment [[chart](https://registry.ngc.nvidia.com/orgs/ohlfw0olaadg/teams/ea-participants/helm-charts/rag-app-text-chatbot)] | No | No | Yes | No | Yes | Milvus |
### Generative AI Model Examples
@@ -89,6 +87,16 @@ These are open source connectors for NVIDIA-hosted and self-hosted API endpoints
|[NVIDIA Triton Inference Server](https://docs.llamaindex.ai/en/stable/examples/llm/nvidia_triton.html) | [LlamaIndex](https://www.llamaindex.ai/) |Yes|Yes|No|Triton inference server provides API access to hosted LLM models over gRPC. |
|[NVIDIA TensorRT-LLM](https://docs.llamaindex.ai/en/stable/examples/llm/nvidia_tensorrt.html) | [LlamaIndex](https://www.llamaindex.ai/) |Yes|Yes|No|TensorRT-LLM provides a Python API to build TensorRT engines with state-of-the-art optimizations for LLM inference on NVIDIA GPUs. |
+
+## Related NVIDIA RAG Projects
+
+- [NVIDIA Tokkio LLM-RAG](https://docs.nvidia.com/ace/latest/workflows/tokkio/text/Tokkio_LLM_RAG_Bot.html): Use Tokkio to add avatar animation for RAG responses.
+
+- [RAG on Windows using TensorRT-LLM and LlamaIndex](https://github.com/NVIDIA/ChatRTX): Create RAG chatbots on Windows using TensorRT-LLM.
+
+- [Hybrid RAG Project on AI Workbench](https://github.com/NVIDIA/workbench-example-hybrid-rag): Run an NVIDIA AI Workbench example project for RAG.
+
+
## Support, Feedback, and Contributing
We're posting these examples on GitHub to support the NVIDIA LLM community and facilitate feedback.
diff --git a/RetrievalAugmentedGeneration/Dockerfile b/RetrievalAugmentedGeneration/Dockerfile
index 463b8cb5f..cb504a084 100644
--- a/RetrievalAugmentedGeneration/Dockerfile
+++ b/RetrievalAugmentedGeneration/Dockerfile
@@ -1,5 +1,5 @@
ARG BASE_IMAGE_URL=nvcr.io/nvidia/base/ubuntu
-ARG BASE_IMAGE_TAG=20.04_x64_2022-09-23
+ARG BASE_IMAGE_TAG=22.04_20240212
FROM ${BASE_IMAGE_URL}:${BASE_IMAGE_TAG}
@@ -11,7 +11,7 @@ RUN apt update && \
apt install -y curl software-properties-common libgl1 libglib2.0-0 && \
add-apt-repository ppa:deadsnakes/ppa && \
apt update && apt install -y python3.10 python3.10-dev python3.10-distutils && \
- apt-get clean
+ apt-get clean
# Install pip for python3.10
RUN curl -sS https://bootstrap.pypa.io/get-pip.py | python3.10
@@ -24,7 +24,7 @@ RUN apt autoremove -y curl software-properties-common
# Install common dependencies for all examples
RUN --mount=type=bind,source=RetrievalAugmentedGeneration/requirements.txt,target=/opt/requirements.txt \
pip3 install --no-cache-dir -r /opt/requirements.txt
-
+
# Install any example specific dependency if available
ARG EXAMPLE_NAME
COPY RetrievalAugmentedGeneration/examples/${EXAMPLE_NAME} /opt/RetrievalAugmentedGeneration/example
@@ -32,12 +32,24 @@ RUN if [ -f "/opt/RetrievalAugmentedGeneration/example/requirements.txt" ] ; the
pip3 install --no-cache-dir -r /opt/RetrievalAugmentedGeneration/example/requirements.txt ; else \
echo "Skipping example dependency installation, since requirements.txt was not found" ; \
fi
+RUN python3.10 -m nltk.downloader averaged_perceptron_tagger
+RUN if [ "${EXAMPLE_NAME}" = "multimodal_rag" ] ; then \
+ apt update && \
+ apt install -y libreoffice && \
+ apt install -y tesseract-ocr ; \
+ fi
# Copy required common modules for all examples
COPY RetrievalAugmentedGeneration/__init__.py /opt/RetrievalAugmentedGeneration/
COPY RetrievalAugmentedGeneration/common /opt/RetrievalAugmentedGeneration/common
COPY integrations /opt/integrations
COPY tools /opt/tools
+RUN mkdir /tmp-data/; mkdir /tmp-data/nltk_data/
+RUN chmod 777 -R /tmp-data
+RUN chown 1000:1000 -R /tmp-data
+ENV NLTK_DATA=/tmp-data/nltk_data/
+ENV HF_HOME=/tmp-data
+
WORKDIR /opt
ENTRYPOINT ["uvicorn", "RetrievalAugmentedGeneration.common.server:app"]
diff --git a/RetrievalAugmentedGeneration/common/configuration.py b/RetrievalAugmentedGeneration/common/configuration.py
index 7a6656f31..da3a7967e 100644
--- a/RetrievalAugmentedGeneration/common/configuration.py
+++ b/RetrievalAugmentedGeneration/common/configuration.py
@@ -67,8 +67,8 @@ class LLMConfig(ConfigWizard):
)
model_engine: str = configfield(
"model_engine",
- default="triton-trt-llm",
- help_txt="The server type of the hosted model. Allowed values are triton-trt-llm and nemo-infer",
+ default="nvidia-ai-endpoints",
+ help_txt="The server type of the hosted model. Allowed values are nvidia-ai-endpoints",
)
model_name_pandas_ai: str = configfield(
"model_name_pandas_ai",
@@ -86,7 +86,7 @@ class TextSplitterConfig(ConfigWizard):
model_name: str = configfield(
"model_name",
- default="WhereIsAI/UAE-Large-V1",
+ default="Snowflake/snowflake-arctic-embed-l",
help_txt="The name of Sentence Transformer model used for SentenceTransformer TextSplitter.",
)
chunk_size: int = configfield(
@@ -110,12 +110,12 @@ class EmbeddingConfig(ConfigWizard):
model_name: str = configfield(
"model_name",
- default="WhereIsAI/UAE-Large-V1",
+ default="snowflake/arctic-embed-l",
help_txt="The name of huggingface embedding model.",
)
model_engine: str = configfield(
"model_engine",
- default="huggingface",
+ default="nvidia-ai-endpoints",
help_txt="The server type of the hosted model. Allowed values are hugginface",
)
dimensions: int = configfield(
@@ -148,6 +148,16 @@ class RetrieverConfig(ConfigWizard):
default=0.25,
help_txt="The minimum confidence score for the retrieved values to be considered",
)
+ nr_url: str = configfield(
+ "nr_url",
+ default='http://retrieval-ms:8000',
+ help_txt="The nemo retriever microservice url",
+ )
+ nr_pipeline: str = configfield(
+ "nr_pipeline",
+ default='ranked_hybrid',
+ help_txt="The name of the nemo retriever pipeline one of ranked_hybrid or hybrid",
+ )
@configclass
@@ -162,12 +172,9 @@ class PromptsConfig(ConfigWizard):
chat_template: str = configfield(
"chat_template",
default=(
- "[INST] <>"
"You are a helpful, respectful and honest assistant."
"Always answer as helpfully as possible, while being safe."
"Please ensure that your responses are positive in nature."
- "<>"
- "[/INST] {context_str} [INST] {query_str} [/INST]"
),
help_txt="Prompt template for chat.",
)
diff --git a/RetrievalAugmentedGeneration/common/server.py b/RetrievalAugmentedGeneration/common/server.py
index 569cb9fe8..ca3acf56d 100644
--- a/RetrievalAugmentedGeneration/common/server.py
+++ b/RetrievalAugmentedGeneration/common/server.py
@@ -37,7 +37,7 @@
from pymilvus.exceptions import MilvusException, MilvusUnavailableException
from RetrievalAugmentedGeneration.common.tracing import llamaindex_instrumentation_wrapper
-logging.basicConfig(level=logging.INFO)
+logging.basicConfig(level=os.environ.get('LOGLEVEL', 'INFO').upper())
logger = logging.getLogger(__name__)
# create the FastAPI server
@@ -193,7 +193,7 @@ async def request_validation_exception_handler(
def health_check():
"""
Perform a Health Check
-
+
Returns 200 when service is up. This does not check the health of downstream services.
"""
@@ -218,7 +218,7 @@ async def upload_document(request: Request, file: UploadFile = File(...)) -> JSO
return JSONResponse(content={"message": "No files provided"}, status_code=200)
try:
- upload_folder = "uploaded_files"
+ upload_folder = "/tmp-data/uploaded_files"
upload_file = os.path.basename(file.filename)
if not upload_file:
raise RuntimeError("Error parsing uploaded filename.")
@@ -285,6 +285,7 @@ async def generate_answer(request: Request, prompt: Prompt) -> StreamingResponse
def response_generator():
resp_id = str(uuid4())
if generator:
+ logger.debug(f"Generated response chunks\n")
for chunk in generator:
chain_response = ChainResponse()
response_choice = ChainResponseChoices(
@@ -296,11 +297,13 @@ def response_generator():
)
chain_response.id = resp_id
chain_response.choices.append(response_choice)
+ logger.debug(response_choice)
yield "data: " + str(chain_response.json()) + "\n\n"
chain_response = ChainResponse()
response_choice = ChainResponseChoices(finish_reason="[DONE]")
chain_response.id = resp_id
chain_response.choices.append(response_choice)
+ logger.debug(response_choice)
yield "data: " + str(chain_response.json()) + "\n\n"
else:
chain_response = ChainResponse()
@@ -412,7 +415,9 @@ async def delete_document(request: Request, filename: str) -> JSONResponse:
try:
example = app.example()
if hasattr(example, "delete_documents") and callable(example.delete_documents):
- example.delete_documents([filename])
+ status = example.delete_documents([filename])
+ if not status:
+ raise Exception(f"Error in deleting document {filename}")
return JSONResponse(content={"message": f"Document {filename} deleted successfully"}, status_code=200)
raise NotImplementedError("Example class has not implemented the delete_document method.")
diff --git a/RetrievalAugmentedGeneration/common/tracing.py b/RetrievalAugmentedGeneration/common/tracing.py
index 81f40627d..4e24337d4 100644
--- a/RetrievalAugmentedGeneration/common/tracing.py
+++ b/RetrievalAugmentedGeneration/common/tracing.py
@@ -17,8 +17,8 @@
import os
import llama_index
-from llama_index.core.callbacks.base import CallbackManager
-from langchain.callbacks.base import BaseCallbackHandler
+from langchain.callbacks.base import BaseCallbackHandler as langchain_base_cb_handler
+from llama_index.core.callbacks.simple_llm_handler import SimpleLLMHandler as llama_index_base_cb_handler
from opentelemetry import trace, context
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
from opentelemetry.sdk.trace import TracerProvider
@@ -40,19 +40,22 @@
trace.set_tracer_provider(provider)
tracer = trace.get_tracer("chain-server")
+
if os.environ.get("ENABLE_TRACING") == "true":
# Configure Propagator used for processing trace context received by the Chain Server
propagator = TraceContextTextMapPropagator()
- # Configure Langchain OpenTelemetry callback handler
+ # Configure Langchain OpenTelemetry callback handler
langchain_cb_handler = langchain_otel_cb.OpenTelemetryCallbackHandler(tracer)
-
+
# Configure LlamaIndex OpenTelemetry callback handler
- llama_index.global_handler = llama_index_otel_cb.OpenTelemetryCallbackHandler(tracer)
+ llama_index_cb_handler = llama_index_otel_cb.OpenTelemetryCallbackHandler(tracer)
+
else:
propagator = CompositePropagator([]) # No-op propagator
- langchain_cb_handler = BaseCallbackHandler()
-
+ langchain_cb_handler = langchain_base_cb_handler()
+ llama_index_cb_handler = llama_index_base_cb_handler()
+
set_global_textmap(propagator)
# Wrapper Function to perform LlamaIndex instrumentation
diff --git a/RetrievalAugmentedGeneration/common/utils.py b/RetrievalAugmentedGeneration/common/utils.py
index c880d9dc9..e98d9e2c1 100644
--- a/RetrievalAugmentedGeneration/common/utils.py
+++ b/RetrievalAugmentedGeneration/common/utils.py
@@ -52,13 +52,15 @@
from llama_index.core.indices.base_retriever import BaseRetriever
from llama_index.core.indices.query.schema import QueryBundle
from llama_index.core.schema import NodeWithScore
+ from RetrievalAugmentedGeneration.common.tracing import llama_index_cb_handler
+ from llama_index.core.callbacks import CallbackManager
except Exception as e:
logger.error(f"Llamaindex import failed with error: {e}")
try:
from langchain.text_splitter import SentenceTransformersTokenTextSplitter
- from langchain.embeddings import HuggingFaceEmbeddings
- from langchain.vectorstores import FAISS
+ from langchain_community.embeddings import HuggingFaceEmbeddings
+ from langchain_community.vectorstores import FAISS
except Exception as e:
logger.error(f"Langchain import failed with error: {e}")
@@ -87,8 +89,6 @@
from langchain_core.embeddings import Embeddings
from langchain_core.language_models.chat_models import SimpleChatModel
from langchain.llms.base import LLM
-from integrations.langchain.llms.triton_trt_llm import TensorRTLLM
-from integrations.langchain.embeddings.nemo_embed import NemoEmbeddings
from RetrievalAugmentedGeneration.common import configuration
if TYPE_CHECKING:
@@ -138,7 +138,8 @@ def set_service_context(**kwargs) -> None:
llm = LangChainLLM(get_llm(**kwargs))
embedding = LangchainEmbedding(get_embedding_model())
service_context = ServiceContext.from_defaults(
- llm=llm, embed_model=embedding
+ llm=llm, embed_model=embedding,
+ callback_manager=CallbackManager([llama_index_cb_handler])
)
set_global_service_context(service_context)
@@ -266,29 +267,17 @@ def get_llm(**kwargs) -> LLM | SimpleChatModel:
settings = get_config()
logger.info(f"Using {settings.llm.model_engine} as model engine for llm. Model name: {settings.llm.model_name}")
- if settings.llm.model_engine == "triton-trt-llm":
- trtllm = TensorRTLLM( # type: ignore
- server_url=settings.llm.server_url,
- model_name=settings.llm.model_name,
- temperature = kwargs.get('temperature', None),
- top_p = kwargs.get('top_p', None),
- tokens = kwargs.get('max_tokens', None)
- )
- unused_params = [key for key in kwargs.keys() if key not in ['temperature', 'top_p', 'max_tokens', 'stream']]
- if unused_params:
- logger.warning(f"The following parameters from kwargs are not supported: {unused_params} for {settings.llm.model_engine}")
- return trtllm
- elif settings.llm.model_engine == "nvidia-ai-endpoints":
+ if settings.llm.model_engine == "nvidia-ai-endpoints":
unused_params = [key for key in kwargs.keys() if key not in ['temperature', 'top_p', 'max_tokens']]
if unused_params:
logger.warning(f"The following parameters from kwargs are not supported: {unused_params} for {settings.llm.model_engine}")
if settings.llm.server_url:
logger.info(f"Using llm model {settings.llm.model_name} hosted at {settings.llm.server_url}")
- return ChatNVIDIA(model=settings.llm.model_name,
+ return ChatNVIDIA(base_url=f"http://{settings.llm.server_url}/v1",
+ model=settings.llm.model_name,
temperature = kwargs.get('temperature', None),
top_p = kwargs.get('top_p', None),
- max_tokens = kwargs.get('max_tokens', None)
- ).mode("nim", base_url=f"http://{settings.llm.server_url}/v1")
+ max_tokens = kwargs.get('max_tokens', None))
else:
logger.info(f"Using llm model {settings.llm.model_name} from api catalog")
return ChatNVIDIA(model=settings.llm.model_name,
@@ -296,7 +285,7 @@ def get_llm(**kwargs) -> LLM | SimpleChatModel:
top_p = kwargs.get('top_p', None),
max_tokens = kwargs.get('max_tokens', None))
else:
- raise RuntimeError("Unable to find any supported Large Language Model server. Supported engines are triton-trt-llm, nvidia-ai-endpoints.")
+ raise RuntimeError("Unable to find any supported Large Language Model server. Supported engine name is nvidia-ai-endpoints.")
@lru_cache
@@ -321,18 +310,12 @@ def get_embedding_model() -> Embeddings:
elif settings.embeddings.model_engine == "nvidia-ai-endpoints":
if settings.embeddings.server_url:
logger.info(f"Using embedding model {settings.embeddings.model_name} hosted at {settings.embeddings.server_url}")
- return NVIDIAEmbeddings(model=settings.embeddings.model_name).mode("nim", base_url=f"http://{settings.embeddings.server_url}/v1")
+ return NVIDIAEmbeddings(base_url=f"http://{settings.embeddings.server_url}/v1", model=settings.embeddings.model_name, truncate="END")
else:
logger.info(f"Using embedding model {settings.embeddings.model_name} hosted at api catalog")
- return NVIDIAEmbeddings(model=settings.embeddings.model_name)
- elif settings.embeddings.model_engine == "nemo-embed":
- nemo_embed = NemoEmbeddings(
- server_url=f"http://{settings.embeddings.server_url}/v1/embeddings",
- model_name=settings.embeddings.model_name,
- )
- return nemo_embed
+ return NVIDIAEmbeddings(model=settings.embeddings.model_name, truncate="END")
else:
- raise RuntimeError("Unable to find any supported embedding model. Supported engine is huggingface.")
+ raise RuntimeError("Unable to find any supported embedding model. Supported engine is huggingface and nvidia-ai-endpoints.")
def get_text_splitter() -> SentenceTransformersTokenTextSplitter:
@@ -376,7 +359,7 @@ def get_docs_vectorstore_langchain(vectorstore: VectorStore) -> List[str]:
logger.error(f"Error occurred while retrieving documents: {e}")
return []
-def del_docs_vectorstore_langchain(vectorstore: VectorStore, filenames: List[str]):
+def del_docs_vectorstore_langchain(vectorstore: VectorStore, filenames: List[str]) -> bool:
"""Delete documents from the vector index implemented in LangChain."""
settings = get_config()
@@ -387,13 +370,21 @@ def del_docs_vectorstore_langchain(vectorstore: VectorStore, filenames: List[str
in_memory_docstore = vectorstore.docstore._dict
for filename in filenames:
ids_list = [doc_id for doc_id, doc_data in in_memory_docstore.items() if extract_filename(doc_data.metadata) == filename]
+ if not len(ids_list):
+ logger.info("File does not exist in the vectorstore")
+ return False
vectorstore.delete(ids_list)
logger.info(f"Deleted documents with filenames {filename}")
elif settings.vector_store.name == "pgvector":
with vectorstore._make_session() as session:
- embedding_doc_store = session.query(vectorstore.EmbeddingStore.custom_id, vectorstore.EmbeddingStore.document, vectorstore.EmbeddingStore.cmetadata).all()
+ collection = vectorstore.get_collection(session)
+ filter_by = vectorstore.EmbeddingStore.collection_id == collection.uuid
+ embedding_doc_store = session.query(vectorstore.EmbeddingStore.custom_id, vectorstore.EmbeddingStore.document, vectorstore.EmbeddingStore.cmetadata).filter(filter_by).all()
for filename in filenames:
ids_list = [doc_id for doc_id, doc_data, metadata in embedding_doc_store if extract_filename(metadata) == filename]
+ if not len(ids_list):
+ logger.info("File does not exist in the vectorstore")
+ return False
vectorstore.delete(ids_list)
logger.info(f"Deleted documents with filenames {filename}")
elif settings.vector_store.name == "milvus":
@@ -401,10 +392,15 @@ def del_docs_vectorstore_langchain(vectorstore: VectorStore, filenames: List[str
milvus_data = vectorstore.col.query(expr="pk >= 0", output_fields=["pk","source", "text"])
for filename in filenames:
ids_list = [metadata["pk"] for metadata in milvus_data if extract_filename(metadata) == filename]
+ if not len(ids_list):
+ logger.info("File does not exist in the vectorstore")
+ return False
vectorstore.col.delete(f"pk in {ids_list}")
logger.info(f"Deleted documents with filenames {filename}")
+ return True
except Exception as e:
logger.error(f"Error occurred while deleting documents: {e}")
+ return False
def get_docs_vectorstore_llamaindex() -> List[str]:
@@ -440,7 +436,7 @@ def get_docs_vectorstore_llamaindex() -> List[str]:
return []
-def del_docs_vectorstore_llamaindex(filenames: List[str]):
+def del_docs_vectorstore_llamaindex(filenames: List[str]) -> bool:
"""Delete documents from the vector index implemented in LlamaIndex."""
settings = get_config()
@@ -460,10 +456,13 @@ def del_docs_vectorstore_llamaindex(filenames: List[str]):
query_res = client.query(collection_name=collection_name, filter=f"filename == '{filename}'",
output_fields=["id"])
if not query_res:
- return
+ logger.info("File does not exist in the vectorstore")
+ return False
ids = [entry.get('id') for entry in query_res]
res = client.delete(collection_name=collection_name, filter=f"id in {str(ids)}")
logger.info(f"Deleted documents with filenames {filename}")
+ return True
except Exception as e:
logger.error(f"Error occurred while deleting documents: {e}")
+ return False
diff --git a/RetrievalAugmentedGeneration/examples/developer_rag/chains.py b/RetrievalAugmentedGeneration/examples/developer_rag/chains.py
index 5c9c5ebb0..65b4c6c27 100644
--- a/RetrievalAugmentedGeneration/examples/developer_rag/chains.py
+++ b/RetrievalAugmentedGeneration/examples/developer_rag/chains.py
@@ -27,6 +27,9 @@
from llama_index.core.node_parser import LangchainNodeParser
from llama_index.llms.langchain import LangChainLLM
from llama_index.embeddings.langchain import LangchainEmbedding
+from RetrievalAugmentedGeneration.common.tracing import llama_index_cb_handler
+from llama_index.core import Settings
+from llama_index.core.callbacks import CallbackManager
from langchain_core.output_parsers.string import StrOutputParser
from langchain_core.prompts.chat import ChatPromptTemplate
@@ -49,7 +52,7 @@
)
# nltk downloader
-nltk.download("averaged_perceptron_tagger")
+# nltk.download("averaged_perceptron_tagger")
# prestage the embedding model
_ = get_embedding_model()
@@ -66,6 +69,7 @@ class QAChatbot(BaseExample):
def ingest_docs(self, filepath: str, filename: str):
"""Ingest documents to the VectorDB."""
try:
+ Settings.callback_manager = CallbackManager([llama_index_cb_handler])
logger.info(f"Ingesting {filename} in vectorDB")
_, ext = os.path.splitext(filename)
@@ -116,36 +120,23 @@ def llm_chain(
logger.info("Using llm to generate response directly without knowledge base.")
set_service_context(**kwargs)
# TODO Include chat_history
- prompt = get_config().prompts.chat_template.format(
- context_str="", query_str=query
- )
+ prompt = get_config().prompts.chat_template
logger.info(f"Prompt used for response generation: {prompt}")
- # stream_complete is returning empty response with NIM
- # TODO: Use llama_index llm wrapper to stream response
- if get_config().llm.model_engine == "triton-trt-llm":
- llm = LangChainLLM(get_llm(**kwargs))
- response = llm.stream_complete(
- prompt,
- tokens=kwargs.get("max_tokens", None),
- callbacks=[self.cb_handler],
- )
- gen_response = (resp.delta for resp in response)
- return gen_response
- else:
- # This is for get_config().llm.model_engine == "nvidia-ai-endpoints-nim"
- user_input = [("user", get_config().prompts.chat_template)]
+ system_message = [("system", prompt)]
+ user_input = [("user", "{query_str}")]
- prompt_template = ChatPromptTemplate.from_messages(user_input)
+ prompt_template = ChatPromptTemplate.from_messages(
+ system_message + user_input
+ )
- llm = get_llm(**kwargs)
+ llm = get_llm(**kwargs)
- chain = prompt_template | llm | StrOutputParser()
- augmented_user_input = "\n\nQuestion: " + query + "\n"
- return chain.stream(
- {"context_str": "", "query_str": query},
- config={"callbacks": [self.cb_handler]},
- )
+ chain = prompt_template | llm | StrOutputParser()
+ return chain.stream(
+ {"query_str": query},
+ config={"callbacks": [self.cb_handler]},
+ )
def rag_chain(
self, query: str, chat_history: List["Message"], **kwargs
@@ -159,7 +150,7 @@ def rag_chain(
retriever = get_doc_retriever(num_nodes=get_config().retriever.top_k)
qa_template = Prompt(get_config().prompts.rag_template)
- logger.info(f"Prompt used for response generation: {qa_template}")
+ logger.info(f"Prompt template used for response generation: {qa_template}")
# Handling Retrieval failure
nodes = retriever.retrieve(query)
diff --git a/RetrievalAugmentedGeneration/examples/multi_turn_rag/chains.py b/RetrievalAugmentedGeneration/examples/multi_turn_rag/chains.py
index 3024d0acc..6dd8ad5fe 100644
--- a/RetrievalAugmentedGeneration/examples/multi_turn_rag/chains.py
+++ b/RetrievalAugmentedGeneration/examples/multi_turn_rag/chains.py
@@ -42,7 +42,6 @@
from RetrievalAugmentedGeneration.common.tracing import langchain_instrumentation_class_wrapper
from operator import itemgetter
-DOCS_DIR = os.path.abspath("./uploaded_files")
document_embedder = get_embedding_model()
text_splitter = None
settings = get_config()
@@ -74,8 +73,7 @@ def ingest_docs(self, filepath: str, filename: str):
raise ValueError(f"{filename} is not a valid Text, PDF or Markdown file")
try:
# Load raw documents from the directory
- # Data is copied to `DOCS_DIR` in common.server:upload_document
- _path = os.path.join(DOCS_DIR, filename)
+ _path = filepath
raw_documents = UnstructuredFileLoader(_path).load()
if raw_documents:
@@ -103,23 +101,25 @@ def llm_chain(
# WAR: Disable chat history (UI consistency).
chat_history = []
conversation_history = [(msg.role, msg.content) for msg in chat_history]
- user_message = [("user", settings.prompts.chat_template)]
+ system_message = [("system", settings.prompts.chat_template)]
+ user_message = [("user", "{query_str}")]
# TODO: Enable this block once conversation history is enabled for llm chain
# Checking if conversation_history is not None and not empty
# prompt_template = ChatPromptTemplate.from_messages(
- # conversation_history + user_message
+ # system_message + conversation_history + user_message
# ) if conversation_history else ChatPromptTemplate.from_messages(
- # user_message
+ # system_message + user_message
# )
prompt_template = ChatPromptTemplate.from_messages(
- user_message
+ system_message + user_message
)
llm = get_llm(**kwargs)
chain = prompt_template | llm | StrOutputParser()
- return chain.stream({"context_str": "", "query_str": query}, config={"callbacks":[self.cb_handler]})
+ logger.info(f"Prompt used for response generation: {prompt_template.format(query_str=query)}")
+ return chain.stream({"query_str": query}, config={"callbacks":[self.cb_handler]})
def rag_chain(self, query: str, chat_history: List["Message"], **kwargs) -> Generator[str, None, None]:
"""Execute a Retrieval Augmented Generation chain using the components defined above."""
@@ -132,7 +132,7 @@ def rag_chain(self, query: str, chat_history: List["Message"], **kwargs) -> Gene
# ("user", "{input}"),
# ]
# )
-
+
# This is a workaround Prompt Template
chat_prompt = ChatPromptTemplate.from_messages(
[
@@ -171,7 +171,9 @@ def rag_chain(self, query: str, chat_history: List["Message"], **kwargs) -> Gene
if not docs:
logger.warning("Retrieval failed to get any relevant context")
return iter(["No response generated from LLM, make sure your query is relavent to the ingested document."])
-
+
+ logger.debug(f"Retrieved docs are: {docs}")
+
chain = retrieval_chain | stream_chain
for chunk in chain.stream({"input": query}, config={"callbacks":[self.cb_handler]}):
@@ -204,6 +206,7 @@ def rag_chain(self, query: str, chat_history: List["Message"], **kwargs) -> Gene
logger.warning("Retrieval failed to get any relevant context")
return iter(["No response generated from LLM, make sure your query is relavent to the ingested document."])
+ logger.debug(f"Retrieved documents are: {docs}")
chain = retrieval_chain | stream_chain
for chunk in chain.stream({"input": query}, config={"callbacks":[self.cb_handler]}):
yield chunk
diff --git a/RetrievalAugmentedGeneration/examples/multimodal_rag/chains.py b/RetrievalAugmentedGeneration/examples/multimodal_rag/chains.py
index fbadbf690..bcd686989 100644
--- a/RetrievalAugmentedGeneration/examples/multimodal_rag/chains.py
+++ b/RetrievalAugmentedGeneration/examples/multimodal_rag/chains.py
@@ -18,6 +18,7 @@
from typing import Generator, List, Dict, Any
from functools import lru_cache
from traceback import print_exc
+from langchain_community.document_loaders import UnstructuredFileLoader
from RetrievalAugmentedGeneration.common.utils import utils_cache
@@ -25,34 +26,29 @@
from RetrievalAugmentedGeneration.common.base import BaseExample
from RetrievalAugmentedGeneration.example.llm.llm_client import LLMClient
-from RetrievalAugmentedGeneration.example.retriever.embedder import NVIDIAEmbedders
-from RetrievalAugmentedGeneration.example.retriever.vector import MilvusVectorClient
-from RetrievalAugmentedGeneration.example.retriever.retriever import Retriever
from RetrievalAugmentedGeneration.example.vectorstore.vectorstore_updater import update_vectorstore
-from RetrievalAugmentedGeneration.common.utils import get_config
+from RetrievalAugmentedGeneration.common.utils import (
+ get_config,
+ create_vectorstore_langchain,
+ get_embedding_model,
+ get_text_splitter,
+ get_docs_vectorstore_langchain,
+ del_docs_vectorstore_langchain,
+ get_vectorstore
+)
from RetrievalAugmentedGeneration.common.tracing import langchain_instrumentation_class_wrapper
+document_embedder = get_embedding_model()
+text_splitter = None
settings = get_config()
sources = []
RESPONSE_PARAPHRASING_MODEL = settings.llm.model_name
-@lru_cache
-def get_vector_index(embed_dim: int = 1024) -> MilvusVectorClient:
- return MilvusVectorClient(hostname="milvus", port="19530", collection_name=os.getenv('COLLECTION_NAME', "vector_db"), embedding_size=embed_dim)
-
-@lru_cache
-def get_embedder(type: str = "query") -> NVIDIAEmbedders:
- if type == "query":
- embedder = NVIDIAEmbedders(name=settings.embeddings.model_name, type="query")
- else:
- embedder = NVIDIAEmbedders(name=settings.embeddings.model_name, type="passage")
- return embedder
-
-@lru_cache
-def get_doc_retriever(type: str = "query") -> Retriever:
- embedder = get_embedder(type)
- embedding_size = embedder.get_embedding_size()
- return Retriever(embedder=get_embedder(type) , vector_client=get_vector_index(embedding_size))
+try:
+ docstore = create_vectorstore_langchain(document_embedder=document_embedder)
+except Exception as e:
+ docstore = None
+ logger.info(f"Unable to connect to vector store during initialization: {e}")
@utils_cache
@lru_cache()
@@ -66,17 +62,18 @@ class MultimodalRAG(BaseExample):
def ingest_docs(self, filepath: str, filename: str):
"""Ingest documents to the VectorDB."""
- if not filename.endswith(".pdf"):
- raise ValueError(f"{filename} is not a valid PDF file. Only PDF files are supported for multimodal rag. The PDF files can contain multimodal data.")
+ if not filename.endswith((".pdf",".pptx")):
+ raise ValueError(f"{filename} is not a valid PDF/PPTX file. Only PDF/PPTX files are supported for multimodal rag. The PDF/PPTX files can contain multimodal data.")
try:
- embedder = get_embedder(type="passage")
- embedding_size = embedder.get_embedding_size()
- update_vectorstore(os.path.abspath(filepath), get_vector_index(embedding_size), embedder, os.getenv('COLLECTION_NAME', "vector_db"))
+ _path = filepath
+ ds = get_vectorstore(docstore, document_embedder)
+ update_vectorstore(_path,ds,document_embedder,os.getenv('COLLECTION_NAME', "vector_db"))
except Exception as e:
logger.error(f"Failed to ingest document due to exception {e}")
- print_exc()
- raise ValueError("Failed to upload document. Please check chain server logs for details.")
+ raise ValueError(
+ "Failed to upload document. Please upload an unstructured text document."
+ )
def llm_chain(
@@ -95,18 +92,35 @@ def rag_chain(self, query: str, chat_history: List["Message"], **kwargs) -> Gene
logger.info("Using rag to generate response from document")
# TODO integrate chat_history
try:
- retriever = get_doc_retriever(type="query")
- context, sources = retriever.get_relevant_docs(query, limit=settings.retriever.top_k)
- if not context:
- logger.warning("Retrieval failed to get any relevant context")
- return iter(["No response generated from LLM, make sure your query is relavent to the ingested document."])
-
- augmented_prompt = "Relevant documents:" + context + "\n\n[[QUESTION]]\n\n" + query
- system_prompt = settings.prompts.rag_template
- logger.info(f"Formulated prompt for RAG chain: {system_prompt}\n{augmented_prompt}")
- response = get_llm(model_name=RESPONSE_PARAPHRASING_MODEL, cb_handler=self.cb_handler, is_response_generator=True, **kwargs).chat_with_prompt(settings.prompts.rag_template, augmented_prompt)
- return response
-
+ ds = get_vectorstore(docstore, document_embedder)
+ if ds:
+ try:
+ logger.info(f"Getting retrieved top k values: {settings.retriever.top_k} with confidence threshold: {settings.retriever.score_threshold}")
+ retriever = ds.as_retriever(search_type="similarity_score_threshold",search_kwargs={"score_threshold": settings.retriever.score_threshold,"k": settings.retriever.top_k})
+ docs = retriever.invoke(input=query, config={"callbacks":[self.cb_handler]})
+ if not docs:
+ logger.warning("Retrieval failed to get any relevant context")
+ return iter(["No response generated from LLM, make sure your query is relavent to the ingested document."])
+
+ augmented_prompt = "Relevant documents:" + docs + "\n\n[[QUESTION]]\n\n" + query
+ system_prompt = settings.prompts.rag_template
+ logger.info(f"Formulated prompt for RAG chain: {system_prompt}\n{augmented_prompt}")
+ response = get_llm(model_name=RESPONSE_PARAPHRASING_MODEL, cb_handler=self.cb_handler, is_response_generator=True, **kwargs).chat_with_prompt(settings.prompts.rag_template, augmented_prompt)
+ return response
+ except Exception as e:
+ logger.info(f"Skipping similarity score as it's not supported by retriever")
+ retriever = ds.as_retriever()
+ docs = retriever.invoke(input=query, config={"callbacks":[self.cb_handler]})
+ if not docs:
+ logger.warning("Retrieval failed to get any relevant context")
+ return iter(["No response generated from LLM, make sure your query is relavent to the ingested document."])
+ docs=[doc.page_content for doc in docs]
+ docs = " ".join(docs)
+ augmented_prompt = "Relevant documents:" + docs + "\n\n[[QUESTION]]\n\n" + query
+ system_prompt = settings.prompts.rag_template
+ logger.info(f"Formulated prompt for RAG chain: {system_prompt}\n{augmented_prompt}")
+ response = get_llm(model_name=RESPONSE_PARAPHRASING_MODEL, cb_handler=self.cb_handler, is_response_generator=True, **kwargs).chat_with_prompt(settings.prompts.rag_template, augmented_prompt)
+ return response
except Exception as e:
logger.warning(f"Failed to generate response due to exception {e}")
logger.warning(
@@ -122,11 +136,12 @@ def document_search(self, content: str, num_docs: int) -> List[Dict[str, Any]]:
"""Search for the most relevant documents for the given search parameters."""
try:
- retriever = get_doc_retriever(type="query")
- context, sources = retriever.get_relevant_docs(content, limit=settings.retriever.top_k)
+ ds = get_vectorstore(docstore, document_embedder)
+ retriever = ds.as_retriever()
+ sources = retriever.invoke(input=content, limit=settings.retriever.top_k, config={"callbacks":[self.cb_handler]})
output = []
- for every_chunk in sources.values():
- entry = {"source": every_chunk['doc_metadata']['filename'], "content": every_chunk['doc_content']}
+ for every_chunk in sources:
+ entry = {"source": every_chunk.metadata['filename'], "content": every_chunk.page_content}
output.append(entry)
return output
except Exception as e:
@@ -135,14 +150,19 @@ def document_search(self, content: str, num_docs: int) -> List[Dict[str, Any]]:
def get_documents(self):
"""Retrieves filenames stored in the vector store."""
- embedding_size = get_embedder(type="passage").get_embedding_size()
- vector_db = get_vector_index(embedding_size)
- decoded_filenames = vector_db.list_filenames()
- return decoded_filenames
+ try:
+ ds = get_vectorstore(docstore, document_embedder)
+ if ds:
+ return get_docs_vectorstore_langchain(ds)
+ except Exception as e:
+ logger.error(f"Vectorstore not initialized. Error details: {e}")
+ return []
def delete_documents(self, filenames: List[str]):
"""Delete documents from the vector index."""
- embedding_size = get_embedder(type="passage").get_embedding_size()
- vector_db = get_vector_index(embedding_size)
- for each_file in filenames:
- vector_db.delete_by_filename(each_file)
\ No newline at end of file
+ try:
+ ds = get_vectorstore(docstore, document_embedder)
+ if ds:
+ return del_docs_vectorstore_langchain(ds, filenames)
+ except Exception as e:
+ logger.error(f"Vectorstore not initialized. Error details: {e}")
diff --git a/RetrievalAugmentedGeneration/examples/multimodal_rag/llm/llm_client.py b/RetrievalAugmentedGeneration/examples/multimodal_rag/llm/llm_client.py
index 559641407..14997d0f2 100644
--- a/RetrievalAugmentedGeneration/examples/multimodal_rag/llm/llm_client.py
+++ b/RetrievalAugmentedGeneration/examples/multimodal_rag/llm/llm_client.py
@@ -13,6 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import logging
+logger = logging.getLogger(__name__)
+
from RetrievalAugmentedGeneration.example.llm.llm import create_llm
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
@@ -23,10 +26,11 @@ class LLMClient:
def __init__(self, model_name="mixtral_8x7b", model_type="NVIDIA", is_response_generator=False, cb_handler=BaseCallbackHandler, **kwargs):
self.llm = create_llm(model_name, model_type, is_response_generator, **kwargs)
self.cb_handler = cb_handler
-
+
def chat_with_prompt(self, system_prompt, prompt):
langchain_prompt = ChatPromptTemplate.from_messages([("system", system_prompt), ("user", "{input}")])
chain = langchain_prompt | self.llm | StrOutputParser()
+ logger.info(f"Prompt used for response generation: {langchain_prompt.format(input=prompt)}")
response = chain.stream({"input": prompt}, config={"callbacks": [self.cb_handler]})
return response
diff --git a/RetrievalAugmentedGeneration/examples/multimodal_rag/requirements.txt b/RetrievalAugmentedGeneration/examples/multimodal_rag/requirements.txt
index 0f43b859c..f1d7a09f7 100644
--- a/RetrievalAugmentedGeneration/examples/multimodal_rag/requirements.txt
+++ b/RetrievalAugmentedGeneration/examples/multimodal_rag/requirements.txt
@@ -1,8 +1,10 @@
-pymupdf==1.23.15
+pdfplumber==0.11.0
gspread==6.0.0
pandas==2.2.0
Pillow==10.2.0
pydantic==2.5.3
pymilvus==2.3.5
-python_pptx==0.6.23
-Requests==2.31.0
\ No newline at end of file
+python-pptx==0.6.23
+Requests==2.31.0
+opencv-python== 4.9.0.80
+pytesseract==0.3.10
\ No newline at end of file
diff --git a/RetrievalAugmentedGeneration/examples/multimodal_rag/retriever/vector.py b/RetrievalAugmentedGeneration/examples/multimodal_rag/retriever/vector.py
index aab9683d2..a8af767ec 100644
--- a/RetrievalAugmentedGeneration/examples/multimodal_rag/retriever/vector.py
+++ b/RetrievalAugmentedGeneration/examples/multimodal_rag/retriever/vector.py
@@ -155,7 +155,7 @@ def list_filenames(self):
List all filenames in the collection.
"""
# Assuming 'filename' is a field in the metadata
-
+
expr = "metadata['filename'] != ''" # Expression to match all entities with a non-empty filename
entities = self.vector_db.query(expr, output_fields=["metadata"])
filenames = list(set([entity['metadata']['filename'] for entity in entities]))
@@ -169,4 +169,4 @@ def delete_by_filename(self, filename):
expr = f"metadata['filename'] == '{filename}'"
self.vector_db.delete(expr)
# Load the collection to make the deletion take effect
- self.vector_db.load()
+ self.vector_db.load()
diff --git a/RetrievalAugmentedGeneration/examples/multimodal_rag/vectorstore/custom_pdf_parser.py b/RetrievalAugmentedGeneration/examples/multimodal_rag/vectorstore/custom_pdf_parser.py
index c54753764..cec1b40fb 100644
--- a/RetrievalAugmentedGeneration/examples/multimodal_rag/vectorstore/custom_pdf_parser.py
+++ b/RetrievalAugmentedGeneration/examples/multimodal_rag/vectorstore/custom_pdf_parser.py
@@ -13,7 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import fitz
+from pdfplumber import open as pdf_open
import pandas as pd
import os
from langchain.docstore.document import Document
@@ -22,6 +22,8 @@
from PIL import Image
from io import BytesIO
import base64
+import cv2
+import pytesseract
from RetrievalAugmentedGeneration.common.tracing import langchain_instrumentation_method_wrapper
def get_b64_image(image_path):
@@ -31,6 +33,12 @@ def get_b64_image(image_path):
b64_string = base64.b64encode(buffered.getvalue()).decode("utf-8")
return b64_string
+def is_bbox_overlapping(bbox1, bbox2):
+ return (bbox1[0]bbox2[0] and bbox1[1]>bbox2[3] and bbox1[3]bbox2[0] and bbox1[1]>bbox2[3] and bbox1[3]= -horizontal_threshold_distance:
- if block_bbox.y1 < bbox.y0 and not before_text:
- before_text = block[4]
- elif block_bbox.y0 > bbox.y1 and not after_text:
- after_text = block[4]
+ if block['y1'] < bbox[1] and not before_text:
+ before_text = block['text']
+ elif block['y0'] > bbox[2] and not after_text:
+ after_text = block['text']
break
return before_text, after_text
-
def process_text_blocks(text_blocks):
char_count_threshold = 500 # Threshold for the number of characters in a group
current_group = []
grouped_blocks = []
current_char_count = 0
-
for block in text_blocks:
- if block[-1] == 0: # Check if the block is of text type
- block_text = block[4]
+ if block['object_type'] in ('char','str'): # Check if the block is of text type
+ block_text = block['text']
block_char_count = len(block_text)
if current_char_count + block_char_count <= char_count_threshold:
@@ -101,170 +127,195 @@ def process_text_blocks(text_blocks):
current_char_count += block_char_count
else:
if current_group:
- grouped_content = "\n".join([b[4] for b in current_group])
+ grouped_content = " ".join([b['text'] for b in current_group])
grouped_blocks.append((current_group[0], grouped_content))
current_group = [block]
current_char_count = block_char_count
# Append the last group
if current_group:
- grouped_content = "\n".join([b[4] for b in current_group])
+ grouped_content = "".join([b['text'] for b in current_group])
grouped_blocks.append((current_group[0], grouped_content))
return grouped_blocks
+def parse_via_ocr(filename, page, pagenum):
+ ocr_docs = []
+ ocr_image = page.to_image(resolution=109)
+ imgrefpath = os.path.join("/tmp-data", "multimodal/ocr_references")
+ if not os.path.exists(imgrefpath):
+ os.makedirs(imgrefpath)
+ image_path = os.path.join(imgrefpath, f"page{pagenum}.png")
+ ocr_image.save(image_path)
+ img = cv2.imread(image_path)
+ ocr_text = pytesseract.image_to_string(img)
+ ocr_metadata = {
+ "x1":0,
+ "y1":0,
+ "x2":0,
+ "x3":0,
+ "source": f"{os.path.basename(filename)}",
+ "image": image_path,
+ "caption": ocr_text,
+ "type": "image",
+ "page_num": pagenum
+ }
+
+ ocr_docs.append(Document(page_content="This is a page with text: " + ocr_text, metadata=ocr_metadata))
+ return ocr_docs
+
def parse_all_tables(filename, page, pagenum, text_blocks, ongoing_tables):
table_docs = []
table_bboxes = []
ctr = 1
- try:
- tables = page.find_tables(horizontal_strategy = "lines_strict", vertical_strategy = "lines_strict")
+ try:
+ tables = page.find_tables(table_settings={"horizontal_strategy":"lines_strict", "vertical_strategy":"lines_strict"})
except Exception as e:
print(f"Error during table extraction: {e}")
return table_docs, table_bboxes, ongoing_tables
if tables:
- for tab in tables:
- if tab.header.external:
- # Check if this table is a continuation of a table from a previous page
- previous_table = ongoing_tables.get(pagenum - 1, None)
- if previous_table:
- # Merge the current table with the previous part
- combined_df = pd.concat([previous_table['dataframe'], tab.to_pandas()])
- ongoing_tables[pagenum] = {"dataframe": combined_df, "bbox": bbox}
- continue
- if not tab.header.external:
- pandas_df = tab.to_pandas()
- tablerefdir = os.path.join(os.getcwd(), "multimodal/table_references")
- if not os.path.exists(tablerefdir):
- os.makedirs(tablerefdir)
- df_xlsx_path = os.path.join(tablerefdir, f"table{ctr}-page{pagenum}.xlsx")
- pandas_df.to_excel(df_xlsx_path)
- bbox = fitz.Rect(tab.bbox)
- table_bboxes.append(bbox)
-
- # Find text around the table
- before_text, after_text = extract_text_around_item(text_blocks, bbox, page.rect.height)
-
- table_img = page.get_pixmap(clip=bbox)
- table_img_path = os.path.join(tablerefdir, f"table{ctr}-page{pagenum}.jpg")
- table_img.save(table_img_path)
- description = process_graph(table_img_path)
- ctr += 1
-
- caption = before_text.replace("\n", " ") + description + after_text.replace("\n", " ")
- if before_text == "" and after_text == "":
- caption = " ".join(tab.header.names)
-
-
- table_metadata = {
- "source": f"{filename[:-4]}-page{pagenum}-table{ctr}",
- "dataframe": df_xlsx_path,
- "image": table_img_path,
- "caption": caption,
- "type": "table",
- "page_num": pagenum
- }
- all_cols = ", ".join(list(pandas_df.columns.values))
- doc = Document(page_content="This is a table with the caption: " + caption + f"\nThe columns are {all_cols}", metadata=table_metadata)
- table_docs.append(doc)
+ for table_num, table in enumerate(tables, start=1):
+ try:
+ tablerefdir = os.path.join("/tmp-data", "vectorstore/table_references")
+ if not os.path.exists(tablerefdir):
+ os.makedirs(tablerefdir)
+ df_xlsx_path = os.path.join(tablerefdir, f"table{table_num}-page{pagenum}.xlsx")
+ page_crop=page.crop(table.bbox)
+ if len(page_crop.extract_tables())>0:
+ table_df_text = page_crop.extract_tables()[0]
+ table_df = text_to_table(table_df_text)
+ table_df.to_excel(df_xlsx_path)
+ # Find text around the table
+ table_bbox = table.bbox
+ before_text, after_text = extract_text_around_item(text_blocks, table_bbox, page.height)
+ # Save table image
+ table_img_path = os.path.join(tablerefdir, f"table{table_num}-page{pagenum}.jpg")
+ img = page_crop.to_image(resolution=109)
+ img.save(table_img_path)
+ description = process_graph(table_img_path)
+ ctr +=1
+ caption = before_text.replace("\n", " ") + description + after_text.replace("\n", " ")
+ if before_text == "" and after_text == "":
+ caption = " ".join(table_df.columns)
+ table_data_text = stringify_table(table_df_text)
+ table_metadata = {
+ "x1":0,
+ "y1":0,
+ "x2":0,
+ "x3":0,
+ "source": f"{os.path.basename(filename)}",
+ "dataframe": df_xlsx_path,
+ "image": table_img_path,
+ "caption": caption,
+ "type": "table",
+ "page_num": pagenum + 1
+ }
+ all_cols = ", ".join(list(table_df.columns.values))
+ doc = Document(page_content="This is a table with the caption: " + caption + f"\nThe columns are {all_cols} and the table data is {table_data_text}", metadata=table_metadata)
+ table_docs.append(doc)
+ except:
+ print(f"Skipping Table {table_num} due to Exception {e}")
return table_docs, table_bboxes, ongoing_tables
def parse_all_images(filename, page, pagenum, text_blocks):
image_docs = []
- image_info_list = page.get_image_info(xrefs=True)
- page_rect = page.rect # Get the dimensions of the page
-
- for image_info in image_info_list:
- xref = image_info['xref']
- if xref == 0:
- continue # Skip inline images or undetectable images
-
- img_bbox = fitz.Rect(image_info['bbox'])
- # Check if the image size is at least 5% of the page size in any dimension
- if img_bbox.width < page_rect.width / 20 or img_bbox.height < page_rect.height / 20:
- continue # Skip very small images
+ image_list = page.images
+ # image_info_list = page.get_image_info(xrefs=True)
+ # page_rect = page.rect # Get the dimensions of the page
+
+ for image_num, image in enumerate(image_list):
+ # xref = image_info['xref']
+ # if xref == 0:
+ # continue # Skip inline images or undetectable images
+ image_bbox = (image['x0'],image['y0'], image['x1'],image['y1'])
+ # Check if the image size is at least 5% of the page size in any dimension
+ if image["width"] < page.width / 20 or image["height"] < page.height / 20:
+ continue # Skip very small images
+
+ # Extract and save the image
+ page_crop = page.crop(image_bbox,strict=False)
+ image_data = page_crop.to_image()
+ imgrefpath = os.path.join("/tmp-data", "multimodal/image_references")
+ if not os.path.exists(imgrefpath):
+ os.makedirs(imgrefpath)
+ image_path = os.path.join(imgrefpath, f"image{image_num}-page{pagenum}.png")
+ image_data.save(image_path)
+ # Find text around the image
+ before_text, after_text = extract_text_around_item(text_blocks, image_bbox, page.height)
+ # skip images without a caption, they are likely just some logo or graphics
+ if before_text == "" and after_text == "":
+ continue
- # Extract and save the image
- extracted_image = page.parent.extract_image(xref)
- image_data = extracted_image["image"]
- imgrefpath = os.path.join(os.getcwd(), "multimodal/image_references")
- if not os.path.exists(imgrefpath):
- os.makedirs(imgrefpath)
- image_path = os.path.join(imgrefpath, f"image{xref}-page{pagenum}.png")
- with open(image_path, "wb") as img_file:
- img_file.write(image_data)
+ # Process the image if it's a graph
+ image_description = " "
+ if is_graph(image_path):
+ image_description = process_graph(image_path)
- # Find text around the image
- before_text, after_text = extract_text_around_item(text_blocks, img_bbox, page.rect.height)
- # skip images without a caption, they are likely just some logo or graphics
- if before_text == "" and after_text == "":
- continue
+ # Combine the texts to form a caption
+ caption = before_text.replace("\n", " ") + image_description + after_text.replace("\n", " ")
- # Process the image if it's a graph
- image_description = " "
- if is_graph(image_path):
- image_description = process_graph(image_path)
+ image_metadata = {
+ "x1":0,
+ "y1":0,
+ "x2":0,
+ "x3":0,
+ "source": f"{os.path.basename(filename)}",
+ "image": image_path,
+ "caption": caption,
+ "type": "image",
+ "page_num": pagenum
+ }
- # Combine the texts to form a caption
- caption = before_text.replace("\n", " ") + image_description + after_text.replace("\n", " ")
+ image_docs.append(Document(page_content="This is an image with the caption: " + caption, metadata=image_metadata))
- image_metadata = {
- "source": f"{filename[:-4]}-page{pagenum}-image{xref}",
- "image": image_path,
- "caption": caption,
- "type": "image",
- "page_num": pagenum
- }
- image_docs.append(Document(page_content="This is an image with the caption: " + caption, metadata=image_metadata))
return image_docs
def get_pdf_documents(filepath):
all_pdf_documents = []
ongoing_tables = {}
try:
- f = fitz.open(filepath)
+ f = pdf_open(filepath)
except Exception as e:
print(f"Error opening or processing the PDF file: {e}")
return []
-
- for i in range(len(f)):
- page = f[i]
- page_docs = []
-
- # Process text blocks
- initial_text_blocks = page.get_text("blocks", sort=True)
-
- # Define thresholds for header and footer (10% of the page height)
- page_height = page.rect.height
- header_threshold = page_height * 0.1
- footer_threshold = page_height * 0.9
-
- # Filter out text blocks that are likely headers or footers
- text_blocks = [block for block in initial_text_blocks if block[-1] == 0 and not (block[1] < header_threshold or block[3] > footer_threshold)]
-
- # Group text blocks by character count
- grouped_text_blocks = process_text_blocks(text_blocks)
-
- # Extract tables and their bounding boxes
- table_docs, table_bboxes, ongoing_tables = parse_all_tables(filepath, page, i, text_blocks, ongoing_tables)
- page_docs.extend(table_docs)
-
- # Extract and process images
- image_docs = parse_all_images(filepath, page, i, text_blocks)
- page_docs.extend(image_docs)
-
- # Process grouped text blocks
- text_block_ctr = 0
- for heading_block, content in grouped_text_blocks:
- text_block_ctr +=1
- heading_bbox = fitz.Rect(heading_block[:4])
- # Check if the heading or its content overlaps with table or image bounding boxes
- if not any(heading_bbox.intersects(table_bbox) for table_bbox in table_bboxes):
- bbox = {"x1": heading_block[0], "y1": heading_block[1], "x2": heading_block[2], "x3": heading_block[3]}
- text_doc = Document(page_content=f"{heading_block[4]}\n{content}", metadata={**bbox, "type": "text", "page_num": i, "source": f"{filepath[:-4]}-page{i}-block{text_block_ctr}"})
- page_docs.append(text_doc)
-
- all_pdf_documents.append(page_docs)
-
+ for page_num, page in enumerate(f.pages):
+ try:
+ page_docs = []
+
+ # Define thresholds for header and footer (10% of the page height)
+ page_height = page.height
+ header_threshold = page_height * 0.1
+ footer_threshold = page_height * 0.9
+
+ # Crop out page to remove footers and headers
+ page_crop = page.crop([0,header_threshold,page.width,footer_threshold])
+ text_blocks = [obj for obj in page_crop.chars if obj['object_type'] == 'char']
+ grouped_text_blocks = process_text_blocks(text_blocks)
+
+ if len(grouped_text_blocks)==0:
+ # Perform OCR on PDF pages
+ ocr_docs = parse_via_ocr(filepath, page_crop, page_num)
+ page_docs.extend(ocr_docs)
+ # Extract tables and their bounding boxes
+ table_docs, table_bboxes, ongoing_tables = parse_all_tables(filepath, page, page_num, text_blocks, ongoing_tables)
+ page_docs.extend(table_docs)
+
+ # Extract and process images
+ image_docs = parse_all_images(filepath, page, page_num, text_blocks)
+ page_docs.extend(image_docs)
+
+ # Process text blocks
+ text_block_ctr = 0
+ for heading_block, content in grouped_text_blocks:
+ text_block_ctr +=1
+ heading_bbox = (heading_block['x0'],heading_block['y0'],heading_block['x1'],heading_block['y1'])
+ # Check if the heading or its content overlaps with table or image bounding boxes
+ if not any(is_bbox_overlapping(heading_bbox,table_bbox) for table_bbox in table_bboxes):
+ bbox = {"x1": heading_bbox[0], "y1": heading_bbox[1], "x2": heading_bbox[2], "x3": heading_bbox[3]}
+ text_doc = Document(page_content=f"{heading_block['text']}\n{content}", metadata={**bbox, "type": "text", "page_num": page_num, "source": f"{os.path.basename(filepath)}"})
+ page_docs.append(text_doc)
+ all_pdf_documents.append(page_docs)
+ except Exception as e:
+ print(f"Skipping the page {page_num} due to Exception {e}")
f.close()
return all_pdf_documents
diff --git a/RetrievalAugmentedGeneration/examples/multimodal_rag/vectorstore/custom_powerpoint_parser.py b/RetrievalAugmentedGeneration/examples/multimodal_rag/vectorstore/custom_powerpoint_parser.py
index d5531a369..791a7d5dc 100644
--- a/RetrievalAugmentedGeneration/examples/multimodal_rag/vectorstore/custom_powerpoint_parser.py
+++ b/RetrievalAugmentedGeneration/examples/multimodal_rag/vectorstore/custom_powerpoint_parser.py
@@ -16,7 +16,7 @@
import os
import subprocess
from pptx import Presentation
-import fitz
+from pdfplumber import open as pdf_open
from langchain.docstore.document import Document
from RetrievalAugmentedGeneration.example.vectorstore.custom_pdf_parser import is_graph, process_graph
@@ -24,7 +24,7 @@
def convert_ppt_to_pdf(ppt_path):
"""Convert a PowerPoint file to PDF using LibreOffice and save in '../../ppt_references/' folder."""
base_name = os.path.basename(ppt_path)
- ppt_name_without_ext = os.path.splitext(base_name)[0].replace(' ', '_')
+ ppt_name_without_ext = os.path.splitext(base_name)[0].replace(" ", "_")
# Use the existing directory '../../ppt_references/'
new_dir_path = os.path.abspath("multimodal/ppt_references")
@@ -38,22 +38,22 @@ def convert_ppt_to_pdf(ppt_path):
return pdf_path
+
def convert_pdf_to_images(pdf_path):
"""Convert a PDF file to a series of images using PyMuPDF and save in '../../ppt_references/' folder."""
- doc = fitz.open(pdf_path)
+ doc = pdf_open(pdf_path)
# Extract the base name of the PDF file and replace spaces with underscores
base_name = os.path.basename(pdf_path)
- pdf_name_without_ext = os.path.splitext(base_name)[0].replace(' ', '_')
+ pdf_name_without_ext = os.path.splitext(base_name)[0].replace(" ", "_")
# Use the existing directory '../../ppt_references/'
new_dir_path = os.path.join(os.getcwd(), "multimodal/ppt_references")
image_paths = []
- for page_num in range(len(doc)):
- page = doc.load_page(page_num)
- pix = page.get_pixmap()
+ for page_num, page in enumerate(doc.pages):
+ pix = page.to_image()
# Save images in the existing directory
output_image_path = os.path.join(new_dir_path, f"{pdf_name_without_ext}_{page_num:04d}.png")
@@ -63,6 +63,7 @@ def convert_pdf_to_images(pdf_path):
doc.close()
return image_paths
+
def extract_text_and_notes_from_ppt(ppt_path):
"""Extract text and notes from a PowerPoint file."""
prs = Presentation(ppt_path)
@@ -70,12 +71,13 @@ def extract_text_and_notes_from_ppt(ppt_path):
for slide in prs.slides:
slide_text = ' '.join([shape.text for shape in slide.shapes if hasattr(shape, "text")])
try:
- notes = slide.notes_slide.notes_text_frame.text if slide.notes_slide else ''
+ notes = slide.notes_slide.notes_text_frame.text if slide.notes_slide else ""
except:
- notes = ''
+ notes = ""
text_and_notes.append((slide_text, notes))
return text_and_notes
+
def process_ppt_file(ppt_path):
"""Process a PowerPoint file."""
pdf_path = os.path.join(os.getcwd(), "multimodal/ppt_references", os.path.basename(ppt_path).replace('.pptx', '.pdf').replace('.ppt', '.pdf'))
@@ -92,14 +94,18 @@ def process_ppt_file(ppt_path):
image_description = " "
if is_graph(image_path):
image_description = process_graph(image_path)
-
+ caption = slide_text + image_description + notes
image_metadata = {
- "source": f"{os.path.basename(ppt_path)}",
- "image": image_path,
- "caption": slide_text + image_description + notes,
- "type": "image",
- "page_num": page_num
+ "x1":0,
+ "y1":0,
+ "x2":0,
+ "x3":0,
+ "source": f"{os.path.basename(ppt_path)}",
+ "image": image_path,
+ "caption": caption,
+ "type": "image",
+ "page_num": page_num
}
processed_data.append(Document(page_content = "This is a slide with the text: " + slide_text + image_description, metadata = image_metadata))
- return processed_data
+ return processed_data
\ No newline at end of file
diff --git a/RetrievalAugmentedGeneration/examples/multimodal_rag/vectorstore/vectorstore_updater.py b/RetrievalAugmentedGeneration/examples/multimodal_rag/vectorstore/vectorstore_updater.py
index 1297761a0..9e833db4d 100644
--- a/RetrievalAugmentedGeneration/examples/multimodal_rag/vectorstore/vectorstore_updater.py
+++ b/RetrievalAugmentedGeneration/examples/multimodal_rag/vectorstore/vectorstore_updater.py
@@ -17,7 +17,6 @@
import os
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import UnstructuredFileLoader
-
from RetrievalAugmentedGeneration.example.vectorstore.custom_powerpoint_parser import process_ppt_file
from RetrievalAugmentedGeneration.example.vectorstore.custom_pdf_parser import get_pdf_documents
@@ -74,17 +73,10 @@ def update_vectorstore(file_path, vector_client, embedder, config_name):
documents = split_text(raw_documents)
# Adding file name to the metadata
- extract_filename = lambda filepath : os.path.splitext(os.path.basename(filepath))[0]
for document in documents:
- document.metadata["filename"] = extract_filename(file_path)
+ document.metadata["filename"] = os.path.basename(file_path)
logger.info("[Step 3/4] Inserting documents into the vector store...")
- # Extracting the page content from each document
- document_contents = [doc.page_content for doc in documents]
-
- # Embedding the documents using the updated embedding function
- document_embeddings = embedder.embed_documents(document_contents, batch_size=10)
-
# Batch insert into Milvus collection
- vector_client.update(documents, document_embeddings, config_name)
+ vector_client.add_documents(documents)
logger.info("[Step 4/4] Saved vector store!")
diff --git a/RetrievalAugmentedGeneration/examples/nvidia_api_catalog/chains.py b/RetrievalAugmentedGeneration/examples/nvidia_api_catalog/chains.py
index ba41b4a63..82f330174 100644
--- a/RetrievalAugmentedGeneration/examples/nvidia_api_catalog/chains.py
+++ b/RetrievalAugmentedGeneration/examples/nvidia_api_catalog/chains.py
@@ -29,7 +29,6 @@
from RetrievalAugmentedGeneration.common.tracing import langchain_instrumentation_class_wrapper
logger = logging.getLogger(__name__)
-DOCS_DIR = os.path.abspath("./uploaded_files")
vector_store_path = "vectorstore.pkl"
document_embedder = get_embedding_model()
text_splitter = None
@@ -49,8 +48,7 @@ def ingest_docs(self, filepath: str, filename: str):
raise ValueError(f"{filename} is not a valid Text, PDF or Markdown file")
try:
# Load raw documents from the directory
- # Data is copied to `DOCS_DIR` in common.server:upload_document
- _path = os.path.join(DOCS_DIR, filename)
+ _path = filepath
raw_documents = UnstructuredFileLoader(_path).load()
if raw_documents:
@@ -92,6 +90,7 @@ def llm_chain(
augmented_user_input = (
"\n\nQuestion: " + query + "\n"
)
+ logger.info(f"Prompt used for response generation: {prompt_template.format(input=augmented_user_input)}")
return chain.stream({"input": augmented_user_input}, config={"callbacks":[self.cb_handler]})
def rag_chain(self, query: str, chat_history: List["Message"], **kwargs) -> Generator[str, None, None]:
@@ -127,6 +126,7 @@ def rag_chain(self, query: str, chat_history: List["Message"], **kwargs) -> Gene
retriever = vs.as_retriever()
docs = retriever.get_relevant_documents(query, callbacks=[self.cb_handler])
+ logger.debug(f"Retrieved documents are: {docs}")
if not docs:
logger.warning("Retrieval failed to get any relevant context")
return iter(["No response generated from LLM, make sure your query is relavent to the ingested document."])
@@ -139,6 +139,7 @@ def rag_chain(self, query: str, chat_history: List["Message"], **kwargs) -> Gene
"Context: " + context + "\n\nQuestion: " + query + "\n"
)
+ logger.info(f"Prompt used for response generation: {prompt_template.format(input=augmented_user_input)}")
return chain.stream({"input": augmented_user_input}, config={"callbacks":[self.cb_handler]})
except Exception as e:
logger.warning(f"Failed to generate response due to exception {e}")
diff --git a/RetrievalAugmentedGeneration/examples/nvidia_api_catalog/requirements.txt b/RetrievalAugmentedGeneration/examples/nvidia_api_catalog/requirements.txt
deleted file mode 100644
index 39556ee63..000000000
--- a/RetrievalAugmentedGeneration/examples/nvidia_api_catalog/requirements.txt
+++ /dev/null
@@ -1 +0,0 @@
-faiss-cpu==1.7.4
\ No newline at end of file
diff --git a/RetrievalAugmentedGeneration/examples/query_decomposition_rag/chains.py b/RetrievalAugmentedGeneration/examples/query_decomposition_rag/chains.py
index a09acc398..1a5b9a084 100644
--- a/RetrievalAugmentedGeneration/examples/query_decomposition_rag/chains.py
+++ b/RetrievalAugmentedGeneration/examples/query_decomposition_rag/chains.py
@@ -16,7 +16,7 @@
"""
This example showcases recursive task decomposition to perform RAG which requires multiple steps.
The agent is a langchain custom LLM agent, which uses 2 tools - search and math.
-It uses OpenAI's GPT-4 model for sub-answer formation, tool prediction and math operations. It uses the deployed LLM for final answer formation.
+It uses Llama3 model for sub-answer formation, tool prediction and math operations.
Search tool is a RAG pipeline, whereas the math tool uses an LLM call to perform mathematical calculations.
"""
@@ -55,7 +55,6 @@
logger = logging.getLogger(__name__)
-DOCS_DIR = os.path.abspath("./uploaded_files")
vector_store_path = "vectorstore.pkl"
document_embedder = get_embedding_model()
settings = get_config()
@@ -89,9 +88,10 @@ def fetch_context(ledger: Ledger) -> str:
return context
template = """Your task is to answer questions. If you cannot answer the question, you can request use for a tool and break the question into specific sub questions. Fill with Nil where no action is required. You should only return a JSON containing the tool and the generated sub questions. Consider the contextual information and only ask for information that you do not already have. Do not return any other explanations or text. The output should be a simple JSON structure! You are given two tools:
-- Search tool
-- Math tool
-
+- Search
+- Math
+Search tool quickly finds and retrieves relevant answers from a given context, providing accurate and precise information to meet search needs.
+Math tool performs essential operations, including multiplication, addition, subtraction, division, and greater than or less than comparisons, providing accurate results with ease. Utilize math tool when asked to find sum, difference of values.
Do not pass sub questions to any tool if they already have an answer in the Contextual Information.
If you have all the information needed to answer the question, mark the Tool_Request as Nil.
@@ -104,6 +104,32 @@ def fetch_context(ledger: Ledger) -> str:
{"Tool_Request": "", "Generated Sub Questions": []}
"""
+math_tool_prompt = """Your task is to identify 2 variables and an operation from given questions. If you cannot answer the question, you can simply return "Not Possible". You should only return a JSON containing the `IsPossible`, `variable1`, `variable2`, and `operation`. Do not return any other explanations or text. The output should be a simple JSON structure!
+ You are given two options for `IsPossible`:
+- Possible
+- Not Possible
+ `variable1` and `variable2` should be real floating point numbers.
+ You are given four options for `operation symbols`:
+- '+' (addition)
+- '-' (subtraction)
+- '*' (multiplication)
+- '/' (division)
+- '=' (equal to)
+- '>' (greater than)
+- '<' (less than)
+- '>=' (greater than or equal to)
+- '<=' (less than or equal to)
+ Only return the symbols for the specified operations and nothing else.
+Contextual Information:
+{{ context }}
+
+Question:
+{{ question }}
+
+{"IsPossible": "", "variable1": [], "variable2": [], "operation": []}
+"""
+
+
class CustomPromptTemplate(BaseChatPromptTemplate):
template: str
tools: List[Tool]
@@ -147,10 +173,10 @@ def parse(self, llm_output: str) -> Union[AgentAction, AgentFinish]:
log=llm_output,
)
- if local_state["Tool_Request"] == "Search tool":
+ if local_state["Tool_Request"] == "Search":
self.ledger.trace += 1
- if local_state["Tool_Request"] in ["Search tool", "Math tool"]:
+ if local_state["Tool_Request"] in ["Search", "Math"]:
return AgentAction(
tool=local_state["Tool_Request"],
tool_input={"sub_questions": local_state["Generated Sub Questions"]},
@@ -166,8 +192,7 @@ def ingest_docs(self, filepath: str, filename: str):
raise ValueError(f"{filename} is not a valid Text, PDF or Markdown file")
try:
# Load raw documents from the directory
- # Data is copied to `DOCS_DIR` in common.server:upload_document
- _path = os.path.join(DOCS_DIR, filename)
+ _path = filepath
raw_documents = UnstructuredFileLoader(_path).load()
if raw_documents:
@@ -206,6 +231,7 @@ def llm_chain(
augmented_user_input = (
"\n\nQuestion: " + query + "\n"
)
+ logger.info(f"Prompt used for response generation: {prompt_template.format(input=augmented_user_input)}")
return chain.stream({"input": augmented_user_input}, config={"callbacks":[self.cb_handler]})
def rag_chain(self, query: str, chat_history: List["Message"], **kwargs) -> Generator[str, None, None]:
@@ -228,7 +254,7 @@ def rag_chain(self, query: str, chat_history: List["Message"], **kwargs) -> Gene
)
llm = get_llm(**kwargs)
chain = final_prompt_template | llm | StrOutputParser()
-
+ logger.info(f"Prompt used for final response generation: {final_prompt_template}")
return chain.stream({}, config={"callbacks":[self.cb_handler]})
except ValueError as e:
logger.warning(f"Failed to get response because {e}")
@@ -244,8 +270,8 @@ def create_agent(self, **kwargs) -> AgentExecutor:
self.kwargs = kwargs
tools = [
- Tool(name="Search tool", func=self.search, description="Searches for the answer from a given context."),
- Tool(name="Math tool", func=self.math, description="Performs mathematical calculations."),
+ Tool(name="Search", func=self.search, description="The Search Tool is a powerful querying system that quickly finds and retrieves relevant answers from a given context, providing accurate and precise information to meet your search needs."),
+ Tool(name="Math", func=self.math, description="The Math Tool is a versatile calculator that performs essential mathematical operations, including multiplication, addition, subtraction, division, and greater than or less than comparisons, providing accurate results with ease."),
]
tool_names = [tool.name for tool in tools]
@@ -295,7 +321,7 @@ def retriever(self, query: str) -> List[str]:
# Currently it's raising an error during invoke.
retriever = vs.as_retriever()
result = retriever.get_relevant_documents(query, callbacks=[self.cb_handler])
- logger.info(result)
+ logger.debug(result)
return [hit.page_content for hit in result]
@@ -332,16 +358,28 @@ def math(self, sub_questions: List[str]):
"""
Places an LLM call to answer mathematical subquestions which do not require search
"""
+ try:
+ prompt = f"{math_tool_prompt}\nQuestion: {sub_questions[0]}"
+ prompt += f"Context:\n{fetch_context(self.ledger)}\n"
+ logger.info(f"Performing Math LLM call with prompt: {prompt}")
+ llm = get_llm(**self.kwargs)
+ sub_answer = llm([HumanMessage(content=prompt)])
+ sub_answer = json.loads(sub_answer.content)
+ final_sub_answer= str(sub_answer['variable1'])+sub_answer['operation']+str(sub_answer['variable2'])
+ final_sub_answer=final_sub_answer+'='+str(eval(final_sub_answer))
+ except:
+ prompt = "Solve this mathematical question:\nQuestion: " + sub_questions[0]
+ prompt += f"Context:\n{fetch_context(self.ledger)}\n"
+ prompt += "Be concise and only return the answer."
+
+ logger.info(f"Performing Math LLM call with prompt: {prompt}")
+ llm = get_llm(**self.kwargs)
+ sub_answer = llm([HumanMessage(content=prompt)])
+ final_sub_answer = sub_answer.content
- prompt = "Solve this mathematical question:\nQuestion: " + sub_questions[0]
- prompt += f"Context:\n{fetch_context(self.ledger)}\n"
- prompt += "Be concise and only return the answer."
- logger.info(f"Performing Math LLM call with prompt: {prompt}")
- llm = get_llm(**self.kwargs)
- sub_answer = llm([HumanMessage(content=prompt)])
self.ledger.question_trace.append(sub_questions[0])
- self.ledger.answer_trace.append(sub_answer.content)
+ self.ledger.answer_trace.append(final_sub_answer)
self.ledger.done = True
diff --git a/RetrievalAugmentedGeneration/examples/query_decomposition_rag/requirements.txt b/RetrievalAugmentedGeneration/examples/query_decomposition_rag/requirements.txt
deleted file mode 100644
index 39556ee63..000000000
--- a/RetrievalAugmentedGeneration/examples/query_decomposition_rag/requirements.txt
+++ /dev/null
@@ -1 +0,0 @@
-faiss-cpu==1.7.4
\ No newline at end of file
diff --git a/RetrievalAugmentedGeneration/examples/structured_data_rag/chains.py b/RetrievalAugmentedGeneration/examples/structured_data_rag/chains.py
index 2f2b3066f..d322bbccb 100644
--- a/RetrievalAugmentedGeneration/examples/structured_data_rag/chains.py
+++ b/RetrievalAugmentedGeneration/examples/structured_data_rag/chains.py
@@ -106,12 +106,12 @@ def read_and_concatenate_csv(self, file_paths_txt):
def ingest_docs(self, filepath: str, filename: str):
"""Ingest documents to the VectorDB."""
-
+
if not filename.endswith(".csv"):
raise ValueError(f"{filename} is not a valid CSV file")
with open(INGESTED_CSV_FILES_LIST, "a+", encoding="UTF-8") as f:
-
+
ref_csv_path = None
try:
@@ -152,8 +152,7 @@ def llm_chain(
system_message + user_input
)
- logger.info("Using prompt for response: %s", prompt)
-
+ logger.info(f"Using prompt for response generation: {prompt.format(input=query)}")
chain = prompt | get_llm(**kwargs) | StrOutputParser()
return chain.stream({"input": query})
@@ -241,4 +240,5 @@ def get_documents(self) -> List[str]:
def delete_documents(self, filenames: List[str]):
"""Delete documents from the vector index."""
- logger.error("delete_documents not implemented")
\ No newline at end of file
+ logger.error("delete_documents not implemented")
+ return True
\ No newline at end of file
diff --git a/RetrievalAugmentedGeneration/frontend/Dockerfile b/RetrievalAugmentedGeneration/frontend/Dockerfile
index 24d85ea55..4fe4e64c1 100644
--- a/RetrievalAugmentedGeneration/frontend/Dockerfile
+++ b/RetrievalAugmentedGeneration/frontend/Dockerfile
@@ -1,5 +1,5 @@
ARG BASE_IMAGE_URL=nvcr.io/nvidia/base/ubuntu
-ARG BASE_IMAGE_TAG=20.04_x64_2022-09-23
+ARG BASE_IMAGE_TAG=22.04_20240212
FROM ${BASE_IMAGE_URL}:${BASE_IMAGE_TAG}
diff --git a/RetrievalAugmentedGeneration/frontend/frontend/chat_client.py b/RetrievalAugmentedGeneration/frontend/frontend/chat_client.py
index 406757363..19d8c42a6 100644
--- a/RetrievalAugmentedGeneration/frontend/frontend/chat_client.py
+++ b/RetrievalAugmentedGeneration/frontend/frontend/chat_client.py
@@ -34,7 +34,7 @@ def __init__(self, server_url: str, model_name: str) -> None:
"""Initialize the client."""
self.server_url = server_url
self._model_name = model_name
- self.default_model = "llama2-7B-chat"
+ self.default_model = "meta/llama3-70b-instruct"
@property
def model_name(self) -> str:
@@ -83,13 +83,6 @@ def predict(
}
],
"use_knowledge_base": use_knowledge_base,
- "temperature": 0.2,
- "top_p": 0.7,
- "max_tokens": num_tokens,
- "seed": 42,
- "bad": ["string"],
- "stop": ["string"],
- "stream": True
}
url = f"{self.server_url}/generate"
_LOGGER.debug(
diff --git a/RetrievalAugmentedGeneration/frontend/frontend/configuration.py b/RetrievalAugmentedGeneration/frontend/frontend/configuration.py
index c1a7333ac..864ae45b8 100644
--- a/RetrievalAugmentedGeneration/frontend/frontend/configuration.py
+++ b/RetrievalAugmentedGeneration/frontend/frontend/configuration.py
@@ -39,6 +39,6 @@ class AppConfig(ConfigWizard):
)
model_name: str = configfield(
"modelName",
- default="llama2-7B-chat",
+ default="meta/llama3-70b-instruct",
help_txt="The name of the hosted LLM model.",
)
diff --git a/RetrievalAugmentedGeneration/frontend/frontend/pages/kb.py b/RetrievalAugmentedGeneration/frontend/frontend/pages/kb.py
index e30bc5b48..b66a2819f 100644
--- a/RetrievalAugmentedGeneration/frontend/frontend/pages/kb.py
+++ b/RetrievalAugmentedGeneration/frontend/frontend/pages/kb.py
@@ -57,7 +57,7 @@ def build_page(client: chat_client.ChatClient) -> gr.Blocks:
message_textbox = gr.Textbox(
label="Message", interactive=False, visible=True
)
-
+
with gr.Row():
delete_button = gr.Button("Delete")
diff --git a/RetrievalAugmentedGeneration/frontend/frontend/tts_utils.py b/RetrievalAugmentedGeneration/frontend/frontend/tts_utils.py
index 1ca4d62ea..2266c138f 100644
--- a/RetrievalAugmentedGeneration/frontend/frontend/tts_utils.py
+++ b/RetrievalAugmentedGeneration/frontend/frontend/tts_utils.py
@@ -101,10 +101,10 @@ def text_to_speech(text, language, voice, enable_tts):
tts_client = riva.client.SpeechSynthesisService(grpc_auth)
_LOGGER.info(f"Calling synthesize_online")
-
- # To manage the 400-character limit for Riva's text-to-speech (TTS), longer answers are segmented by adding 'full stops' at every 400 characters
- for i in range(len(text)//400):
- indx = text.rfind(' ',i*400)
+
+ # To manage the 400-character limit for Riva's text-to-speech (TTS), longer answers are segmented by adding 'full stops' at every 300 characters (300 instead of 400 to take in account phoneme expansion)
+ for i in range((len(text)//300)+1):
+ indx = text.rfind(' ',0,(i+1)*300)
text = text[:indx]+' . '+text[indx:]
response = tts_client.synthesize_online(
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/Dockerfile b/RetrievalAugmentedGeneration/llm-inference-server/Dockerfile
deleted file mode 100644
index ef47aa245..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/Dockerfile
+++ /dev/null
@@ -1,22 +0,0 @@
-ARG BASE_IMAGE_URL=nvcr.io/nvidia/nemo/nemofw-inference
-ARG BASE_IMAGE_TAG=23.10-for-rag
-
-FROM ${BASE_IMAGE_URL}:${BASE_IMAGE_TAG}
-
-ENV LD_LIBRARY_PATH=/opt/tritonserver/backends/tensorrtllm:$LD_LIBRARY_PATH
-
-# install model-server automation
-COPY conversion_scripts /opt/conversion_scripts
-COPY ensemble_models /opt/ensemble_models
-COPY model_server /opt/model_server
-COPY model_server_client /opt/model_server_client
-RUN --mount=type=bind,source=requirements.txt,target=/opt/requirements.txt \
- pip install --no-cache-dir -r /opt/requirements.txt
-
-# Create basic directories
-
-RUN mkdir /model && chmod 1777 /model && \
- mkdir -p /home/triton-server && chown 1000:1000 /home/triton-server && chmod 700 /home/triton-server
-
-WORKDIR /opt
-ENTRYPOINT ["/usr/bin/python3", "-m", "model_server"]
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/conversion_scripts/llama/build.py b/RetrievalAugmentedGeneration/llm-inference-server/conversion_scripts/llama/build.py
deleted file mode 100644
index 2a57d4cdb..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/conversion_scripts/llama/build.py
+++ /dev/null
@@ -1,776 +0,0 @@
-# SPDX-FileCopyrightText: Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-# SPDX-License-Identifier: Apache-2.0
-#
-# 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.
-import argparse
-import json
-import os
-import time
-from pathlib import Path
-
-import tensorrt as trt
-import tensorrt_llm
-import torch
-import torch.multiprocessing as mp
-from tensorrt_llm._utils import str_dtype_to_trt
-from tensorrt_llm.builder import Builder
-from tensorrt_llm.layers.attention import PositionEmbeddingType
-from tensorrt_llm.logger import logger
-from tensorrt_llm.mapping import Mapping
-from tensorrt_llm.models import (
- fp8_quantize,
- smooth_quantize,
- weight_only_groupwise_quantize,
- weight_only_quantize,
-)
-from tensorrt_llm.network import net_guard
-from tensorrt_llm.plugin.plugin import ContextFMHAType
-from tensorrt_llm.quantization import QuantMode
-from transformers import LlamaConfig, LlamaForCausalLM
-from weight import (
- get_scaling_factors,
- load_from_awq_llama,
- load_from_binary,
- load_from_gptq_llama,
- load_from_hf_llama,
- load_from_meta_llama,
-)
-
-from weight import parse_ft_config # isort:skip
-
-MODEL_NAME = "llama"
-
-# 2 routines: get_engine_name, serialize_engine
-# are direct copy from gpt example, TODO: put in utils?
-
-import onnx
-import tensorrt as trt
-from onnx import TensorProto, helper
-
-
-def trt_dtype_to_onnx(dtype):
- if dtype == trt.float16:
- return TensorProto.DataType.FLOAT16
- elif dtype == trt.float32:
- return TensorProto.DataType.FLOAT
- elif dtype == trt.int32:
- return TensorProto.DataType.INT32
- else:
- raise TypeError("%s is not supported" % dtype)
-
-
-def to_onnx(network, path):
- inputs = []
- for i in range(network.num_inputs):
- network_input = network.get_input(i)
- inputs.append(
- helper.make_tensor_value_info(
- network_input.name,
- trt_dtype_to_onnx(network_input.dtype),
- list(network_input.shape),
- )
- )
-
- outputs = []
- for i in range(network.num_outputs):
- network_output = network.get_output(i)
- outputs.append(
- helper.make_tensor_value_info(
- network_output.name,
- trt_dtype_to_onnx(network_output.dtype),
- list(network_output.shape),
- )
- )
-
- nodes = []
- for i in range(network.num_layers):
- layer = network.get_layer(i)
- layer_inputs = []
- for j in range(layer.num_inputs):
- ipt = layer.get_input(j)
- if ipt is not None:
- layer_inputs.append(layer.get_input(j).name)
- layer_outputs = [layer.get_output(j).name for j in range(layer.num_outputs)]
- nodes.append(
- helper.make_node(
- str(layer.type),
- name=layer.name,
- inputs=layer_inputs,
- outputs=layer_outputs,
- domain="com.nvidia",
- )
- )
-
- onnx_model = helper.make_model(
- helper.make_graph(nodes, "attention", inputs, outputs, initializer=None),
- producer_name="NVIDIA",
- )
- onnx.save(onnx_model, path)
-
-
-def get_engine_name(model, dtype, tp_size, pp_size, rank):
- if pp_size == 1:
- return "{}_{}_tp{}_rank{}.engine".format(model, dtype, tp_size, rank)
- return "{}_{}_tp{}_pp{}_rank{}.engine".format(model, dtype, tp_size, pp_size, rank)
-
-
-def serialize_engine(engine, path):
- logger.info(f"Serializing engine to {path}...")
- tik = time.time()
- with open(path, "wb") as f:
- f.write(bytearray(engine))
- tok = time.time()
- t = time.strftime("%H:%M:%S", time.gmtime(tok - tik))
- logger.info(f"Engine serialized. Total time: {t}")
-
-
-def parse_arguments():
- parser = argparse.ArgumentParser()
- parser.add_argument("--world_size", type=int, default=1)
- parser.add_argument("--tp_size", type=int, default=1)
- parser.add_argument("--pp_size", type=int, default=1)
- parser.add_argument("--model_dir", type=str, default=None)
- parser.add_argument("--ft_model_dir", type=str, default=None)
- parser.add_argument("--meta_ckpt_dir", type=str, default=None)
- parser.add_argument("--quant_ckpt_path", type=str, default=None)
- parser.add_argument(
- "--dtype",
- type=str,
- default="float16",
- choices=["float32", "bfloat16", "float16"],
- )
- parser.add_argument(
- "--timing_cache",
- type=str,
- default="model.cache",
- help="The path of to read timing cache from, will be ignored if the file does not exist",
- )
- parser.add_argument("--log_level", type=str, default="info")
- parser.add_argument("--vocab_size", type=int, default=32000)
- parser.add_argument("--n_layer", type=int, default=32)
- parser.add_argument("--n_positions", type=int, default=2048)
- parser.add_argument("--n_embd", type=int, default=4096)
- parser.add_argument("--n_head", type=int, default=32)
- parser.add_argument("--n_kv_head", type=int, default=None)
- parser.add_argument("--multiple_of", type=int, default=256)
- parser.add_argument("--ffn_dim_multiplier", type=float, default=1.0)
- parser.add_argument("--inter_size", type=int, default=None)
- parser.add_argument("--hidden_act", type=str, default="silu")
- parser.add_argument("--rms_norm_eps", type=float, default=1e-06)
- parser.add_argument("--max_batch_size", type=int, default=8)
- parser.add_argument("--max_input_len", type=int, default=2048)
- parser.add_argument("--max_output_len", type=int, default=512)
- parser.add_argument("--max_beam_width", type=int, default=1)
- parser.add_argument("--rotary_base", type=float, default=10000.0)
- parser.add_argument("--rotary_scaling", nargs=2, type=str, default=None)
- parser.add_argument(
- "--use_gpt_attention_plugin",
- nargs="?",
- const="float16",
- type=str,
- default=False,
- choices=["float16", "bfloat16", "float32"],
- )
- parser.add_argument(
- "--use_gemm_plugin",
- nargs="?",
- const="float16",
- type=str,
- default=False,
- choices=["float16", "bfloat16", "float32"],
- )
- parser.add_argument(
- "--use_rmsnorm_plugin",
- nargs="?",
- const="float16",
- type=str,
- default=False,
- choices=["float16", "float32", "bfloat16"],
- )
- parser.add_argument("--parallel_build", default=False, action="store_true")
- parser.add_argument("--enable_context_fmha", default=False, action="store_true")
- parser.add_argument(
- "--enable_context_fmha_fp32_acc", default=False, action="store_true"
- )
- parser.add_argument("--visualize", default=False, action="store_true")
- parser.add_argument("--enable_debug_output", default=False, action="store_true")
- parser.add_argument("--gpus_per_node", type=int, default=8)
- parser.add_argument("--builder_opt", type=int, default=None)
- parser.add_argument(
- "--output_dir",
- type=str,
- default="llama_outputs",
- help="The path to save the serialized engine files, timing cache file and model configs",
- )
- parser.add_argument("--remove_input_padding", default=False, action="store_true")
-
- # Arguments related to the quantization of the model.
- parser.add_argument(
- "--use_smooth_quant",
- default=False,
- action="store_true",
- help="Use the SmoothQuant method to quantize activations and weights for the various GEMMs."
- "See --per_channel and --per_token for finer-grained quantization options.",
- )
- parser.add_argument(
- "--per_channel",
- default=False,
- action="store_true",
- help="By default, we use a single static scaling factor for the GEMM's result. "
- "per_channel instead uses a different static scaling factor for each channel. "
- "The latter is usually more accurate, but a little slower.",
- )
- parser.add_argument(
- "--per_token",
- default=False,
- action="store_true",
- help="By default, we use a single static scaling factor to scale activations in the int8 range. "
- "per_token chooses at run time, and for each token, a custom scaling factor. "
- "The latter is usually more accurate, but a little slower.",
- )
- parser.add_argument(
- "--per_group",
- default=False,
- action="store_true",
- help="By default, we use a single static scaling factor to scale weights in the int4 range. "
- "per_group chooses at run time, and for each group, a custom scaling factor. "
- "The flag is built for GPTQ/AWQ quantization.",
- )
- parser.add_argument(
- "--group_size",
- type=int,
- default=128,
- help="Group size used in GPTQ/AWQ quantization.",
- )
- parser.add_argument(
- "--int8_kv_cache",
- default=False,
- action="store_true",
- help="By default, we use dtype for KV cache. int8_kv_cache chooses int8 quantization for KV",
- )
- parser.add_argument(
- "--use_parallel_embedding",
- action="store_true",
- default=False,
- help="By default embedding parallelism is disabled. By setting this flag, embedding parallelism is enabled",
- )
- parser.add_argument(
- "--embedding_sharding_dim",
- type=int,
- default=1, # Meta does TP on hidden dim
- choices=[0, 1],
- help="By default the embedding lookup table is sharded along vocab dimension (embedding_sharding_dim=0). "
- "To shard it along hidden dimension, set embedding_sharding_dim=1"
- "Note: embedding sharing is only enabled when embedding_sharding_dim = 0",
- )
- parser.add_argument(
- "--enable_fp8",
- default=False,
- action="store_true",
- help="Use FP8 Linear layer for Attention QKV/Dense and MLP.",
- )
- parser.add_argument(
- "--fp8_kv_cache",
- default=False,
- action="store_true",
- help="By default, we use dtype for KV cache. fp8_kv_cache chooses int8 quantization for KV",
- )
- parser.add_argument(
- "--quantized_fp8_model_path",
- type=str,
- default=None,
- help="Path of a quantized model checkpoint in .npz format",
- )
- parser.add_argument(
- "--use_weight_only",
- default=False,
- action="store_true",
- help="Quantize weights for the various GEMMs to INT4/INT8."
- "See --weight_only_precision to set the precision",
- )
- parser.add_argument(
- "--weight_only_precision",
- const="int8",
- type=str,
- nargs="?",
- default="int8",
- choices=["int8", "int4", "int4_awq", "int4_gptq"],
- help="Define the precision for the weights when using weight-only quantization."
- "You must also use --use_weight_only for that argument to have an impact.",
- )
- parser.add_argument(
- "--use_inflight_batching",
- action="store_true",
- default=False,
- help="Activates inflight batching mode of gptAttentionPlugin.",
- )
- parser.add_argument(
- "--paged_kv_cache",
- action="store_true",
- default=False,
- help="By default we use contiguous KV cache. By setting this flag you enable paged KV cache",
- )
- parser.add_argument(
- "--tokens_per_block",
- type=int,
- default=64,
- help="Number of tokens per block in paged KV cache",
- )
- parser.add_argument(
- "--max_num_tokens",
- type=int,
- default=None,
- help="Define the max number of tokens supported by the engine",
- )
- parser.add_argument(
- "--strongly_typed",
- default=False,
- action="store_true",
- help="This option is introduced with trt 9.1.0.1+ and will reduce the building time significantly for fp8.",
- )
- parser.add_argument(
- "--use_custom_all_reduce",
- action="store_true",
- help="Activates latency-optimized algorithm for all-reduce instead of NCCL.",
- )
-
- args = parser.parse_args()
- tensorrt_llm.logger.set_level(args.log_level)
-
- assert not (
- args.use_smooth_quant and args.use_weight_only
- ), "You cannot enable both SmoothQuant and INT8 weight-only together."
-
- if not args.remove_input_padding:
- if args.use_gpt_attention_plugin:
- logger.warning(
- f"It is recommended to specify --remove_input_padding when using GPT attention plugin"
- )
-
- if args.use_inflight_batching:
- if not args.use_gpt_attention_plugin:
- args.use_gpt_attention_plugin = "float16"
- logger.info(
- f"Using GPT attention plugin for inflight batching mode. Setting to default '{args.use_gpt_attention_plugin}'"
- )
- if not args.remove_input_padding:
- args.remove_input_padding = True
- logger.info("Using remove input padding for inflight batching mode.")
- if not args.paged_kv_cache:
- args.paged_kv_cache = True
- logger.info("Using paged KV cache for inflight batching mode.")
-
- if args.use_smooth_quant:
- args.quant_mode = QuantMode.use_smooth_quant(args.per_token, args.per_channel)
- elif args.use_weight_only:
- if args.per_group:
- args.quant_mode = QuantMode.from_description(
- quantize_weights=True,
- quantize_activations=False,
- per_token=False,
- per_channel=False,
- per_group=True,
- use_int4_weights=True,
- )
- else:
- args.quant_mode = QuantMode.use_weight_only(
- args.weight_only_precision == "int4"
- )
- else:
- args.quant_mode = QuantMode(0)
-
- if args.int8_kv_cache:
- args.quant_mode = args.quant_mode.set_int8_kv_cache()
- elif args.fp8_kv_cache:
- args.quant_mode = args.quant_mode.set_fp8_kv_cache()
- if args.enable_fp8:
- args.quant_mode = args.quant_mode.set_fp8_qdq()
-
- if args.rotary_scaling is not None:
- rotary_scaling = {
- "type": args.rotary_scaling[0],
- "factor": float(args.rotary_scaling[1]),
- }
- assert rotary_scaling["type"] in ["linear", "dynamic"]
- assert rotary_scaling["factor"] > 1.0
- args.rotary_scaling = rotary_scaling
- if rotary_scaling["type"] == "dynamic":
- assert not args.remove_input_padding, "TODO: Not supported yet"
-
- # Since gpt_attenttion_plugin is the only way to apply RoPE now,
- # force use the plugin for now with the correct data type.
- args.use_gpt_attention_plugin = args.dtype
- if args.model_dir is not None:
- hf_config = LlamaConfig.from_pretrained(args.model_dir)
- args.inter_size = (
- hf_config.intermediate_size
- ) # override the inter_size for LLaMA
- args.n_embd = hf_config.hidden_size
- args.n_head = hf_config.num_attention_heads
- if hasattr(hf_config, "num_key_value_heads"):
- args.n_kv_head = hf_config.num_key_value_heads
- args.n_layer = hf_config.num_hidden_layers
- args.n_positions = hf_config.max_position_embeddings
- args.vocab_size = hf_config.vocab_size
- args.hidden_act = hf_config.hidden_act
- args.rms_norm_eps = hf_config.rms_norm_eps
- elif args.meta_ckpt_dir is not None:
- with open(Path(args.meta_ckpt_dir, "params.json")) as fp:
- meta_config: dict = json.load(fp)
- args.n_embd = meta_config["dim"]
- args.n_head = meta_config["n_heads"]
- args.n_layer = meta_config["n_layers"]
- args.n_kv_head = meta_config.get("n_kv_heads", args.n_head)
- args.multiple_of = meta_config["multiple_of"]
- args.ffn_dim_multiplier = meta_config.get("ffn_dim_multiplier", 1)
- n_embd = int(4 * args.n_embd * 2 / 3)
- args.inter_size = args.multiple_of * (
- (int(n_embd * args.ffn_dim_multiplier) + args.multiple_of - 1)
- // args.multiple_of
- )
- args.rms_norm_eps = meta_config["norm_eps"]
- elif args.ft_model_dir is not None:
- (
- n_embd,
- n_head,
- n_layer,
- n_positions,
- vocab_size,
- hidden_act,
- inter_size,
- n_kv_head,
- ) = parse_ft_config(Path(args.ft_model_dir) / "config.ini")
- args.inter_size = inter_size # override the inter_size for LLaMA
- args.n_kv_head = n_kv_head
- args.n_embd = n_embd
- args.n_head = n_head
- args.n_layer = n_layer
- args.n_positions = n_positions
- args.vocab_size = vocab_size
- args.hidden_act = hidden_act
- args.rms_norm_eps = 1e-06
- logger.warning("Set rms_norm_eps to 1e-06 directly.")
- assert args.use_gpt_attention_plugin, "LLaMa must use gpt attention plugin"
- if args.n_kv_head is None:
- args.n_kv_head = args.n_head
- elif args.n_kv_head != args.n_head:
- assert (
- args.n_head % args.n_kv_head
- ) == 0, "MQA/GQA requires the number of heads to be divisible by the number of K/V heads."
- assert (args.n_kv_head % args.tp_size) == 0 or (
- args.tp_size % args.n_kv_head
- ) == 0, (
- "MQA/GQA requires either the number of K/V heads to be divisible by the tensor parallelism size OR "
- "the tensor parallelism size to be divisible by the number of K/V heads."
- )
-
- if args.dtype == "bfloat16":
- assert args.use_gemm_plugin, "Please use gemm plugin when dtype is bfloat16"
-
- assert args.pp_size * args.tp_size == args.world_size
-
- if args.max_num_tokens is not None:
- assert args.enable_context_fmha
-
- if args.inter_size is None:
- # this should not be need when loading a real model
- # but it is helpful when creating a dummy model without loading any real weights
- n_embd = int(4 * args.n_embd * 2 / 3)
- args.inter_size = args.multiple_of * (
- (int(n_embd * args.ffn_dim_multiplier) + args.multiple_of - 1)
- // args.multiple_of
- )
- logger.info(f"Setting inter_size to {args.inter_size}.")
-
- return args
-
-
-def build_rank_engine(
- builder: Builder,
- builder_config: tensorrt_llm.builder.BuilderConfig,
- engine_name,
- rank,
- args,
-):
- """
- @brief: Build the engine on the given rank.
- @param rank: The rank to build the engine.
- @param args: The cmd line arguments.
- @return: The built engine.
- """
- dtype = str_dtype_to_trt(args.dtype)
- mapping = Mapping(
- world_size=args.world_size,
- rank=rank,
- tp_size=args.tp_size,
- pp_size=args.pp_size,
- )
-
- assert (
- args.n_layer % args.pp_size == 0
- ), f"num_layers {args.n_layer} must be a multiple of pipeline parallelism size {args.pp_size}"
-
- # Initialize Module
- tensorrt_llm_llama = tensorrt_llm.models.LLaMAForCausalLM(
- num_layers=args.n_layer,
- num_heads=args.n_head,
- num_kv_heads=args.n_kv_head,
- hidden_size=args.n_embd,
- vocab_size=args.vocab_size,
- hidden_act=args.hidden_act,
- max_position_embeddings=args.n_positions,
- dtype=dtype,
- mlp_hidden_size=args.inter_size,
- position_embedding_type=PositionEmbeddingType.rope_gpt_neox,
- mapping=mapping,
- rotary_base=args.rotary_base,
- rotary_scaling=args.rotary_scaling,
- use_parallel_embedding=args.use_parallel_embedding,
- embedding_sharding_dim=args.embedding_sharding_dim,
- quant_mode=args.quant_mode,
- rms_norm_eps=args.rms_norm_eps,
- )
- if args.use_smooth_quant:
- tensorrt_llm_llama = smooth_quantize(tensorrt_llm_llama, args.quant_mode)
- elif args.use_weight_only:
- if args.weight_only_precision == "int8":
- tensorrt_llm_llama = weight_only_quantize(
- tensorrt_llm_llama, args.quant_mode
- )
- elif args.weight_only_precision == "int4":
- tensorrt_llm_llama = weight_only_quantize(
- tensorrt_llm_llama, args.quant_mode
- )
- elif args.weight_only_precision == "int4_awq":
- tensorrt_llm_llama = weight_only_groupwise_quantize(
- model=tensorrt_llm_llama,
- quant_mode=args.quant_mode,
- group_size=args.group_size,
- zero=False,
- pre_quant_scale=True,
- exclude_modules=[],
- )
- elif args.weight_only_precision == "int4_gptq":
- tensorrt_llm_llama = weight_only_groupwise_quantize(
- model=tensorrt_llm_llama,
- quant_mode=args.quant_mode,
- group_size=args.group_size,
- zero=True,
- pre_quant_scale=False,
- )
- elif args.enable_fp8 or args.fp8_kv_cache:
- logger.info(f"Loading scaling factors from " f"{args.quantized_fp8_model_path}")
- quant_scales = get_scaling_factors(
- args.quantized_fp8_model_path,
- num_layers=args.n_layer,
- quant_mode=args.quant_mode,
- )
- tensorrt_llm_llama = fp8_quantize(
- tensorrt_llm_llama, quant_mode=args.quant_mode, quant_scales=quant_scales
- )
- if args.per_group:
- load_func = (
- load_from_awq_llama
- if args.weight_only_precision == "int4_awq"
- else load_from_gptq_llama
- )
- load_func(
- tensorrt_llm_llama=tensorrt_llm_llama,
- quant_ckpt_path=args.quant_ckpt_path,
- mapping=mapping,
- dtype=args.dtype,
- )
- elif args.meta_ckpt_dir is not None:
- load_from_meta_llama(
- tensorrt_llm_llama, args.meta_ckpt_dir, mapping, args.dtype
- )
- elif args.model_dir is not None:
- logger.info(f"Loading HF LLaMA ... from {args.model_dir}")
- tik = time.time()
- hf_llama = LlamaForCausalLM.from_pretrained(
- args.model_dir,
- device_map={"model": "cpu", "lm_head": "cpu"}, # Load to CPU memory
- torch_dtype="auto",
- )
- tok = time.time()
- t = time.strftime("%H:%M:%S", time.gmtime(tok - tik))
- logger.info(f"HF LLaMA loaded. Total time: {t}")
- load_from_hf_llama(
- tensorrt_llm_llama, hf_llama, mapping=mapping, dtype=args.dtype
- )
- del hf_llama
- elif args.ft_model_dir is not None:
- load_from_binary(
- tensorrt_llm_llama,
- args.ft_model_dir,
- mapping,
- fp16=(args.dtype == "float16"),
- multi_query_mode=(args.n_kv_head != args.n_head),
- )
-
- # Module -> Network
- network = builder.create_network()
- network.trt_network.name = engine_name
- if args.use_gpt_attention_plugin:
- network.plugin_config.set_gpt_attention_plugin(
- dtype=args.use_gpt_attention_plugin
- )
- if args.use_gemm_plugin:
- network.plugin_config.set_gemm_plugin(dtype=args.use_gemm_plugin)
- if args.use_rmsnorm_plugin:
- network.plugin_config.set_rmsnorm_plugin(dtype=args.use_rmsnorm_plugin)
-
- # Quantization plugins.
- if args.use_smooth_quant:
- network.plugin_config.set_smooth_quant_gemm_plugin(dtype=args.dtype)
- network.plugin_config.set_rmsnorm_quantization_plugin(dtype=args.dtype)
- network.plugin_config.set_quantize_tensor_plugin()
- network.plugin_config.set_quantize_per_token_plugin()
- assert not (args.enable_context_fmha and args.enable_context_fmha_fp32_acc)
- if args.enable_context_fmha:
- network.plugin_config.set_context_fmha(ContextFMHAType.enabled)
- if args.enable_context_fmha_fp32_acc:
- network.plugin_config.set_context_fmha(ContextFMHAType.enabled_with_fp32_acc)
- if args.use_weight_only:
- if args.per_group:
- network.plugin_config.set_weight_only_groupwise_quant_matmul_plugin(
- dtype="float16"
- )
- else:
- network.plugin_config.set_weight_only_quant_matmul_plugin(dtype="float16")
- if args.world_size > 1:
- network.plugin_config.set_nccl_plugin(args.dtype, args.use_custom_all_reduce)
- if args.remove_input_padding:
- network.plugin_config.enable_remove_input_padding()
- if args.paged_kv_cache:
- network.plugin_config.enable_paged_kv_cache(args.tokens_per_block)
-
- with net_guard(network):
- # Prepare
- network.set_named_parameters(tensorrt_llm_llama.named_parameters())
-
- # Forward
- inputs = tensorrt_llm_llama.prepare_inputs(
- args.max_batch_size,
- args.max_input_len,
- args.max_output_len,
- True,
- args.max_beam_width,
- args.max_num_tokens,
- )
- tensorrt_llm_llama(*inputs)
- if args.enable_debug_output:
- # mark intermediate nodes' outputs
- for k, v in tensorrt_llm_llama.named_network_outputs():
- v = v.trt_tensor
- v.name = k
- network.trt_network.mark_output(v)
- v.dtype = dtype
- if args.visualize:
- model_path = os.path.join(args.output_dir, "test.onnx")
- to_onnx(network.trt_network, model_path)
-
- tensorrt_llm.graph_rewriting.optimize(network)
-
- engine = None
-
- # Network -> Engine
- engine = builder.build_engine(network, builder_config)
- if rank == 0:
- config_path = os.path.join(args.output_dir, "config.json")
- builder.save_config(builder_config, config_path)
- return engine
-
-
-def build(rank, args):
- torch.cuda.set_device(rank % args.gpus_per_node)
- logger.set_level(args.log_level)
- if not os.path.exists(args.output_dir):
- os.makedirs(args.output_dir)
-
- # when doing serializing build, all ranks share one engine
- builder = Builder()
-
- cache = None
- for cur_rank in range(args.world_size):
- # skip other ranks if parallel_build is enabled
- if args.parallel_build and cur_rank != rank:
- continue
- # NOTE: when only int8 kv cache is used together with paged kv cache no int8 tensors are exposed to TRT
- int8_trt_flag = args.quant_mode.has_act_and_weight_quant() or (
- not args.paged_kv_cache and args.quant_mode.has_int8_kv_cache()
- )
- builder_config = builder.create_builder_config(
- name=MODEL_NAME,
- precision=args.dtype,
- timing_cache=args.timing_cache if cache is None else cache,
- tensor_parallel=args.tp_size,
- pipeline_parallel=args.pp_size,
- parallel_build=args.parallel_build,
- num_layers=args.n_layer,
- num_heads=args.n_head,
- num_kv_heads=args.n_kv_head,
- hidden_size=args.n_embd,
- vocab_size=args.vocab_size,
- hidden_act=args.hidden_act,
- max_position_embeddings=args.n_positions,
- max_batch_size=args.max_batch_size,
- max_input_len=args.max_input_len,
- max_output_len=args.max_output_len,
- max_num_tokens=args.max_num_tokens,
- int8=int8_trt_flag,
- fp8=args.quant_mode.has_fp8_qdq(),
- quant_mode=args.quant_mode,
- strongly_typed=args.strongly_typed,
- opt_level=args.builder_opt,
- )
- engine_name = get_engine_name(
- MODEL_NAME, args.dtype, args.tp_size, args.pp_size, cur_rank
- )
- engine = build_rank_engine(builder, builder_config, engine_name, cur_rank, args)
- assert engine is not None, f"Failed to build engine for rank {cur_rank}"
-
- if cur_rank == 0:
- # Use in-memory timing cache for multiple builder passes.
- if not args.parallel_build:
- cache = builder_config.trt_builder_config.get_timing_cache()
-
- serialize_engine(engine, os.path.join(args.output_dir, engine_name))
-
- if rank == 0:
- ok = builder.save_timing_cache(
- builder_config, os.path.join(args.output_dir, "model.cache")
- )
- assert ok, "Failed to save timing cache."
-
-
-if __name__ == "__main__":
- args = parse_arguments()
- tik = time.time()
- if (
- args.parallel_build
- and args.world_size > 1
- and torch.cuda.device_count() >= args.world_size
- ):
- logger.warning(
- f"Parallelly build TensorRT engines. Please make sure that all of the {args.world_size} GPUs are totally free."
- )
- mp.spawn(build, nprocs=args.world_size, args=(args,))
- else:
- args.parallel_build = False
- logger.info("Serially build TensorRT engines.")
- build(0, args)
-
- tok = time.time()
- t = time.strftime("%H:%M:%S", time.gmtime(tok - tik))
- logger.info(f"Total time of building all {args.world_size} engines: {t}")
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/conversion_scripts/llama/weight.py b/RetrievalAugmentedGeneration/llm-inference-server/conversion_scripts/llama/weight.py
deleted file mode 100644
index 692ae67ff..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/conversion_scripts/llama/weight.py
+++ /dev/null
@@ -1,1446 +0,0 @@
-# SPDX-FileCopyrightText: Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-# SPDX-License-Identifier: Apache-2.0
-#
-# 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.
-import configparser
-import time
-from operator import attrgetter
-from pathlib import Path
-from typing import Dict, List, Optional, Union
-
-import numpy as np
-import tensorrt_llm
-import tensorrt_llm.logger as logger
-import torch
-from safetensors import safe_open
-from tensorrt_llm._utils import str_dtype_to_torch, torch_to_numpy
-from tensorrt_llm.mapping import Mapping
-from tensorrt_llm.models import LLaMAForCausalLM
-from tensorrt_llm.models.quantized.quant import get_dummy_quant_scales
-from tensorrt_llm.quantization import QuantMode
-
-
-def get_scaling_factors(
- model_path: Union[str, Path],
- num_layers: int,
- quant_mode: Optional[QuantMode] = None,
-) -> Optional[Dict[str, List[int]]]:
- """Get the scaling factors for LLaMA model
-
- Returns a dictionary of scaling factors for the selected layers of the
- LLaMA model.
-
- Args:
- model_path (str): Path to the quantized LLaMA model
- layers (list): List of layers to get the scaling factors for. If None,
- all layers are selected.
-
- Returns:
- dict: Dictionary of scaling factors for the selected layers of the
- LLaMA model.
-
- example:
-
- {
- 'qkv_act': qkv_act_scale,
- 'qkv_weights': qkv_weights_scale,
- 'qkv_output' : qkv_outputs_scale,
- 'dense_act': dense_act_scale,
- 'dense_weights': dense_weights_scale,
- 'fc_act': fc_act_scale,
- 'fc_weights': fc_weights_scale,
- 'gate_act': gate_act_scale,
- 'gate_weights': gate_weights_scale,
- 'proj_act': proj_act_scale,
- 'proj_weights': proj_weights_scale,
- }
- """
-
- if model_path is None:
- logger.warning(
- f"--quantized_fp8_model_path not specified. "
- f"Initialize quantization scales automatically."
- )
- return get_dummy_quant_scales(num_layers)
- weight_dict = np.load(model_path)
-
- # yapf: disable
- scaling_factor = {
- 'qkv_act': [],
- 'qkv_weights': [],
- 'qkv_output': [],
- 'dense_act': [],
- 'dense_weights': [],
- 'fc_act': [],
- 'fc_weights': [],
- 'gate_act': [],
- 'gate_weights': [],
- 'proj_act': [],
- 'proj_weights': [],
- }
-
- for layer in range(num_layers):
- scaling_factor['qkv_act'].append(max(
- weight_dict[f'_np:layers:{layer}:attention:qkv:q:activation_scaling_factor'].item(),
- weight_dict[f'_np:layers:{layer}:attention:qkv:k:activation_scaling_factor'].item(),
- weight_dict[f'_np:layers:{layer}:attention:qkv:v:activation_scaling_factor'].item()
- ))
- scaling_factor['qkv_weights'].append(max(
- weight_dict[f'_np:layers:{layer}:attention:qkv:q:weights_scaling_factor'].item(),
- weight_dict[f'_np:layers:{layer}:attention:qkv:k:weights_scaling_factor'].item(),
- weight_dict[f'_np:layers:{layer}:attention:qkv:v:weights_scaling_factor'].item()
- ))
- if quant_mode is not None and quant_mode.has_fp8_kv_cache():
- # Not calibrarting KV cache.
- scaling_factor['qkv_output'].append(1.0)
- scaling_factor['dense_act'].append(weight_dict[f'_np:layers:{layer}:attention:dense:activation_scaling_factor'].item())
- scaling_factor['dense_weights'].append(weight_dict[f'_np:layers:{layer}:attention:dense:weights_scaling_factor'].item())
- scaling_factor['fc_act'].append(weight_dict[f'_np:layers:{layer}:mlp:fc:activation_scaling_factor'].item())
- scaling_factor['fc_weights'].append(weight_dict[f'_np:layers:{layer}:mlp:fc:weights_scaling_factor'].item())
- scaling_factor['gate_act'].append(weight_dict[f'_np:layers:{layer}:mlp:gate:activation_scaling_factor'].item())
- scaling_factor['gate_weights'].append(weight_dict[f'_np:layers:{layer}:mlp:gate:weights_scaling_factor'].item())
- scaling_factor['proj_act'].append(weight_dict[f'_np:layers:{layer}:mlp:proj:activation_scaling_factor'].item())
- scaling_factor['proj_weights'].append(weight_dict[f'_np:layers:{layer}:mlp:proj:weights_scaling_factor'].item())
- # yapf: enable
- for k, v in scaling_factor.items():
- assert (
- len(v) == num_layers
- ), f"Expect scaling factor {k} of length {num_layers}, got {len(v)}"
-
- return scaling_factor
-
-
-def gen_suffix(rank, use_smooth_quant, quant_per_channel):
- suffix = f"{rank}.bin"
- if use_smooth_quant:
- sq_prefix = "int8."
- if quant_per_channel:
- sq_prefix += "col."
- suffix = sq_prefix + suffix
- return suffix
-
-
-def extract_layer_idx(name):
- ss = name.split(".")
- for s in ss:
- if s.isdigit():
- return s
- return None
-
-
-def split(v, tp_size, idx, dim=0):
- if tp_size == 1:
- return v
- if len(v.shape) == 1:
- return np.ascontiguousarray(np.split(v, tp_size)[idx])
- else:
- return np.ascontiguousarray(np.split(v, tp_size, axis=dim)[idx])
-
-
-def dup_kv_weight(v, num_head, tp_size):
- assert tp_size % num_head == 0
- reps = tp_size // num_head
- head_size = v.shape[0] // num_head
- v = v.reshape(num_head, head_size, -1)[:, None, :, :].expand(
- num_head, reps, head_size, v.shape[1]
- )
- return v.reshape(num_head * reps * head_size, -1).clone()
-
-
-def parse_ft_config(ini_file):
- gpt_config = configparser.ConfigParser()
- gpt_config.read(ini_file)
-
- n_embd = gpt_config.getint("llama", "hidden_size")
- n_head = gpt_config.getint("llama", "num_attention_heads")
- n_layer = gpt_config.getint("llama", "num_hidden_layers")
- n_positions = gpt_config.getint("llama", "max_position_embeddings")
- vocab_size = gpt_config.getint("llama", "vocab_size")
- hidden_act = gpt_config.get("llama", "hidden_act")
- inter_size = gpt_config.getint("llama", "intermediate_size", fallback=None)
- n_kv_head = gpt_config.getint("llama", "num_key_value_heads", fallback=None)
-
- if inter_size is None:
- inter_size = 4 * n_embd
-
- return (
- n_embd,
- n_head,
- n_layer,
- n_positions,
- vocab_size,
- hidden_act,
- inter_size,
- n_kv_head,
- )
-
-
-def load_from_hf_llama(
- tensorrt_llm_llama: tensorrt_llm.models.LLaMAForCausalLM,
- hf_llama,
- mapping=Mapping(),
- dtype="float32",
-):
- tensorrt_llm.logger.info("Loading weights from HF LLaMA...")
- tik = time.time()
-
- quant_mode = getattr(tensorrt_llm_llama, "quant_mode", QuantMode(0))
- if quant_mode.is_int8_weight_only():
- plugin_weight_only_quant_type = torch.int8
- elif quant_mode.is_int4_weight_only():
- plugin_weight_only_quant_type = torch.quint4x2
- use_weight_only = quant_mode.is_weight_only()
- num_kv_heads = tensorrt_llm_llama.num_kv_heads
- mha_mode = num_kv_heads == tensorrt_llm_llama.num_heads
-
- model_params = dict(hf_llama.named_parameters())
- for l in range(hf_llama.config.num_hidden_layers):
- prefix = f"model.layers.{l}.self_attn."
- q_weight = model_params[prefix + "q_proj.weight"]
- k_weight = model_params[prefix + "k_proj.weight"]
- v_weight = model_params[prefix + "v_proj.weight"]
- if not mha_mode:
- head_size = tensorrt_llm_llama.hidden_size // tensorrt_llm_llama.num_heads
- if num_kv_heads < mapping.tp_size:
- # duplicate the KV heads up to tensor_parallel
- k_weight = dup_kv_weight(k_weight, num_kv_heads, mapping.tp_size)
- v_weight = dup_kv_weight(v_weight, num_kv_heads, mapping.tp_size)
- assert (k_weight.shape[0] % (mapping.tp_size * head_size)) == 0
- assert (v_weight.shape[0] % (mapping.tp_size * head_size)) == 0
- qkv_weight = [q_weight, k_weight, v_weight]
- else:
- qkv_weight = torch.cat([q_weight, k_weight, v_weight], dim=0)
-
- model_params[prefix + "qkv_proj.weight"] = qkv_weight
-
- torch_dtype = str_dtype_to_torch(dtype)
- layers_per_pipeline_stage = hf_llama.config.num_hidden_layers // mapping.pp_size
- layers_range = list(
- range(
- mapping.pp_rank * layers_per_pipeline_stage,
- (mapping.pp_rank + 1) * layers_per_pipeline_stage,
- 1,
- )
- )
- for k, v in model_params.items():
- if isinstance(v, list):
- v = [torch_to_numpy(vv.to(torch_dtype).detach().cpu()) for vv in v]
- else:
- v = torch_to_numpy(v.to(torch_dtype).detach().cpu())
- if "model.embed_tokens.weight" in k:
- if tensorrt_llm_llama.use_parallel_embedding:
- v = split(
- v,
- mapping.tp_size,
- mapping.tp_rank,
- tensorrt_llm_llama.embedding_sharding_dim,
- )
- if mapping.is_first_pp_rank():
- tensorrt_llm_llama.vocab_embedding.weight.value = v
- elif "model.norm.weight" in k:
- if mapping.is_last_pp_rank():
- tensorrt_llm_llama.ln_f.weight.value = v
- elif "lm_head.weight" in k:
- if mapping.is_last_pp_rank():
- tensorrt_llm_llama.lm_head.weight.value = np.ascontiguousarray(
- split(v, mapping.tp_size, mapping.tp_rank)
- )
- else:
- layer_idx = extract_layer_idx(k)
- if layer_idx is None or int(layer_idx) not in layers_range:
- continue
- idx = int(layer_idx) - mapping.pp_rank * layers_per_pipeline_stage
- if idx >= tensorrt_llm_llama.num_layers:
- continue
- if "input_layernorm.weight" in k:
- tensorrt_llm_llama.layers[idx].input_layernorm.weight.value = v
- elif "post_attention_layernorm.weight" in k:
- dst = tensorrt_llm_llama.layers[idx].post_layernorm.weight
- dst.value = v
- elif "self_attn.qkv_proj.weight" in k:
- dst = tensorrt_llm_llama.layers[idx].attention.qkv.weight
- if not mha_mode:
- assert isinstance(v, list) and len(v) == 3
- wq = split(v[0], mapping.tp_size, mapping.tp_rank)
- wk = split(v[1], mapping.tp_size, mapping.tp_rank)
- wv = split(v[2], mapping.tp_size, mapping.tp_rank)
- split_v = np.concatenate((wq, wk, wv))
- else:
- q_emb = v.shape[0] // 3
- model_emb = v.shape[1]
- v = v.reshape(3, q_emb, model_emb)
- split_v = split(v, mapping.tp_size, mapping.tp_rank, dim=1)
- split_v = split_v.reshape(3 * (q_emb // mapping.tp_size), model_emb)
- if use_weight_only:
- v = np.ascontiguousarray(split_v.transpose())
- (
- processed_torch_weights,
- torch_weight_scales,
- ) = torch.ops.fastertransformer.symmetric_quantize_last_axis_of_batched_matrix(
- torch.tensor(v), plugin_weight_only_quant_type
- )
- # workaround for trt not supporting int8 inputs in plugins currently
- dst.value = processed_torch_weights.view(
- dtype=torch.float32
- ).numpy()
- scales = tensorrt_llm_llama.layers[
- idx
- ].attention.qkv.per_channel_scale
- scales.value = torch_weight_scales.numpy()
- else:
- dst.value = np.ascontiguousarray(split_v)
- elif "self_attn.o_proj.weight" in k:
- dst = tensorrt_llm_llama.layers[idx].attention.dense.weight
- split_v = split(v, mapping.tp_size, mapping.tp_rank, dim=1)
- if use_weight_only:
- v = np.ascontiguousarray(split_v.transpose())
- (
- processed_torch_weights,
- torch_weight_scales,
- ) = torch.ops.fastertransformer.symmetric_quantize_last_axis_of_batched_matrix(
- torch.tensor(v), plugin_weight_only_quant_type
- )
- # workaround for trt not supporting int8 inputs in plugins currently
- dst.value = processed_torch_weights.view(
- dtype=torch.float32
- ).numpy()
- scales = tensorrt_llm_llama.layers[
- idx
- ].attention.dense.per_channel_scale
- scales.value = torch_weight_scales.numpy()
- else:
- dst.value = np.ascontiguousarray(split_v)
- elif "mlp.up_proj.weight" in k:
- dst = tensorrt_llm_llama.layers[idx].mlp.gate.weight
- split_v = split(v, mapping.tp_size, mapping.tp_rank, dim=0)
- if use_weight_only:
- v = np.ascontiguousarray(split_v.transpose())
- (
- processed_torch_weights,
- torch_weight_scales,
- ) = torch.ops.fastertransformer.symmetric_quantize_last_axis_of_batched_matrix(
- torch.tensor(v), plugin_weight_only_quant_type
- )
- # workaround for trt not supporting int8 inputs in plugins currently
- dst.value = processed_torch_weights.view(
- dtype=torch.float32
- ).numpy()
- scales = tensorrt_llm_llama.layers[idx].mlp.gate.per_channel_scale
- scales.value = torch_weight_scales.numpy()
- else:
- dst.value = np.ascontiguousarray(split_v)
- elif "mlp.down_proj.weight" in k:
- dst = tensorrt_llm_llama.layers[idx].mlp.proj.weight
- split_v = split(v, mapping.tp_size, mapping.tp_rank, dim=1)
- if use_weight_only:
- v = np.ascontiguousarray(split_v.transpose())
- (
- processed_torch_weights,
- torch_weight_scales,
- ) = torch.ops.fastertransformer.symmetric_quantize_last_axis_of_batched_matrix(
- torch.tensor(v), plugin_weight_only_quant_type
- )
- # workaround for trt not supporting int8 inputs in plugins currently
- dst.value = processed_torch_weights.view(
- dtype=torch.float32
- ).numpy()
- scales = tensorrt_llm_llama.layers[idx].mlp.proj.per_channel_scale
- scales.value = torch_weight_scales.numpy()
- else:
- dst.value = np.ascontiguousarray(split_v)
- elif "mlp.gate_proj.weight" in k:
- dst = tensorrt_llm_llama.layers[idx].mlp.fc.weight
- split_v = split(v, mapping.tp_size, mapping.tp_rank, dim=0)
- if use_weight_only:
- v = np.ascontiguousarray(split_v.transpose())
- (
- processed_torch_weights,
- torch_weight_scales,
- ) = torch.ops.fastertransformer.symmetric_quantize_last_axis_of_batched_matrix(
- torch.tensor(v), plugin_weight_only_quant_type
- )
- # workaround for trt not supporting int8 inputs in plugins currently
- dst.value = processed_torch_weights.view(
- dtype=torch.float32
- ).numpy()
- scales = tensorrt_llm_llama.layers[idx].mlp.fc.per_channel_scale
- scales.value = torch_weight_scales.numpy()
- else:
- dst.value = np.ascontiguousarray(split_v)
-
- tok = time.time()
- t = time.strftime("%H:%M:%S", time.gmtime(tok - tik))
- tensorrt_llm.logger.info(f"Weights loaded. Total time: {t}")
- return
-
-
-def load_from_meta_llama(
- tensorrt_llm_llama: tensorrt_llm.models.LLaMAForCausalLM,
- meta_ckpt_dir,
- mapping=Mapping(),
- dtype="float32",
-):
- torch_dtype = str_dtype_to_torch(dtype)
-
- def gather_ckpts(ckpts):
- gathered = {}
- for k in ckpts[0]:
- d = 0
- if any([n in k for n in ["wo", "w2", "tok"]]):
- d = 1
- if "norm" in k or "rope" in k: # no TP
- gathered[k] = ckpts[0][k].clone()
- else:
- gathered[k] = torch.cat([pt[k] for pt in ckpts], dim=d).clone()
- return gathered
-
- def split_ckpt(ckpt, ranks_per_ckpt, ckpt_rank):
- split_ckpt = {}
- for k in ckpt:
- d = 0
- if any([n in k for n in ["wo", "w2", "tok"]]):
- d = 1
- if "norm" in k or "rope" in k: # no TP
- split_ckpt[k] = ckpt[k].clone()
- elif tensorrt_llm_llama.num_kv_heads < mapping.tp_size and any(
- [n in k for n in ["wk", "wv"]]
- ):
- assert mapping.tp_size % tensorrt_llm_llama.num_kv_heads == 0
- # special case: we need to duplicate KV head
- tmp = dup_kv_weight(
- ckpt[k], tensorrt_llm_llama.num_kv_heads, mapping.tp_size
- )
- split_ckpt[k] = torch.split(tmp, tmp.shape[d] // ranks_per_ckpt, dim=d)[
- ckpt_rank
- ].clone()
- else:
- split_ckpt[k] = torch.split(
- ckpt[k], ckpt[k].shape[d] // ranks_per_ckpt, dim=d
- )[ckpt_rank].clone()
- return split_ckpt
-
- def get_current_weights(num_ckpts):
- if num_ckpts > mapping.tp_size:
- # combine ckpts
- assert (num_ckpts % mapping.tp_size) == 0
- nf = num_ckpts // mapping.tp_size
- fs = nf * mapping.tp_rank
- file_ids = list(range(fs, fs + nf))
- ckpts = []
- for f in file_ids:
- ckpt = torch.load(
- Path(meta_ckpt_dir, f"consolidated.{f:02d}.pth"), map_location="cpu"
- )
- ckpts.append(ckpt)
- return gather_ckpts(ckpts)
- elif num_ckpts < mapping.tp_size:
- # split ckpt
- assert (mapping.tp_size % num_ckpts) == 0
- ranks_per_ckpt = mapping.tp_size // num_ckpts
- ckpt_fid = mapping.tp_rank // ranks_per_ckpt
- ckpt_rank = mapping.tp_rank % ranks_per_ckpt
- nH_per_ckpt = tensorrt_llm_llama.num_heads // num_ckpts
- assert (nH_per_ckpt % ranks_per_ckpt) == 0
- ckpt = torch.load(
- Path(meta_ckpt_dir, f"consolidated.{ckpt_fid:02d}.pth"),
- map_location="cpu",
- )
- return split_ckpt(ckpt, ranks_per_ckpt, ckpt_rank)
-
- # num_ckpts == tensor_parallel, 1:1 mapping from files to TP
- return torch.load(
- Path(meta_ckpt_dir, f"consolidated.{mapping.tp_rank:02d}.pth"),
- map_location="cpu",
- )
-
- def permute(w, nH, d, dH):
- # due to MQA's wk, nH*dH != d could be true
- return w.view(nH, dH // 2, 2, d).transpose(1, 2).reshape(nH * dH, d)
-
- if not hasattr(load_from_meta_llama, "saved_embed"):
- load_from_meta_llama.saved_embed = None
-
- def gather_embedding(cur_embed, name: str, num_ckpts):
- if mapping.tp_size == 1:
- # even if num_ckpts > 1, get_current_weights will already have it gathered
- return cur_embed
- if load_from_meta_llama.saved_embed is None:
- embeds = [None] * num_ckpts
- for i in range(num_ckpts):
- ckpt = torch.load(
- Path(meta_ckpt_dir, f"consolidated.{i:02d}.pth"), map_location="cpu"
- )
- embeds[i] = ckpt[name]
- embed = torch.cat(embeds, dim=1).to(torch_dtype)
- load_from_meta_llama.saved_embed = torch_to_numpy(
- embed
- ) # cache the embedding, not needed if no refit
- return load_from_meta_llama.saved_embed
-
- tensorrt_llm.logger.info("Loading weights from Meta LLaMA checkpoints ...")
- tik = time.time()
-
- quant_mode = getattr(tensorrt_llm_llama, "quant_mode", QuantMode(0))
- if quant_mode.is_int8_weight_only():
- torch.int8
- elif quant_mode.is_int4_weight_only():
- torch.quint4x2
- quant_mode.is_weight_only()
- num_kv_heads = tensorrt_llm_llama.num_kv_heads
- mha_mode = num_kv_heads == tensorrt_llm_llama.num_heads
-
- ckpts = list(Path(meta_ckpt_dir).glob("consolidated.*.pth"))
- num_ckpts = len(ckpts)
- # llama/llama2 doesn't have MQA. So, simplifying loader logic by not worrying about it.
- assert (
- num_kv_heads > 1 or num_kv_heads >= num_ckpts
- ), f"We don't know how the {num_kv_heads} KV heads are distributed among {num_ckpts} checkpoints."
-
- head_size = tensorrt_llm_llama.hidden_size // tensorrt_llm_llama.num_heads
- ckpt = get_current_weights(num_ckpts)
- layers_range = list(
- range(
- mapping.pp_rank * tensorrt_llm_llama.num_layers,
- (mapping.pp_rank + 1) * tensorrt_llm_llama.num_layers,
- 1,
- )
- )
-
- for l in layers_range:
- prefix = f"layers.{l}.attention."
- q_weight = permute(
- ckpt[prefix + "wq.weight"].clone(),
- nH=(tensorrt_llm_llama.num_heads // mapping.tp_size),
- d=tensorrt_llm_llama.hidden_size,
- dH=head_size,
- )
- if num_kv_heads < mapping.tp_size and num_ckpts >= mapping.tp_size:
- assert mapping.tp_size % num_kv_heads == 0
- assert False, "Not supported yet"
- k_weight = permute(
- ckpt[prefix + "wk.weight"].clone(),
- nH=((num_kv_heads + mapping.tp_size - 1) // mapping.tp_size),
- d=tensorrt_llm_llama.hidden_size,
- dH=head_size,
- )
- v_weight = ckpt[prefix + "wv.weight"].clone()
-
- qkv_weight = torch.cat([q_weight, k_weight, v_weight], dim=0)
- ckpt[prefix + "qkv.weight"] = qkv_weight
-
- for k, v in ckpt.items():
- v = torch_to_numpy(v.to(torch_dtype).detach().cpu())
- if "tok_embeddings" in k:
- if not tensorrt_llm_llama.use_parallel_embedding:
- v = gather_embedding(v, k, num_ckpts)
- elif tensorrt_llm_llama.embedding_sharding_dim == 0:
- # this needs a gather and then resplit along different dims
- v = gather_embedding(v, k, num_ckpts)
- v = split(v, mapping.tp_size, mapping.tp_rank, 0)
- if mapping.is_first_pp_rank():
- tensorrt_llm_llama.vocab_embedding.weight.value = v
- elif "output" in k:
- if mapping.is_last_pp_rank():
- tensorrt_llm_llama.lm_head.weight.value = v
- elif k == "norm.weight":
- if mapping.is_last_pp_rank():
- tensorrt_llm_llama.ln_f.weight.value = v
- else:
- # layer specific weights
- layer_idx = extract_layer_idx(k)
- if layer_idx is None:
- continue
- idx = int(layer_idx) - mapping.pp_rank * tensorrt_llm_llama.num_layers
- if idx >= tensorrt_llm_llama.num_layers:
- continue
- if "attention_norm.weight" in k:
- tensorrt_llm_llama.layers[idx].input_layernorm.weight.value = v
- elif "ffn_norm.weight" in k:
- tensorrt_llm_llama.layers[idx].post_layernorm.weight.value = v
- elif "feed_forward.w3.weight" in k:
- tensorrt_llm_llama.layers[idx].mlp.gate.weight.value = v
- elif "feed_forward.w2.weight" in k:
- tensorrt_llm_llama.layers[idx].mlp.proj.weight.value = v
- elif "feed_forward.w1.weight" in k:
- tensorrt_llm_llama.layers[idx].mlp.fc.weight.value = v
- elif "attention.wo.weight" in k:
- tensorrt_llm_llama.layers[idx].attention.dense.weight.value = v
- elif "attention.qkv.weight" in k:
- tensorrt_llm_llama.layers[idx].attention.qkv.weight.value = v
-
- tok = time.time()
- t = time.strftime("%H:%M:%S", time.gmtime(tok - tik))
- tensorrt_llm.logger.info(f"Weights loaded. Total time: {t}")
- return
-
-
-def load_from_binary(
- tensorrt_llm_llama: LLaMAForCausalLM,
- dir_path,
- mapping=Mapping(),
- fp16=False,
- multi_query_mode=False,
-):
- tensorrt_llm.logger.info("Loading weights from FT...")
- tik = time.time()
-
- quant_mode = getattr(tensorrt_llm_llama, "quant_mode", QuantMode(0))
-
- (
- n_embd,
- n_head,
- n_layer,
- n_positions,
- vocab_size,
- hidden_act,
- inter_size,
- n_kv_head,
- ) = parse_ft_config(Path(dir_path) / "config.ini")
- np_dtype = np.float16 if fp16 else np.float32
-
- def fromfile(dir_path, name, shape=None, dtype=None):
- dtype = np_dtype if dtype is None else dtype
- p = dir_path + "/" + name
- if Path(p).exists():
- t = np.fromfile(p, dtype=dtype)
- if shape is not None:
- t = t.reshape(shape)
- return t
- return None
-
- def set_smoothquant_scale_factors(
- module,
- pre_scale_weight,
- dir_path,
- basename,
- shape,
- per_tok_dyn,
- per_channel,
- is_qkv=False,
- rank=None,
- ):
- suffix = "bin"
- if per_channel:
- if rank is not None:
- suffix = f"{rank}." + suffix
- suffix = "col." + suffix
-
- col_shape = shape if (per_channel or is_qkv) else [1, 1]
-
- if per_tok_dyn:
- if pre_scale_weight is not None:
- pre_scale_weight.value = np.array([1.0], dtype=np.float32)
- if is_qkv and not per_channel:
- t = fromfile(
- dir_path,
- f"{basename}scale_w_quant_orig.{rank}.{suffix}",
- col_shape,
- np.float32,
- )
- else:
- t = fromfile(
- dir_path,
- f"{basename}scale_w_quant_orig.{suffix}",
- col_shape,
- np.float32,
- )
- module.per_channel_scale.value = t
- else:
- t = fromfile(dir_path, f"{basename}scale_x_orig_quant.bin", [1], np.float32)
- pre_scale_weight.value = t
- if is_qkv:
- t = fromfile(
- dir_path,
- f"{basename}scale_y_accum_quant.{rank}.{suffix}",
- col_shape,
- np.float32,
- )
- else:
- t = fromfile(
- dir_path,
- f"{basename}scale_y_accum_quant.{suffix}",
- col_shape,
- np.float32,
- )
- module.per_channel_scale.value = t
- t = fromfile(
- dir_path, f"{basename}scale_y_quant_orig.bin", [1, 1], np.float32
- )
- module.act_scale.value = t
-
- def set_smoother(module, dir_path, base_name, shape, rank):
- suffix = f"{rank}.bin"
- t = fromfile(dir_path, f"{base_name}.smoother.{suffix}", shape, np.float32)
- module.smoother.value = t
-
- # Determine the quantization mode.
- quant_mode = getattr(tensorrt_llm_llama, "quant_mode", QuantMode(0))
- if quant_mode.is_int8_weight_only():
- plugin_weight_only_quant_type = torch.int8
- elif quant_mode.is_int4_weight_only():
- plugin_weight_only_quant_type = torch.quint4x2
- # Do we use SmoothQuant?
- use_smooth_quant = quant_mode.has_act_and_weight_quant()
- # Do we use quantization per token?
- quant_per_token_dyn = quant_mode.has_per_token_dynamic_scaling()
- # Do we use quantization per channel?
- quant_per_channel = quant_mode.has_per_channel_scaling()
-
- # Do we use INT4/INT8 weight-only?
- use_weight_only = quant_mode.is_weight_only()
-
- # Int8 KV cache
- use_int8_kv_cache = quant_mode.has_int8_kv_cache()
-
- def sq_trick(x):
- return x.view(np.float32) if use_smooth_quant else x
-
- # Debug
- suffix = gen_suffix(mapping.tp_rank, use_smooth_quant, quant_per_channel)
- # The type of weights.
- w_type = np_dtype if not use_smooth_quant else np.int8
-
- if mapping.is_first_pp_rank():
- tensorrt_llm_llama.vocab_embedding.weight.value = fromfile(
- dir_path, "vocab_embedding.weight.bin", [vocab_size, n_embd]
- )
-
- if mapping.is_last_pp_rank():
- tensorrt_llm_llama.ln_f.weight.value = fromfile(dir_path, "ln_f.weight.bin")
- # share input embedding
- lm_head_weight = fromfile(dir_path, "lm_head.weight.bin", [vocab_size, n_embd])
-
- if vocab_size % mapping.tp_size != 0:
- # padding
- vocab_size_padded = tensorrt_llm_llama.lm_head.out_features * mapping.tp_size
- pad_width = vocab_size_padded - vocab_size
- lm_head_weight = np.pad(
- lm_head_weight, ((0, pad_width), (0, 0)), "constant", constant_values=0
- )
- if mapping.is_last_pp_rank():
- tensorrt_llm_llama.lm_head.weight.value = np.ascontiguousarray(
- split(lm_head_weight, mapping.tp_size, mapping.tp_rank)
- )
-
- layers_range = list(
- range(
- mapping.pp_rank * tensorrt_llm_llama.num_layers,
- (mapping.pp_rank + 1) * tensorrt_llm_llama.num_layers,
- 1,
- )
- )
-
- for i in layers_range:
- n_groups = n_head // n_kv_head
- c_attn_out_dim = (
- (3 * n_embd // mapping.tp_size)
- if not multi_query_mode
- else (
- n_embd // mapping.tp_size
- + (n_embd // n_head * n_groups) // mapping.tp_size * 2
- )
- )
- idx = i - mapping.pp_rank * tensorrt_llm_llama.num_layers
- tensorrt_llm_llama.layers[idx].input_layernorm.weight.value = fromfile(
- dir_path, "model.layers." + str(i) + ".input_layernorm.weight.bin"
- )
- t = fromfile(
- dir_path,
- "model.layers." + str(i) + ".attention.query_key_value.weight." + suffix,
- [n_embd, c_attn_out_dim],
- w_type,
- )
- if t is not None:
- dst = tensorrt_llm_llama.layers[idx].attention.qkv.weight
- if use_smooth_quant:
- dst.value = sq_trick(np.ascontiguousarray(np.transpose(t, [1, 0])))
- set_smoothquant_scale_factors(
- tensorrt_llm_llama.layers[idx].attention.qkv,
- tensorrt_llm_llama.layers[idx].input_layernorm.scale_to_int,
- dir_path,
- "model.layers." + str(i) + ".attention.query_key_value.",
- [1, c_attn_out_dim],
- quant_per_token_dyn,
- quant_per_channel,
- rank=mapping.tp_rank,
- is_qkv=True,
- )
- elif use_weight_only:
- (
- processed_torch_weights,
- torch_weight_scales,
- ) = torch.ops.fastertransformer.symmetric_quantize_last_axis_of_batched_matrix(
- torch.tensor(t), plugin_weight_only_quant_type
- )
- # workaround for trt not supporting int8 inputs in plugins currently
- dst.value = processed_torch_weights.view(dtype=torch.float32).numpy()
- scales = tensorrt_llm_llama.layers[i].attention.qkv.per_channel_scale
- scales.value = torch_weight_scales.numpy()
- else:
- dst.value = np.ascontiguousarray(np.transpose(t, [1, 0]))
-
- dst = tensorrt_llm_llama.layers[idx].attention.dense.weight
- t = fromfile(
- dir_path,
- "model.layers." + str(i) + ".attention.dense.weight." + suffix,
- [n_embd // mapping.tp_size, n_embd],
- w_type,
- )
- if use_smooth_quant:
- dst.value = sq_trick(np.ascontiguousarray(np.transpose(t, [1, 0])))
- dense_scale = getattr(
- tensorrt_llm_llama.layers[idx].attention,
- "quantization_scaling_factor",
- None,
- )
- set_smoothquant_scale_factors(
- tensorrt_llm_llama.layers[idx].attention.dense,
- dense_scale,
- dir_path,
- "model.layers." + str(i) + ".attention.dense.",
- [1, n_embd],
- quant_per_token_dyn,
- quant_per_channel,
- )
- set_smoother(
- tensorrt_llm_llama.layers[idx].attention.dense,
- dir_path,
- "model.layers." + str(i) + ".attention.dense",
- [1, n_embd // mapping.tp_size],
- mapping.tp_rank,
- )
- elif use_weight_only:
- (
- processed_torch_weights,
- torch_weight_scales,
- ) = torch.ops.fastertransformer.symmetric_quantize_last_axis_of_batched_matrix(
- torch.tensor(t), plugin_weight_only_quant_type
- )
- # workaround for trt not supporting int8 inputs in plugins currently
- dst.value = processed_torch_weights.view(dtype=torch.float32).numpy()
- scales = tensorrt_llm_llama.layers[i].attention.dense.per_channel_scale
- scales.value = torch_weight_scales.numpy()
- else:
- dst.value = np.ascontiguousarray(np.transpose(t, [1, 0]))
-
- dst = tensorrt_llm_llama.layers[idx].post_layernorm.weight
- dst.value = fromfile(
- dir_path, "model.layers." + str(i) + ".post_layernorm.weight.bin"
- )
-
- t = fromfile(
- dir_path,
- "model.layers." + str(i) + ".mlp.fc.weight." + suffix,
- [n_embd, inter_size // mapping.tp_size],
- w_type,
- )
-
- if use_smooth_quant:
- tensorrt_llm_llama.layers[idx].mlp.fc.weight.value = sq_trick(
- np.ascontiguousarray(np.transpose(t, [1, 0]))
- )
- set_smoothquant_scale_factors(
- tensorrt_llm_llama.layers[idx].mlp.fc,
- tensorrt_llm_llama.layers[idx].post_layernorm.scale_to_int,
- dir_path,
- "model.layers." + str(i) + ".mlp.fc.",
- [1, inter_size // mapping.tp_size],
- quant_per_token_dyn,
- quant_per_channel,
- rank=mapping.tp_rank,
- )
- elif use_weight_only:
- dst = tensorrt_llm_llama.layers[i].mlp.fc.weight
- (
- processed_torch_weights,
- torch_weight_scales,
- ) = torch.ops.fastertransformer.symmetric_quantize_last_axis_of_batched_matrix(
- torch.tensor(t), plugin_weight_only_quant_type
- )
- # workaround for trt not supporting int8 inputs in plugins currently
- dst.value = processed_torch_weights.view(dtype=torch.float32).numpy()
- scales = tensorrt_llm_llama.layers[i].mlp.fc.per_channel_scale
- scales.value = torch_weight_scales.numpy()
- else:
- tensorrt_llm_llama.layers[idx].mlp.fc.weight.value = np.ascontiguousarray(
- np.transpose(t, [1, 0])
- )
-
- t = fromfile(
- dir_path,
- "model.layers." + str(i) + ".mlp.gate.weight." + suffix,
- [n_embd, inter_size // mapping.tp_size],
- w_type,
- )
- if use_smooth_quant:
- tensorrt_llm_llama.layers[idx].mlp.gate.weight.value = sq_trick(
- np.ascontiguousarray(np.transpose(t, [1, 0]))
- )
- set_smoothquant_scale_factors(
- tensorrt_llm_llama.layers[idx].mlp.gate,
- tensorrt_llm_llama.layers[idx].post_layernorm.scale_to_int,
- dir_path,
- "model.layers." + str(i) + ".mlp.gate.",
- [1, inter_size // mapping.tp_size],
- quant_per_token_dyn,
- quant_per_channel,
- rank=mapping.tp_rank,
- )
- elif use_weight_only:
- dst = tensorrt_llm_llama.layers[i].mlp.gate.weight
- (
- processed_torch_weights,
- torch_weight_scales,
- ) = torch.ops.fastertransformer.symmetric_quantize_last_axis_of_batched_matrix(
- torch.tensor(t), plugin_weight_only_quant_type
- )
- # workaround for trt not supporting int8 inputs in plugins currently
- dst.value = processed_torch_weights.view(dtype=torch.float32).numpy()
- scales = tensorrt_llm_llama.layers[i].mlp.gate.per_channel_scale
- scales.value = torch_weight_scales.numpy()
- else:
- tensorrt_llm_llama.layers[idx].mlp.gate.weight.value = np.ascontiguousarray(
- np.transpose(t, [1, 0])
- )
-
- t = fromfile(
- dir_path,
- "model.layers." + str(i) + ".mlp.proj.weight." + suffix,
- [inter_size // mapping.tp_size, n_embd],
- w_type,
- )
- if use_smooth_quant:
- tensorrt_llm_llama.layers[idx].mlp.proj.weight.value = sq_trick(
- np.ascontiguousarray(np.transpose(t, [1, 0]))
- )
- proj_scale = getattr(
- tensorrt_llm_llama.layers[idx].mlp, "quantization_scaling_factor", None
- )
- set_smoothquant_scale_factors(
- tensorrt_llm_llama.layers[idx].mlp.proj,
- proj_scale,
- dir_path,
- "model.layers." + str(i) + ".mlp.proj.",
- [1, n_embd],
- quant_per_token_dyn,
- quant_per_channel,
- )
- set_smoother(
- tensorrt_llm_llama.layers[idx].mlp.proj,
- dir_path,
- "model.layers." + str(i) + ".mlp.proj",
- [1, inter_size // mapping.tp_size],
- mapping.tp_rank,
- )
- elif use_weight_only:
- dst = tensorrt_llm_llama.layers[i].mlp.proj.weight
- (
- processed_torch_weights,
- torch_weight_scales,
- ) = torch.ops.fastertransformer.symmetric_quantize_last_axis_of_batched_matrix(
- torch.tensor(t), plugin_weight_only_quant_type
- )
- # workaround for trt not supporting int8 inputs in plugins currently
- dst.value = processed_torch_weights.view(dtype=torch.float32).numpy()
- scales = tensorrt_llm_llama.layers[i].mlp.proj.per_channel_scale
- scales.value = torch_weight_scales.numpy()
- else:
- tensorrt_llm_llama.layers[idx].mlp.proj.weight.value = np.ascontiguousarray(
- np.transpose(t, [1, 0])
- )
-
- if use_int8_kv_cache:
- t = fromfile(
- dir_path,
- "model.layers."
- + str(i)
- + ".attention.query_key_value.scale_y_quant_orig.bin",
- [1],
- np.float32,
- )
- tensorrt_llm_llama.layers[idx].attention.kv_orig_quant_scale.value = 1.0 / t
- tensorrt_llm_llama.layers[idx].attention.kv_quant_orig_scale.value = t
-
- tok = time.time()
- t = time.strftime("%H:%M:%S", time.gmtime(tok - tik))
- tensorrt_llm.logger.info(f"Weights loaded. Total time: {t}")
-
-
-def load_from_gptq_llama(
- tensorrt_llm_llama, quant_ckpt_path, mapping=Mapping(), dtype="float16"
-):
- tensorrt_llm.logger.info("Loading weights from groupwise GPTQ LLaMA safetensors...")
- tik = time.time()
-
- if quant_ckpt_path.endswith(".safetensors"):
- groupwise_qweight_safetensors = safe_open(
- quant_ckpt_path, framework="pt", device=0
- )
- model_params = {
- key: groupwise_qweight_safetensors.get_tensor(key)
- for key in groupwise_qweight_safetensors.keys()
- }
- elif quant_ckpt_path.endswith(".pt"):
- model_params = torch.load(quant_ckpt_path, map_location=torch.device("cpu"))
- else:
- assert False, "Quantized checkpoint format not supported!"
-
- def unpack_int32_into_int8(w_packed):
- # Unpack inputs packed in int32/float32 into uint4 and store them in int8 format
- w_packed_int4x2 = w_packed.contiguous().view(torch.uint8)
- w_unpacked = torch.zeros(
- w_packed_int4x2.shape[0], w_packed_int4x2.shape[1] * 2, dtype=torch.int8
- )
- w_unpacked[:, ::2] = w_packed_int4x2 % 16
- w_unpacked[:, 1::2] = w_packed_int4x2 // 16
- return w_unpacked.contiguous()
-
- def preprocess_groupwise_weight_params(
- weight_name, qweight_int32=None, qzeros_int32=None, scales_fp16=None
- ):
- if weight_name is not None:
- qweight_int32 = model_params[weight_name].cpu()
- qzeros_int32 = model_params[weight_name[:-7] + "qzeros"].cpu()
- scales_fp16 = model_params[weight_name[:-7] + "scales"].cpu()
-
- UINT4_TO_INT4_FLAG = 1
- GPTQ_FLAG = 1
- packer = torch.ops.fastertransformer.pack_int8_tensor_to_packed_int4
- preprocessor = torch.ops.fastertransformer.preprocess_weights_for_mixed_gemm
-
- qweight_unpacked_int8 = (
- unpack_int32_into_int8(qweight_int32.T).T.contiguous() - 8
- )
- qweight_interleaved = preprocessor(
- packer(qweight_unpacked_int8), torch.quint4x2
- ).view(torch.float32)
- # zeros = zeros * scales
- qzeros_unpacked_int32 = unpack_int32_into_int8(qzeros_int32)
- zeros_x_scales_fp16 = (
- -qzeros_unpacked_int32 + 8 * UINT4_TO_INT4_FLAG - GPTQ_FLAG
- ) * scales_fp16
- zeros_x_scales_fp16 = zeros_x_scales_fp16.half()
-
- # return processed interleaved weight, original scales and zeros * scales
- return (
- qweight_interleaved.contiguous(),
- scales_fp16.contiguous(),
- zeros_x_scales_fp16.contiguous(),
- )
-
- layer_ids = [extract_layer_idx(key) for key in groupwise_qweight_safetensors.keys()]
- layer_ids = [int(layer_idx) for layer_idx in layer_ids if layer_idx is not None]
- num_hidden_layers = max(layer_ids) + 1
- num_kv_heads = tensorrt_llm_llama.num_kv_heads
- mha_mode = num_kv_heads == tensorrt_llm_llama.num_heads
- suffixs = ["qweight", "qzeros", "scales"]
-
- layers_per_pipeline_stage = num_hidden_layers // mapping.pp_size
- layers_range = list(
- range(
- mapping.pp_rank * layers_per_pipeline_stage,
- (mapping.pp_rank + 1) * layers_per_pipeline_stage,
- 1,
- )
- )
-
- for l in layers_range:
- prefix = f"model.layers.{l}.self_attn."
- split_qkv_suf = []
-
- for suf in suffixs:
- q_part = model_params[prefix + "q_proj." + suf].cpu()
- k_part = model_params[prefix + "k_proj." + suf].cpu()
- v_part = model_params[prefix + "v_proj." + suf].cpu()
- qkv_part = torch.cat([q_part, k_part, v_part], dim=0)
- dim = qkv_part.shape
- qkv_part = qkv_part.reshape(3, dim[0] // 3, dim[1])
- split_qkv = qkv_part.split(dim[1] // mapping.tp_size, dim=2)[
- mapping.tp_rank
- ]
- split_qkv = torch.cat(
- [
- split_qkv[0, :, :].squeeze(0),
- split_qkv[1, :, :].squeeze(0),
- split_qkv[2, :, :].squeeze(0),
- ],
- dim=1,
- )
- split_qkv_suf.append(split_qkv)
-
- th_qweight, th_zero, th_scale = preprocess_groupwise_weight_params(
- None, split_qkv_suf[0], split_qkv_suf[1], split_qkv_suf[2]
- )
-
- idx = l - mapping.pp_rank * layers_per_pipeline_stage
- tensorrt_llm_llama.layers[idx].attention.qkv.qweight.value = th_qweight.numpy()
- tensorrt_llm_llama.layers[idx].attention.qkv.scale.value = th_zero.numpy()
- tensorrt_llm_llama.layers[idx].attention.qkv.zero.value = th_scale.numpy()
-
- torch_dtype = str_dtype_to_torch(dtype)
-
- for k, v in model_params.items():
- if isinstance(v, list):
- v = [torch_to_numpy(vv.to(torch_dtype).detach().cpu()) for vv in v]
- else:
- v = torch_to_numpy(v.to(torch_dtype).detach().cpu())
- if "model.embed_tokens.weight" in k:
- if mapping.is_first_pp_rank():
- tensorrt_llm_llama.vocab_embedding.weight.value = v
- elif "model.norm.weight" in k:
- if mapping.is_last_pp_rank():
- tensorrt_llm_llama.ln_f.weight.value = v
- elif "lm_head.weight" in k:
- if mapping.is_last_pp_rank():
- tensorrt_llm_llama.lm_head.weight.value = np.ascontiguousarray(
- split(v, mapping.tp_size, mapping.tp_rank)
- )
- else:
- layer_idx = extract_layer_idx(k)
- if layer_idx is None:
- continue
- idx = int(layer_idx)
- if idx not in layers_range:
- continue
- idx = idx - mapping.pp_rank * layers_per_pipeline_stage
-
- if "input_layernorm.weight" in k:
- tensorrt_llm_llama.layers[idx].input_layernorm.weight.value = v
- elif "post_attention_layernorm.weight" in k:
- tensorrt_llm_llama.layers[idx].post_layernorm.weight.value = v
- elif "self_attn.o_proj.qweight" in k:
- split_v_suf = []
- for suf in suffixs:
- v = model_params[k[:-7] + suf].cpu()
- split_v = v.split(v.shape[0] // mapping.tp_size, dim=0)[
- mapping.tp_rank
- ]
- split_v_suf.append(split_v)
- th_qweight, th_zero, th_scale = preprocess_groupwise_weight_params(
- None, split_v_suf[0], split_v_suf[1], split_v_suf[2]
- )
- tensorrt_llm_llama.layers[
- idx
- ].attention.dense.qweight.value = th_qweight.numpy()
- tensorrt_llm_llama.layers[
- idx
- ].attention.dense.scale.value = th_zero.numpy()
- tensorrt_llm_llama.layers[
- idx
- ].attention.dense.zero.value = th_scale.numpy()
- elif "mlp.up_proj.qweight" in k:
- split_v_suf = []
- for suf in suffixs:
- v = model_params[k[:-7] + suf].cpu()
- split_v = v.split(v.shape[1] // mapping.tp_size, dim=1)[
- mapping.tp_rank
- ]
- split_v_suf.append(split_v)
- th_qweight, th_zero, th_scale = preprocess_groupwise_weight_params(
- None, split_v_suf[0], split_v_suf[1], split_v_suf[2]
- )
- tensorrt_llm_llama.layers[
- idx
- ].mlp.gate.qweight.value = th_qweight.numpy()
- tensorrt_llm_llama.layers[idx].mlp.gate.scale.value = th_zero.numpy()
- tensorrt_llm_llama.layers[idx].mlp.gate.zero.value = th_scale.numpy()
- elif "mlp.down_proj.qweight" in k:
- split_v_suf = []
- for suf in suffixs:
- v = model_params[k[:-7] + suf].cpu()
- split_v = v.split(v.shape[0] // mapping.tp_size, dim=0)[
- mapping.tp_rank
- ]
- split_v_suf.append(split_v)
- th_qweight, th_zero, th_scale = preprocess_groupwise_weight_params(
- None, split_v_suf[0], split_v_suf[1], split_v_suf[2]
- )
- tensorrt_llm_llama.layers[
- idx
- ].mlp.proj.qweight.value = th_qweight.numpy()
- tensorrt_llm_llama.layers[idx].mlp.proj.scale.value = th_zero.numpy()
- tensorrt_llm_llama.layers[idx].mlp.proj.zero.value = th_scale.numpy()
- elif "mlp.gate_proj.qweight" in k:
- split_v_suf = []
- for suf in suffixs:
- v = model_params[k[:-7] + suf].cpu()
- split_v = v.split(v.shape[1] // mapping.tp_size, dim=1)[
- mapping.tp_rank
- ]
- split_v_suf.append(split_v)
- th_qweight, th_zero, th_scale = preprocess_groupwise_weight_params(
- None, split_v_suf[0], split_v_suf[1], split_v_suf[2]
- )
- tensorrt_llm_llama.layers[idx].mlp.fc.qweight.value = th_qweight.numpy()
- tensorrt_llm_llama.layers[idx].mlp.fc.scale.value = th_zero.numpy()
- tensorrt_llm_llama.layers[idx].mlp.fc.zero.value = th_scale.numpy()
-
- tok = time.time()
- t = time.strftime("%H:%M:%S", time.gmtime(tok - tik))
- tensorrt_llm.logger.info(f"Weights loaded. Total time: {t}")
- return
-
-
-def load_from_awq_llama(
- tensorrt_llm_llama: LLaMAForCausalLM,
- quant_ckpt_path,
- mapping=Mapping(),
- dtype="float16",
-):
- tensorrt_llm.logger.info("Loading weights from groupwise AWQ LLaMA safetensors...")
- tik = time.time()
-
- if quant_ckpt_path.endswith(".safetensors"):
- groupwise_qweight_safetensors = safe_open(
- quant_ckpt_path, framework="pt", device=0
- )
- awq_llama = {
- key: groupwise_qweight_safetensors.get_tensor(key)
- for key in groupwise_qweight_safetensors.keys()
- }
- elif quant_ckpt_path.endswith(".pt"):
- awq_llama = torch.load(quant_ckpt_path, map_location=torch.device("cpu"))
- else:
- assert False, "Quantized checkpoint format not supported!"
-
- group_size = (
- awq_llama["model.layers.0.self_attn.o_proj.weight"].numel()
- // awq_llama["model.layers.0.self_attn.o_proj.weight_quantizer._amax"].numel()
- )
-
- awq_llama_block_names = [
- "input_layernorm.weight",
- "post_attention_layernorm.weight",
- ]
-
- tensorrt_llm_llama_block_names = [
- "input_layernorm.weight",
- "post_layernorm.weight",
- ]
-
- getattr(tensorrt_llm_llama, "quant_mode", QuantMode(0))
-
- packer = torch.ops.fastertransformer.pack_int8_tensor_to_packed_int4
- preprocessor = torch.ops.fastertransformer.preprocess_weights_for_mixed_gemm
- torch_dtype = str_dtype_to_torch(dtype)
-
- def AWQ_quantize_pack_preprocess(weight, scale):
- scale = scale.repeat_interleave(group_size, dim=0)
- weight = weight / scale
- qweight_int8 = torch.clamp(torch.round(weight.cuda()).char(), -8, 7)
- int4_weight = packer(qweight_int8.cpu())
- int4_weight = preprocessor(int4_weight, torch.quint4x2)
- return int4_weight.view(torch.float32).cpu().numpy()
-
- def process_and_assign_weight(awq_llama, mPrefix, mOp, tp_dim=0):
- weight = awq_llama[mPrefix + ".weight"].T.contiguous()
- [k, n] = weight.shape
- weight = weight.split(weight.shape[tp_dim] // mapping.tp_size, dim=tp_dim)[
- mapping.tp_rank
- ]
- amax = (
- awq_llama[mPrefix + ".weight_quantizer._amax"]
- .reshape((n, int(k / group_size)))
- .T.contiguous()
- )
- amax = amax.split(amax.shape[tp_dim] // mapping.tp_size, dim=tp_dim)[
- mapping.tp_rank
- ]
- pre_quant_scale = awq_llama[
- mPrefix + ".input_quantizer._pre_quant_scale"
- ].reshape((1, k))
- if tp_dim == 0:
- pre_quant_scale = pre_quant_scale.split(k // mapping.tp_size, dim=1)[
- mapping.tp_rank
- ]
- scale = amax / 8.0
- mOp.qweight.value = AWQ_quantize_pack_preprocess(weight, scale)
- mOp.scale.value = scale.to(torch_dtype).cpu().numpy()
- mOp.pre_quant_scale.value = pre_quant_scale.to(torch_dtype).cpu().numpy()
-
- def deSmooth(weight, pre_quant_scale):
- [k, n] = weight.shape
- pre_quant_scale = pre_quant_scale.repeat((n, 1)).transpose(1, 0).contiguous()
- weight = weight * pre_quant_scale
- return weight
-
- def reSmooth(weight, pre_quant_scale):
- [k, n] = weight.shape
- pre_quant_scale = pre_quant_scale.repeat((n, 1)).transpose(1, 0).contiguous()
- weight = weight / pre_quant_scale
- return weight
-
- def get_scale(weight):
- weight = weight.T.contiguous()
- [n, k] = weight.shape
- weight = weight.reshape(n, int(k / group_size), group_size)
- weight = torch.abs(weight.reshape(-1, group_size))
- amax, idx = weight.max(1)
- amax = amax.reshape(n, int(k / group_size)).T.contiguous()
- return amax / 8
-
- def reSmooth_and_get_scale(weight, pre_quant_scale, avg_pre_quant_scale):
- weight = deSmooth(weight, pre_quant_scale)
- weight = reSmooth(weight, avg_pre_quant_scale)
- scale = get_scale(weight)
- return weight, scale
-
- def process_and_assign_qkv_weight(awq_llama, prefix, mOp):
- q_weight = awq_llama[prefix + "self_attn.q_proj.weight"].T.contiguous()
- k_weight = awq_llama[prefix + "self_attn.k_proj.weight"].T.contiguous()
- v_weight = awq_llama[prefix + "self_attn.v_proj.weight"].T.contiguous()
- k = q_weight.shape[0]
-
- q_weight = q_weight.split(q_weight.shape[1] // mapping.tp_size, dim=1)[
- mapping.tp_rank
- ]
- k_weight = k_weight.split(k_weight.shape[1] // mapping.tp_size, dim=1)[
- mapping.tp_rank
- ]
- v_weight = v_weight.split(v_weight.shape[1] // mapping.tp_size, dim=1)[
- mapping.tp_rank
- ]
-
- q_pre_quant_scale = awq_llama[
- prefix + "self_attn.q_proj.input_quantizer._pre_quant_scale"
- ].reshape((1, k))
- k_pre_quant_scale = awq_llama[
- prefix + "self_attn.k_proj.input_quantizer._pre_quant_scale"
- ].reshape((1, k))
- v_pre_quant_scale = awq_llama[
- prefix + "self_attn.v_proj.input_quantizer._pre_quant_scale"
- ].reshape((1, k))
-
- qkv_pre_quant_scale = (
- q_pre_quant_scale + k_pre_quant_scale + v_pre_quant_scale
- ) / 3.0
- q_weight, q_scale = reSmooth_and_get_scale(
- q_weight, q_pre_quant_scale, qkv_pre_quant_scale
- )
- k_weight, k_scale = reSmooth_and_get_scale(
- k_weight, k_pre_quant_scale, qkv_pre_quant_scale
- )
- v_weight, v_scale = reSmooth_and_get_scale(
- v_weight, v_pre_quant_scale, qkv_pre_quant_scale
- )
-
- qkv_weights = torch.cat((q_weight, k_weight, v_weight), dim=1)
- qkv_scale = torch.cat((q_scale, k_scale, v_scale), dim=1)
-
- mOp.pre_quant_scale.value = qkv_pre_quant_scale.to(torch_dtype).cpu().numpy()
- mOp.qweight.value = AWQ_quantize_pack_preprocess(qkv_weights, qkv_scale)
- mOp.scale.value = qkv_scale.to(torch_dtype).cpu().numpy()
-
- # Check if we need to pad vocab
- v = awq_llama.get("model.embed_tokens.weight")
- [vocab_size, k] = v.shape
- pad_vocab = False
- pad_vocab_size = vocab_size
- if vocab_size % 64 != 0:
- pad_vocab = True
- pad_vocab_size = int((vocab_size + 63) / 64) * 64
- if pad_vocab:
- new_v = torch.zeros([pad_vocab_size, k])
- new_v[:vocab_size, :] = v
- v = new_v
- if mapping.is_first_pp_rank():
- tensorrt_llm_llama.vocab_embedding.weight.value = (
- v.to(torch_dtype).cpu().numpy()
- )
-
- layer_ids = [extract_layer_idx(key) for key in awq_llama.keys()]
- layer_ids = [int(layer_idx) for layer_idx in layer_ids if layer_idx is not None]
-
- num_hidden_layers = max(layer_ids) + 1
- layers_per_pipeline_stage = num_hidden_layers // mapping.pp_size
- layers_range = list(
- range(
- mapping.pp_rank * layers_per_pipeline_stage,
- (mapping.pp_rank + 1) * layers_per_pipeline_stage,
- 1,
- )
- )
-
- for layer_idx in layers_range:
- prefix = "model.layers." + str(layer_idx) + "."
- tensorrt_llm.logger.info(f"Process weights in layer: {layer_idx}")
- for idx, awq_attr in enumerate(awq_llama_block_names):
- v = awq_llama[prefix + awq_attr]
- layer = attrgetter(tensorrt_llm_llama_block_names[idx])(
- tensorrt_llm_llama.layers[layer_idx]
- )
- setattr(layer, "value", v.to(torch_dtype).cpu().numpy())
-
- # Attention QKV Linear
- # concatenate the Q, K, V layers weights.
- process_and_assign_qkv_weight(
- awq_llama, prefix, tensorrt_llm_llama.layers[layer_idx].attention.qkv
- )
-
- # Attention Dense (out_proj) Linear
- mPrefix = prefix + "self_attn.o_proj"
- mOp = tensorrt_llm_llama.layers[layer_idx].attention.dense
- process_and_assign_weight(awq_llama, mPrefix, mOp, 0)
-
- # MLP up_proj (mlp.gate) Linear
- mPrefix = prefix + "mlp.up_proj"
- mOp = tensorrt_llm_llama.layers[layer_idx].mlp.gate
- process_and_assign_weight(awq_llama, mPrefix, mOp, 1)
-
- # MLP down_proj (mlp.proj) Linear
- mPrefix = prefix + "mlp.down_proj"
- mOp = tensorrt_llm_llama.layers[layer_idx].mlp.proj
- process_and_assign_weight(awq_llama, mPrefix, mOp, 0)
-
- # MLP gate_proj (mlp.fc) Linear
- mPrefix = prefix + "mlp.gate_proj"
- mOp = tensorrt_llm_llama.layers[layer_idx].mlp.fc
- process_and_assign_weight(awq_llama, mPrefix, mOp, 1)
-
- v = awq_llama["model.norm.weight"]
- if mapping.is_last_pp_rank():
- tensorrt_llm_llama.ln_f.weight.value = v.to(torch_dtype).cpu().numpy()
-
- # lm_head
- if pad_vocab:
- weight = awq_llama["lm_head.weight"]
- [vocab_size, k] = weight.shape
- new_weight = torch.zeros([pad_vocab_size, k])
- new_weight[:vocab_size, :] = weight
- new_weight = new_weight.T.contiguous()
- amax = awq_llama["lm_head.weight_quantizer._amax"].reshape(
- [vocab_size, k // group_size]
- )
- new_amax = torch.ones([pad_vocab_size, k // group_size])
- new_amax[:vocab_size, :] = amax
- new_amax = new_amax.T.contiguous()
- new_scale = new_amax / 8
- tensorrt_llm_llama.lm_head.qweight.value = AWQ_quantize_pack_preprocess(
- new_weight, new_scale
- )
- tensorrt_llm_llama.lm_head.scale.value = new_scale.to(torch_dtype).cpu().numpy()
- tensorrt_llm_llama.lm_head.pre_quant_scale.value = (
- awq_llama["lm_head.input_quantizer._pre_quant_scale"]
- .to(torch_dtype)
- .cpu()
- .numpy()
- )
- else:
- mPrefix = "lm_head"
- mOp = tensorrt_llm_llama.lm_head
- if mapping.is_last_pp_rank():
- process_and_assign_weight(awq_llama, mPrefix, mOp, 1)
-
- tok = time.time()
- t = time.strftime("%H:%M:%S", time.gmtime(tok - tik))
- tensorrt_llm.logger.info(f"Weights loaded. Total time: {t}")
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/gptnext/ensemble/config.pbtxt b/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/gptnext/ensemble/config.pbtxt
deleted file mode 100755
index cbd087ce9..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/gptnext/ensemble/config.pbtxt
+++ /dev/null
@@ -1,228 +0,0 @@
-# Copyright 2023, NVIDIA CORPORATION & AFFILIATES. 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.
-
-name: "ensemble"
-platform: "ensemble"
-max_batch_size: 128
-input [
- {
- name: "text_input"
- data_type: TYPE_STRING
- dims: [ -1 ]
- },
- {
- name: "max_tokens"
- data_type: TYPE_UINT32
- dims: [ -1 ]
- },
- {
- name: "end_id"
- data_type: TYPE_UINT32
- dims: [ 1 ]
- optional: true
- },
- {
- name: "pad_id"
- data_type: TYPE_UINT32
- dims: [ 1 ]
- optional: true
- },
- {
- name: "top_k"
- data_type: TYPE_UINT32
- dims: [ 1 ]
- optional: true
- },
- {
- name: "top_p"
- data_type: TYPE_FP32
- dims: [ 1 ]
- optional: true
- },
- {
- name: "temperature"
- data_type: TYPE_FP32
- dims: [ 1 ]
- optional: true
- },
- {
- name: "length_penalty"
- data_type: TYPE_FP32
- dims: [ 1 ]
- optional: true
- },
- {
- name: "repetition_penalty"
- data_type: TYPE_FP32
- dims: [ 1 ]
- optional: true
- },
- {
- name: "min_length"
- data_type: TYPE_UINT32
- dims: [ 1 ]
- optional: true
- },
- {
- name: "presence_penalty"
- data_type: TYPE_FP32
- dims: [ 1 ]
- optional: true
- },
- {
- name: "random_seed"
- data_type: TYPE_UINT64
- dims: [ 1 ]
- optional: true
- },
- {
- name: "beam_width"
- data_type: TYPE_UINT32
- dims: [ 1 ]
- optional: true
- },
- {
- name: "stream"
- data_type: TYPE_BOOL
- dims: [ 1 ]
- optional: true
- }
-]
-output [
- {
- name: "text_output"
- data_type: TYPE_STRING
- dims: [ -1, -1 ]
- }
-]
-ensemble_scheduling {
- step [
- {
- model_name: "preprocessing"
- model_version: -1
- input_map {
- key: "QUERY"
- value: "text_input"
- }
- input_map {
- key: "REQUEST_OUTPUT_LEN"
- value: "max_tokens"
- }
- output_map {
- key: "REQUEST_INPUT_LEN"
- value: "_REQUEST_INPUT_LEN"
- }
- output_map {
- key: "INPUT_ID"
- value: "_INPUT_ID"
- }
- output_map {
- key: "REQUEST_OUTPUT_LEN"
- value: "_REQUEST_OUTPUT_LEN"
- }
- },
- {
- model_name: "tensorrt_llm"
- model_version: -1
- input_map {
- key: "input_ids"
- value: "_INPUT_ID"
- }
- input_map {
- key: "input_lengths"
- value: "_REQUEST_INPUT_LEN"
- }
- input_map {
- key: "request_output_len"
- value: "_REQUEST_OUTPUT_LEN"
- }
- input_map {
- key: "end_id"
- value: "end_id"
- }
- input_map {
- key: "pad_id"
- value: "pad_id"
- }
- input_map {
- key: "runtime_top_k"
- value: "top_k"
- }
- input_map {
- key: "runtime_top_p"
- value: "top_p"
- }
- input_map {
- key: "temperature"
- value: "temperature"
- }
- input_map {
- key: "len_penalty"
- value: "length_penalty"
- }
- input_map {
- key: "repetition_penalty"
- value: "repetition_penalty"
- }
- input_map {
- key: "min_length"
- value: "min_length"
- }
- input_map {
- key: "presence_penalty"
- value: "presence_penalty"
- }
- input_map {
- key: "random_seed"
- value: "random_seed"
- }
- input_map {
- key: "beam_width"
- value: "beam_width"
- }
- input_map {
- key: "streaming"
- value: "stream"
- }
- output_map {
- key: "output_ids"
- value: "_TOKENS_BATCH"
- }
- },
- {
- model_name: "postprocessing"
- model_version: -1
- input_map {
- key: "TOKENS_BATCH"
- value: "_TOKENS_BATCH"
- }
- output_map {
- key: "OUTPUT"
- value: "text_output"
- }
- }
- ]
-}
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/gptnext/postprocessing/1/model.py b/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/gptnext/postprocessing/1/model.py
deleted file mode 100755
index bb8a73782..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/gptnext/postprocessing/1/model.py
+++ /dev/null
@@ -1,158 +0,0 @@
-# -*- coding: utf-8 -*-
-import json
-import os
-
-import numpy as np
-import triton_python_backend_utils as pb_utils
-from transformers import LlamaTokenizer
-
-TOKENIZER_DIR = os.environ.get("TOKENIZER_DIR", "/model")
-
-SPACE_CHAR = 9601
-NEWLINE_CHAR = 60
-STOP_TOKEN = 2
-
-
-class TritonPythonModel:
- """Your Python model must use the same class name. Every Python model
- that is created must have "TritonPythonModel" as the class name.
- """
-
- def initialize(self, args):
- """`initialize` is called only once when the model is being loaded.
- Implementing `initialize` function is optional. This function allows
- the model to initialize any state associated with this model.
- Parameters
- ----------
- args : dict
- Both keys and values are strings. The dictionary keys and values are:
- * model_config: A JSON string containing the model configuration
- * model_instance_kind: A string containing model instance kind
- * model_instance_device_id: A string containing model instance device ID
- * model_repository: Model repository path
- * model_version: Model version
- * model_name: Model name
- """
- # Parse model configs
- self.model_config = model_config = json.loads(args["model_config"])
-
- # Parse model output configs
- output_config = pb_utils.get_output_config_by_name(model_config, "OUTPUT")
-
- # Convert Triton types to numpy types
- self.output_dtype = pb_utils.triton_string_to_numpy(output_config["data_type"])
-
- self.tokenizer = LlamaTokenizer.from_pretrained(TOKENIZER_DIR, legacy=False)
- vocab = self.tokenizer.convert_ids_to_tokens(
- list(range(self.tokenizer.vocab_size))
- )
-
- def execute(self, requests):
- """`execute` must be implemented in every Python model. `execute`
- function receives a list of pb_utils.InferenceRequest as the only
- argument. This function is called when an inference is requested
- for this model. Depending on the batching configuration (e.g. Dynamic
- Batching) used, `requests` may contain multiple requests. Every
- Python model, must create one pb_utils.InferenceResponse for every
- pb_utils.InferenceRequest in `requests`. If there is an error, you can
- set the error argument when creating a pb_utils.InferenceResponse.
- Parameters
- ----------
- requests : list
- A list of pb_utils.InferenceRequest
- Returns
- -------
- list
- A list of pb_utils.InferenceResponse. The length of this list must
- be the same as `requests`
- """
-
- responses = []
-
- # Every Python backend must iterate over everyone of the requests
- # and create a pb_utils.InferenceResponse for each of them.
- for request in requests:
- # Get input tensors
- tokens_batch = pb_utils.get_input_tensor_by_name(
- request, "TOKENS_BATCH"
- ).as_numpy()
-
- # Reshape Input
- # tokens_batch = tokens_batch.reshape([-1, tokens_batch.shape[0]])
- # tokens_batch = tokens_batch.T
-
- # Postprocessing output data.
- outputs = self._postprocessing(tokens_batch)
-
- # Create output tensors. You need pb_utils.Tensor
- # objects to create pb_utils.InferenceResponse.
- output_tensor = pb_utils.Tensor(
- "OUTPUT", np.array(outputs).astype(self.output_dtype)
- )
-
- # Create InferenceResponse. You can set an error here in case
- # there was a problem with handling this inference request.
- # Below is an example of how you can set errors in inference
- # response:
- #
- # pb_utils.InferenceResponse(
- # output_tensors=..., TritonError("An error occurred"))
- inference_response = pb_utils.InferenceResponse(
- output_tensors=[output_tensor]
- )
- responses.append(inference_response)
-
- # You should return a list of pb_utils.InferenceResponse. Length
- # of this list must match the length of `requests` list.
- return responses
-
- def finalize(self):
- """`finalize` is called only once when the model is being unloaded.
- `Implementing `finalize` function is optional. This function allows
- the model to perform any necessary clean ups before exit.
- """
- pb_utils.Logger.log("Finalizing the Post-Processing Model.")
-
- def _id_to_token(self, token_id):
- # handle special tokens (end of string, unknown, etc)
- try:
- special_token_index = self.tokenizer.all_special_ids.index(token_id)
- return self.tokenizer.all_special_tokens[special_token_index]
- except ValueError:
- pass
-
- # handle typical tokens
- tokens = self.tokenizer.convert_ids_to_tokens(token_id)
- if ord(tokens[0]) == SPACE_CHAR:
- return f" {tokens[1:]}"
- if ord(tokens[0]) == NEWLINE_CHAR:
- return "\n"
- return tokens
-
- def _postprocessing(self, tokens_batch):
- tokens_batch = tokens_batch.tolist()
- return [
- self._id_to_token(token_id)
- for beam_tokens in tokens_batch
- for token_ids in beam_tokens
- for token_id in token_ids
- ]
-
- # for beam_tokens in tokens_batch:
- # for token_ids in beam_tokens:
- # for token_id in token_ids:
- # # handle special tokens (end of string, unknown, etc)
- # special_token = self.tokenizer.added_tokens_decoder.get(token_id)
- # if special_token:
- # tokens = special_token.content
-
- # # handle typical tokens
- # else:
- # tokens = self.tokenizer.convert_ids_to_tokens(token_id)
- # if ord(tokens[0]) == SPACE_CHAR:
- # tokens = f" {tokens[1:]}"
- # elif ord(tokens[0]) == NEWLINE_CHAR:
- # tokens = "\n"
-
- # outputs.append(tokens)
- # return outputs
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/gptnext/postprocessing/config.pbtxt b/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/gptnext/postprocessing/config.pbtxt
deleted file mode 100755
index 3c3ea10d4..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/gptnext/postprocessing/config.pbtxt
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright 2023, NVIDIA CORPORATION & AFFILIATES. 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.
-
-name: "postprocessing"
-backend: "python"
-max_batch_size: 128
-input [
- {
- name: "TOKENS_BATCH"
- data_type: TYPE_INT32
- dims: [ -1, -1 ]
- }
-]
-output [
- {
- name: "OUTPUT"
- data_type: TYPE_STRING
- dims: [ -1, -1 ]
- }
-]
-
-instance_group [
- {
- count: 1
- kind: KIND_CPU
- }
-]
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/gptnext/preprocessing/1/model.py b/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/gptnext/preprocessing/1/model.py
deleted file mode 100644
index 44e8b9c4a..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/gptnext/preprocessing/1/model.py
+++ /dev/null
@@ -1,244 +0,0 @@
-# Copyright 2023, NVIDIA CORPORATION & AFFILIATES. 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.
-
-
-import csv
-import json
-import os
-
-import numpy as np
-import torch
-import triton_python_backend_utils as pb_utils
-from torch.nn.utils.rnn import pad_sequence
-from transformers import LlamaTokenizer
-
-TOKENIZER_DIR = os.environ.get("TOKENIZER_DIR", "/model")
-
-END_ID = 2
-
-# SYSTEM_PROMPT = (
-# """You are a helpful, respectful and honest assistant."""
-# """Always answer as helpfully as possible, while being safe."""
-# """Please ensure that your responses are positive in nature."""
-# )
-
-# LLAMA_PROMPT_TEMPLATE = (
-# "[INST] <>"
-# "{system_prompt}"
-# "<>"
-# "[/INST] {context} [INST] {question} [/INST]"
-# )
-
-
-class TritonPythonModel:
- """Your Python model must use the same class name. Every Python model
- that is created must have "TritonPythonModel" as the class name.
- """
-
- def initialize(self, args):
- """`initialize` is called only once when the model is being loaded.
- Implementing `initialize` function is optional. This function allows
- the model to initialize any state associated with this model.
- Parameters
- ----------
- args : dict
- Both keys and values are strings. The dictionary keys and values are:
- * model_config: A JSON string containing the model configuration
- * model_instance_kind: A string containing model instance kind
- * model_instance_device_id: A string containing model instance device ID
- * model_repository: Model repository path
- * model_version: Model version
- * model_name: Model name
- """
- # Parse model configs
- self.model_config = model_config = json.loads(args["model_config"])
-
- # Parse model output configs and convert Triton types to numpy types
- input_names = ["INPUT_ID", "REQUEST_INPUT_LEN"]
- for input_name in input_names:
- setattr(
- self,
- input_name.lower() + "_dtype",
- pb_utils.triton_string_to_numpy(
- pb_utils.get_output_config_by_name(model_config, input_name)[
- "data_type"
- ]
- ),
- )
-
- self.encoder = LlamaTokenizer.from_pretrained(TOKENIZER_DIR, legacy=False)
-
- def execute(self, requests):
- """`execute` must be implemented in every Python model. `execute`
- function receives a list of pb_utils.InferenceRequest as the only
- argument. This function is called when an inference is requested
- for this model. Depending on the batching configuration (e.g. Dynamic
- Batching) used, `requests` may contain multiple requests. Every
- Python model, must create one pb_utils.InferenceResponse for every
- pb_utils.InferenceRequest in `requests`. If there is an error, you can
- set the error argument when creating a pb_utils.InferenceResponse.
- Parameters
- ----------
- requests : list
- A list of pb_utils.InferenceRequest
- Returns
- -------
- list
- A list of pb_utils.InferenceResponse. The length of this list must
- be the same as `requests`
- """
-
- responses = []
-
- # Every Python backend must iterate over everyone of the requests
- # and create a pb_utils.InferenceResponse for each of them.
- for request in requests:
- # Get input tensors
- query = pb_utils.get_input_tensor_by_name(request, "QUERY").as_numpy()
- request_output_len = pb_utils.get_input_tensor_by_name(
- request, "REQUEST_OUTPUT_LEN"
- ).as_numpy()
-
- input_id, request_input_len = self._create_request(query)
-
- # Create output tensors. You need pb_utils.Tensor
- # objects to create pb_utils.InferenceResponse.
- input_id_tensor = pb_utils.Tensor(
- "INPUT_ID", np.array(input_id).astype(self.input_id_dtype)
- )
- request_input_len_tensor = pb_utils.Tensor(
- "REQUEST_INPUT_LEN",
- np.array(request_input_len).astype(self.request_input_len_dtype),
- )
- request_output_len_tensor = pb_utils.Tensor(
- "REQUEST_OUTPUT_LEN", request_output_len
- )
-
- # Create InferenceResponse. You can set an error here in case
- # there was a problem with handling this inference request.
- # Below is an example of how you can set errors in inference
- # response:
- #
- # pb_utils.InferenceResponse(
- # output_tensors=..., TritonError("An error occurred"))
- inference_response = pb_utils.InferenceResponse(
- output_tensors=[
- input_id_tensor,
- request_input_len_tensor,
- request_output_len_tensor,
- ]
- )
- responses.append(inference_response)
-
- # You should return a list of pb_utils.InferenceResponse. Length
- # of this list must match the length of `requests` list.
- return responses
-
- def finalize(self):
- """`finalize` is called only once when the model is being unloaded.
- Implementing `finalize` function is optional. This function allows
- the model to perform any necessary clean ups before exit.
- """
- pb_utils.Logger.log("Finalizing the Pre-Processing Model.")
-
- def _create_request(self, prompts):
- """
- prompts : batch string (2D numpy array)
- """
-
- start_ids = [
- torch.IntTensor(self.encoder.encode(prompt[0].decode()))
- for prompt in prompts
- ]
-
- start_lengths = torch.IntTensor([[len(ids)] for ids in start_ids])
-
- start_ids = pad_sequence(start_ids, batch_first=True, padding_value=END_ID)
-
- return start_ids, start_lengths
-
- def _create_word_list(self, word_dict):
- flat_ids = []
- offsets = []
- for word_dict_item in word_dict:
- item_flat_ids = []
- item_offsets = []
-
- words = list(csv.reader([word_dict_item[0].decode()]))[0]
- for word in words:
- ids = self._encode(word)
-
- if len(ids) == 0:
- continue
-
- item_flat_ids += ids
- item_offsets.append(len(ids))
-
- flat_ids.append(np.array(item_flat_ids))
- offsets.append(np.cumsum(np.array(item_offsets)))
-
- pad_to = max(1, max(len(ids) for ids in flat_ids))
-
- for i, (ids, offs) in enumerate(zip(flat_ids, offsets)):
- flat_ids[i] = np.pad(ids, (0, pad_to - len(ids)), constant_values=0)
- offsets[i] = np.pad(offs, (0, pad_to - len(offs)), constant_values=-1)
-
- return np.array([flat_ids, offsets], dtype="int32").transpose((1, 0, 2))
-
- def to_word_list_format(self, word_dict):
- flat_ids = []
- offsets = []
- for word_dict_item in word_dict:
- item_flat_ids = []
- item_offsets = []
-
- if isinstance(word_dict_item[0], bytes):
- word_dict_item = [word_dict_item[0].decode()]
-
- words = list(csv.reader(word_dict_item))[0]
- for word in words:
- ids = self.encoder.encode(word)
-
- if len(ids) == 0:
- continue
-
- item_flat_ids += ids
- item_offsets.append(len(ids))
-
- flat_ids.append(np.array(item_flat_ids))
- offsets.append(np.cumsum(np.array(item_offsets)))
-
- pad_to = max(1, max(len(ids) for ids in flat_ids))
-
- for i, (ids, offs) in enumerate(zip(flat_ids, offsets)):
- flat_ids[i] = np.pad(ids, (0, pad_to - len(ids)), constant_values=0)
- offsets[i] = np.pad(offs, (0, pad_to - len(offs)), constant_values=-1)
-
- return np.array([flat_ids, offsets], dtype="int32").transpose((1, 0, 2))
-
- def _encode(self, sentence):
- sentence = sentence.decode() if isinstance(sentence, bytes) else sentence
- return self.encoder.encode(sentence)
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/gptnext/preprocessing/config.pbtxt b/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/gptnext/preprocessing/config.pbtxt
deleted file mode 100644
index d2e3029a9..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/gptnext/preprocessing/config.pbtxt
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright 2023, NVIDIA CORPORATION & AFFILIATES. 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.
-
-name: "preprocessing"
-backend: "python"
-max_batch_size: 128
-input [
- {
- name: "QUERY"
- data_type: TYPE_STRING
- dims: [ -1 ]
- },
- {
- name: "REQUEST_OUTPUT_LEN"
- data_type: TYPE_UINT32
- dims: [ -1 ]
- }
-]
-output [
- {
- name: "INPUT_ID"
- data_type: TYPE_INT32
- dims: [ -1 ]
- },
- {
- name: "REQUEST_INPUT_LEN"
- data_type: TYPE_INT32
- dims: [ 1 ]
- },
- {
- name: "REQUEST_OUTPUT_LEN"
- data_type: TYPE_UINT32
- dims: [ -1 ]
- }
-]
-
-instance_group [
- {
- count: 1
- kind: KIND_CPU
- }
-]
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/gptnext/tensorrt_llm/1/.gitkeep b/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/gptnext/tensorrt_llm/1/.gitkeep
deleted file mode 100644
index e69de29bb..000000000
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/gptnext/tensorrt_llm/config.pbtxt.j2 b/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/gptnext/tensorrt_llm/config.pbtxt.j2
deleted file mode 100644
index 4b719b046..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/gptnext/tensorrt_llm/config.pbtxt.j2
+++ /dev/null
@@ -1,208 +0,0 @@
-# Copyright 2023, NVIDIA CORPORATION & AFFILIATES. 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.
-
-name: "tensorrt_llm"
-backend: "tensorrtllm"
-max_batch_size: 128
-
-model_transaction_policy {
- decoupled: {{ decoupled_mode }}
-}
-
-input [
- {
- name: "input_ids"
- data_type: TYPE_INT32
- dims: [ -1 ]
- },
- {
- name: "input_lengths"
- data_type: TYPE_INT32
- dims: [ 1 ]
- reshape: { shape: [ ] }
- },
- {
- name: "request_output_len"
- data_type: TYPE_UINT32
- dims: [ 1 ]
- },
- {
- name: "end_id"
- data_type: TYPE_UINT32
- dims: [ 1 ]
- reshape: { shape: [ ] }
- optional: true
- },
- {
- name: "pad_id"
- data_type: TYPE_UINT32
- dims: [ 1 ]
- reshape: { shape: [ ] }
- optional: true
- },
- {
- name: "beam_width"
- data_type: TYPE_UINT32
- dims: [ 1 ]
- reshape: { shape: [ ] }
- optional: true
- },
- {
- name: "temperature"
- data_type: TYPE_FP32
- dims: [ 1 ]
- reshape: { shape: [ ] }
- optional: true
- },
- {
- name: "runtime_top_k"
- data_type: TYPE_UINT32
- dims: [ 1 ]
- reshape: { shape: [ ] }
- optional: true
- },
- {
- name: "runtime_top_p"
- data_type: TYPE_FP32
- dims: [ 1 ]
- reshape: { shape: [ ] }
- optional: true
- },
- {
- name: "len_penalty"
- data_type: TYPE_FP32
- dims: [ 1 ]
- reshape: { shape: [ ] }
- optional: true
- },
- {
- name: "repetition_penalty"
- data_type: TYPE_FP32
- dims: [ 1 ]
- reshape: { shape: [ ] }
- optional: true
- },
- {
- name: "min_length"
- data_type: TYPE_UINT32
- dims: [ 1 ]
- reshape: { shape: [ ] }
- optional: true
- },
- {
- name: "presence_penalty"
- data_type: TYPE_FP32
- dims: [ 1 ]
- reshape: { shape: [ ] }
- optional: true
- },
- {
- name: "random_seed"
- data_type: TYPE_UINT64
- dims: [ 1 ]
- reshape: { shape: [ ] }
- optional: true
- },
- {
- name: "stop"
- data_type: TYPE_BOOL
- dims: [ 1 ]
- optional: true
- },
- {
- name: "streaming"
- data_type: TYPE_BOOL
- dims: [ 1 ]
- optional: true
- }
-]
-output [
- {
- name: "output_ids"
- data_type: TYPE_INT32
- dims: [ -1, -1 ]
- }
-]
-instance_group [
- {
- count: 1
- kind : KIND_CPU
- }
-]
-parameters: {
- key: "max_beam_width"
- value: {
- string_value: "1"
- }
-}
-parameters: {
- key: "FORCE_CPU_ONLY_INPUT_TENSORS"
- value: {
- string_value: "no"
- }
-}
-parameters: {
- key: "gpt_model_type"
- value: {
- string_value: "{{ gpt_model_type }}"
- }
-}
-parameters: {
- key: "gpt_model_path"
- value: {
- string_value: "{{ engine_dir }}"
- }
-}
-parameters: {
- key: "max_tokens_in_paged_kv_cache"
- value: {
- string_value: ""
- }
-}
-parameters: {
- key: "batch_scheduler_policy"
- value: {
- string_value: "guaranteed_completion"
- }
-}
-parameters: {
- key: "kv_cache_free_gpu_mem_fraction"
- value: {
- string_value: ".75"
- }
-}
-parameters: {
- key: "max_num_sequences"
- value: {
- string_value: ""
- }
-}
-parameters: {
- key: "enable_trt_overlap"
- value: {
- string_value: ""
- }
-}
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/llama/ensemble/1/.tmp b/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/llama/ensemble/1/.tmp
deleted file mode 100644
index e69de29bb..000000000
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/llama/ensemble/config.pbtxt b/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/llama/ensemble/config.pbtxt
deleted file mode 100755
index cbd087ce9..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/llama/ensemble/config.pbtxt
+++ /dev/null
@@ -1,228 +0,0 @@
-# Copyright 2023, NVIDIA CORPORATION & AFFILIATES. 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.
-
-name: "ensemble"
-platform: "ensemble"
-max_batch_size: 128
-input [
- {
- name: "text_input"
- data_type: TYPE_STRING
- dims: [ -1 ]
- },
- {
- name: "max_tokens"
- data_type: TYPE_UINT32
- dims: [ -1 ]
- },
- {
- name: "end_id"
- data_type: TYPE_UINT32
- dims: [ 1 ]
- optional: true
- },
- {
- name: "pad_id"
- data_type: TYPE_UINT32
- dims: [ 1 ]
- optional: true
- },
- {
- name: "top_k"
- data_type: TYPE_UINT32
- dims: [ 1 ]
- optional: true
- },
- {
- name: "top_p"
- data_type: TYPE_FP32
- dims: [ 1 ]
- optional: true
- },
- {
- name: "temperature"
- data_type: TYPE_FP32
- dims: [ 1 ]
- optional: true
- },
- {
- name: "length_penalty"
- data_type: TYPE_FP32
- dims: [ 1 ]
- optional: true
- },
- {
- name: "repetition_penalty"
- data_type: TYPE_FP32
- dims: [ 1 ]
- optional: true
- },
- {
- name: "min_length"
- data_type: TYPE_UINT32
- dims: [ 1 ]
- optional: true
- },
- {
- name: "presence_penalty"
- data_type: TYPE_FP32
- dims: [ 1 ]
- optional: true
- },
- {
- name: "random_seed"
- data_type: TYPE_UINT64
- dims: [ 1 ]
- optional: true
- },
- {
- name: "beam_width"
- data_type: TYPE_UINT32
- dims: [ 1 ]
- optional: true
- },
- {
- name: "stream"
- data_type: TYPE_BOOL
- dims: [ 1 ]
- optional: true
- }
-]
-output [
- {
- name: "text_output"
- data_type: TYPE_STRING
- dims: [ -1, -1 ]
- }
-]
-ensemble_scheduling {
- step [
- {
- model_name: "preprocessing"
- model_version: -1
- input_map {
- key: "QUERY"
- value: "text_input"
- }
- input_map {
- key: "REQUEST_OUTPUT_LEN"
- value: "max_tokens"
- }
- output_map {
- key: "REQUEST_INPUT_LEN"
- value: "_REQUEST_INPUT_LEN"
- }
- output_map {
- key: "INPUT_ID"
- value: "_INPUT_ID"
- }
- output_map {
- key: "REQUEST_OUTPUT_LEN"
- value: "_REQUEST_OUTPUT_LEN"
- }
- },
- {
- model_name: "tensorrt_llm"
- model_version: -1
- input_map {
- key: "input_ids"
- value: "_INPUT_ID"
- }
- input_map {
- key: "input_lengths"
- value: "_REQUEST_INPUT_LEN"
- }
- input_map {
- key: "request_output_len"
- value: "_REQUEST_OUTPUT_LEN"
- }
- input_map {
- key: "end_id"
- value: "end_id"
- }
- input_map {
- key: "pad_id"
- value: "pad_id"
- }
- input_map {
- key: "runtime_top_k"
- value: "top_k"
- }
- input_map {
- key: "runtime_top_p"
- value: "top_p"
- }
- input_map {
- key: "temperature"
- value: "temperature"
- }
- input_map {
- key: "len_penalty"
- value: "length_penalty"
- }
- input_map {
- key: "repetition_penalty"
- value: "repetition_penalty"
- }
- input_map {
- key: "min_length"
- value: "min_length"
- }
- input_map {
- key: "presence_penalty"
- value: "presence_penalty"
- }
- input_map {
- key: "random_seed"
- value: "random_seed"
- }
- input_map {
- key: "beam_width"
- value: "beam_width"
- }
- input_map {
- key: "streaming"
- value: "stream"
- }
- output_map {
- key: "output_ids"
- value: "_TOKENS_BATCH"
- }
- },
- {
- model_name: "postprocessing"
- model_version: -1
- input_map {
- key: "TOKENS_BATCH"
- value: "_TOKENS_BATCH"
- }
- output_map {
- key: "OUTPUT"
- value: "text_output"
- }
- }
- ]
-}
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/llama/postprocessing/1/model.py b/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/llama/postprocessing/1/model.py
deleted file mode 100755
index 0e563c960..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/llama/postprocessing/1/model.py
+++ /dev/null
@@ -1,173 +0,0 @@
-# -*- coding: utf-8 -*-
-# SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-# SPDX-License-Identifier: Apache-2.0
-#
-# 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.
-
-import json
-import os
-
-import numpy as np
-import triton_python_backend_utils as pb_utils
-from transformers import LlamaTokenizer
-
-TOKENIZER_DIR = os.environ.get("TOKENIZER_DIR", "/model")
-
-SPACE_CHAR = 9601
-NEWLINE_CHAR = 60
-STOP_TOKEN = 2
-
-
-class TritonPythonModel:
- """Your Python model must use the same class name. Every Python model
- that is created must have "TritonPythonModel" as the class name.
- """
-
- def initialize(self, args):
- """`initialize` is called only once when the model is being loaded.
- Implementing `initialize` function is optional. This function allows
- the model to initialize any state associated with this model.
- Parameters
- ----------
- args : dict
- Both keys and values are strings. The dictionary keys and values are:
- * model_config: A JSON string containing the model configuration
- * model_instance_kind: A string containing model instance kind
- * model_instance_device_id: A string containing model instance device ID
- * model_repository: Model repository path
- * model_version: Model version
- * model_name: Model name
- """
- # Parse model configs
- self.model_config = model_config = json.loads(args["model_config"])
-
- # Parse model output configs
- output_config = pb_utils.get_output_config_by_name(model_config, "OUTPUT")
-
- # Convert Triton types to numpy types
- self.output_dtype = pb_utils.triton_string_to_numpy(output_config["data_type"])
-
- self.tokenizer = LlamaTokenizer.from_pretrained(TOKENIZER_DIR, legacy=False)
- vocab = self.tokenizer.convert_ids_to_tokens(
- list(range(self.tokenizer.vocab_size))
- )
-
- def execute(self, requests):
- """`execute` must be implemented in every Python model. `execute`
- function receives a list of pb_utils.InferenceRequest as the only
- argument. This function is called when an inference is requested
- for this model. Depending on the batching configuration (e.g. Dynamic
- Batching) used, `requests` may contain multiple requests. Every
- Python model, must create one pb_utils.InferenceResponse for every
- pb_utils.InferenceRequest in `requests`. If there is an error, you can
- set the error argument when creating a pb_utils.InferenceResponse.
- Parameters
- ----------
- requests : list
- A list of pb_utils.InferenceRequest
- Returns
- -------
- list
- A list of pb_utils.InferenceResponse. The length of this list must
- be the same as `requests`
- """
-
- responses = []
-
- # Every Python backend must iterate over everyone of the requests
- # and create a pb_utils.InferenceResponse for each of them.
- for request in requests:
- # Get input tensors
- tokens_batch = pb_utils.get_input_tensor_by_name(
- request, "TOKENS_BATCH"
- ).as_numpy()
-
- # Reshape Input
- # tokens_batch = tokens_batch.reshape([-1, tokens_batch.shape[0]])
- # tokens_batch = tokens_batch.T
-
- # Postprocessing output data.
- outputs = self._postprocessing(tokens_batch)
-
- # Create output tensors. You need pb_utils.Tensor
- # objects to create pb_utils.InferenceResponse.
- output_tensor = pb_utils.Tensor(
- "OUTPUT", np.array(outputs).astype(self.output_dtype)
- )
-
- # Create InferenceResponse. You can set an error here in case
- # there was a problem with handling this inference request.
- # Below is an example of how you can set errors in inference
- # response:
- #
- # pb_utils.InferenceResponse(
- # output_tensors=..., TritonError("An error occurred"))
- inference_response = pb_utils.InferenceResponse(
- output_tensors=[output_tensor]
- )
- responses.append(inference_response)
-
- # You should return a list of pb_utils.InferenceResponse. Length
- # of this list must match the length of `requests` list.
- return responses
-
- def finalize(self):
- """`finalize` is called only once when the model is being unloaded.
- `Implementing `finalize` function is optional. This function allows
- the model to perform any necessary clean ups before exit.
- """
- pb_utils.Logger.log("Finalizing the Post-Processing Model.")
-
- def _id_to_token(self, token_id):
- # handle special tokens (end of string, unknown, etc)
- try:
- special_token_index = self.tokenizer.all_special_ids.index(token_id)
- return self.tokenizer.all_special_tokens[special_token_index]
- except ValueError:
- pass
-
- # handle typical tokens
- tokens = self.tokenizer.convert_ids_to_tokens(token_id)
- if ord(tokens[0]) == SPACE_CHAR:
- return f" {tokens[1:]}"
- if ord(tokens[0]) == NEWLINE_CHAR:
- return "\n"
- return tokens
-
- def _postprocessing(self, tokens_batch):
- tokens_batch = tokens_batch.tolist()
- return [
- self._id_to_token(token_id)
- for beam_tokens in tokens_batch
- for token_ids in beam_tokens
- for token_id in token_ids
- ]
-
- # for beam_tokens in tokens_batch:
- # for token_ids in beam_tokens:
- # for token_id in token_ids:
- # # handle special tokens (end of string, unknown, etc)
- # special_token = self.tokenizer.added_tokens_decoder.get(token_id)
- # if special_token:
- # tokens = special_token.content
-
- # # handle typical tokens
- # else:
- # tokens = self.tokenizer.convert_ids_to_tokens(token_id)
- # if ord(tokens[0]) == SPACE_CHAR:
- # tokens = f" {tokens[1:]}"
- # elif ord(tokens[0]) == NEWLINE_CHAR:
- # tokens = "\n"
-
- # outputs.append(tokens)
- # return outputs
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/llama/postprocessing/config.pbtxt b/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/llama/postprocessing/config.pbtxt
deleted file mode 100755
index 3c3ea10d4..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/llama/postprocessing/config.pbtxt
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright 2023, NVIDIA CORPORATION & AFFILIATES. 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.
-
-name: "postprocessing"
-backend: "python"
-max_batch_size: 128
-input [
- {
- name: "TOKENS_BATCH"
- data_type: TYPE_INT32
- dims: [ -1, -1 ]
- }
-]
-output [
- {
- name: "OUTPUT"
- data_type: TYPE_STRING
- dims: [ -1, -1 ]
- }
-]
-
-instance_group [
- {
- count: 1
- kind: KIND_CPU
- }
-]
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/llama/preprocessing/1/model.py b/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/llama/preprocessing/1/model.py
deleted file mode 100644
index 44e8b9c4a..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/llama/preprocessing/1/model.py
+++ /dev/null
@@ -1,244 +0,0 @@
-# Copyright 2023, NVIDIA CORPORATION & AFFILIATES. 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.
-
-
-import csv
-import json
-import os
-
-import numpy as np
-import torch
-import triton_python_backend_utils as pb_utils
-from torch.nn.utils.rnn import pad_sequence
-from transformers import LlamaTokenizer
-
-TOKENIZER_DIR = os.environ.get("TOKENIZER_DIR", "/model")
-
-END_ID = 2
-
-# SYSTEM_PROMPT = (
-# """You are a helpful, respectful and honest assistant."""
-# """Always answer as helpfully as possible, while being safe."""
-# """Please ensure that your responses are positive in nature."""
-# )
-
-# LLAMA_PROMPT_TEMPLATE = (
-# "[INST] <>"
-# "{system_prompt}"
-# "<>"
-# "[/INST] {context} [INST] {question} [/INST]"
-# )
-
-
-class TritonPythonModel:
- """Your Python model must use the same class name. Every Python model
- that is created must have "TritonPythonModel" as the class name.
- """
-
- def initialize(self, args):
- """`initialize` is called only once when the model is being loaded.
- Implementing `initialize` function is optional. This function allows
- the model to initialize any state associated with this model.
- Parameters
- ----------
- args : dict
- Both keys and values are strings. The dictionary keys and values are:
- * model_config: A JSON string containing the model configuration
- * model_instance_kind: A string containing model instance kind
- * model_instance_device_id: A string containing model instance device ID
- * model_repository: Model repository path
- * model_version: Model version
- * model_name: Model name
- """
- # Parse model configs
- self.model_config = model_config = json.loads(args["model_config"])
-
- # Parse model output configs and convert Triton types to numpy types
- input_names = ["INPUT_ID", "REQUEST_INPUT_LEN"]
- for input_name in input_names:
- setattr(
- self,
- input_name.lower() + "_dtype",
- pb_utils.triton_string_to_numpy(
- pb_utils.get_output_config_by_name(model_config, input_name)[
- "data_type"
- ]
- ),
- )
-
- self.encoder = LlamaTokenizer.from_pretrained(TOKENIZER_DIR, legacy=False)
-
- def execute(self, requests):
- """`execute` must be implemented in every Python model. `execute`
- function receives a list of pb_utils.InferenceRequest as the only
- argument. This function is called when an inference is requested
- for this model. Depending on the batching configuration (e.g. Dynamic
- Batching) used, `requests` may contain multiple requests. Every
- Python model, must create one pb_utils.InferenceResponse for every
- pb_utils.InferenceRequest in `requests`. If there is an error, you can
- set the error argument when creating a pb_utils.InferenceResponse.
- Parameters
- ----------
- requests : list
- A list of pb_utils.InferenceRequest
- Returns
- -------
- list
- A list of pb_utils.InferenceResponse. The length of this list must
- be the same as `requests`
- """
-
- responses = []
-
- # Every Python backend must iterate over everyone of the requests
- # and create a pb_utils.InferenceResponse for each of them.
- for request in requests:
- # Get input tensors
- query = pb_utils.get_input_tensor_by_name(request, "QUERY").as_numpy()
- request_output_len = pb_utils.get_input_tensor_by_name(
- request, "REQUEST_OUTPUT_LEN"
- ).as_numpy()
-
- input_id, request_input_len = self._create_request(query)
-
- # Create output tensors. You need pb_utils.Tensor
- # objects to create pb_utils.InferenceResponse.
- input_id_tensor = pb_utils.Tensor(
- "INPUT_ID", np.array(input_id).astype(self.input_id_dtype)
- )
- request_input_len_tensor = pb_utils.Tensor(
- "REQUEST_INPUT_LEN",
- np.array(request_input_len).astype(self.request_input_len_dtype),
- )
- request_output_len_tensor = pb_utils.Tensor(
- "REQUEST_OUTPUT_LEN", request_output_len
- )
-
- # Create InferenceResponse. You can set an error here in case
- # there was a problem with handling this inference request.
- # Below is an example of how you can set errors in inference
- # response:
- #
- # pb_utils.InferenceResponse(
- # output_tensors=..., TritonError("An error occurred"))
- inference_response = pb_utils.InferenceResponse(
- output_tensors=[
- input_id_tensor,
- request_input_len_tensor,
- request_output_len_tensor,
- ]
- )
- responses.append(inference_response)
-
- # You should return a list of pb_utils.InferenceResponse. Length
- # of this list must match the length of `requests` list.
- return responses
-
- def finalize(self):
- """`finalize` is called only once when the model is being unloaded.
- Implementing `finalize` function is optional. This function allows
- the model to perform any necessary clean ups before exit.
- """
- pb_utils.Logger.log("Finalizing the Pre-Processing Model.")
-
- def _create_request(self, prompts):
- """
- prompts : batch string (2D numpy array)
- """
-
- start_ids = [
- torch.IntTensor(self.encoder.encode(prompt[0].decode()))
- for prompt in prompts
- ]
-
- start_lengths = torch.IntTensor([[len(ids)] for ids in start_ids])
-
- start_ids = pad_sequence(start_ids, batch_first=True, padding_value=END_ID)
-
- return start_ids, start_lengths
-
- def _create_word_list(self, word_dict):
- flat_ids = []
- offsets = []
- for word_dict_item in word_dict:
- item_flat_ids = []
- item_offsets = []
-
- words = list(csv.reader([word_dict_item[0].decode()]))[0]
- for word in words:
- ids = self._encode(word)
-
- if len(ids) == 0:
- continue
-
- item_flat_ids += ids
- item_offsets.append(len(ids))
-
- flat_ids.append(np.array(item_flat_ids))
- offsets.append(np.cumsum(np.array(item_offsets)))
-
- pad_to = max(1, max(len(ids) for ids in flat_ids))
-
- for i, (ids, offs) in enumerate(zip(flat_ids, offsets)):
- flat_ids[i] = np.pad(ids, (0, pad_to - len(ids)), constant_values=0)
- offsets[i] = np.pad(offs, (0, pad_to - len(offs)), constant_values=-1)
-
- return np.array([flat_ids, offsets], dtype="int32").transpose((1, 0, 2))
-
- def to_word_list_format(self, word_dict):
- flat_ids = []
- offsets = []
- for word_dict_item in word_dict:
- item_flat_ids = []
- item_offsets = []
-
- if isinstance(word_dict_item[0], bytes):
- word_dict_item = [word_dict_item[0].decode()]
-
- words = list(csv.reader(word_dict_item))[0]
- for word in words:
- ids = self.encoder.encode(word)
-
- if len(ids) == 0:
- continue
-
- item_flat_ids += ids
- item_offsets.append(len(ids))
-
- flat_ids.append(np.array(item_flat_ids))
- offsets.append(np.cumsum(np.array(item_offsets)))
-
- pad_to = max(1, max(len(ids) for ids in flat_ids))
-
- for i, (ids, offs) in enumerate(zip(flat_ids, offsets)):
- flat_ids[i] = np.pad(ids, (0, pad_to - len(ids)), constant_values=0)
- offsets[i] = np.pad(offs, (0, pad_to - len(offs)), constant_values=-1)
-
- return np.array([flat_ids, offsets], dtype="int32").transpose((1, 0, 2))
-
- def _encode(self, sentence):
- sentence = sentence.decode() if isinstance(sentence, bytes) else sentence
- return self.encoder.encode(sentence)
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/llama/preprocessing/config.pbtxt b/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/llama/preprocessing/config.pbtxt
deleted file mode 100644
index d2e3029a9..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/llama/preprocessing/config.pbtxt
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright 2023, NVIDIA CORPORATION & AFFILIATES. 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.
-
-name: "preprocessing"
-backend: "python"
-max_batch_size: 128
-input [
- {
- name: "QUERY"
- data_type: TYPE_STRING
- dims: [ -1 ]
- },
- {
- name: "REQUEST_OUTPUT_LEN"
- data_type: TYPE_UINT32
- dims: [ -1 ]
- }
-]
-output [
- {
- name: "INPUT_ID"
- data_type: TYPE_INT32
- dims: [ -1 ]
- },
- {
- name: "REQUEST_INPUT_LEN"
- data_type: TYPE_INT32
- dims: [ 1 ]
- },
- {
- name: "REQUEST_OUTPUT_LEN"
- data_type: TYPE_UINT32
- dims: [ -1 ]
- }
-]
-
-instance_group [
- {
- count: 1
- kind: KIND_CPU
- }
-]
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/llama/tensorrt_llm/1/.gitkeep b/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/llama/tensorrt_llm/1/.gitkeep
deleted file mode 100644
index e69de29bb..000000000
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/llama/tensorrt_llm/config.pbtxt.j2 b/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/llama/tensorrt_llm/config.pbtxt.j2
deleted file mode 100644
index 4b719b046..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/ensemble_models/llama/tensorrt_llm/config.pbtxt.j2
+++ /dev/null
@@ -1,208 +0,0 @@
-# Copyright 2023, NVIDIA CORPORATION & AFFILIATES. 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.
-
-name: "tensorrt_llm"
-backend: "tensorrtllm"
-max_batch_size: 128
-
-model_transaction_policy {
- decoupled: {{ decoupled_mode }}
-}
-
-input [
- {
- name: "input_ids"
- data_type: TYPE_INT32
- dims: [ -1 ]
- },
- {
- name: "input_lengths"
- data_type: TYPE_INT32
- dims: [ 1 ]
- reshape: { shape: [ ] }
- },
- {
- name: "request_output_len"
- data_type: TYPE_UINT32
- dims: [ 1 ]
- },
- {
- name: "end_id"
- data_type: TYPE_UINT32
- dims: [ 1 ]
- reshape: { shape: [ ] }
- optional: true
- },
- {
- name: "pad_id"
- data_type: TYPE_UINT32
- dims: [ 1 ]
- reshape: { shape: [ ] }
- optional: true
- },
- {
- name: "beam_width"
- data_type: TYPE_UINT32
- dims: [ 1 ]
- reshape: { shape: [ ] }
- optional: true
- },
- {
- name: "temperature"
- data_type: TYPE_FP32
- dims: [ 1 ]
- reshape: { shape: [ ] }
- optional: true
- },
- {
- name: "runtime_top_k"
- data_type: TYPE_UINT32
- dims: [ 1 ]
- reshape: { shape: [ ] }
- optional: true
- },
- {
- name: "runtime_top_p"
- data_type: TYPE_FP32
- dims: [ 1 ]
- reshape: { shape: [ ] }
- optional: true
- },
- {
- name: "len_penalty"
- data_type: TYPE_FP32
- dims: [ 1 ]
- reshape: { shape: [ ] }
- optional: true
- },
- {
- name: "repetition_penalty"
- data_type: TYPE_FP32
- dims: [ 1 ]
- reshape: { shape: [ ] }
- optional: true
- },
- {
- name: "min_length"
- data_type: TYPE_UINT32
- dims: [ 1 ]
- reshape: { shape: [ ] }
- optional: true
- },
- {
- name: "presence_penalty"
- data_type: TYPE_FP32
- dims: [ 1 ]
- reshape: { shape: [ ] }
- optional: true
- },
- {
- name: "random_seed"
- data_type: TYPE_UINT64
- dims: [ 1 ]
- reshape: { shape: [ ] }
- optional: true
- },
- {
- name: "stop"
- data_type: TYPE_BOOL
- dims: [ 1 ]
- optional: true
- },
- {
- name: "streaming"
- data_type: TYPE_BOOL
- dims: [ 1 ]
- optional: true
- }
-]
-output [
- {
- name: "output_ids"
- data_type: TYPE_INT32
- dims: [ -1, -1 ]
- }
-]
-instance_group [
- {
- count: 1
- kind : KIND_CPU
- }
-]
-parameters: {
- key: "max_beam_width"
- value: {
- string_value: "1"
- }
-}
-parameters: {
- key: "FORCE_CPU_ONLY_INPUT_TENSORS"
- value: {
- string_value: "no"
- }
-}
-parameters: {
- key: "gpt_model_type"
- value: {
- string_value: "{{ gpt_model_type }}"
- }
-}
-parameters: {
- key: "gpt_model_path"
- value: {
- string_value: "{{ engine_dir }}"
- }
-}
-parameters: {
- key: "max_tokens_in_paged_kv_cache"
- value: {
- string_value: ""
- }
-}
-parameters: {
- key: "batch_scheduler_policy"
- value: {
- string_value: "guaranteed_completion"
- }
-}
-parameters: {
- key: "kv_cache_free_gpu_mem_fraction"
- value: {
- string_value: ".75"
- }
-}
-parameters: {
- key: "max_num_sequences"
- value: {
- string_value: ""
- }
-}
-parameters: {
- key: "enable_trt_overlap"
- value: {
- string_value: ""
- }
-}
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/model_server/__init__.py b/RetrievalAugmentedGeneration/llm-inference-server/model_server/__init__.py
deleted file mode 100644
index f0aa9420a..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/model_server/__init__.py
+++ /dev/null
@@ -1,93 +0,0 @@
-# SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-# SPDX-License-Identifier: Apache-2.0
-#
-# 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.
-
-"""Model-Server converts LLMs to TensorRT engines and hosts them with Triton."""
-import argparse
-import logging
-
-from .conversion import ConversionOptions, convert
-from .errors import ModelServerException
-from .model import Model, ModelFormats
-from .server import ModelServer
-
-_LOGGER = logging.getLogger(__name__)
-
-
-def _should_convert(args: argparse.Namespace, model: "Model") -> bool:
- """Determine if the conversion step should run."""
- if args.force_conversion:
- return True
-
- if args.no_conversion:
- return False
-
- return model.conversion_is_needed()
-
-
-def main(args: argparse.Namespace) -> int:
- """Execute the model server."""
-
- # load the model directory
- _LOGGER.info("Reading the model directory.")
- model = Model(model_type=args.type, world_size=args.world_size)
-
- if model._format == ModelFormats.UNKNOWN:
- raise ModelServerException(
- f"""No known model formats detected in the provided MODEL_DIRECTORY.
- Supported formats are Pytorch(.pth or .pt), Huggingface (.bin) and Onnx (.onnx).
- Please check if the absolute path provided with the help of environment variable
- MODEL_DIRECTORY in compose.env file is correct and has been set properly."""
- )
-
- # calculate the default parallism parameters
- if not args.tensor_parallelism:
- args.tensor_parallelism = max(
- int(model.world_size / args.pipeline_parallelism), 1
- )
- if args.pipeline_parallelism * args.tensor_parallelism != model.world_size:
- raise ModelServerException(
- "Tensor Parallelism * Pipeline Parallelism must be equal to World Size"
- )
-
- conversion_opts = ConversionOptions(
- max_input_length=args.max_input_length,
- max_output_length=args.max_output_length,
- tensor_parallelism=args.tensor_parallelism,
- pipline_parallelism=args.pipeline_parallelism,
- quantization = args.quantization,
- )
-
- # print discovered model parameters
- _LOGGER.info("Model file format: %s", model.format.name)
- _LOGGER.info("World Size: %d", model.world_size)
- _LOGGER.info("Max input length: %s", args.max_input_length)
- _LOGGER.info("Max output length: %s", args.max_output_length)
- _LOGGER.info("Compute Capability: %s", model.compute_cap)
- _LOGGER.info("Quantization: %s", conversion_opts.quantization)
-
- # convert model
- if _should_convert(args, model):
- _LOGGER.info("Starting TensorRT Conversion.")
- convert(model, conversion_opts)
- else:
- _LOGGER.info("TensorRT Conversion not required. Skipping.")
-
- # host model
- if not args.no_hosting:
- _LOGGER.info("Starting Triton Inference Server.")
- inference_server = ModelServer(model, args.http)
- return inference_server.run()
-
- return 0
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/model_server/__main__.py b/RetrievalAugmentedGeneration/llm-inference-server/model_server/__main__.py
deleted file mode 100644
index a72a7a005..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/model_server/__main__.py
+++ /dev/null
@@ -1,203 +0,0 @@
-# SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-# SPDX-License-Identifier: Apache-2.0
-#
-# 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.
-
-"""Main entrypoint for the model-server application."""
-import argparse
-import logging
-import os
-import sys
-
-from . import main
-from .errors import ModelServerException
-from .model import ModelTypes
-
-TERMINATION_LOG = "/dev/termination-log"
-
-_LOG_FMT = f"[{os.getpid()}] %(asctime)15s [%(levelname)7s] - %(name)s - %(message)s"
-_LOG_DATE_FMT = "%b %d %H:%M:%S"
-_LOGGER = logging.getLogger("main")
-
-
-def parse_args() -> argparse.Namespace:
- """Parse the comamnd line arguments."""
- parser = argparse.ArgumentParser(
- prog="model-server",
- description="Ingest models and host them with NVIDIA TensorRT LLM",
- )
-
- # options
- parser.add_argument(
- "-w",
- "--world-size",
- default=None,
- type=int,
- help="The number of GPUs to shard the model across. "
- + "By default, this value will be equal to the number of available GPUs.",
- )
- parser.add_argument(
- "--force-conversion",
- action="store_true",
- help="When this flag is set, the TensorRT engine conversion will occur, "
- + "even if a valid engine is in the cache.",
- )
- parser.add_argument(
- "--no-conversion",
- action="store_true",
- help="Skip the conversion. If no engine is available in the cache, an error will be raised.",
- )
- parser.add_argument(
- "--no-hosting",
- action="store_true",
- help="Do not start the Triton Inference Server. Only convert the model then exit.",
- )
- parser.add_argument(
- "-v",
- "--verbose",
- action="count",
- default=1,
- help="increase output verbosity",
- )
- parser.add_argument(
- "-q",
- "--quiet",
- action="count",
- default=0,
- help="decrease output verbosity",
- )
-
- # builder customization
- parser.add_argument(
- "--max-input-length",
- type=int,
- default=3000,
- help="maximum number of input tokens",
- )
- parser.add_argument(
- "--max-output-length",
- type=int,
- default=512,
- help="maximum number of output tokens",
- )
- parser.add_argument(
- "--tensor-parallelism",
- type=int,
- default=None,
- help="number of tensor parallelism divisions (default: world_size/pipeline_parallelism)",
- )
- parser.add_argument(
- "--pipeline-parallelism",
- type=int,
- default=1,
- help="number of pipeline parallism divisions (default: 1)",
- )
-
- parser.add_argument(
- "--quantization",
- type=str,
- default=None,
- help="Quantization type to be used for LLMs",
- )
-
- # server customization
- parser.add_argument(
- "--http",
- action="store_true",
- help="change the api server to http instead of grpc (note: this will disable token streaming)",
- )
-
- # positional arguments
- supported_model_types = [e.name.lower().replace("_", "-") for e in ModelTypes]
- parser.add_argument(
- "type",
- metavar="TYPE",
- choices=supported_model_types,
- type=str.lower,
- help=f"{supported_model_types} The type of model to process.",
- )
-
- args = parser.parse_args()
-
- if args.force_conversion and args.no_conversion:
- parser.error("--force_conversion and --no-conversion are mutually exclusive.")
-
- return args
-
-
-def _bootstrap_logging(verbosity: int = 0) -> None:
- """Configure Python's logger according to the given verbosity level.
-
- :param verbosity: The desired verbosity level. Must be one of 0, 1, or 2.
- :type verbosity: typing.Literal[0, 1, 2]
- """
- # determine log level
- verbosity = min(2, max(0, verbosity)) # limit verbosity to 0-2
- log_level = [logging.WARN, logging.INFO, logging.DEBUG][verbosity]
-
- # configure python's logger
- logging.basicConfig(format=_LOG_FMT, datefmt=_LOG_DATE_FMT, level=log_level)
- # update existing loggers
- _LOGGER.setLevel(log_level)
- # pylint: disable-next=no-member; false positive
- for logger_name in logging.root.manager.loggerDict:
- logger = logging.getLogger(logger_name)
- for handler in logger.handlers:
- handler.setFormatter(logging.Formatter(fmt=_LOG_FMT, datefmt=_LOG_DATE_FMT))
-
-
-def _k8s_error_handler(err: Exception) -> None:
- """When running in Kubernetes, write errors to the termination log."""
- with open(TERMINATION_LOG, "w", encoding="UTF-8") as term_log:
- # recursively write nested exceptions
- def _write_errors_to_term_log(e: BaseException) -> None:
- term_log.write(f"{type(e)}: {e}\n")
- if e.__cause__:
- _write_errors_to_term_log(e.__cause__)
-
- _write_errors_to_term_log(err)
-
-
-def _error_handler(err: Exception) -> int:
- """Catch and handle exceptions from the applicaiton."""
- # keybaord interrupts are fine
- if isinstance(err, KeyboardInterrupt):
- return 0
-
- # on k8s, write errors to log file
- if os.path.isfile(TERMINATION_LOG):
- _k8s_error_handler(err)
-
- # raise uncaught errors
- if not isinstance(err, ModelServerException):
- raise err
-
- # gracefully handle caught errors
- _LOGGER.error(str(err))
-
- # if there is a nested error, raise it
- if err.__cause__:
- raise err.__cause__
-
- # we decided to quite gracefully
- return 1
-
-
-if __name__ == "__main__":
- try:
- _ARGS = parse_args()
- _bootstrap_logging(_ARGS.verbose - _ARGS.quiet)
- sys.exit(main(_ARGS))
- # pylint: disable-next=broad-exception-caught; Error handling based on type is done in the handler
- except Exception as _ERR:
- sys.exit(_error_handler(_ERR))
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/model_server/conversion/__init__.py b/RetrievalAugmentedGeneration/llm-inference-server/model_server/conversion/__init__.py
deleted file mode 100644
index f729920bd..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/model_server/conversion/__init__.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-# SPDX-License-Identifier: Apache-2.0
-#
-# 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.
-
-"""This module contains the logic for doing model conversions to TensorRT."""
-from dataclasses import dataclass
-from typing import Optional
-
-from ..errors import ModelServerException
-from ..model import Model, ModelFormats, ModelTypes
-
-
-@dataclass
-class ConversionOptions:
- """Class containing the options used in TRT conversion."""
-
- max_input_length: int
- max_output_length: int
- pipline_parallelism: int
- tensor_parallelism: int
- vocab_size: Optional[int] = None
- quantization: Optional[str] = ""
-
-
-def convert(model: Model, opts: ConversionOptions) -> None:
- """
- Convert the provided model to TensorRT.
-
- Supported types and formats:
- +----------+---------+---------+---------+---------+---------+
- | | NEMO | PYTORCH | ONNX | HFACE | UNKNOWN |
- +----------+---------+---------+---------+---------+---------+
- | LLAMA | ✅ | ✅ | ❌ | ✅ | ❌ |
- | GPTNEXT | ✅ | ❌ | ❌ | ❌ | ❌ |
- +----------+---------+---------+---------+---------+---------+
- """
- if model.format == ModelFormats.NEMO:
- # pylint: disable-next=import-outside-toplevel # preventing circular imports
- from . import nemo
-
- nemo.convert(model, opts)
-
- elif model.type == ModelTypes.LLAMA:
- # pylint: disable-next=import-outside-toplevel # preventing circular imports
- from . import llama
-
- opts.vocab_size = 32000
- llama.convert(model, opts)
-
- elif model.type == ModelTypes.CODE_LLAMA:
- # pylint: disable-next=import-outside-toplevel # preventing circular imports
- from . import llama
-
- opts.vocab_size = 32016
- llama.convert(model, opts)
-
- else:
- supported_types = [e.name for e in ModelTypes]
- raise ModelServerException(
- f"Unsupported model type. Conversion is supported for the following types: {supported_types}"
- )
-
- model.write_hash()
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/model_server/conversion/llama.py b/RetrievalAugmentedGeneration/llm-inference-server/model_server/conversion/llama.py
deleted file mode 100644
index 60b93c667..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/model_server/conversion/llama.py
+++ /dev/null
@@ -1,127 +0,0 @@
-# SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-# SPDX-License-Identifier: Apache-2.0
-#
-# 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.
-
-"""This module contains the logic for exporting a Llama model in PyTorch format to TensorRT."""
-import logging
-import os
-import subprocess
-import sys
-import typing
-
-from ..errors import ModelServerException, UnsupportedFormatException
-from ..model import Model
-from . import ConversionOptions
-
-_CONVERSION_SCRIPTS = "/opt/conversion_scripts/llama"
-
-_CHECKPOINT_ARGS_FLAGS = {"PYTORCH": "--meta_ckpt_dir", "HUGGINGFACE": "--model_dir"}
-_QUANTIZATIONS = ["int4_awq"]
-
-_LOGGER = logging.getLogger(__name__)
-
-def find_pt_file(directory):
- for root, dirs, files in os.walk(directory):
- for file in files:
- if file.endswith(".pt"):
- return os.path.join(root, file)
- return None
-
-def convert(model: Model, opts: ConversionOptions) -> None:
- """Convert a llama model."""
- _LOGGER.debug("Running Llama model conversion.")
- _LOGGER.info(f"Model Format: {model.format.name}")
-
- # construct builder executable path
- cwd = _CONVERSION_SCRIPTS
- exe = [sys.executable, "build.py"]
-
- # construct builder env variables
- env = os.environ
-
- # construct builder arguments
- try:
- raw_args: typing.List[str] = [
- "--max_input_len",
- str(opts.max_input_length),
- "--max_output_len",
- str(opts.max_output_length),
- "--dtype",
- "float16",
- "--use_gpt_attention_plugin",
- "float16",
- "--use_inflight_batching",
- "--paged_kv_cache",
- "--remove_input_padding",
- "--use_gemm_plugin",
- "float16",
- "--output_dir",
- model.engine_dir,
- "--world_size",
- str(model.world_size),
- "--tp_size",
- str(opts.tensor_parallelism),
- "--pp_size",
- str(opts.pipline_parallelism),
- "--vocab_size",
- str(opts.vocab_size),
- ]
-
- if opts.quantization:
- if opts.quantization == "int4_awq" and model.format.name == "PYTORCH":
- ckpt_dir = find_pt_file(model.model_dir)
- raw_args.extend([
- "--use_weight_only",
- "--weight_only_precision",
- "int4_awq",
- "--per_group",
- "--quant_ckpt_path",
- str(ckpt_dir),
- ])
- else:
- raise Exception(
- "Unsupported quantization or model format, " \
- + f"supported quantizations: {_QUANTIZATIONS}, " \
- + "with format: PYTORCH"
- )
- else:
- raw_args.extend([
- _CHECKPOINT_ARGS_FLAGS[model.format.name],
- model.model_dir,
- ])
-
- except KeyError as err:
- raise UnsupportedFormatException(
- model.format.name, ["PyTorch", "Hugging Face"]
- ) from err
-
- # start the builder
- _LOGGER.debug(
- "Starting Llama exporter with the command: %s", " ".join(exe + raw_args)
- )
- _LOGGER.debug("Starting Llama exporter with the env vars: %s", repr(env))
- with subprocess.Popen(exe + raw_args, env=env, cwd=cwd) as proc:
- try:
- retcode = proc.wait()
- except KeyboardInterrupt:
- proc.kill()
- except Exception as err:
- raise ModelServerException(
- "Error running TensorRT model conversion."
- ) from err
- else:
- if retcode != 0:
- raise ModelServerException(
- "TensorRT conversion returned a non-zero exit code."
- )
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/model_server/conversion/nemo.py b/RetrievalAugmentedGeneration/llm-inference-server/model_server/conversion/nemo.py
deleted file mode 100644
index 437f30751..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/model_server/conversion/nemo.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-# SPDX-License-Identifier: Apache-2.0
-#
-# 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.
-
-"""This module contains the code for converting any .nemo formatted model to TRT LLM."""
-import logging
-import os
-from glob import glob
-from tarfile import TarFile
-from typing import IO, cast
-
-import yaml
-
-# pylint: disable-next=import-error
-from nemo.export import TensorRTLLM # type: ignore
-
-from ..errors import ModelServerException
-from ..model import Model
-from . import ConversionOptions
-
-_LOGGER = logging.getLogger(__name__)
-
-
-def convert(model: Model, opts: ConversionOptions) -> None:
- """Convert a .nemo formatted model."""
- # find the .nemo model file
- model_files = glob(os.path.join(model.model_dir, "*.nemo"))
- if len(model_files) > 1:
- raise ModelServerException(
- "More than one NeMo checkpoint found in the model directory. "
- + "Please only include one NeMo checkpoint file."
- )
-
- # verify that the model parallelism matchines the
- config = {}
- with TarFile(model_files[0], "r") as archive:
- try:
- config_file = cast(IO[bytes], archive.extractfile("./model_config.yaml"))
- except KeyError:
- config_file = cast(IO[bytes], archive.extractfile("model_config.yaml"))
- config = yaml.safe_load(config_file)
- config_file.close()
-
- # run the nemo to trt llm conversion
- trt_llm_exporter = TensorRTLLM(model_dir=model.engine_dir)
- _LOGGER.info(".nemo to TensorRT Conversion started. This will take a few minutes.")
- _LOGGER.info(model.engine_dir)
- trt_llm_exporter.export(
- nemo_checkpoint_path=model_files[0],
- model_type=model.family,
- n_gpus=model.world_size,
- max_input_token=opts.max_input_length,
- max_output_token=opts.max_output_length
- )
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/model_server/errors.py b/RetrievalAugmentedGeneration/llm-inference-server/model_server/errors.py
deleted file mode 100644
index 5609a58a9..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/model_server/errors.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-# SPDX-License-Identifier: Apache-2.0
-#
-# 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.
-
-"""The custom errors raised by the model server."""
-import typing
-
-
-class ModelServerException(Exception):
- """The base class for any custom expections."""
-
-
-class UnsupportedFormatException(ModelServerException):
- """An error that indicates the model format is not supported for the provided type."""
-
- def __init__(self, model_type: str, supported: typing.List[str]):
- """Initialize the exception."""
- super().__init__(
- "Unsupported model type and format combination. "
- + f"{model_type} models are supported in the following formats: {str(supported)}"
- )
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/model_server/model.py b/RetrievalAugmentedGeneration/llm-inference-server/model_server/model.py
deleted file mode 100644
index 0f83459ba..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/model_server/model.py
+++ /dev/null
@@ -1,246 +0,0 @@
-# SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-# SPDX-License-Identifier: Apache-2.0
-#
-# 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.
-
-"""This module contains the model class that represents the model mounted to the container."""
-import glob
-import hashlib
-import logging
-import os
-import pathlib
-import subprocess
-import typing
-from enum import Enum, auto, unique
-
-from .errors import ModelServerException
-
-DEFAULT_MODEL_DIR = "/model"
-HASH_COMMAND = "sha1sum"
-_LOGGER = logging.getLogger(__name__)
-
-
-def _fast_hash_dir(dir_path: str) -> str:
- """
- Read the files in a directory and quickly create a hash.
-
- This hash IS NOT cryptographically secure, but it is designed to be computed as quickly as reasonably possible.
- This function will only hash top level files and will not traverse directories.
- """
- # create a threaded pool of workers to calculate individual hases
- workers = []
- for obj in os.listdir(dir_path):
- obj_path = os.path.join(dir_path, obj)
- if not os.path.isfile(obj_path):
- continue
-
- workers += [
- # pylint: disable-next=consider-using-with
- subprocess.Popen(
- [HASH_COMMAND, obj_path], stdout=subprocess.PIPE, stderr=subprocess.PIPE
- )
- ]
-
- # wait for workers to complete
- all_shas = b""
- for proc in workers:
- stdout, _ = proc.communicate()
- all_shas += stdout.split(b" ", maxsplit=1)[0]
-
- hasher = hashlib.sha1(usedforsecurity=False)
- hasher.update(all_shas)
- return hasher.hexdigest()
-
-
-@unique
-class ModelFormats(Enum):
- """A Enumerator containing all of the supported model types."""
-
- UNKNOWN = auto()
- ONNX = auto()
- PYTORCH = auto()
- HUGGINGFACE = auto()
- NEMO = auto()
-
-
-@unique
-class ModelTypes(Enum):
- """A enumerator of the supported model types."""
-
- LLAMA = auto()
- CODE_LLAMA = auto()
- GPTNEXT = auto()
-
- @property
- def family(self) -> str:
- """Return the family grouping of the model."""
- return ["llama", "llama", "gptnext"][self.value - 1]
-
-
-class Model:
- """A representation of the mounted model."""
-
- def __init__(
- self,
- model_type: str,
- model_dir: typing.Optional[str] = None,
- world_size: typing.Optional[int] = None,
- ):
- """Initialize the model class."""
- try:
- self._type = ModelTypes[model_type.upper().replace("-", "_")]
- except KeyError as err:
- raise ModelServerException(f"Unrecognized model type {type}") from err
-
- self._model_dir = model_dir or DEFAULT_MODEL_DIR
- self._gpu_info = self._init_gpu_info(world_size=world_size)
- self._hash: typing.Optional[str] = None
- self._engine_dir = self._init_engine_dir()
- self._format = self._init_model_format()
-
- @classmethod
- def _init_gpu_info(
- cls,
- world_size: typing.Optional[int] = None,
- ) -> typing.Dict[str, typing.Union[str, int]]:
- """
- Get the product name and architecture for the first GPU in the system.
-
- Returns
- -------
- Tuple: A tuple of the product name and architecture.
- """
- query_cmd = ["nvidia-smi", "--query-gpu=compute_cap", "--format=csv,noheader"]
- gpu_info_raw = subprocess.check_output(query_cmd)
- compute_caps = [cap.decode() for cap in gpu_info_raw.strip().split(b"\n")]
- # FUTURE: convert this to use nvml instead
-
- # do basic error checking
- if len(compute_caps) == 0:
- raise ModelServerException("No GPUs attached to the container.")
- if len(set(compute_caps)) > 1:
- raise ModelServerException(
- "Attached GPUs are dissimilar. All GPUs must be of the same type."
- )
- if not world_size:
- world_size = len(compute_caps)
-
- return {"compute_cap": compute_caps[0], "world_size": world_size}
-
- def _init_engine_dir(self) -> str:
- """Create and return the path to the TensorRT cache directory for this model."""
- cache_dir = f"trt-w{self.world_size}-cc{self.compute_cap}"
- cache_path = os.path.join(self.model_dir, cache_dir)
- pathlib.Path(cache_path).mkdir(parents=True, exist_ok=True)
- return cache_path
-
- def _init_model_format(self) -> ModelFormats:
- """Determine the format of model that has been mounted."""
- # look for nemo checkpoints
- nemo_count = self._file_ext_count("nemo")
- if nemo_count == 1:
- return ModelFormats.NEMO
- if nemo_count > 1:
- raise ModelServerException(
- f"Only one nemo checkpoint file may be in the model directory. Found {nemo_count}",
- )
-
- # look for pytorch saved models
- pytorch_count = self._file_ext_count("pth") + self._file_ext_count("pt")
- if pytorch_count:
- return ModelFormats.PYTORCH
-
- # look for huggingface saved models
- hf_count = self._file_ext_count("bin")
- if hf_count:
- return ModelFormats.HUGGINGFACE
-
- # look for onnx models
- onnx_count = self._file_ext_count("onnx")
- if onnx_count:
- return ModelFormats.ONNX
-
- return ModelFormats.UNKNOWN
-
- def _file_ext_count(self, extension: str) -> int:
- """Count the files in a directory with a given extension."""
- path = os.path.join(self.model_dir, f"*.{extension}")
- return len(glob.glob(path))
-
- @property
- def type(self) -> ModelTypes:
- """Return the type of the model."""
- return self._type
-
- @property
- def family(self) -> str:
- """Return the model family grouping."""
- return self._type.family
-
- @property
- def model_dir(self) -> str:
- """Return the stored model directory."""
- return self._model_dir
-
- @property
- def engine_dir(self) -> str:
- """Return the stored engine directory."""
- return self._engine_dir
-
- @property
- def world_size(self) -> int:
- """Return the world size."""
- ws = self._gpu_info["world_size"]
- return typing.cast(int, ws)
-
- @property
- def compute_cap(self) -> str:
- """Return the compute capability version."""
- cc = self._gpu_info["compute_cap"]
- return typing.cast(str, cc)
-
- @property
- def format(self) -> ModelFormats:
- """Return the format of the model."""
- return self._format
-
- @property
- def hash(self) -> str:
- """Return the hash of the model."""
- if not self._hash:
- _LOGGER.info("Calculating model hash.")
- self._hash = _fast_hash_dir(self.model_dir)
- return self._hash
-
- @property
- def _last_hash_path(self) -> str:
- """Return the path to the last known hash file."""
- return os.path.join(self.engine_dir, "hash")
-
- def conversion_is_needed(self) -> bool:
- """Determine if the engine conversion is required."""
- if not os.path.isfile(self._last_hash_path):
- _LOGGER.debug("No engine file exists. Will generate an engine file.")
- return True
- with open(self._last_hash_path, "r", encoding="ASCII") as hash_file:
- last_hash = hash_file.read()
- if last_hash != self.hash:
- _LOGGER.debug("Change in model hash detected. Will regnerate engine file.")
- return True
- _LOGGER.debug("Existing engine file found.")
- return False
-
- def write_hash(self) -> None:
- """Write the model hash to the engine directory."""
- with open(self._last_hash_path, "w", encoding="ASCII") as hash_file:
- hash_file.write(self.hash)
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/model_server/server.py b/RetrievalAugmentedGeneration/llm-inference-server/model_server/server.py
deleted file mode 100644
index 272234ec5..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/model_server/server.py
+++ /dev/null
@@ -1,155 +0,0 @@
-# SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-# SPDX-License-Identifier: Apache-2.0
-#
-# 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.
-
-"""This module contains the code to statup triton inference servers."""
-import logging
-import os
-import subprocess
-import typing
-
-from jinja2 import Environment, FileSystemLoader
-
-from .model import Model, ModelFormats
-
-_ENSEMBLE_MODEL_DIR = "/opt/ensemble_models"
-_TRITON_BIN = "/opt/tritonserver/bin/tritonserver"
-_MPIRUN_BIN = "/usr/local/mpi/bin/mpirun"
-_LOGGER = logging.getLogger(__name__)
-
-
-class ModelServer:
- """Abstraction of a multi-gpu triton inference server cluster."""
-
- def __init__(self, model: Model, http: bool = False) -> None:
- """Initialize the model server."""
- self._model = model
- self._http = http
-
- @property
- def _decoupled_mode(self) -> str:
- """Indicate if the Triton models should be hosted in decoupled mode for streaming."""
- if self._model.format == ModelFormats.NEMO:
- return "false"
- return "true" if not self._http else "false"
-
- @property
- def _allow_http(self) -> str:
- """Indicate if Triton should allow http connections."""
- if self._model.format == ModelFormats.NEMO:
- return "true"
- return "true" if self._http else "false"
-
- @property
- def _allow_grpc(self) -> str:
- """Inidicate if Triton should allow grpc connections."""
- return "true" if not self._http else "false"
-
- @property
- def _tokenizer_model_dir(self) -> str:
- """Inidicate where the tokenizer model can be found."""
- if self._model.format == ModelFormats.NEMO:
- return self._model.engine_dir
- return self._model.model_dir
-
- @property
- def _gpt_model_type(self) -> str:
- """Indicate the TRT LLM Backend mode."""
- if self._model.format == ModelFormats.NEMO:
- return "V1"
- return "inflight_fused_batching"
-
- @property
- def model_repository(self) -> str:
- """Return the triton model repository."""
- return os.path.join(_ENSEMBLE_MODEL_DIR, self._model.family)
-
- def _triton_server_cmd(self, rank: int) -> typing.List[str]:
- """Generate the command to start a single triton server of given rank."""
- return [
- "-n",
- "1",
- _TRITON_BIN,
- "--allow-http",
- self._allow_http,
- "--allow-grpc",
- self._allow_grpc,
- "--model-repository",
- self.model_repository,
- "--disable-auto-complete-config",
- f"--backend-config=python,shm-region-prefix-name=prefix{rank}_",
- ":",
- ]
-
- @property
- def _cmd(self) -> typing.List[str]:
- """Generate the full command."""
- cmd = [_MPIRUN_BIN]
- for rank in range(self._model.world_size):
- cmd += self._triton_server_cmd(rank)
- return cmd
-
- @property
- def _env(self) -> typing.Dict[str, str]:
- """Return the environment variable for the triton inference server."""
- env = dict(os.environ)
- env["TRT_ENGINE_DIR"] = self._model.engine_dir
- env["TOKENIZER_DIR"] = self._tokenizer_model_dir
- if os.getuid() == 0:
- _LOGGER.warning(
- "Triton server will be running as root. It is recommended that you don't run this container as root."
- )
- env["OMPI_ALLOW_RUN_AS_ROOT"] = "1"
- env["OMPI_ALLOW_RUN_AS_ROOT_CONFIRM"] = "1"
- return env
-
- def _render_model_templates(self) -> None:
- """Render and Jinja templates in the model directory."""
- env = Environment(
- loader=FileSystemLoader(searchpath=self.model_repository),
- autoescape=False,
- ) # nosec; all the provided values are from code, not the user
-
- template_path = os.path.join("tensorrt_llm", "config.pbtxt.j2")
- output_path = os.path.join(
- self.model_repository, "tensorrt_llm", "config.pbtxt"
- )
-
- template = env.get_template(template_path)
-
- with open(output_path, "w", encoding="UTF-8") as out:
- template_args = {
- "engine_dir": self._model.engine_dir,
- "decoupled_mode": self._decoupled_mode,
- "gpt_model_type": self._gpt_model_type,
- }
- out.write(template.render(**template_args))
-
- def run(self) -> int:
- """Start the triton inference server."""
- cmd = self._cmd
- env = self._env
-
- _LOGGER.debug("Rendering the ensemble models.")
- self._render_model_templates()
-
- _LOGGER.debug("Starting triton with the command: %s", " ".join(cmd))
- _LOGGER.debug("Starting triton with the env vars: %s", repr(env))
- with subprocess.Popen(cmd, env=env) as proc:
- try:
- retcode = proc.wait()
- except KeyboardInterrupt:
- proc.kill()
- return 0
- return retcode
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/model_server_client/trt_llm.py b/RetrievalAugmentedGeneration/llm-inference-server/model_server_client/trt_llm.py
deleted file mode 100644
index 7291db4c1..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/model_server_client/trt_llm.py
+++ /dev/null
@@ -1,544 +0,0 @@
-# SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
-# SPDX-License-Identifier: Apache-2.0
-#
-# 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.
-
-"""A Langchain LLM component for connecting to Triton + TensorRT LLM backend."""
-# pylint: disable=too-many-lines
-import abc
-import json
-import queue
-import random
-import time
-from functools import partial
-from typing import Any, Callable, Dict, List, Optional, Type, Union
-
-import google.protobuf.json_format
-import numpy as np
-import tritonclient.grpc as grpcclient
-import tritonclient.http as httpclient
-from tritonclient.grpc.service_pb2 import ModelInferResponse
-from tritonclient.utils import np_to_triton_dtype
-
-try:
- from langchain.callbacks.manager import CallbackManagerForLLMRun
- from langchain.llms.base import LLM
- from langchain.pydantic_v1 import Field, root_validator
-
- USE_LANGCHAIN = True
-except ImportError:
- USE_LANGCHAIN = False
-
-
-STOP_WORDS = [""]
-RANDOM_SEED = 0
-
-if USE_LANGCHAIN:
- # pylint: disable-next=too-few-public-methods # Interface is defined by LangChain
- class TensorRTLLM(LLM): # type: ignore # LLM class not typed in langchain
- """A custom Langchain LLM class that integrates with TRTLLM triton models.
-
- Arguments:
- server_url: (str) The URL of the Triton inference server to use.
- model_name: (str) The name of the Triton TRT model to use.
- temperature: (str) Temperature to use for sampling
- top_p: (float) The top-p value to use for sampling
- top_k: (float) The top k values use for sampling
- beam_width: (int) Last n number of tokens to penalize
- repetition_penalty: (int) Last n number of tokens to penalize
- length_penalty: (float) The penalty to apply repeated tokens
- tokens: (int) The maximum number of tokens to generate.
- client: The client object used to communicate with the inference server
- """
-
- server_url: str = Field(None, alias="server_url")
-
- # # all the optional arguments
- model_name: str = "ensemble"
- temperature: Optional[float] = 1.0
- top_p: Optional[float] = 0
- top_k: Optional[int] = 1
- tokens: Optional[int] = 100
- beam_width: Optional[int] = 1
- repetition_penalty: Optional[float] = 1.0
- length_penalty: Optional[float] = 1.0
- client: Any
- streaming: Optional[bool] = True
-
- @root_validator() # type: ignore # typing not declared in langchain
- @classmethod
- def validate_environment(cls, values: Dict[str, Any]) -> Dict[str, Any]:
- """Validate that python package exists in environment."""
- try:
- if values.get("streaming", True):
- values["client"] = GrpcTritonClient(values["server_url"])
- else:
- values["client"] = HttpTritonClient(values["server_url"])
-
- except ImportError as err:
- raise ImportError(
- "Could not import triton client python package. "
- "Please install it with `pip install tritonclient[all]`."
- ) from err
- return values
-
- @property
- def _get_model_default_parameters(self) -> Dict[str, Any]:
- return {
- "tokens": self.tokens,
- "top_k": self.top_k,
- "top_p": self.top_p,
- "temperature": self.temperature,
- "repetition_penalty": self.repetition_penalty,
- "length_penalty": self.length_penalty,
- "beam_width": self.beam_width,
- }
-
- @property
- def _invocation_params(self, **kwargs: Any) -> Dict[str, Any]:
- params = {**self._get_model_default_parameters, **kwargs}
- return params
-
- @property
- def _identifying_params(self) -> Dict[str, Any]:
- """Get all the identifying parameters."""
- return {
- "server_url": self.server_url,
- "model_name": self.model_name,
- }
-
- @property
- def _llm_type(self) -> str:
- return "triton_tensorrt"
-
- def _call(
- self,
- prompt: str,
- stop: Optional[List[str]] = None, # pylint: disable=unused-argument
- run_manager: Optional[CallbackManagerForLLMRun] = None,
- **kwargs: Any,
- ) -> str:
- """
- Execute an inference request.
-
- Args:
- prompt: The prompt to pass into the model.
- stop: A list of strings to stop generation when encountered
-
- Returns:
- The string generated by the model
- """
- text_callback = None
- if run_manager:
- text_callback = partial(
- run_manager.on_llm_new_token, verbose=self.verbose
- )
-
- invocation_params = self._get_model_default_parameters
- invocation_params.update(kwargs)
- invocation_params["prompt"] = [[prompt]]
- model_params = self._identifying_params
- model_params.update(kwargs)
- request_id = str(random.randint(1, 9999999)) # nosec
-
- self.client.load_model(model_params["model_name"])
- if isinstance(self.client, GrpcTritonClient):
- return self._streaming_request(
- model_params, request_id, invocation_params, text_callback
- )
- return self._request(model_params, invocation_params, text_callback)
-
- def _streaming_request(
- self,
- model_params: Dict[str, Any],
- request_id: str,
- invocation_params: Dict[str, Any],
- text_callback: Optional[Callable[[str], None]],
- ) -> str:
- """Request a streaming inference session."""
- result_queue = self.client.request_streaming(
- model_params["model_name"], request_id, **invocation_params
- )
-
- response = ""
- for token in result_queue:
- if text_callback:
- text_callback(token)
- response = response + token
- return response
-
- def _request(
- self,
- model_params: Dict[str, Any],
- invocation_params: Dict[str, Any],
- text_callback: Optional[Callable[[str], None]],
- ) -> str:
- """Request a streaming inference session."""
- token: str = self.client.request(
- model_params["model_name"], **invocation_params
- )
- if text_callback:
- text_callback(token)
- return token
-
-
-class StreamingResponseGenerator(queue.Queue[Optional[str]]):
- """A Generator that provides the inference results from an LLM."""
-
- def __init__(
- self, client: "GrpcTritonClient", request_id: str, force_batch: bool
- ) -> None:
- """Instantiate the generator class."""
- super().__init__()
- self._client = client
- self.request_id = request_id
- self._batch = force_batch
-
- def __iter__(self) -> "StreamingResponseGenerator":
- """Return self as a generator."""
- return self
-
- def __next__(self) -> str:
- """Return the next retrieved token."""
- val = self.get()
- if val is None or val in STOP_WORDS:
- self._stop_stream()
- raise StopIteration()
- return val
-
- def _stop_stream(self) -> None:
- """Drain and shutdown the Triton stream."""
- self._client.stop_stream(
- "tensorrt_llm", self.request_id, signal=not self._batch
- )
-
-
-class _BaseTritonClient(abc.ABC):
- """An abstraction of the connection to a triton inference server."""
-
- def __init__(self, server_url: str) -> None:
- """Initialize the client."""
- self._server_url = server_url
- self._client = self._inference_server_client(server_url)
-
- @property
- @abc.abstractmethod
- def _inference_server_client(
- self,
- ) -> Union[
- Type[grpcclient.InferenceServerClient], Type[httpclient.InferenceServerClient]
- ]:
- """Return the prefered InferenceServerClient class."""
-
- @property
- @abc.abstractmethod
- def _infer_input(
- self,
- ) -> Union[Type[grpcclient.InferInput], Type[httpclient.InferInput]]:
- """Return the preferred InferInput."""
-
- @property
- @abc.abstractmethod
- def _infer_output(
- self,
- ) -> Union[
- Type[grpcclient.InferRequestedOutput], Type[httpclient.InferRequestedOutput]
- ]:
- """Return the preferred InferRequestedOutput."""
-
- def load_model(self, model_name: str, timeout: int = 1000) -> None:
- """Load a model into the server."""
- if self._client.is_model_ready(model_name):
- return
-
- self._client.load_model(model_name)
- t0 = time.perf_counter()
- t1 = t0
- while not self._client.is_model_ready(model_name) and t1 - t0 < timeout:
- t1 = time.perf_counter()
-
- if not self._client.is_model_ready(model_name):
- raise RuntimeError(f"Failed to load {model_name} on Triton in {timeout}s")
-
- def get_model_list(self) -> List[str]:
- """Get a list of models loaded in the triton server."""
- res = self._client.get_model_repository_index(as_json=True)
- return [model["name"] for model in res["models"]]
-
- def get_model_concurrency(self, model_name: str, timeout: int = 1000) -> int:
- """Get the modle concurrency."""
- self.load_model(model_name, timeout)
- instances = self._client.get_model_config(model_name, as_json=True)["config"][
- "instance_group"
- ]
- return sum(instance["count"] * len(instance["gpus"]) for instance in instances)
-
- def _generate_stop_signals(
- self,
- ) -> List[Union[grpcclient.InferInput, httpclient.InferInput]]:
- """Generate the signal to stop the stream."""
- inputs = [
- self._infer_input("input_ids", [1, 1], "INT32"),
- self._infer_input("input_lengths", [1, 1], "INT32"),
- self._infer_input("request_output_len", [1, 1], "UINT32"),
- self._infer_input("stop", [1, 1], "BOOL"),
- ]
- inputs[0].set_data_from_numpy(np.empty([1, 1], dtype=np.int32))
- inputs[1].set_data_from_numpy(np.zeros([1, 1], dtype=np.int32))
- inputs[2].set_data_from_numpy(np.array([[0]], dtype=np.uint32))
- inputs[3].set_data_from_numpy(np.array([[True]], dtype="bool"))
- return inputs
-
- def _generate_outputs(
- self,
- ) -> List[Union[grpcclient.InferRequestedOutput, httpclient.InferRequestedOutput]]:
- """Generate the expected output structure."""
- return [self._infer_output("text_output")]
-
- def _prepare_tensor(
- self, name: str, input_data: Any
- ) -> Union[grpcclient.InferInput, httpclient.InferInput]:
- """Prepare an input data structure."""
- t = self._infer_input(
- name, input_data.shape, np_to_triton_dtype(input_data.dtype)
- )
- t.set_data_from_numpy(input_data)
- return t
-
- def _generate_inputs( # pylint: disable=too-many-arguments,too-many-locals
- self,
- prompt: str,
- tokens: int = 300,
- temperature: float = 1.0,
- top_k: float = 1,
- top_p: float = 0,
- beam_width: int = 1,
- repetition_penalty: float = 1,
- length_penalty: float = 1.0,
- stream: bool = True,
- ) -> List[Union[grpcclient.InferInput, httpclient.InferInput]]:
- """Create the input for the triton inference server."""
- query = np.array(prompt).astype(object)
- request_output_len = np.array([tokens]).astype(np.uint32).reshape((1, -1))
- runtime_top_k = np.array([top_k]).astype(np.uint32).reshape((1, -1))
- runtime_top_p = np.array([top_p]).astype(np.float32).reshape((1, -1))
- temperature_array = np.array([temperature]).astype(np.float32).reshape((1, -1))
- len_penalty = np.array([length_penalty]).astype(np.float32).reshape((1, -1))
- repetition_penalty_array = (
- np.array([repetition_penalty]).astype(np.float32).reshape((1, -1))
- )
- random_seed = np.array([RANDOM_SEED]).astype(np.uint64).reshape((1, -1))
- beam_width_array = np.array([beam_width]).astype(np.uint32).reshape((1, -1))
- streaming_data = np.array([[stream]], dtype=bool)
-
- inputs = [
- self._prepare_tensor("text_input", query),
- self._prepare_tensor("max_tokens", request_output_len),
- self._prepare_tensor("top_k", runtime_top_k),
- self._prepare_tensor("top_p", runtime_top_p),
- self._prepare_tensor("temperature", temperature_array),
- self._prepare_tensor("length_penalty", len_penalty),
- self._prepare_tensor("repetition_penalty", repetition_penalty_array),
- self._prepare_tensor("random_seed", random_seed),
- self._prepare_tensor("beam_width", beam_width_array),
- self._prepare_tensor("stream", streaming_data),
- ]
- return inputs
-
- def _trim_batch_response(self, result_str: str) -> str:
- """Trim the resulting response from a batch request by removing provided prompt and extra generated text."""
- # extract the generated part of the prompt
- split = result_str.split("[/INST]", 1)
- generated = split[-1]
- end_token = generated.find("")
- if end_token == -1:
- return generated
- generated = generated[:end_token].strip()
- return generated
-
-
-class GrpcTritonClient(_BaseTritonClient):
- """GRPC connection to a triton inference server."""
-
- @property
- def _inference_server_client(
- self,
- ) -> Type[grpcclient.InferenceServerClient]:
- """Return the prefered InferenceServerClient class."""
- return grpcclient.InferenceServerClient # type: ignore
-
- @property
- def _infer_input(self) -> Type[grpcclient.InferInput]:
- """Return the preferred InferInput."""
- return grpcclient.InferInput # type: ignore
-
- @property
- def _infer_output(
- self,
- ) -> Type[grpcclient.InferRequestedOutput]:
- """Return the preferred InferRequestedOutput."""
- return grpcclient.InferRequestedOutput # type: ignore
-
- def _send_stop_signals(self, model_name: str, request_id: str) -> None:
- """Send the stop signal to the Triton Inference server."""
- stop_inputs = self._generate_stop_signals()
- self._client.async_stream_infer(
- model_name,
- stop_inputs,
- request_id=request_id,
- parameters={"Streaming": True},
- )
-
- @staticmethod
- def _process_result(result: Dict[str, str]) -> str:
- """Post-process the result from the server."""
- message = ModelInferResponse()
- generated_text: str = ""
- google.protobuf.json_format.Parse(json.dumps(result), message)
- infer_result = grpcclient.InferResult(message)
- np_res = infer_result.as_numpy("text_output")
-
- generated_text = ""
- if np_res is not None:
- generated_text = "".join([token.decode() for token in np_res])
-
- return generated_text
-
- def _stream_callback(
- self,
- result_queue: queue.Queue[Union[Optional[Dict[str, str]], str]],
- force_batch: bool,
- result: Any,
- error: str,
- ) -> None:
- """Add streamed result to queue."""
- if error:
- result_queue.put(error)
- else:
- response_raw = result.get_response(as_json=True)
- if "outputs" in response_raw:
- # the very last response might have no output, just the final flag
- response = self._process_result(response_raw)
- if force_batch:
- response = self._trim_batch_response(response)
-
- if response in STOP_WORDS:
- result_queue.put(None)
- else:
- result_queue.put(response)
-
- if response_raw["parameters"]["triton_final_response"]["bool_param"]:
- # end of the generation
- result_queue.put(None)
-
- # pylint: disable-next=too-many-arguments
- def _send_prompt_streaming(
- self,
- model_name: str,
- request_inputs: Any,
- request_outputs: Optional[Any],
- request_id: str,
- result_queue: StreamingResponseGenerator,
- force_batch: bool = False,
- ) -> None:
- """Send the prompt and start streaming the result."""
- self._client.start_stream(
- callback=partial(self._stream_callback, result_queue, force_batch)
- )
- self._client.async_stream_infer(
- model_name=model_name,
- inputs=request_inputs,
- outputs=request_outputs,
- request_id=request_id,
- )
-
- def request_streaming(
- self,
- model_name: str,
- request_id: Optional[str] = None,
- force_batch: bool = False,
- **params: Any,
- ) -> StreamingResponseGenerator:
- """Request a streaming connection."""
- if not self._client.is_model_ready(model_name):
- raise RuntimeError("Cannot request streaming, model is not loaded")
-
- if not request_id:
- request_id = str(random.randint(1, 9999999)) # nosec
-
- result_queue = StreamingResponseGenerator(self, request_id, force_batch)
- inputs = self._generate_inputs(stream=not force_batch, **params)
- outputs = self._generate_outputs()
- self._send_prompt_streaming(
- model_name,
- inputs,
- outputs,
- request_id,
- result_queue,
- force_batch,
- )
- return result_queue
-
- def stop_stream(
- self, model_name: str, request_id: str, signal: bool = True
- ) -> None:
- """Close the streaming connection."""
- if signal:
- self._send_stop_signals(model_name, request_id)
- self._client.stop_stream()
-
-
-class HttpTritonClient(_BaseTritonClient):
- """HTTP connection to a triton inference server."""
-
- @property
- def _inference_server_client(
- self,
- ) -> Type[httpclient.InferenceServerClient]:
- """Return the prefered InferenceServerClient class."""
- return httpclient.InferenceServerClient # type: ignore
-
- @property
- def _infer_input(self) -> Type[httpclient.InferInput]:
- """Return the preferred InferInput."""
- return httpclient.InferInput # type: ignore
-
- @property
- def _infer_output(
- self,
- ) -> Type[httpclient.InferRequestedOutput]:
- """Return the preferred InferRequestedOutput."""
- return httpclient.InferRequestedOutput # type: ignore
-
- def request(
- self,
- model_name: str,
- **params: Any,
- ) -> str:
- """Request inferencing from the triton server."""
- if not self._client.is_model_ready(model_name):
- raise RuntimeError("Cannot request streaming, model is not loaded")
-
- # create model inputs and outputs
- inputs = self._generate_inputs(stream=False, **params)
- outputs = self._generate_outputs()
-
- # call the model for inference
- result = self._client.infer(model_name, inputs=inputs, outputs=outputs)
- result_str = "".join(
- [val.decode("utf-8") for val in result.as_numpy("text_output").tolist()]
- )
-
- # extract the generated part of the prompt
- # return(result_str)
- return self._trim_batch_response(result_str)
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/requirements.txt b/RetrievalAugmentedGeneration/llm-inference-server/requirements.txt
deleted file mode 100644
index 3f6a77344..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/requirements.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-jinja2
-langchain
-numpy
-protobuf
-requests
-tritonclient[all]
-pyyaml
diff --git a/RetrievalAugmentedGeneration/llm-inference-server/tools/resize_nemo_model.sh b/RetrievalAugmentedGeneration/llm-inference-server/tools/resize_nemo_model.sh
deleted file mode 100755
index fa35fe16c..000000000
--- a/RetrievalAugmentedGeneration/llm-inference-server/tools/resize_nemo_model.sh
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/bin/bash
-set -x
-
-MODEL_STORE="$1"
-MODEL_IN="$2"
-MODEL_IN_DIR=$(cd $(dirname "$MODEL_IN"); pwd)
-MODEL_OUT="$3"
-MODEL_OUT_DIR=$(cd $(dirname "$MODEL_OUT"); pwd)
-TARGET_SIZE="$4"
-
-TRAINING_CONTAINER="nvcr.io/nvaie/nemo-framework-training:23.08.03"
-
-# init
-echo $MODEL_IN " -> " $MODEL_OUT
-cd "$MODEL_STORE"
-mkdir -p "$MODEL_OUT_DIR"
-
-# find tokenizer
-tar xvf $MODEL_IN model_config.yaml
-mv model_config.yaml "$MODEL_OUT_DIR"
-tokenizer=$(grep "tokenizer_model" gpt_8b_strict_skua_bf16_nemo_yi_dong_us_v1.0-tp1/model_config.yaml | awk -F: '{
- print $3 }')
-tar xvf $MODEL_IN $tokenizer
-mv $tokenizer $MODEL_OUT_DIR
-
-# run conversion
-docker run --rm -it --gpus all --ipc host \
- -v $MODEL_STORE:$MODEL_STORE \
- -w $MODEL_STORE \
- $TRAINING_CONTAINER \
- /usr/bin/python3 \
- /opt/NeMo/examples/nlp/language_modeling/megatron_change_num_partitions.py \
- --model_file $MODEL_IN \
- --target_file $MODEL_OUT \
- --tensor_model_parallel_size=-1 \
- --target_tensor_model_parallel_size=$TARGET_SIZE \
- --pipeline_model_parallel_size=-1 \
- --target_pipeline_model_parallel_size=1 \
- --precision=bf16 \
- --tokenizer_model_path $MODEL_OUT_DIR/$tokenizer
diff --git a/RetrievalAugmentedGeneration/requirements.txt b/RetrievalAugmentedGeneration/requirements.txt
index 7f230915b..d24f72f81 100644
--- a/RetrievalAugmentedGeneration/requirements.txt
+++ b/RetrievalAugmentedGeneration/requirements.txt
@@ -3,8 +3,9 @@ uvicorn[standard]==0.27.1
python-multipart==0.0.9
langchain==0.1.9
unstructured[all-docs]==0.12.5
-sentence-transformers==2.5.1
+sentence-transformers==3.0.0
llama-index-core==0.10.27
+llama-index-readers-file==0.1.22
llama-index-llms-langchain==0.1.3
llama-index-embeddings-langchain==0.1.2
llama-index-vector-stores-milvus==0.1.6
@@ -17,9 +18,7 @@ asyncpg==0.29.0
psycopg2-binary==2.9.9
pgvector==0.2.5
langchain-core==0.1.29
-langchain-nvidia-ai-endpoints==0.0.11
-langchain-nvidia-trt==0.0.1rc0
-nemollm==0.3.4
+langchain-nvidia-ai-endpoints==0.1.1
opentelemetry-sdk==1.23.0
opentelemetry-api==1.23.0
opentelemetry-exporter-otlp-proto-grpc==1.23.0
diff --git a/deploy/compose/compose.env b/deploy/compose/compose.env
index 929b33c6b..f7b90945b 100644
--- a/deploy/compose/compose.env
+++ b/deploy/compose/compose.env
@@ -1,44 +1,39 @@
-# full path to the local copy of the model weights
+# Path where models will be stored
# NOTE: This should be an absolute path and not relative path
-export MODEL_DIRECTORY="/home/nvidia/llama2_13b_chat_hf_v1/"
+export MODEL_DIRECTORY="/home/ubuntu/model-cache"
-# the number of GPUs needed by nemollm inference ms to deploy the model
-export NUM_GPU=1
+# GPU id which nemo embedding ms will use
+# export EMBEDDING_MS_GPU_ID=0
# To control which GPU the vector database uses, specify the device ID.
# export VECTORSTORE_GPU_DEVICE_ID=0
+# GPU id which ranking ms will use (Make sure it is different from the one used for nim ms)
+# export RANKING_MS_GPU_ID=1
+
# Fill this out if you dont have a GPU. Leave this empty if you have a local GPU
export NVIDIA_API_KEY=${NVIDIA_API_KEY}
-# flag to enable activation aware quantization for the LLM
-# export QUANTIZATION="int4_awq"
-
-# the architecture of the model. eg: llama, gptnext (for nemotron use gptnext)
-export MODEL_ARCHITECTURE="llama"
-
-
-# the name of the model being used - only for displaying on rag-playground
-# export MODEL_NAME="Llama-2-13b-chat-hf"
-
-# [OPTIONAL] the maximum number of input tokens
-# export MODEL_MAX_INPUT_LENGTH=3000
-
# [OPTIONAL] the number of GPUs to make available to the inference server
# export INFERENCE_GPU_COUNT="all"
# [OPTIONAL] the base directory inside which all persistent volumes will be created
# export DOCKER_VOLUME_DIRECTORY="."
-# full path to the model store directory storing the nemo embedding model
-export EMBEDDING_MODEL_DIRECTORY="/home/nvidia/nv-embed-qa_v4"
# name of the nemo embedding model
-export EMBEDDING_MODEL_NAME="NV-Embed-QA"
-export EMBEDDING_MODEL_CKPT_NAME="NV-Embed-QA-4.nemo"
+# Both arctic-embed-l & NV-Embed-QA are versions of e5-large-unsupervised
+export APP_EMBEDDINGS_MODELNAME="NV-Embed-QA"
+export EMBEDDING_MODEL_CKPT_NAME="snowflake-arctic-embed-l"
+export EMBEDDING_MODEL_PATH="https://huggingface.co/Snowflake/snowflake-arctic-embed-l"
-# GPU id which nemo embedding ms will use
-# export EMBEDDING_MS_GPU_ID=0
+# name of the nemo re-rank model
+export RANKING_MODEL_NAME="NV-Rerank-QA-Mistral-4B"
+export RANKING_MODEL_CKPT_NAME="nv-rerank-qa-mistral-4b_v2"
+export RANKING_MODEL_PATH="ohlfw0olaadg/ea-participants/nv-rerank-qa-mistral-4b:2"
+
+# name of the nemo retriever pipeline one of ranked_hybrid or hybrid
+NEMO_RETRIEVER_PIPELINE="ranked_hybrid"
# parameters for PGVector, update this when using PGVector Vector store
# export POSTGRES_PASSWORD=password
@@ -69,3 +64,12 @@ export TTS_SAMPLE_RATE=48000
export OPENTELEMETRY_CONFIG_FILE="./configs/otel-collector-config.yaml"
# the config file for Jaeger
export JAEGER_CONFIG_FILE="./configs/jaeger.yaml"
+
+# [OPTIONAL] Set the logging level for the chain server. Possible values are NOTSET, DEBUG, INFO, WARN, ERROR, CRITICAL.
+export LOGLEVEL="INFO"
+
+# User permissoin for containers
+export DOCKER_USER=$(id -u):$(id -g)
+
+# Download script path, this will be mounted at runtime
+export DOWNLOAD_SCRIPT=$PWD/deploy/compose/download_model.sh
diff --git a/deploy/compose/docker-compose-evaluation-application.yaml b/deploy/compose/docker-compose-evaluation-application.yaml
index 66ea7461e..efe4d506b 100644
--- a/deploy/compose/docker-compose-evaluation-application.yaml
+++ b/deploy/compose/docker-compose-evaluation-application.yaml
@@ -1,7 +1,7 @@
services:
rag_evaluator:
container_name: rag-evaluator
- image: rag-evaluator:latest
+ image: rag-evaluator:${TAG:-latest}
build:
context: ../../
dockerfile: ./tools/evaluation/Dockerfile
@@ -18,7 +18,7 @@ services:
synthetic_data_generator:
container_name: data-generator
- image: data-generator:latest
+ image: data-generator:${TAG:-latest}
build:
context: ../../
dockerfile: ./tools/evaluation/Dockerfile
diff --git a/deploy/compose/docker-compose-nemotron.yaml b/deploy/compose/docker-compose-nemotron.yaml
deleted file mode 100644
index 930555f7c..000000000
--- a/deploy/compose/docker-compose-nemotron.yaml
+++ /dev/null
@@ -1,184 +0,0 @@
-services:
-
- llm:
- container_name: llm-inference-server
- image: llm-inference-server:latest
- build:
- context: ../.././RetrievalAugmentedGeneration/llm-inference-server/
- dockerfile: Dockerfile
- volumes:
- - ${MODEL_DIRECTORY:?please update the env file and source it before running}:/model
- command: ${MODEL_ARCHITECTURE:?please update the env file and source it before running} --http --max-input-length ${MODEL_MAX_INPUT_LENGTH:-3000} ${QUANTIZATION:+--quantization $QUANTIZATION}
- ports:
- - "8000:8000"
- - "8001:8001"
- - "8002:8002"
- expose:
- - "8000"
- - "8001"
- - "8002"
- shm_size: 20gb
- deploy:
- resources:
- reservations:
- devices:
- - driver: nvidia
- device_ids: ["0", "1"]
- capabilities: [gpu]
-
- jupyter-server:
- container_name: notebook-server
- image: notebook-server:latest
- build:
- context: ../../
- dockerfile: ./notebooks/Dockerfile.notebooks
- ports:
- - "8888:8888"
- expose:
- - "8888"
- deploy:
- resources:
- reservations:
- devices:
- - driver: nvidia
- count: 1
- capabilities: [gpu]
- depends_on:
- - "llm"
-
- etcd:
- container_name: milvus-etcd
- image: quay.io/coreos/etcd:v3.5.5
- environment:
- - ETCD_AUTO_COMPACTION_MODE=revision
- - ETCD_AUTO_COMPACTION_RETENTION=1000
- - ETCD_QUOTA_BACKEND_BYTES=4294967296
- - ETCD_SNAPSHOT_COUNT=50000
- volumes:
- - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/etcd:/etcd
- command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd
- healthcheck:
- test: ["CMD", "etcdctl", "endpoint", "health"]
- interval: 30s
- timeout: 20s
- retries: 3
-
- minio:
- container_name: milvus-minio
- image: minio/minio:RELEASE.2023-03-20T20-16-18Z
- environment:
- MINIO_ACCESS_KEY: minioadmin
- MINIO_SECRET_KEY: minioadmin
- ports:
- - "9011:9011"
- - "9010:9010"
- volumes:
- - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/minio:/minio_data
- command: minio server /minio_data --console-address ":9011" --address ":9010"
- healthcheck:
- test: ["CMD", "curl", "-f", "http://localhost:9010/minio/health/live"]
- interval: 30s
- timeout: 20s
- retries: 3
-
- milvus:
- container_name: milvus-standalone
- image: milvusdb/milvus:v2.4.0.1-gpu-beta
- command: ["milvus", "run", "standalone"]
- environment:
- ETCD_ENDPOINTS: etcd:2379
- MINIO_ADDRESS: minio:9010
- KNOWHERE_GPU_MEM_POOL_SIZE: 2048;4096
- volumes:
- - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/milvus:/var/lib/milvus
- healthcheck:
- test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"]
- interval: 30s
- start_period: 90s
- timeout: 20s
- retries: 3
- ports:
- - "19530:19530"
- - "9091:9091"
- depends_on:
- - "etcd"
- - "minio"
- deploy:
- resources:
- reservations:
- devices:
- - driver: nvidia
- capabilities: ["gpu"]
- count: 1
-
- chain-server:
- container_name: chain-server
- image: chain-server:latest
- build:
- context: ../../
- dockerfile: ./RetrievalAugmentedGeneration/Dockerfile
- args:
- EXAMPLE_NAME: ${RAG_EXAMPLE}
- command: --port 8081 --host 0.0.0.0
- environment:
- APP_VECTORSTORE_URL: "http://milvus:19530"
- APP_VECTORSTORE_NAME: "milvus"
- COLLECTION_NAME: ${RAG_EXAMPLE}
- MILVUS_DB: ${RAG_EXAMPLE}
- APP_LLM_SERVERURL: "llm:8001"
- APP_LLM_MODELNAME: ensemble
- APP_LLM_MODELENGINE: triton-trt-llm
- OTEL_EXPORTER_OTLP_ENDPOINT: http://otel-collector:4317
- OTEL_EXPORTER_OTLP_PROTOCOL: grpc
- ENABLE_TRACING: false
- APP_RETRIEVER_TOPK: 4
- APP_RETRIEVER_SCORETHRESHOLD: 0.25
- ports:
- - "8081:8081"
- expose:
- - "8081"
- shm_size: 5gb
- deploy:
- resources:
- reservations:
- devices:
- - driver: nvidia
- count: 1
- capabilities: [gpu]
- # healthcheck:
- # test: ["CMD", "curl", "-f", "http://localhost:8080/"]
- # interval: 30s
- # timeout: 20s
- # retries: 3
- depends_on:
- - "milvus"
- - "llm"
-
- rag-playground:
- container_name: rag-playground
- image: rag-playground:latest
- build:
- context: ../.././RetrievalAugmentedGeneration/frontend/
- dockerfile: Dockerfile
- command: --port 8090
- environment:
- APP_SERVERURL: http://chain-server
- APP_SERVERPORT: 8081
- APP_MODELNAME: ${MODEL_NAME:-${MODEL_ARCHITECTURE}}
- OTEL_EXPORTER_OTLP_ENDPOINT: http://otel-collector:4317
- OTEL_EXPORTER_OTLP_PROTOCOL: grpc
- ENABLE_TRACING: false
- RIVA_API_URI: ${RIVA_API_URI:-}
- RIVA_API_KEY: ${RIVA_API_KEY:-}
- RIVA_FUNCTION_ID: ${RIVA_FUNCTION_ID:-}
- TTS_SAMPLE_RATE: ${TTS_SAMPLE_RATE:-48000}
- ports:
- - "8090:8090"
- expose:
- - "8090"
- depends_on:
- - chain-server
-
-networks:
- default:
- name: nvidia-llm
diff --git a/deploy/compose/docker-compose-nim-ms.yaml b/deploy/compose/docker-compose-nim-ms.yaml
index a7a372718..310943fd4 100644
--- a/deploy/compose/docker-compose-nim-ms.yaml
+++ b/deploy/compose/docker-compose-nim-ms.yaml
@@ -1,14 +1,16 @@
services:
nemollm-inference:
container_name: nemollm-inference-microservice
- image: nvcr.io/ohlfw0olaadg/ea-participants/nim_llm:24.02
+ image: nvcr.io/nim/meta/llama3-8b-instruct:1.0.0
volumes:
- - ${MODEL_DIRECTORY:?please update the env file and source it before running}:/model-store
- command: nemollm_inference_ms --model ${APP_LLM_MODELNAME:-mixtral-8x7b-instruct} --openai_port 9999 --nemo_port 9998 --num_gpus=${NUM_GPU:-1}
+ - ${MODEL_DIRECTORY}:/opt/nim/.cache
+ user: ${DOCKER_USER}
ports:
- - "9999:9999"
+ - "8000:8000"
expose:
- - "9999"
+ - "8000"
+ environment:
+ NGC_API_KEY: ${NGC_API_KEY}
shm_size: 20gb
deploy:
resources:
@@ -17,17 +19,20 @@ services:
- driver: nvidia
count: ${INFERENCE_GPU_COUNT:-all}
capabilities: [gpu]
+ profiles: ["llm-embedding", "nemo-retriever"]
nemollm-embedding:
container_name: nemo-retriever-embedding-microservice
- image: nvcr.io/ohlfw0olaadg/ea-participants/nemo-retriever-embedding-microservice:24.02
+ image: nvcr.io/ohlfw0olaadg/ea-participants/nemo-retriever-embedding-microservice:24.04
volumes:
- - ${EMBEDDING_MODEL_DIRECTORY:?please update the env file and source it before running}:/model-checkpoint-path
- command: bin/web -p 9080 -c /model-checkpoint-path/${EMBEDDING_MODEL_CKPT_NAME} -g model_config_templates/${EMBEDDING_MODEL_NAME}_template.yaml
+ - $MODEL_DIRECTORY:/model-checkpoint-path
+ - $MODEL_DIRECTORY/embedding/cache:/model-store/
+ command: ["/bin/bash", "-c", "[ -f /model-store/service_config.yaml ] && bin/web -m /model-store -p 9080 || bin/web -p 9080 -c /model-checkpoint-path/${EMBEDDING_MODEL_CKPT_NAME} -g model_config_templates/${APP_EMBEDDINGS_MODELNAME}_template.yaml"]
ports:
- "9080:9080"
expose:
- "9080"
+ user: ${DOCKER_USER}
shm_size: 8gb
deploy:
resources:
@@ -43,6 +48,116 @@ services:
timeout: 20s
retries: 3
start_period: 10m
+ depends_on:
+ nemollm-embedding-download-ngc:
+ condition: service_completed_successfully
+ nemollm-embedding-download-hf:
+ condition: service_completed_successfully
+ profiles: ["llm-embedding", "nemo-retriever"]
+
+ ranking-ms:
+ image: "nvcr.io/ohlfw0olaadg/ea-participants/nemo-retriever-reranking-microservice:24.04"
+ volumes:
+ - $MODEL_DIRECTORY:/model-checkpoint-path
+ - $MODEL_DIRECTORY/reranking/cache:/triton-model-repository/
+ command: ["/bin/bash", "-c", "[ -f /triton-model-repository/service_config.yaml ] && ./bin/web -p 8080 -r /triton-model-repository || bin/web -p 8080 -c /model-checkpoint-path/${RANKING_MODEL_CKPT_NAME} -g model_config_templates/${RANKING_MODEL_NAME}_template.yaml"]
+ ports:
+ - "1976:8080"
+ user: ${DOCKER_USER}
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
+ interval: 10s
+ timeout: 20s
+ retries: 100
+ deploy:
+ resources:
+ reservations:
+ devices:
+ - driver: nvidia
+ device_ids: ['${RANKING_MS_GPU_ID:-0}']
+ capabilities: [gpu]
+ depends_on:
+ ranking-model-download-ngc:
+ condition: service_completed_successfully
+ ranking-model-download-hf:
+ condition: service_completed_successfully
+ profiles: ["nemo-retriever"]
+
+ nemollm-embedding-download-ngc:
+ container_name: nemollm-embedding-download-ngc
+ image: nvcr.io/ohlfw0olaadg/ea-participants/ngc-cli:v3.41.2
+ user: ${DOCKER_USER}
+ entrypoint: ["bash", "/download_script.sh"]
+ volumes:
+ - source: $MODEL_DIRECTORY
+ target: /model-store
+ type: bind
+ - source: $DOWNLOAD_SCRIPT
+ target: /download_script.sh
+ type: bind
+ environment:
+ NGC_CLI_API_KEY: ${NGC_API_KEY}
+ NGC_CLI_ORG: ${NGC_CLI_ORG}
+ MODEL_PATH: ${EMBEDDING_MODEL_PATH}
+ MODEL_DOWNLOAD_PATH: /model-store/${EMBEDDING_MODEL_CKPT_NAME}
+ MODEL_TYPE: "embedding"
+ profiles: ["llm-embedding", "nemo-retriever"]
+
+ nemollm-embedding-download-hf:
+ container_name: nemollm-embedding-download-hf
+ image: bitnami/git:latest
+ user: ${DOCKER_USER}
+ entrypoint: ["bash", "/download_script.sh"]
+ volumes:
+ - source: $MODEL_DIRECTORY
+ target: /model-store
+ type: bind
+ - source: $DOWNLOAD_SCRIPT
+ target: /download_script.sh
+ type: bind
+ environment:
+ MODEL_PATH: ${EMBEDDING_MODEL_PATH}
+ MODEL_DOWNLOAD_PATH: /model-store/${EMBEDDING_MODEL_CKPT_NAME}
+ MODEL_TYPE: "embedding"
+ profiles: ["llm-embedding", "nemo-retriever"]
+
+ ranking-model-download-ngc:
+ container_name: ranking-model-download-ngc
+ image: nvcr.io/ohlfw0olaadg/ea-participants/ngc-cli:v3.41.2
+ user: ${DOCKER_USER}
+ entrypoint: ["bash", "/download_script.sh"]
+ volumes:
+ - source: $MODEL_DIRECTORY
+ target: /model-store
+ type: bind
+ - source: $DOWNLOAD_SCRIPT
+ target: /download_script.sh
+ type: bind
+ environment:
+ NGC_CLI_API_KEY: ${NGC_API_KEY}
+ NGC_CLI_ORG: ${NGC_CLI_ORG}
+ MODEL_PATH: ${RANKING_MODEL_PATH}
+ MODEL_DOWNLOAD_PATH: /model-store/${RANKING_MODEL_CKPT_NAME}
+ MODEL_TYPE: "reranking"
+ profiles: ["nemo-retriever"]
+
+ ranking-model-download-hf:
+ container_name: ranking-model-download-hf
+ image: bitnami/git:latest
+ user: ${DOCKER_USER}
+ entrypoint: ["bash", "/download_script.sh"]
+ volumes:
+ - source: $MODEL_DIRECTORY
+ target: /model-store
+ type: bind
+ - source: $DOWNLOAD_SCRIPT
+ target: /download_script.sh
+ type: bind
+ environment:
+ MODEL_PATH: ${RANKING_MODEL_PATH}
+ MODEL_DOWNLOAD_PATH: /model-store/${RANKING_MODEL_CKPT_NAME}
+ MODEL_TYPE: "reranking"
+ profiles: ["nemo-retriever"]
networks:
default:
diff --git a/deploy/compose/docker-compose-vectordb.yaml b/deploy/compose/docker-compose-vectordb.yaml
index d26e9c590..98c625ab7 100644
--- a/deploy/compose/docker-compose-vectordb.yaml
+++ b/deploy/compose/docker-compose-vectordb.yaml
@@ -12,6 +12,8 @@ services:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-password}
- POSTGRES_USER=${POSTGRES_USER:-postgres}
- POSTGRES_DB=${POSTGRES_DB:-api}
+ profiles: ["llm-embedding"]
+
etcd:
container_name: milvus-etcd
@@ -29,10 +31,11 @@ services:
interval: 30s
timeout: 20s
retries: 3
+ profiles: ["llm-embedding", "nemo-retriever"]
minio:
container_name: milvus-minio
- image: minio/minio:RELEASE.2023-03-20T20-16-18Z
+ image: minio/minio:RELEASE.2024-05-01T01-11-10Z
environment:
MINIO_ACCESS_KEY: minioadmin
MINIO_SECRET_KEY: minioadmin
@@ -47,10 +50,11 @@ services:
interval: 30s
timeout: 20s
retries: 3
+ profiles: ["llm-embedding", "nemo-retriever"]
milvus:
container_name: milvus-standalone
- image: milvusdb/milvus:v2.4.0.1-gpu-beta
+ image: milvusdb/milvus:v2.4.4-gpu
command: ["milvus", "run", "standalone"]
environment:
ETCD_ENDPOINTS: etcd:2379
@@ -77,6 +81,41 @@ services:
- driver: nvidia
capabilities: ["gpu"]
device_ids: ['${VECTORSTORE_GPU_DEVICE_ID:-0}']
+ profiles: ["llm-embedding", "nemo-retriever"]
+
+ elasticsearch:
+ image: "docker.elastic.co/elasticsearch/elasticsearch:8.12.0"
+ ports:
+ - 9200:9200
+ restart: on-failure
+ environment:
+ - discovery.type=single-node
+ - "ES_JAVA_OPTS=-Xms1024m -Xmx1024m"
+ - xpack.security.enabled=false
+ - xpack.license.self_generated.type=basic
+ - network.host=0.0.0.0
+ - cluster.routing.allocation.disk.threshold_enabled=false
+ hostname: elasticsearch
+ healthcheck:
+ test: ["CMD", "curl", "-s", "-f", "http://localhost:9200/_cat/health"]
+ interval: 10s
+ timeout: 1s
+ retries: 10
+ profiles: ["nemo-retriever"]
+
+ postgres:
+ image: postgres:16.1
+ restart: always
+ environment:
+ POSTGRES_PASSWORD: pgadmin
+ volumes:
+ - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/postgres_data:/var/lib/postgresql/data:Z
+ healthcheck:
+ test: ["CMD-SHELL", "sh -c 'pg_isready -U postgres -d postgres'"]
+ interval: 10s
+ timeout: 3s
+ retries: 3
+ profiles: ["nemo-retriever"]
networks:
default:
diff --git a/deploy/compose/download_model.sh b/deploy/compose/download_model.sh
new file mode 100644
index 000000000..4bb0c2064
--- /dev/null
+++ b/deploy/compose/download_model.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+mkdir -p /model-store/embedding/cache
+mkdir -p /model-store/reranking/cache
+
+mkdir -p $MODEL_DOWNLOAD_PATH
+echo "Downloading model in $MODEL_DOWNLOAD_PATH $MODEL_PATH"
+
+if [[ "$MODEL_PATH" == *"huggingface"* ]]; then
+
+ if command -v git &> /dev/null; then
+ if [[ $(find $MODEL_DOWNLOAD_PATH -name "config.json" | wc -l) -eq 0 ]]; then
+ echo "Downloading from hf"
+ GIT_CLONE_PROTECTION_ACTIVE=false git clone $MODEL_PATH $MODEL_DOWNLOAD_PATH
+ pushd $MODEL_DOWNLOAD_PATH
+ git lfs install --local
+ git lfs pull
+ fi
+
+ fi
+
+else
+ if command -v ngc &> /dev/null; then
+ if [[ $(find $MODEL_DOWNLOAD_PATH -name "config.json" | wc -l) -eq 0 ]]; then
+ echo "Downloading from ngc"
+ echo ngc registry model download-version --dest /model-store $MODEL_PATH
+ ngc registry model download-version --dest /model-store $MODEL_PATH
+ fi
+ fi
+fi
diff --git a/deploy/compose/rag-app-api-catalog-text-chatbot.yaml b/deploy/compose/rag-app-api-catalog-text-chatbot.yaml
index cda076426..c0da6a6f0 100644
--- a/deploy/compose/rag-app-api-catalog-text-chatbot.yaml
+++ b/deploy/compose/rag-app-api-catalog-text-chatbot.yaml
@@ -1,7 +1,7 @@
services:
chain-server:
container_name: chain-server
- image: chain-server:latest
+ image: chain-server:${TAG:-latest}
build:
context: ../../
dockerfile: ./RetrievalAugmentedGeneration/Dockerfile
@@ -11,14 +11,14 @@ services:
environment:
APP_VECTORSTORE_URL: "http://milvus:19530"
APP_VECTORSTORE_NAME: "milvus"
- APP_LLM_MODELNAME: ${APP_LLM_MODELNAME:-ai-mixtral-8x7b-instruct}
+ APP_LLM_MODELNAME: ${APP_LLM_MODELNAME:-"meta/llama3-70b-instruct"}
APP_LLM_MODELENGINE: nvidia-ai-endpoints
APP_LLM_SERVERURL: ${APP_LLM_SERVERURL:-""}
- APP_EMBEDDINGS_MODELNAME: ${APP_EMBEDDINGS_MODELNAME:-ai-embed-qa-4}
- APP_EMBEDDINGS_MODELENGINE: nvidia-ai-endpoints
+ APP_EMBEDDINGS_MODELNAME: ${APP_EMBEDDINGS_MODELNAME:-snowflake/arctic-embed-l}
+ APP_EMBEDDINGS_MODELENGINE: ${APP_EMBEDDINGS_MODELENGINE:-nvidia-ai-endpoints}
APP_EMBEDDINGS_SERVERURL: ${APP_EMBEDDINGS_SERVERURL:-""}
- APP_TEXTSPLITTER_MODELNAME: WhereIsAI/UAE-Large-V1
- APP_TEXTSPLITTER_CHUNKSIZE: 510
+ APP_TEXTSPLITTER_MODELNAME: Snowflake/snowflake-arctic-embed-l
+ APP_TEXTSPLITTER_CHUNKSIZE: 506
APP_TEXTSPLITTER_CHUNKOVERLAP: 200
NVIDIA_API_KEY: ${NVIDIA_API_KEY}
APP_PROMPTS_CHATTEMPLATE: "You are a helpful, respectful and honest assistant. Always answer as helpfully as possible, while being safe. Please ensure that your responses are positive in nature."
@@ -26,12 +26,13 @@ services:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-password}
POSTGRES_USER: ${POSTGRES_USER:-postgres}
POSTGRES_DB: ${POSTGRES_DB:-api}
- COLLECTION_NAME: nvidia_api_catalog
+ COLLECTION_NAME: ${COLLECTION_NAME:-nvidia_api_catalog}
APP_RETRIEVER_TOPK: 4
APP_RETRIEVER_SCORETHRESHOLD: 0.25
OTEL_EXPORTER_OTLP_ENDPOINT: http://otel-collector:4317
OTEL_EXPORTER_OTLP_PROTOCOL: grpc
ENABLE_TRACING: false
+ LOGLEVEL: ${LOGLEVEL:-INFO}
ports:
- "8081:8081"
expose:
@@ -47,7 +48,7 @@ services:
rag-playground:
container_name: rag-playground
- image: rag-playground:latest
+ image: rag-playground:${TAG:-latest}
build:
context: ../.././RetrievalAugmentedGeneration/frontend/
dockerfile: Dockerfile
@@ -55,7 +56,7 @@ services:
environment:
APP_SERVERURL: http://chain-server
APP_SERVERPORT: 8081
- APP_MODELNAME: ${APP_LLM_MODELNAME:-ai-mixtral-8x7b-instruct}
+ APP_MODELNAME: ${APP_LLM_MODELNAME:-"meta/llama3-70b-instruct"}
RIVA_API_URI: ${RIVA_API_URI:-}
RIVA_API_KEY: ${RIVA_API_KEY:-}
RIVA_FUNCTION_ID: ${RIVA_FUNCTION_ID:-}
diff --git a/deploy/compose/rag-app-multimodal-chatbot.yaml b/deploy/compose/rag-app-multimodal-chatbot.yaml
index 89bdf5f9b..cd44a7109 100644
--- a/deploy/compose/rag-app-multimodal-chatbot.yaml
+++ b/deploy/compose/rag-app-multimodal-chatbot.yaml
@@ -1,7 +1,7 @@
services:
chain-server:
container_name: chain-server
- image: chain-server:latest
+ image: chain-server:${TAG:-latest}
build:
context: ../../
dockerfile: ./RetrievalAugmentedGeneration/Dockerfile
@@ -9,13 +9,13 @@ services:
EXAMPLE_NAME: multimodal_rag
command: --port 8081 --host 0.0.0.0
environment:
- APP_LLM_MODELNAME: ${APP_LLM_MODELNAME:-ai-mixtral-8x7b-instruct}
+ APP_LLM_MODELNAME: ${APP_LLM_MODELNAME:-"meta/llama3-8b-instruct"}
APP_LLM_MODELENGINE: nvidia-ai-endpoints
APP_LLM_SERVERURL: ${APP_LLM_SERVERURL:-""}
- APP_EMBEDDINGS_MODELNAME: ${APP_EMBEDDINGS_MODELNAME:-ai-embed-qa-4}
- APP_EMBEDDINGS_MODELENGINE: nvidia-ai-endpoints
+ APP_EMBEDDINGS_MODELNAME: ${APP_EMBEDDINGS_MODELNAME:-snowflake/arctic-embed-l}
+ APP_EMBEDDINGS_MODELENGINE: ${APP_EMBEDDINGS_MODELENGINE:-nvidia-ai-endpoints}
APP_EMBEDDINGS_SERVERURL: ${APP_EMBEDDINGS_SERVERURL:-""}
- APP_TEXTSPLITTER_MODELNAME: WhereIsAI/UAE-Large-V1
+ APP_TEXTSPLITTER_MODELNAME: Snowflake/snowflake-arctic-embed-l
APP_TEXTSPLITTER_CHUNKSIZE: 510
APP_TEXTSPLITTER_CHUNKOVERLAP: 200
NVIDIA_API_KEY: ${NVIDIA_API_KEY}
@@ -23,12 +23,13 @@ services:
APP_RETRIEVER_SCORETHRESHOLD: 0.25
APP_VECTORSTORE_URL: "http://milvus:19530"
APP_VECTORSTORE_NAME: "milvus"
- COLLECTION_NAME: multimodal_rag
+ COLLECTION_NAME: ${COLLECTION_NAME:-multimodal_rag}
APP_PROMPTS_CHATTEMPLATE: "You are a helpful and friendly multimodal intelligent AI assistant named Multimodal Chatbot Assistant. You are an expert in the content of the document provided and can provide information using both text and images. The user may also provide an image input, and you will use the image description to retrieve similar images, tables and text. The context given below will provide some technical or financial documentation and whitepapers to help you answer the question. Based on this context, answer the question truthfully. If the question is not related to this, please refrain from answering. Most importantly, if the context provided does not include information about the question from the user, reply saying that you don't know. Do not utilize any information that is not provided in the documents below. All documents will be preceded by tags, for example [[DOCUMENT 1]], [[DOCUMENT 2]], and so on. You can reference them in your reply but without the brackets, so just say document 1 or 2. The question will be preceded by a [[QUESTION]] tag. Be succinct, clear, and helpful. Remember to describe everything in detail by using the knowledge provided, or reply that you don't know the answer. Do not fabricate any responses. Note that you have the ability to reference images, tables, and other multimodal elements when necessary. You can also refer to the image provided by the user, if any."
APP_PROMPTS_RAGTEMPLATE: "You are a helpful and friendly multimodal intelligent AI assistant named Multimodal Chatbot Assistant. You are an expert in the content of the document provided and can provide information using both text and images. The user may also provide an image input, and you will use the image description to retrieve similar images, tables and text. The context given below will provide some technical or financial documentation and whitepapers to help you answer the question. Based on this context, answer the question truthfully. If the question is not related to this, please refrain from answering. Most importantly, if the context provided does not include information about the question from the user, reply saying that you don't know. Do not utilize any information that is not provided in the documents below. All documents will be preceded by tags, for example [[DOCUMENT 1]], [[DOCUMENT 2]], and so on. You can reference them in your reply but without the brackets, so just say document 1 or 2. The question will be preceded by a [[QUESTION]] tag. Be succinct, clear, and helpful. Remember to describe everything in detail by using the knowledge provided, or reply that you don't know the answer. Do not fabricate any responses. Note that you have the ability to reference images, tables, and other multimodal elements when necessary. You can also refer to the image provided by the user, if any."
OTEL_EXPORTER_OTLP_ENDPOINT: http://otel-collector:4317
OTEL_EXPORTER_OTLP_PROTOCOL: grpc
ENABLE_TRACING: false
+ LOGLEVEL: ${LOGLEVEL:-INFO}
ports:
- "8081:8081"
expose:
@@ -37,7 +38,7 @@ services:
rag-playground:
container_name: rag-playground
- image: rag-playground:latest
+ image: rag-playground:${TAG:-latest}
build:
context: ../.././RetrievalAugmentedGeneration/frontend/
dockerfile: Dockerfile
@@ -45,7 +46,7 @@ services:
environment:
APP_SERVERURL: http://chain-server
APP_SERVERPORT: 8081
- APP_MODELNAME: ${APP_LLM_MODELNAME:-ai-mixtral-8x7b-instruct}
+ APP_MODELNAME: ${APP_LLM_MODELNAME:-"meta/llama3-8b-instruct"}
RIVA_API_URI: ${RIVA_API_URI:-}
RIVA_API_KEY: ${RIVA_API_KEY:-}
RIVA_FUNCTION_ID: ${RIVA_FUNCTION_ID:-}
diff --git a/deploy/compose/rag-app-multiturn-chatbot.yaml b/deploy/compose/rag-app-multiturn-chatbot.yaml
index f6d18e2cb..c8251e876 100644
--- a/deploy/compose/rag-app-multiturn-chatbot.yaml
+++ b/deploy/compose/rag-app-multiturn-chatbot.yaml
@@ -1,7 +1,7 @@
services:
chain-server:
container_name: chain-server
- image: chain-server:latest
+ image: chain-server:${TAG:-latest}
build:
context: ../../
dockerfile: ./RetrievalAugmentedGeneration/Dockerfile
@@ -11,14 +11,14 @@ services:
environment:
APP_VECTORSTORE_URL: "http://milvus:19530"
APP_VECTORSTORE_NAME: "milvus"
- APP_LLM_MODELNAME: ${APP_LLM_MODELNAME:-ai-mixtral-8x7b-instruct}
+ APP_LLM_MODELNAME: ${APP_LLM_MODELNAME:-"meta/llama3-8b-instruct"}
APP_LLM_MODELENGINE: nvidia-ai-endpoints
APP_LLM_SERVERURL: ${APP_LLM_SERVERURL:-""}
- APP_EMBEDDINGS_MODELNAME: ${APP_EMBEDDINGS_MODELNAME:-ai-embed-qa-4}
- APP_EMBEDDINGS_MODELENGINE: nvidia-ai-endpoints
+ APP_EMBEDDINGS_MODELNAME: ${APP_EMBEDDINGS_MODELNAME:-snowflake/arctic-embed-l}
+ APP_EMBEDDINGS_MODELENGINE: ${APP_EMBEDDINGS_MODELENGINE:-nvidia-ai-endpoints}
APP_EMBEDDINGS_SERVERURL: ${APP_EMBEDDINGS_SERVERURL:-""}
- APP_TEXTSPLITTER_MODELNAME: WhereIsAI/UAE-Large-V1
- APP_TEXTSPLITTER_CHUNKSIZE: 510
+ APP_TEXTSPLITTER_MODELNAME: Snowflake/snowflake-arctic-embed-l
+ APP_TEXTSPLITTER_CHUNKSIZE: 506
APP_TEXTSPLITTER_CHUNKOVERLAP: 200
NVIDIA_API_KEY: ${NVIDIA_API_KEY}
APP_RETRIEVER_TOPK: 4
@@ -26,10 +26,11 @@ services:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-password}
POSTGRES_USER: ${POSTGRES_USER:-postgres}
POSTGRES_DB: ${POSTGRES_DB:-api}
- COLLECTION_NAME: multi_turn_rag
+ COLLECTION_NAME: ${COLLECTION_NAME:-multi_turn_rag}
OTEL_EXPORTER_OTLP_ENDPOINT: http://otel-collector:4317
OTEL_EXPORTER_OTLP_PROTOCOL: grpc
ENABLE_TRACING: false
+ LOGLEVEL: ${LOGLEVEL:-INFO}
ports:
- "8081:8081"
expose:
@@ -45,7 +46,7 @@ services:
rag-playground:
container_name: rag-playground
- image: rag-playground:latest
+ image: rag-playground:${TAG:-latest}
build:
context: ../.././RetrievalAugmentedGeneration/frontend/
dockerfile: Dockerfile
@@ -53,7 +54,7 @@ services:
environment:
APP_SERVERURL: http://chain-server
APP_SERVERPORT: 8081
- APP_MODELNAME: ${APP_LLM_MODELNAME:-ai-mixtral-8x7b-instruct}
+ APP_MODELNAME: ${APP_LLM_MODELNAME:-"meta/llama3-8b-instruct"}
RIVA_API_URI: ${RIVA_API_URI:-}
RIVA_API_KEY: ${RIVA_API_KEY:-}
RIVA_FUNCTION_ID: ${RIVA_FUNCTION_ID:-}
diff --git a/deploy/compose/rag-app-query-decomposition-agent.yaml b/deploy/compose/rag-app-query-decomposition-agent.yaml
index 5972621d4..9bb8448bb 100644
--- a/deploy/compose/rag-app-query-decomposition-agent.yaml
+++ b/deploy/compose/rag-app-query-decomposition-agent.yaml
@@ -1,7 +1,7 @@
services:
chain-server:
container_name: chain-server
- image: chain-server:latest
+ image: chain-server:${TAG:-latest}
build:
context: ../../
dockerfile: ./RetrievalAugmentedGeneration/Dockerfile
@@ -11,14 +11,14 @@ services:
environment:
APP_VECTORSTORE_URL: "http://milvus:19530"
APP_VECTORSTORE_NAME: "milvus"
- APP_LLM_MODELNAME: ${APP_LLM_MODELNAME:-ai-llama2-70b}
+ APP_LLM_MODELNAME: ${APP_LLM_MODELNAME:-"meta/llama3-70b-instruct"}
APP_LLM_MODELENGINE: nvidia-ai-endpoints
APP_LLM_SERVERURL: ${APP_LLM_SERVERURL:-""}
- APP_EMBEDDINGS_MODELNAME: ${APP_EMBEDDINGS_MODELNAME:-ai-embed-qa-4}
- APP_EMBEDDINGS_MODELENGINE: nvidia-ai-endpoints
+ APP_EMBEDDINGS_MODELNAME: ${APP_EMBEDDINGS_MODELNAME:-snowflake/arctic-embed-l}
+ APP_EMBEDDINGS_MODELENGINE: ${APP_EMBEDDINGS_MODELENGINE:-nvidia-ai-endpoints}
APP_EMBEDDINGS_SERVERURL: ${APP_EMBEDDINGS_SERVERURL:-""}
- APP_TEXTSPLITTER_MODELNAME: WhereIsAI/UAE-Large-V1
- APP_TEXTSPLITTER_CHUNKSIZE: 510
+ APP_TEXTSPLITTER_MODELNAME: Snowflake/snowflake-arctic-embed-l
+ APP_TEXTSPLITTER_CHUNKSIZE: 506
APP_TEXTSPLITTER_CHUNKOVERLAP: 200
NVIDIA_API_KEY: ${NVIDIA_API_KEY}
APP_PROMPTS_CHATTEMPLATE: "You are a helpful, respectful and honest assistant. Always answer as helpfully as possible, while being safe. Please ensure that your responses are positive in nature."
@@ -28,10 +28,11 @@ services:
POSTGRES_DB: ${POSTGRES_DB:-api}
APP_RETRIEVER_TOPK: 4
APP_RETRIEVER_SCORETHRESHOLD: 0.25
- COLLECTION_NAME: query_decomposition
+ COLLECTION_NAME: ${COLLECTION_NAME:-query_decomposition}
OTEL_EXPORTER_OTLP_ENDPOINT: http://otel-collector:4317
OTEL_EXPORTER_OTLP_PROTOCOL: grpc
ENABLE_TRACING: false
+ LOGLEVEL: ${LOGLEVEL:-INFO}
ports:
- "8081:8081"
expose:
@@ -47,7 +48,7 @@ services:
rag-playground:
container_name: rag-playground
- image: rag-playground:latest
+ image: rag-playground:${TAG:-latest}
build:
context: ../.././RetrievalAugmentedGeneration/frontend/
dockerfile: Dockerfile
@@ -55,7 +56,7 @@ services:
environment:
APP_SERVERURL: http://chain-server
APP_SERVERPORT: 8081
- APP_MODELNAME: ${APP_LLM_MODELNAME:-ai-llama2-70b}
+ APP_MODELNAME: ${APP_LLM_MODELNAME:-"meta/llama3-70b-instruct"}
RIVA_API_URI: ${RIVA_API_URI:-}
RIVA_API_KEY: ${RIVA_API_KEY:-}
RIVA_FUNCTION_ID: ${RIVA_FUNCTION_ID:-}
diff --git a/deploy/compose/rag-app-structured-data-chatbot.yaml b/deploy/compose/rag-app-structured-data-chatbot.yaml
index fd95f6786..c8723d896 100644
--- a/deploy/compose/rag-app-structured-data-chatbot.yaml
+++ b/deploy/compose/rag-app-structured-data-chatbot.yaml
@@ -1,7 +1,7 @@
services:
chain-server:
container_name: chain-server
- image: chain-server:latest
+ image: chain-server:${TAG:-latest}
build:
context: ../../
dockerfile: ./RetrievalAugmentedGeneration/Dockerfile
@@ -9,15 +9,16 @@ services:
EXAMPLE_NAME: structured_data_rag
command: --port 8081 --host 0.0.0.0
environment:
- APP_LLM_MODELNAME: ${APP_LLM_MODELNAME:-ai-llama3-70b}
+ APP_LLM_MODELNAME: ${APP_LLM_MODELNAME:-meta/llama3-70b-instruct}
APP_LLM_MODELENGINE: nvidia-ai-endpoints
APP_LLM_SERVERURL: ${APP_LLM_SERVERURL:-""}
- APP_LLM_MODELNAMEPANDASAI: ${APP_LLM_MODELNAME:-ai-llama3-70b}
+ APP_LLM_MODELNAMEPANDASAI: ${APP_LLM_MODELNAME:-meta/llama3-70b-instruct}
APP_PROMPTS_CHATTEMPLATE: "You are a helpful, respectful and honest assistant. Always answer as helpfully as possible, while being safe. Please ensure that your responses are positive in nature."
APP_PROMPTS_RAGTEMPLATE: "You are a helpful AI assistant named Envie. You will reply to questions only based on the context that you are provided. If something is out of context, you will refrain from replying and politely decline to respond to the user."
NVIDIA_API_KEY: ${NVIDIA_API_KEY}
- COLLECTION_NAME: structured_data_rag
+ COLLECTION_NAME: ${COLLECTION_NAME:-structured_data_rag}
CSV_NAME: PdM_machines
+ LOGLEVEL: ${LOGLEVEL:-INFO}
ports:
- "8081:8081"
expose:
@@ -33,7 +34,7 @@ services:
rag-playground:
container_name: rag-playground
- image: rag-playground:latest
+ image: rag-playground:${TAG:-latest}
build:
context: ../.././RetrievalAugmentedGeneration/frontend/
dockerfile: Dockerfile
@@ -41,7 +42,7 @@ services:
environment:
APP_SERVERURL: http://chain-server
APP_SERVERPORT: 8081
- APP_MODELNAME: ${APP_LLM_MODELNAME:-ai-llama3-70b}
+ APP_MODELNAME: ${APP_LLM_MODELNAME:-meta/llama3-70b-instruct}
RIVA_API_URI: ${RIVA_API_URI:-}
RIVA_API_KEY: ${RIVA_API_KEY:-}
RIVA_FUNCTION_ID: ${RIVA_FUNCTION_ID:-}
diff --git a/deploy/compose/rag-app-text-chatbot.yaml b/deploy/compose/rag-app-text-chatbot.yaml
index 6d5a602fb..1342367ea 100644
--- a/deploy/compose/rag-app-text-chatbot.yaml
+++ b/deploy/compose/rag-app-text-chatbot.yaml
@@ -1,33 +1,7 @@
services:
- llm:
- container_name: llm-inference-server
- image: llm-inference-server:latest
- build:
- context: ../.././RetrievalAugmentedGeneration/llm-inference-server/
- dockerfile: Dockerfile
- volumes:
- - ${MODEL_DIRECTORY:?please update the env file and source it before running}:/model
- command: ${MODEL_ARCHITECTURE:?please update the env file and source it before running} --max-input-length ${MODEL_MAX_INPUT_LENGTH:-3000} ${QUANTIZATION:+--quantization $QUANTIZATION}
- ports:
- - "8000:8000"
- - "8001:8001"
- - "8002:8002"
- expose:
- - "8000"
- - "8001"
- - "8002"
- shm_size: 20gb
- deploy:
- resources:
- reservations:
- devices:
- - driver: nvidia
- count: ${INFERENCE_GPU_COUNT:-all}
- capabilities: [gpu]
-
jupyter-server:
container_name: notebook-server
- image: notebook-server:latest
+ image: notebook-server:${TAG:-latest}
build:
context: ../../
dockerfile: ./notebooks/Dockerfile.notebooks # replace GPU enabled Dockerfile ./notebooks/Dockerfile.gpu_notebook
@@ -45,7 +19,7 @@ services:
chain-server:
container_name: chain-server
- image: chain-server:latest
+ image: chain-server:${TAG:-latest}
build:
context: ../../
dockerfile: ./RetrievalAugmentedGeneration/Dockerfile
@@ -55,25 +29,26 @@ services:
environment:
APP_VECTORSTORE_URL: "http://milvus:19530"
APP_VECTORSTORE_NAME: "milvus"
- APP_LLM_SERVERURL: ${APP_LLM_SERVERURL:-"llm:8001"}
- APP_LLM_MODELNAME: ${APP_LLM_MODELNAME:-ensemble}
- APP_LLM_MODELENGINE: ${APP_LLM_MODELENGINE:-triton-trt-llm}
- APP_EMBEDDINGS_MODELNAME: ${APP_EMBEDDINGS_MODELNAME:-WhereIsAI/UAE-Large-V1}
- APP_EMBEDDINGS_MODELENGINE: ${APP_EMBEDDINGS_MODELENGINE:-huggingface}
+ APP_EMBEDDINGS_MODELNAME: ${APP_EMBEDDINGS_MODELNAME:-snowflake/arctic-embed-l}
+ APP_EMBEDDINGS_MODELENGINE: ${APP_EMBEDDINGS_MODELENGINE:-nvidia-ai-endpoints}
APP_EMBEDDINGS_SERVERURL: ${APP_EMBEDDINGS_SERVERURL:-""}
+ APP_LLM_SERVERURL: ${APP_LLM_SERVERURL:-""}
+ APP_LLM_MODELNAME: ${APP_LLM_MODELNAME:-"meta/llama3-8b-instruct"}
+ APP_LLM_MODELENGINE: ${APP_LLM_MODELENGINE:-nvidia-ai-endpoints}
NVIDIA_API_KEY: ${NVIDIA_API_KEY}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-password}
POSTGRES_USER: ${POSTGRES_USER:-postgres}
POSTGRES_DB: ${POSTGRES_DB:-api}
- COLLECTION_NAME: developer_rag
+ COLLECTION_NAME: ${COLLECTION_NAME:-developer_rag}
APP_RETRIEVER_TOPK: 4
APP_RETRIEVER_SCORETHRESHOLD: 0.25
OTEL_EXPORTER_OTLP_ENDPOINT: http://otel-collector:4317
OTEL_EXPORTER_OTLP_PROTOCOL: grpc
ENABLE_TRACING: false
- APP_TEXTSPLITTER_MODELNAME: WhereIsAI/UAE-Large-V1
- APP_TEXTSPLITTER_CHUNKSIZE: 510
+ APP_TEXTSPLITTER_MODELNAME: Snowflake/snowflake-arctic-embed-l
+ APP_TEXTSPLITTER_CHUNKSIZE: 506
APP_TEXTSPLITTER_CHUNKOVERLAP: 200
+ LOGLEVEL: ${LOGLEVEL:-INFO}
ports:
- "8081:8081"
expose:
@@ -86,12 +61,10 @@ services:
- driver: nvidia
count: 1
capabilities: [gpu]
- depends_on:
- - "llm"
rag-playground:
container_name: rag-playground
- image: rag-playground:latest
+ image: rag-playground:${TAG:-latest}
build:
context: ../.././RetrievalAugmentedGeneration/frontend/
dockerfile: Dockerfile
@@ -99,7 +72,7 @@ services:
environment:
APP_SERVERURL: http://chain-server
APP_SERVERPORT: 8081
- APP_MODELNAME: ${MODEL_NAME:-${MODEL_ARCHITECTURE}}
+ APP_MODELNAME: ${APP_LLM_MODELNAME:-"meta/llama3-8b-instruct"}
OTEL_EXPORTER_OTLP_ENDPOINT: http://otel-collector:4317
OTEL_EXPORTER_OTLP_PROTOCOL: grpc
ENABLE_TRACING: false
diff --git a/deploy/k8s-operator/kube-trailblazer/.dockerignore b/deploy/k8s-operator/kube-trailblazer/.dockerignore
deleted file mode 100644
index 0f046820f..000000000
--- a/deploy/k8s-operator/kube-trailblazer/.dockerignore
+++ /dev/null
@@ -1,4 +0,0 @@
-# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file
-# Ignore build and test binaries.
-bin/
-testbin/
diff --git a/deploy/k8s-operator/kube-trailblazer/.patches/root.go b/deploy/k8s-operator/kube-trailblazer/.patches/root.go
deleted file mode 100644
index fa1eb832a..000000000
--- a/deploy/k8s-operator/kube-trailblazer/.patches/root.go
+++ /dev/null
@@ -1,8 +0,0 @@
-package chart
-
-// NotRoot not root
-func (ch *Chart) NotRoot() {
- ch.parent = nil
- ch.dependencies = nil
- ch.Metadata.Dependencies = nil
-}
diff --git a/deploy/k8s-operator/kube-trailblazer/Dockerfile b/deploy/k8s-operator/kube-trailblazer/Dockerfile
deleted file mode 100644
index e4d416857..000000000
--- a/deploy/k8s-operator/kube-trailblazer/Dockerfile
+++ /dev/null
@@ -1,56 +0,0 @@
-# Build the manager binary
-FROM golang:1.20 as builder
-ARG TARGETOS
-ARG TARGETARCH
-
-WORKDIR /workspace
-# Copy the Go Modules manifests
-COPY go.mod go.mod
-COPY go.sum go.sum
-# cache deps before building and copying source so that we don't need to re-download as much
-# and so that source changes don't invalidate our downloaded layer
-#RUN go mod download
-COPY vendor/ vendor/
-
-# Copy the go source
-COPY main.go main.go
-COPY api/ api/
-COPY controllers/ controllers/
-COPY pkg/ pkg/
-COPY .kustomize/ /kustomize/
-COPY helm-charts/ helm-charts/
-COPY helm-plugins/ helm-plugins/
-COPY Makefile Makefile
-COPY Makefile.helm.mk Makefile.helm.mk
-
-RUN chown -R 65532:65532 /kustomize
-
-RUN ["make", "helm-repo-index"]
-# Build
-# the GOARCH has not a default value to allow the binary be built according to the host where the command
-# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO
-# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore,
-# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform.
-RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager main.go
-
-# Use distroless as minimal base image to package the manager binary
-# Refer to https://github.com/GoogleContainerTools/distroless for more details
-#FROM gcr.io/distroless/static:nonroot
-FROM debian:bullseye-slim
-#FROM ubuntu:latest
-ENV HELM_PLUGINS /opt/helm-plugins
-
-WORKDIR /
-COPY --from=builder /workspace/manager .
-
-COPY --from=builder --chown=65532:65532 /kustomize /kustomize
-COPY --from=builder --chown=65532:65532 /workspace/build/helm-charts /helm-charts
-COPY --from=builder --chown=65532:65532 /workspace/helm-plugins /opt/helm-plugins
-
-COPY artifacts/kustomize /usr/local/bin/kustomize
-
-COPY NVIDIA_AI_Product_License_1Sept2023.pdf /
-
-USER 65532:65532
-
-ENTRYPOINT ["/manager"]
diff --git a/deploy/k8s-operator/kube-trailblazer/Makefile b/deploy/k8s-operator/kube-trailblazer/Makefile
deleted file mode 100644
index e09f92afd..000000000
--- a/deploy/k8s-operator/kube-trailblazer/Makefile
+++ /dev/null
@@ -1,282 +0,0 @@
-include *.mk
-# VERSION defines the project version for the bundle.
-# Update this value when you upgrade the version of your project.
-# To re-generate a bundle for another specific version without changing the standard setup, you can:
-# - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2)
-# - use environment variables to overwrite this value (e.g export VERSION=0.0.2)
-VERSION ?= 0.0.1
-
-# CHANNELS define the bundle channels used in the bundle.
-# Add a new line here if you would like to change its default config. (E.g CHANNELS = "candidate,fast,stable")
-# To re-generate a bundle for other specific channels without changing the standard setup, you can:
-# - use the CHANNELS as arg of the bundle target (e.g make bundle CHANNELS=candidate,fast,stable)
-# - use environment variables to overwrite this value (e.g export CHANNELS="candidate,fast,stable")
-ifneq ($(origin CHANNELS), undefined)
-BUNDLE_CHANNELS := --channels=$(CHANNELS)
-endif
-
-# DEFAULT_CHANNEL defines the default channel used in the bundle.
-# Add a new line here if you would like to change its default config. (E.g DEFAULT_CHANNEL = "stable")
-# To re-generate a bundle for any other default channel without changing the default setup, you can:
-# - use the DEFAULT_CHANNEL as arg of the bundle target (e.g make bundle DEFAULT_CHANNEL=stable)
-# - use environment variables to overwrite this value (e.g export DEFAULT_CHANNEL="stable")
-ifneq ($(origin DEFAULT_CHANNEL), undefined)
-BUNDLE_DEFAULT_CHANNEL := --default-channel=$(DEFAULT_CHANNEL)
-endif
-BUNDLE_METADATA_OPTS ?= $(BUNDLE_CHANNELS) $(BUNDLE_DEFAULT_CHANNEL)
-
-# IMAGE_TAG_BASE defines the docker.io namespace and part of the image name for remote images.
-# This variable is used to construct full image tags for bundle and catalog images.
-#
-# For example, running 'make bundle-build bundle-push catalog-build catalog-push' will build and push both
-# nvidia.com/kube-trailblazer-bundle:$VERSION and nvidia.com/kube-trailblazer-catalog:$VERSION.
-IMAGE_TAG_BASE ?= nvidia.com/kube-trailblazer
-
-# BUNDLE_IMG defines the image:tag used for the bundle.
-# You can use it as an arg. (E.g make bundle-build BUNDLE_IMG=/:)
-BUNDLE_IMG ?= $(IMAGE_TAG_BASE)-bundle:v$(VERSION)
-
-# BUNDLE_GEN_FLAGS are the flags passed to the operator-sdk generate bundle command
-BUNDLE_GEN_FLAGS ?= -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS)
-
-# USE_IMAGE_DIGESTS defines if images are resolved via tags or digests
-# You can enable this value if you would like to use SHA Based Digests
-# To enable set flag to true
-USE_IMAGE_DIGESTS ?= false
-ifeq ($(USE_IMAGE_DIGESTS), true)
- BUNDLE_GEN_FLAGS += --use-image-digests
-endif
-
-# Set the Operator SDK version to use. By default, what is installed on the system is used.
-# This is useful for CI or a project to utilize a specific version of the operator-sdk toolkit.
-OPERATOR_SDK_VERSION ?= v1.32.0
-
-# Image URL to use all building/pushing image targets
-IMG ?= controller:latest
-# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
-ENVTEST_K8S_VERSION = 1.26.0
-
-# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
-ifeq (,$(shell go env GOBIN))
-GOBIN=$(shell go env GOPATH)/bin
-else
-GOBIN=$(shell go env GOBIN)
-endif
-
-# Setting SHELL to bash allows bash commands to be executed by recipes.
-# Options are set to exit when a recipe line exits non-zero or a piped command fails.
-SHELL = /usr/bin/env bash -o pipefail
-.SHELLFLAGS = -ec
-
-.PHONY: all
-all: build
-
-##@ General
-
-# The help target prints out all targets with their descriptions organized
-# beneath their categories. The categories are represented by '##@' and the
-# target descriptions by '##'. The awk commands is responsible for reading the
-# entire set of makefiles included in this invocation, looking for lines of the
-# file as xyz: ## something, and then pretty-format the target and help. Then,
-# if there's a line with ##@ something, that gets pretty-printed as a category.
-# More info on the usage of ANSI control characters for terminal formatting:
-# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters
-# More info on the awk command:
-# http://linuxcommand.org/lc3_adv_awk.php
-
-.PHONY: help
-help: ## Display this help.
- @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
-
-##@ Development
-
-.PHONY: manifests
-manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
- $(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
-
-.PHONY: generate
-generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
- $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."
-
-.PHONY: fmt
-fmt: ## Run go fmt against code.
- go fmt ./...
-
-.PHONY: vet
-vet: ## Run go vet against code.
- go vet ./...
-
-.PHONY: test
-test: manifests generate fmt vet envtest ## Run tests.
- KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test ./... -coverprofile cover.out
-
-##@ Build
-
-.PHONY: build
-build: manifests generate fmt vet patch ## Build manager binary.
- go build -o bin/manager main.go
-
-.PHONY: run
-run: manifests generate fmt vet ## Run a controller from your host.
- go run ./main.go
-
-# If you wish built the manager image targeting other platforms you can use the --platform flag.
-# (i.e. docker build --platform linux/arm64 ). However, you must enable docker buildKit for it.
-# More info: https://docs.docker.com/develop/develop-images/build_enhancements/
-.PHONY: docker-build
-docker-build: go-mod manifests generate patch # test ## Build docker image with the manager.
- docker build -t ${IMG} .
-
-.PHONY: docker-push
-docker-push: ## Push docker image with the manager.
- docker push ${IMG}
-
-# PLATFORMS defines the target platforms for the manager image be build to provide support to multiple
-# architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to:
-# - able to use docker buildx . More info: https://docs.docker.com/build/buildx/
-# - have enable BuildKit, More info: https://docs.docker.com/develop/develop-images/build_enhancements/
-# - be able to push the image for your registry (i.e. if you do not inform a valid value via IMG=> then the export will fail)
-# To properly provided solutions that supports more than one platform you should use this option.
-PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
-.PHONY: docker-buildx
-docker-buildx: test ## Build and push docker image for the manager for cross-platform support
- # copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile
- sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross
- - docker buildx create --name project-v3-builder
- docker buildx use project-v3-builder
- - docker buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross .
- - docker buildx rm project-v3-builder
- rm Dockerfile.cross
-
-##@ Deployment
-
-ifndef ignore-not-found
- ignore-not-found = false
-endif
-
-.PHONY: install
-install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
- $(KUSTOMIZE) build config/crd | kubectl apply -f -
-
-.PHONY: uninstall
-uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
- $(KUSTOMIZE) build config/crd | kubectl delete --ignore-not-found=$(ignore-not-found) -f -
-
-.PHONY: deploy
-deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
- cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
- $(KUSTOMIZE) build config/default | kubectl apply -f -
-
-.PHONY: undeploy
-undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
- $(KUSTOMIZE) build config/default | kubectl delete --ignore-not-found=$(ignore-not-found) -f -
-
-##@ Build Dependencies
-
-## Location to install dependencies to
-LOCALBIN ?= $(shell pwd)/bin
-$(LOCALBIN):
- mkdir -p $(LOCALBIN)
-
-## Tool Binaries
-KUSTOMIZE ?= $(LOCALBIN)/kustomize
-CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen
-ENVTEST ?= $(LOCALBIN)/setup-envtest
-
-## Tool Versions
-KUSTOMIZE_VERSION ?= v3.8.7
-CONTROLLER_TOOLS_VERSION ?= v0.11.1
-
-KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"
-.PHONY: kustomize
-kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. If wrong version is installed, it will be removed before downloading.
-$(KUSTOMIZE): $(LOCALBIN)
- @if test -x $(LOCALBIN)/kustomize && ! $(LOCALBIN)/kustomize version | grep -q $(KUSTOMIZE_VERSION); then \
- echo "$(LOCALBIN)/kustomize version is not expected $(KUSTOMIZE_VERSION). Removing it before installing."; \
- rm -rf $(LOCALBIN)/kustomize; \
- fi
- test -s $(LOCALBIN)/kustomize || { curl -Ss $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN); }
-
-.PHONY: controller-gen
-controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary. If wrong version is installed, it will be overwritten.
-$(CONTROLLER_GEN): $(LOCALBIN)
- test -s $(LOCALBIN)/controller-gen && $(LOCALBIN)/controller-gen --version | grep -q $(CONTROLLER_TOOLS_VERSION) || \
- GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION)
-
-.PHONY: envtest
-envtest: $(ENVTEST) ## Download envtest-setup locally if necessary.
-$(ENVTEST): $(LOCALBIN)
- test -s $(LOCALBIN)/setup-envtest || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
-
-.PHONY: operator-sdk
-OPERATOR_SDK ?= $(LOCALBIN)/operator-sdk
-operator-sdk: ## Download operator-sdk locally if necessary.
-ifeq (,$(wildcard $(OPERATOR_SDK)))
-ifeq (, $(shell which operator-sdk 2>/dev/null))
- @{ \
- set -e ;\
- mkdir -p $(dir $(OPERATOR_SDK)) ;\
- OS=$(shell go env GOOS) && ARCH=$(shell go env GOARCH) && \
- curl -sSLo $(OPERATOR_SDK) https://github.com/operator-framework/operator-sdk/releases/download/$(OPERATOR_SDK_VERSION)/operator-sdk_$${OS}_$${ARCH} ;\
- chmod +x $(OPERATOR_SDK) ;\
- }
-else
-OPERATOR_SDK = $(shell which operator-sdk)
-endif
-endif
-
-.PHONY: bundle
-bundle: manifests kustomize operator-sdk ## Generate bundle manifests and metadata, then validate generated files.
- $(OPERATOR_SDK) generate kustomize manifests -q
- cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG)
- $(KUSTOMIZE) build config/manifests | $(OPERATOR_SDK) generate bundle $(BUNDLE_GEN_FLAGS)
- $(OPERATOR_SDK) bundle validate ./bundle
-
-.PHONY: bundle-build
-bundle-build: ## Build the bundle image.
- docker build -f bundle.Dockerfile -t $(BUNDLE_IMG) .
-
-.PHONY: bundle-push
-bundle-push: ## Push the bundle image.
- $(MAKE) docker-push IMG=$(BUNDLE_IMG)
-
-.PHONY: opm
-OPM = ./bin/opm
-opm: ## Download opm locally if necessary.
-ifeq (,$(wildcard $(OPM)))
-ifeq (,$(shell which opm 2>/dev/null))
- @{ \
- set -e ;\
- mkdir -p $(dir $(OPM)) ;\
- OS=$(shell go env GOOS) && ARCH=$(shell go env GOARCH) && \
- curl -sSLo $(OPM) https://github.com/operator-framework/operator-registry/releases/download/v1.23.0/$${OS}-$${ARCH}-opm ;\
- chmod +x $(OPM) ;\
- }
-else
-OPM = $(shell which opm)
-endif
-endif
-
-# A comma-separated list of bundle images (e.g. make catalog-build BUNDLE_IMGS=example.com/operator-bundle:v0.1.0,example.com/operator-bundle:v0.2.0).
-# These images MUST exist in a registry and be pull-able.
-BUNDLE_IMGS ?= $(BUNDLE_IMG)
-
-# The image tag given to the resulting catalog image (e.g. make catalog-build CATALOG_IMG=example.com/operator-catalog:v0.2.0).
-CATALOG_IMG ?= $(IMAGE_TAG_BASE)-catalog:v$(VERSION)
-
-# Set CATALOG_BASE_IMG to an existing catalog image tag to add $BUNDLE_IMGS to that image.
-ifneq ($(origin CATALOG_BASE_IMG), undefined)
-FROM_INDEX_OPT := --from-index $(CATALOG_BASE_IMG)
-endif
-
-# Build a catalog image by adding bundle images to an empty catalog using the operator package manager tool, 'opm'.
-# This recipe invokes 'opm' in 'semver' bundle add mode. For more information on add modes, see:
-# https://github.com/operator-framework/community-operators/blob/7f1438c/docs/packaging-operator.md#updating-your-existing-operator
-.PHONY: catalog-build
-catalog-build: opm ## Build a catalog image.
- $(OPM) index add --container-tool docker --mode semver --tag $(CATALOG_IMG) --bundles $(BUNDLE_IMGS) $(FROM_INDEX_OPT)
-
-# Push the catalog image.
-.PHONY: catalog-push
-catalog-push: ## Push a catalog image.
- $(MAKE) docker-push IMG=$(CATALOG_IMG)
diff --git a/deploy/k8s-operator/kube-trailblazer/Makefile.helm.mk b/deploy/k8s-operator/kube-trailblazer/Makefile.helm.mk
deleted file mode 100644
index 80f3978dd..000000000
--- a/deploy/k8s-operator/kube-trailblazer/Makefile.helm.mk
+++ /dev/null
@@ -1,62 +0,0 @@
-HELM_CHARTS_DIR = helm-charts
-HELM_BUILD_ROOT_DIR = build
-HELM_BUILD_DIR = $(HELM_BUILD_ROOT_DIR)/$(HELM_CHARTS_DIR)
-HELM_REPOS = $(shell ls -d $(HELM_BUILD_DIR)/*/)
-
-
-
-helm-lint: helm helm-copy-charts
- @echo "=> HelmRepo: $(HELM_REPOS)"
- @for repo in $(HELM_REPOS); do \
- cd $$repo; \
- helm lint -f ../global-values.yaml `ls -d */`; \
- cd ../../..; \
- done
-
-helm-repo-index: helm-lint
- @for repo in $(HELM_REPOS); do \
- cd $$repo; \
- helm package `ls -d */`; \
- file_url=`echo $$repo |sed 's/$(HELM_BUILD_ROOT_DIR)\///g'`; \
- helm repo index . --url=file:///$$file_url; \
- cd ../../..; \
- done
-
-
-helm-copy-charts:
- rm -rf $(HELM_BUILD_DIR)
- mkdir -p $(HELM_BUILD_DIR)
- cp -r $(HELM_CHARTS_DIR)/* $(HELM_BUILD_DIR)
-
-
-helm:
-ifeq (, $(shell which helm))
- @{ \
- set -e ;\
- HELM_GEN_TMP_DIR=$$(mktemp -d) ;\
- cd $$HELM_GEN_TMP_DIR ;\
- OS=$(shell go env GOOS) && ARCH=$(shell go env GOARCH); \
- curl https://get.helm.sh/helm-v3.6.0-$$OS-$$ARCH.tar.gz -o helm.tar.gz ;\
- tar xvfpz helm.tar.gz ;\
- mv linux-amd64/helm /usr/local/bin ;\
- chmod +x /usr/local/bin/helm ;\
- rm -rf $$HELM_GEN_TMP_DIR ;\
- }
-HELM=/usr/local/bin/helm
-else
-HELM=$(shell which helm)
-endif
-
-
-# Operator specific
-
-CSPLIT ?= csplit - --prefix="" --suppress-matched --suffix-format="%04d_operator_manifests.yaml" /---/ '{*}' 1>/dev/null
-HELM_CHART_NAME = developer-llm-operator
-
-.PHONY: helm-chart
-
-helm-chart: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
- cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
- cd $(HELM_CHARTS_DIR)/staging/$(HELM_CHART_NAME)/templates && $(KUSTOMIZE) build ../../../../config/default | $(CSPLIT)
-## Remove namespace creation, helm can do that ...
- rm $(HELM_CHARTS_DIR)/staging/$(HELM_CHART_NAME)/templates/0000_operator_manifests.yaml
diff --git a/deploy/k8s-operator/kube-trailblazer/Makefile.helmer.mk b/deploy/k8s-operator/kube-trailblazer/Makefile.helmer.mk
deleted file mode 100644
index 36612e043..000000000
--- a/deploy/k8s-operator/kube-trailblazer/Makefile.helmer.mk
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-.PHONY: go-mod
-go-mod: ## Runs go mod tidy/vendor to sync vendor directory with go.mod.
- go mod tidy
- go mod vendor
-
-.PHONY: patch
-patch:
- cp .patches/root.go vendor/helm.sh/helm/v3/pkg/chart/.
-
diff --git a/deploy/k8s-operator/kube-trailblazer/NVIDIA_AI_Product_License_1Sept2023.pdf b/deploy/k8s-operator/kube-trailblazer/NVIDIA_AI_Product_License_1Sept2023.pdf
deleted file mode 100644
index 749f02857..000000000
Binary files a/deploy/k8s-operator/kube-trailblazer/NVIDIA_AI_Product_License_1Sept2023.pdf and /dev/null differ
diff --git a/deploy/k8s-operator/kube-trailblazer/PROJECT b/deploy/k8s-operator/kube-trailblazer/PROJECT
deleted file mode 100644
index a0762acbf..000000000
--- a/deploy/k8s-operator/kube-trailblazer/PROJECT
+++ /dev/null
@@ -1,23 +0,0 @@
-# Code generated by tool. DO NOT EDIT.
-# This file is used to track the info used to scaffold your project
-# and allow the plugins properly work.
-# More info: https://book.kubebuilder.io/reference/project-config.html
-domain: nvidia.com
-layout:
-- go.kubebuilder.io/v3
-plugins:
- manifests.sdk.operatorframework.io/v2: {}
- scorecard.sdk.operatorframework.io/v2: {}
-projectName: kube-trailblazer
-repo: github.com/nvidia/kube-trailblazer
-resources:
-- api:
- crdVersion: v1
- namespaced: true
- controller: true
- domain: nvidia.com
- group: package
- kind: HelmPipeline
- path: github.com/nvidia/kube-trailblazer/api/v1alpha1
- version: v1alpha1
-version: "3"
diff --git a/deploy/k8s-operator/kube-trailblazer/api/v1alpha1/groupversion_info.go b/deploy/k8s-operator/kube-trailblazer/api/v1alpha1/groupversion_info.go
deleted file mode 100644
index 84c28e79c..000000000
--- a/deploy/k8s-operator/kube-trailblazer/api/v1alpha1/groupversion_info.go
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-Copyright 2023.
-
-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.
-*/
-
-// Package v1alpha1 contains API Schema definitions for the package v1alpha1 API group
-// +kubebuilder:object:generate=true
-// +groupName=package.nvidia.com
-package v1alpha1
-
-import (
- "k8s.io/apimachinery/pkg/runtime/schema"
- "sigs.k8s.io/controller-runtime/pkg/scheme"
-)
-
-var (
- // GroupVersion is group version used to register these objects
- GroupVersion = schema.GroupVersion{Group: "package.nvidia.com", Version: "v1alpha1"}
-
- // SchemeBuilder is used to add go types to the GroupVersionKind scheme
- SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
-
- // AddToScheme adds the types in this group-version to the given scheme.
- AddToScheme = SchemeBuilder.AddToScheme
-)
diff --git a/deploy/k8s-operator/kube-trailblazer/api/v1alpha1/helmpipeline_types.go b/deploy/k8s-operator/kube-trailblazer/api/v1alpha1/helmpipeline_types.go
deleted file mode 100644
index a04c6e032..000000000
--- a/deploy/k8s-operator/kube-trailblazer/api/v1alpha1/helmpipeline_types.go
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-Copyright 2023.
-
-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.
-*/
-
-package v1alpha1
-
-import (
- "github.com/nvidia/kube-trailblazer/pkg/helmer"
- operatorv1 "github.com/openshift/api/operator/v1"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-)
-
-// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
-// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
-
-// HelmPipelineSpec defines the desired state of HelmPipeline
-type HelmPipelineSpec struct {
- // Orchard: A planned and managed group of Helm trees.
- Pipeline helmer.Pipeline `json:"pipeline"`
- // +kubebuilder:validation:Optional
- ManagementState operatorv1.ManagementState `json:"managementState,omitempty"` // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
-}
-
-// HelmPipelineStatus defines the observed state of HelmPipeline
-type HelmPipelineStatus struct {
- // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
- // Important: Run "make" to regenerate code after modifying this file
-}
-
-//+kubebuilder:object:root=true
-//+kubebuilder:subresource:status
-
-// HelmPipeline is the Schema for the helmpipelines API
-type HelmPipeline struct {
- metav1.TypeMeta `json:",inline"`
- metav1.ObjectMeta `json:"metadata,omitempty"`
-
- Spec HelmPipelineSpec `json:"spec,omitempty"`
- Status HelmPipelineStatus `json:"status,omitempty"`
-}
-
-//+kubebuilder:object:root=true
-
-// HelmPipelineList contains a list of HelmPipeline
-type HelmPipelineList struct {
- metav1.TypeMeta `json:",inline"`
- metav1.ListMeta `json:"metadata,omitempty"`
- Items []HelmPipeline `json:"items"`
-}
-
-func init() {
- SchemeBuilder.Register(&HelmPipeline{}, &HelmPipelineList{})
-}
diff --git a/deploy/k8s-operator/kube-trailblazer/api/v1alpha1/zz_generated.deepcopy.go b/deploy/k8s-operator/kube-trailblazer/api/v1alpha1/zz_generated.deepcopy.go
deleted file mode 100644
index a21890900..000000000
--- a/deploy/k8s-operator/kube-trailblazer/api/v1alpha1/zz_generated.deepcopy.go
+++ /dev/null
@@ -1,123 +0,0 @@
-//go:build !ignore_autogenerated
-// +build !ignore_autogenerated
-
-/*
-Copyright 2023.
-
-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.
-*/
-
-// Code generated by controller-gen. DO NOT EDIT.
-
-package v1alpha1
-
-import (
- "github.com/nvidia/kube-trailblazer/pkg/helmer"
- runtime "k8s.io/apimachinery/pkg/runtime"
-)
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *HelmPipeline) DeepCopyInto(out *HelmPipeline) {
- *out = *in
- out.TypeMeta = in.TypeMeta
- in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
- in.Spec.DeepCopyInto(&out.Spec)
- out.Status = in.Status
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmPipeline.
-func (in *HelmPipeline) DeepCopy() *HelmPipeline {
- if in == nil {
- return nil
- }
- out := new(HelmPipeline)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *HelmPipeline) DeepCopyObject() runtime.Object {
- if c := in.DeepCopy(); c != nil {
- return c
- }
- return nil
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *HelmPipelineList) DeepCopyInto(out *HelmPipelineList) {
- *out = *in
- out.TypeMeta = in.TypeMeta
- in.ListMeta.DeepCopyInto(&out.ListMeta)
- if in.Items != nil {
- in, out := &in.Items, &out.Items
- *out = make([]HelmPipeline, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
- }
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmPipelineList.
-func (in *HelmPipelineList) DeepCopy() *HelmPipelineList {
- if in == nil {
- return nil
- }
- out := new(HelmPipelineList)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *HelmPipelineList) DeepCopyObject() runtime.Object {
- if c := in.DeepCopy(); c != nil {
- return c
- }
- return nil
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *HelmPipelineSpec) DeepCopyInto(out *HelmPipelineSpec) {
- *out = *in
- if in.Pipeline != nil {
- in, out := &in.Pipeline, &out.Pipeline
- *out = make(helmer.Pipeline, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
- }
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmPipelineSpec.
-func (in *HelmPipelineSpec) DeepCopy() *HelmPipelineSpec {
- if in == nil {
- return nil
- }
- out := new(HelmPipelineSpec)
- in.DeepCopyInto(out)
- return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *HelmPipelineStatus) DeepCopyInto(out *HelmPipelineStatus) {
- *out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmPipelineStatus.
-func (in *HelmPipelineStatus) DeepCopy() *HelmPipelineStatus {
- if in == nil {
- return nil
- }
- out := new(HelmPipelineStatus)
- in.DeepCopyInto(out)
- return out
-}
diff --git a/deploy/k8s-operator/kube-trailblazer/config/crd/bases/package.nvidia.com_helmpipelines.yaml b/deploy/k8s-operator/kube-trailblazer/config/crd/bases/package.nvidia.com_helmpipelines.yaml
deleted file mode 100644
index a3c682b48..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/crd/bases/package.nvidia.com_helmpipelines.yaml
+++ /dev/null
@@ -1,234 +0,0 @@
----
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
- annotations:
- controller-gen.kubebuilder.io/version: v0.11.1
- creationTimestamp: null
- name: helmpipelines.package.nvidia.com
-spec:
- group: package.nvidia.com
- names:
- kind: HelmPipeline
- listKind: HelmPipelineList
- plural: helmpipelines
- singular: helmpipeline
- scope: Namespaced
- versions:
- - name: v1alpha1
- schema:
- openAPIV3Schema:
- description: HelmPipeline is the Schema for the helmpipelines API
- properties:
- apiVersion:
- description: 'APIVersion defines the versioned schema of this representation
- of an object. Servers should convert recognized schemas to the latest
- internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
- type: string
- kind:
- description: 'Kind is a string value representing the REST resource this
- object represents. Servers may infer this from the endpoint the client
- submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
- type: string
- metadata:
- type: object
- spec:
- description: HelmPipelineSpec defines the desired state of HelmPipeline
- properties:
- managementState:
- pattern: ^(Managed|Unmanaged|Force|Removed)$
- type: string
- pipeline:
- description: 'Orchard: A planned and managed group of Helm trees.'
- items:
- description: A shelter of vines or branches or of latticework covered
- with climbing shrubs or vines, also latin for tree
- properties:
- chartSpec:
- properties:
- atomic:
- description: Atomic indicates whether to install resources
- atomically. 'Wait' will automatically be set to true when
- using Atomic.
- type: boolean
- chart:
- type: string
- cleanupOnFail:
- description: CleanupOnFail indicates whether to cleanup
- the release on failure.
- type: boolean
- createNamespace:
- description: CreateNamespace indicates whether to create
- the namespace if it does not exist.
- type: boolean
- dependencyUpdate:
- description: DependencyUpdate indicates whether to update
- the chart release if the dependencies have changed.
- type: boolean
- description:
- description: Description specifies a custom description
- for the uninstalled release
- type: string
- disableHooks:
- description: DisableHooks indicates whether to disable hooks.
- type: boolean
- dryRun:
- description: DryRun indicates whether to perform a dry run.
- type: boolean
- force:
- description: Force indicates whether to force the operation.
- type: boolean
- generateName:
- description: GenerateName indicates that the release name
- should be generated.
- type: boolean
- keepHistory:
- description: KeepHistory indicates whether to retain or
- purge the release history during uninstall
- type: boolean
- maxHistory:
- description: MaxHistory limits the maximum number of revisions
- saved per release.
- type: integer
- nameTemplate:
- description: NameTemplate is the template used to generate
- the release name if GenerateName is configured.
- type: string
- namespace:
- description: Namespace where the chart release is deployed.
- Note that helmclient.Options.Namespace should ideally
- match the namespace configured here.
- type: string
- recreate:
- description: Recreate indicates whether to recreate the
- release if it already exists.
- type: boolean
- release:
- type: string
- replace:
- description: Replace indicates whether to replace the chart
- release if it already exists.
- type: boolean
- resetValues:
- description: ResetValues indicates whether to reset the
- values.yaml file during installation.
- type: boolean
- reuseValues:
- description: ReuseValues indicates whether to reuse the
- values.yaml file during installation.
- type: boolean
- skipCRDs:
- description: SkipCRDs indicates whether to skip CRDs during
- installation.
- type: boolean
- subNotes:
- description: SubNotes indicates whether to print sub-notes.
- type: boolean
- timeout:
- description: Timeout configures the time to wait for any
- individual Kubernetes operation (like Jobs for hooks).
- format: int64
- type: integer
- upgradeCRDs:
- description: Upgrade indicates whether to perform a CRD
- upgrade during installation.
- type: boolean
- valuesOptions:
- description: Specify values similar to the cli
- properties:
- JSONValues:
- items:
- type: string
- type: array
- fileValues:
- items:
- type: string
- type: array
- strinValues:
- items:
- type: string
- type: array
- valueFiles:
- items:
- type: string
- type: array
- values:
- items:
- type: string
- type: array
- required:
- - JSONValues
- - fileValues
- - strinValues
- - valueFiles
- - values
- type: object
- valuesYaml:
- description: ValuesYaml is the values.yaml content. use
- string instead of map[string]interface{} https://github.com/kubernetes-sigs/kubebuilder/issues/528#issuecomment-466449483
- and https://github.com/kubernetes-sigs/controller-tools/pull/317
- type: string
- version:
- description: Version of the chart release.
- type: string
- wait:
- description: Wait indicates whether to wait for the release
- to be deployed or not.
- type: boolean
- waitForJobs:
- description: WaitForJobs indicates whether to wait for completion
- of release Jobs before marking the release as successful.
- 'Wait' has to be specified for this to take effect. The
- timeout may be specified via the 'Timeout' field.
- type: boolean
- required:
- - chart
- type: object
- chartValues:
- description: TODO ChartValues json.RawMessage `json:"chartValues"`
- type: object
- x-kubernetes-preserve-unknown-fields: true
- releaseName:
- type: string
- repoEntry:
- description: Entry represents a collection of parameters for
- chart repository, since we cannot annotate the internal helm
- struct we're doing it here
- properties:
- caFile:
- type: string
- certFile:
- type: string
- insecure_skip_tls_verify:
- type: boolean
- keyFile:
- type: string
- name:
- type: string
- pass_credentials_all:
- type: boolean
- password:
- type: string
- url:
- type: string
- username:
- type: string
- required:
- - url
- type: object
- required:
- - chartSpec
- - repoEntry
- type: object
- type: array
- required:
- - pipeline
- type: object
- status:
- description: HelmPipelineStatus defines the observed state of HelmPipeline
- type: object
- type: object
- served: true
- storage: true
- subresources:
- status: {}
diff --git a/deploy/k8s-operator/kube-trailblazer/config/crd/kustomization.yaml b/deploy/k8s-operator/kube-trailblazer/config/crd/kustomization.yaml
deleted file mode 100644
index f6c2911b7..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/crd/kustomization.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-# This kustomization.yaml is not intended to be run by itself,
-# since it depends on service name and namespace that are out of this kustomize package.
-# It should be run by config/default
-resources:
-- bases/package.nvidia.com_helmpipelines.yaml
-#+kubebuilder:scaffold:crdkustomizeresource
-
-patchesStrategicMerge:
-# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix.
-# patches here are for enabling the conversion webhook for each CRD
-#- patches/webhook_in_helmpipelines.yaml
-#+kubebuilder:scaffold:crdkustomizewebhookpatch
-
-# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix.
-# patches here are for enabling the CA injection for each CRD
-#- patches/cainjection_in_helmpipelines.yaml
-#+kubebuilder:scaffold:crdkustomizecainjectionpatch
-
-# the following config is for teaching kustomize how to do kustomization for CRDs.
-configurations:
-- kustomizeconfig.yaml
diff --git a/deploy/k8s-operator/kube-trailblazer/config/crd/kustomizeconfig.yaml b/deploy/k8s-operator/kube-trailblazer/config/crd/kustomizeconfig.yaml
deleted file mode 100644
index ec5c150a9..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/crd/kustomizeconfig.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
-# This file is for teaching kustomize how to substitute name and namespace reference in CRD
-nameReference:
-- kind: Service
- version: v1
- fieldSpecs:
- - kind: CustomResourceDefinition
- version: v1
- group: apiextensions.k8s.io
- path: spec/conversion/webhook/clientConfig/service/name
-
-namespace:
-- kind: CustomResourceDefinition
- version: v1
- group: apiextensions.k8s.io
- path: spec/conversion/webhook/clientConfig/service/namespace
- create: false
-
-varReference:
-- path: metadata/annotations
diff --git a/deploy/k8s-operator/kube-trailblazer/config/crd/patches/cainjection_in_helmpipelines.yaml b/deploy/k8s-operator/kube-trailblazer/config/crd/patches/cainjection_in_helmpipelines.yaml
deleted file mode 100644
index 4ca9b78ba..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/crd/patches/cainjection_in_helmpipelines.yaml
+++ /dev/null
@@ -1,7 +0,0 @@
-# The following patch adds a directive for certmanager to inject CA into the CRD
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
- annotations:
- cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
- name: helmpipelines.package.nvidia.com
diff --git a/deploy/k8s-operator/kube-trailblazer/config/crd/patches/webhook_in_helmpipelines.yaml b/deploy/k8s-operator/kube-trailblazer/config/crd/patches/webhook_in_helmpipelines.yaml
deleted file mode 100644
index e52065b94..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/crd/patches/webhook_in_helmpipelines.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-# The following patch enables a conversion webhook for the CRD
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
- name: helmpipelines.package.nvidia.com
-spec:
- conversion:
- strategy: Webhook
- webhook:
- clientConfig:
- service:
- namespace: system
- name: webhook-service
- path: /convert
- conversionReviewVersions:
- - v1
diff --git a/deploy/k8s-operator/kube-trailblazer/config/default/kustomization.yaml b/deploy/k8s-operator/kube-trailblazer/config/default/kustomization.yaml
deleted file mode 100644
index be30e9553..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/default/kustomization.yaml
+++ /dev/null
@@ -1,72 +0,0 @@
-# Adds namespace to all resources.
-namespace: kube-trailblazer-system
-
-# Value of this field is prepended to the
-# names of all resources, e.g. a deployment named
-# "wordpress" becomes "alices-wordpress".
-# Note that it should also match with the prefix (text before '-') of the namespace
-# field above.
-namePrefix: kube-trailblazer-
-
-# Labels to add to all resources and selectors.
-#commonLabels:
-# someName: someValue
-
-bases:
-- ../crd
-- ../rbac
-- ../manager
-# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in
-# crd/kustomization.yaml
-#- ../webhook
-# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required.
-#- ../certmanager
-# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'.
-#- ../prometheus
-
-patchesStrategicMerge:
-# Protect the /metrics endpoint by putting it behind auth.
-# If you want your controller-manager to expose the /metrics
-# endpoint w/o any authn/z, please comment the following line.
-- manager_auth_proxy_patch.yaml
-
-
-
-# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in
-# crd/kustomization.yaml
-#- manager_webhook_patch.yaml
-
-# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'.
-# Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks.
-# 'CERTMANAGER' needs to be enabled to use ca injection
-#- webhookcainjection_patch.yaml
-
-# the following config is for teaching kustomize how to do var substitution
-vars:
-# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix.
-#- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR
-# objref:
-# kind: Certificate
-# group: cert-manager.io
-# version: v1
-# name: serving-cert # this name should match the one in certificate.yaml
-# fieldref:
-# fieldpath: metadata.namespace
-#- name: CERTIFICATE_NAME
-# objref:
-# kind: Certificate
-# group: cert-manager.io
-# version: v1
-# name: serving-cert # this name should match the one in certificate.yaml
-#- name: SERVICE_NAMESPACE # namespace of the service
-# objref:
-# kind: Service
-# version: v1
-# name: webhook-service
-# fieldref:
-# fieldpath: metadata.namespace
-#- name: SERVICE_NAME
-# objref:
-# kind: Service
-# version: v1
-# name: webhook-service
diff --git a/deploy/k8s-operator/kube-trailblazer/config/default/manager_auth_proxy_patch.yaml b/deploy/k8s-operator/kube-trailblazer/config/default/manager_auth_proxy_patch.yaml
deleted file mode 100644
index b75126616..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/default/manager_auth_proxy_patch.yaml
+++ /dev/null
@@ -1,55 +0,0 @@
-# This patch inject a sidecar container which is a HTTP proxy for the
-# controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews.
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: controller-manager
- namespace: system
-spec:
- template:
- spec:
- affinity:
- nodeAffinity:
- requiredDuringSchedulingIgnoredDuringExecution:
- nodeSelectorTerms:
- - matchExpressions:
- - key: kubernetes.io/arch
- operator: In
- values:
- - amd64
- - arm64
- - ppc64le
- - s390x
- - key: kubernetes.io/os
- operator: In
- values:
- - linux
- containers:
- - name: kube-rbac-proxy
- securityContext:
- allowPrivilegeEscalation: false
- capabilities:
- drop:
- - "ALL"
- image: gcr.io/kubebuilder/kube-rbac-proxy:v0.13.1
- args:
- - "--secure-listen-address=0.0.0.0:8443"
- - "--upstream=http://127.0.0.1:8080/"
- - "--logtostderr=true"
- - "--v=0"
- ports:
- - containerPort: 8443
- protocol: TCP
- name: https
- resources:
- limits:
- cpu: 500m
- memory: 128Mi
- requests:
- cpu: 5m
- memory: 64Mi
- - name: manager
- args:
- - "--health-probe-bind-address=:8081"
- - "--metrics-bind-address=127.0.0.1:8080"
- - "--leader-elect"
diff --git a/deploy/k8s-operator/kube-trailblazer/config/default/manager_config_patch.yaml b/deploy/k8s-operator/kube-trailblazer/config/default/manager_config_patch.yaml
deleted file mode 100644
index f6f589169..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/default/manager_config_patch.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: controller-manager
- namespace: system
-spec:
- template:
- spec:
- containers:
- - name: manager
diff --git a/deploy/k8s-operator/kube-trailblazer/config/manager/kustomization.yaml b/deploy/k8s-operator/kube-trailblazer/config/manager/kustomization.yaml
deleted file mode 100644
index b20824356..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/manager/kustomization.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-resources:
-- manager.yaml
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-images:
-- name: controller
- newName: nvcr.io/nvstaging/cloud-native/developer-llm-operator
- newTag: v0.0.1
diff --git a/deploy/k8s-operator/kube-trailblazer/config/manager/manager.yaml b/deploy/k8s-operator/kube-trailblazer/config/manager/manager.yaml
deleted file mode 100644
index ec2f77cb3..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/manager/manager.yaml
+++ /dev/null
@@ -1,105 +0,0 @@
-apiVersion: v1
-kind: Namespace
-metadata:
- labels:
- control-plane: controller-manager
- app.kubernetes.io/name: namespace
- app.kubernetes.io/instance: system
- app.kubernetes.io/component: manager
- app.kubernetes.io/created-by: kube-trailblazer
- app.kubernetes.io/part-of: kube-trailblazer
- app.kubernetes.io/managed-by: kustomize
- name: system
----
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: controller-manager
- namespace: system
- labels:
- control-plane: controller-manager
- app.kubernetes.io/name: deployment
- app.kubernetes.io/instance: controller-manager
- app.kubernetes.io/component: manager
- app.kubernetes.io/created-by: kube-trailblazer
- app.kubernetes.io/part-of: kube-trailblazer
- app.kubernetes.io/managed-by: kustomize
-spec:
- selector:
- matchLabels:
- control-plane: controller-manager
- replicas: 1
- template:
- metadata:
- annotations:
- kubectl.kubernetes.io/default-container: manager
- labels:
- control-plane: controller-manager
- spec:
- # TODO(user): Uncomment the following code to configure the nodeAffinity expression
- # according to the platforms which are supported by your solution.
- # It is considered best practice to support multiple architectures. You can
- # build your manager image using the makefile target docker-buildx.
- # affinity:
- # nodeAffinity:
- # requiredDuringSchedulingIgnoredDuringExecution:
- # nodeSelectorTerms:
- # - matchExpressions:
- # - key: kubernetes.io/arch
- # operator: In
- # values:
- # - amd64
- # - arm64
- # - ppc64le
- # - s390x
- # - key: kubernetes.io/os
- # operator: In
- # values:
- # - linux
- securityContext:
- runAsNonRoot: true
- # TODO(user): For common cases that do not require escalating privileges
- # it is recommended to ensure that all your Pods/Containers are restrictive.
- # More info: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted
- # Please uncomment the following code if your project does NOT have to work on old Kubernetes
- # versions < 1.19 or on vendors versions which do NOT support this field by default (i.e. Openshift < 4.11 ).
- # seccompProfile:
- # type: RuntimeDefault
- containers:
- - command:
- - /manager
- args:
- - --leader-elect
- image: controller:latest
- name: manager
- imagePullPolicy: Always
- securityContext:
- allowPrivilegeEscalation: false
- capabilities:
- drop:
- - "ALL"
- livenessProbe:
- httpGet:
- path: /healthz
- port: 8081
- initialDelaySeconds: 15
- periodSeconds: 20
- readinessProbe:
- httpGet:
- path: /readyz
- port: 8081
- initialDelaySeconds: 5
- periodSeconds: 10
- # TODO(user): Configure the resources accordingly based on the project requirements.
- # More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
- resources:
- limits:
- cpu: 500m
- memory: 512Mi
- requests:
- cpu: 100m
- memory: 128Mi
- serviceAccountName: controller-manager
- terminationGracePeriodSeconds: 10
- imagePullSecrets:
- - name: nvcrio
diff --git a/deploy/k8s-operator/kube-trailblazer/config/manifests/kustomization.yaml b/deploy/k8s-operator/kube-trailblazer/config/manifests/kustomization.yaml
deleted file mode 100644
index 4230a0127..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/manifests/kustomization.yaml
+++ /dev/null
@@ -1,27 +0,0 @@
-# These resources constitute the fully configured set of manifests
-# used to generate the 'manifests/' directory in a bundle.
-resources:
-- bases/kube-trailblazer.clusterserviceversion.yaml
-- ../default
-- ../samples
-- ../scorecard
-
-# [WEBHOOK] To enable webhooks, uncomment all the sections with [WEBHOOK] prefix.
-# Do NOT uncomment sections with prefix [CERTMANAGER], as OLM does not support cert-manager.
-# These patches remove the unnecessary "cert" volume and its manager container volumeMount.
-#patchesJson6902:
-#- target:
-# group: apps
-# version: v1
-# kind: Deployment
-# name: controller-manager
-# namespace: system
-# patch: |-
-# # Remove the manager container's "cert" volumeMount, since OLM will create and mount a set of certs.
-# # Update the indices in this path if adding or removing containers/volumeMounts in the manager's Deployment.
-# - op: remove
-# path: /spec/template/spec/containers/1/volumeMounts/0
-# # Remove the "cert" volume, since OLM will create and mount a set of certs.
-# # Update the indices in this path if adding or removing volumes in the manager's Deployment.
-# - op: remove
-# path: /spec/template/spec/volumes/0
diff --git a/deploy/k8s-operator/kube-trailblazer/config/prometheus/kustomization.yaml b/deploy/k8s-operator/kube-trailblazer/config/prometheus/kustomization.yaml
deleted file mode 100644
index ed137168a..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/prometheus/kustomization.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-resources:
-- monitor.yaml
diff --git a/deploy/k8s-operator/kube-trailblazer/config/prometheus/monitor.yaml b/deploy/k8s-operator/kube-trailblazer/config/prometheus/monitor.yaml
deleted file mode 100644
index aa105981c..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/prometheus/monitor.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
-
-# Prometheus Monitor Service (Metrics)
-apiVersion: monitoring.coreos.com/v1
-kind: ServiceMonitor
-metadata:
- labels:
- control-plane: controller-manager
- app.kubernetes.io/name: servicemonitor
- app.kubernetes.io/instance: controller-manager-metrics-monitor
- app.kubernetes.io/component: metrics
- app.kubernetes.io/created-by: kube-trailblazer
- app.kubernetes.io/part-of: kube-trailblazer
- app.kubernetes.io/managed-by: kustomize
- name: controller-manager-metrics-monitor
- namespace: system
-spec:
- endpoints:
- - path: /metrics
- port: https
- scheme: https
- bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
- tlsConfig:
- insecureSkipVerify: true
- selector:
- matchLabels:
- control-plane: controller-manager
diff --git a/deploy/k8s-operator/kube-trailblazer/config/rbac/auth_proxy_client_clusterrole.yaml b/deploy/k8s-operator/kube-trailblazer/config/rbac/auth_proxy_client_clusterrole.yaml
deleted file mode 100644
index 9dcad6a9f..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/rbac/auth_proxy_client_clusterrole.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- labels:
- app.kubernetes.io/name: clusterrole
- app.kubernetes.io/instance: metrics-reader
- app.kubernetes.io/component: kube-rbac-proxy
- app.kubernetes.io/created-by: kube-trailblazer
- app.kubernetes.io/part-of: kube-trailblazer
- app.kubernetes.io/managed-by: kustomize
- name: metrics-reader
-rules:
-- nonResourceURLs:
- - "/metrics"
- verbs:
- - get
diff --git a/deploy/k8s-operator/kube-trailblazer/config/rbac/auth_proxy_role.yaml b/deploy/k8s-operator/kube-trailblazer/config/rbac/auth_proxy_role.yaml
deleted file mode 100644
index c893b21ab..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/rbac/auth_proxy_role.yaml
+++ /dev/null
@@ -1,24 +0,0 @@
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- labels:
- app.kubernetes.io/name: clusterrole
- app.kubernetes.io/instance: proxy-role
- app.kubernetes.io/component: kube-rbac-proxy
- app.kubernetes.io/created-by: kube-trailblazer
- app.kubernetes.io/part-of: kube-trailblazer
- app.kubernetes.io/managed-by: kustomize
- name: proxy-role
-rules:
-- apiGroups:
- - authentication.k8s.io
- resources:
- - tokenreviews
- verbs:
- - create
-- apiGroups:
- - authorization.k8s.io
- resources:
- - subjectaccessreviews
- verbs:
- - create
diff --git a/deploy/k8s-operator/kube-trailblazer/config/rbac/auth_proxy_role_binding.yaml b/deploy/k8s-operator/kube-trailblazer/config/rbac/auth_proxy_role_binding.yaml
deleted file mode 100644
index 22adf7212..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/rbac/auth_proxy_role_binding.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
-metadata:
- labels:
- app.kubernetes.io/name: clusterrolebinding
- app.kubernetes.io/instance: proxy-rolebinding
- app.kubernetes.io/component: kube-rbac-proxy
- app.kubernetes.io/created-by: kube-trailblazer
- app.kubernetes.io/part-of: kube-trailblazer
- app.kubernetes.io/managed-by: kustomize
- name: proxy-rolebinding
-roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: ClusterRole
- name: proxy-role
-subjects:
-- kind: ServiceAccount
- name: controller-manager
- namespace: system
diff --git a/deploy/k8s-operator/kube-trailblazer/config/rbac/auth_proxy_service.yaml b/deploy/k8s-operator/kube-trailblazer/config/rbac/auth_proxy_service.yaml
deleted file mode 100644
index 1f6f8afc3..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/rbac/auth_proxy_service.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-apiVersion: v1
-kind: Service
-metadata:
- labels:
- control-plane: controller-manager
- app.kubernetes.io/name: service
- app.kubernetes.io/instance: controller-manager-metrics-service
- app.kubernetes.io/component: kube-rbac-proxy
- app.kubernetes.io/created-by: kube-trailblazer
- app.kubernetes.io/part-of: kube-trailblazer
- app.kubernetes.io/managed-by: kustomize
- name: controller-manager-metrics-service
- namespace: system
-spec:
- ports:
- - name: https
- port: 8443
- protocol: TCP
- targetPort: https
- selector:
- control-plane: controller-manager
diff --git a/deploy/k8s-operator/kube-trailblazer/config/rbac/helmpipeline_editor_role.yaml b/deploy/k8s-operator/kube-trailblazer/config/rbac/helmpipeline_editor_role.yaml
deleted file mode 100644
index 85316651e..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/rbac/helmpipeline_editor_role.yaml
+++ /dev/null
@@ -1,31 +0,0 @@
-# permissions for end users to edit helmpipelines.
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- labels:
- app.kubernetes.io/name: clusterrole
- app.kubernetes.io/instance: helmpipeline-editor-role
- app.kubernetes.io/component: rbac
- app.kubernetes.io/created-by: kube-trailblazer
- app.kubernetes.io/part-of: kube-trailblazer
- app.kubernetes.io/managed-by: kustomize
- name: helmpipeline-editor-role
-rules:
-- apiGroups:
- - package.nvidia.com
- resources:
- - helmpipelines
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - package.nvidia.com
- resources:
- - helmpipelines/status
- verbs:
- - get
diff --git a/deploy/k8s-operator/kube-trailblazer/config/rbac/helmpipeline_viewer_role.yaml b/deploy/k8s-operator/kube-trailblazer/config/rbac/helmpipeline_viewer_role.yaml
deleted file mode 100644
index 2f837d67a..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/rbac/helmpipeline_viewer_role.yaml
+++ /dev/null
@@ -1,27 +0,0 @@
-# permissions for end users to view helmpipelines.
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- labels:
- app.kubernetes.io/name: clusterrole
- app.kubernetes.io/instance: helmpipeline-viewer-role
- app.kubernetes.io/component: rbac
- app.kubernetes.io/created-by: kube-trailblazer
- app.kubernetes.io/part-of: kube-trailblazer
- app.kubernetes.io/managed-by: kustomize
- name: helmpipeline-viewer-role
-rules:
-- apiGroups:
- - package.nvidia.com
- resources:
- - helmpipelines
- verbs:
- - get
- - list
- - watch
-- apiGroups:
- - package.nvidia.com
- resources:
- - helmpipelines/status
- verbs:
- - get
diff --git a/deploy/k8s-operator/kube-trailblazer/config/rbac/kustomization.yaml b/deploy/k8s-operator/kube-trailblazer/config/rbac/kustomization.yaml
deleted file mode 100644
index 731832a6a..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/rbac/kustomization.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-resources:
-# All RBAC will be applied under this service account in
-# the deployment namespace. You may comment out this resource
-# if your manager will use a service account that exists at
-# runtime. Be sure to update RoleBinding and ClusterRoleBinding
-# subjects if changing service account names.
-- service_account.yaml
-- role.yaml
-- role_binding.yaml
-- leader_election_role.yaml
-- leader_election_role_binding.yaml
-# Comment the following 4 lines if you want to disable
-# the auth proxy (https://github.com/brancz/kube-rbac-proxy)
-# which protects your /metrics endpoint.
-- auth_proxy_service.yaml
-- auth_proxy_role.yaml
-- auth_proxy_role_binding.yaml
-- auth_proxy_client_clusterrole.yaml
diff --git a/deploy/k8s-operator/kube-trailblazer/config/rbac/leader_election_role.yaml b/deploy/k8s-operator/kube-trailblazer/config/rbac/leader_election_role.yaml
deleted file mode 100644
index f7fc4f769..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/rbac/leader_election_role.yaml
+++ /dev/null
@@ -1,44 +0,0 @@
-# permissions to do leader election.
-apiVersion: rbac.authorization.k8s.io/v1
-kind: Role
-metadata:
- labels:
- app.kubernetes.io/name: role
- app.kubernetes.io/instance: leader-election-role
- app.kubernetes.io/component: rbac
- app.kubernetes.io/created-by: kube-trailblazer
- app.kubernetes.io/part-of: kube-trailblazer
- app.kubernetes.io/managed-by: kustomize
- name: leader-election-role
-rules:
-- apiGroups:
- - ""
- resources:
- - configmaps
- verbs:
- - get
- - list
- - watch
- - create
- - update
- - patch
- - delete
-- apiGroups:
- - coordination.k8s.io
- resources:
- - leases
- verbs:
- - get
- - list
- - watch
- - create
- - update
- - patch
- - delete
-- apiGroups:
- - ""
- resources:
- - events
- verbs:
- - create
- - patch
diff --git a/deploy/k8s-operator/kube-trailblazer/config/rbac/leader_election_role_binding.yaml b/deploy/k8s-operator/kube-trailblazer/config/rbac/leader_election_role_binding.yaml
deleted file mode 100644
index 881e07c93..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/rbac/leader_election_role_binding.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
-apiVersion: rbac.authorization.k8s.io/v1
-kind: RoleBinding
-metadata:
- labels:
- app.kubernetes.io/name: rolebinding
- app.kubernetes.io/instance: leader-election-rolebinding
- app.kubernetes.io/component: rbac
- app.kubernetes.io/created-by: kube-trailblazer
- app.kubernetes.io/part-of: kube-trailblazer
- app.kubernetes.io/managed-by: kustomize
- name: leader-election-rolebinding
-roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: Role
- name: leader-election-role
-subjects:
-- kind: ServiceAccount
- name: controller-manager
- namespace: system
diff --git a/deploy/k8s-operator/kube-trailblazer/config/rbac/role.yaml b/deploy/k8s-operator/kube-trailblazer/config/rbac/role.yaml
deleted file mode 100644
index 4e80601cf..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/rbac/role.yaml
+++ /dev/null
@@ -1,1228 +0,0 @@
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- creationTimestamp: null
- name: manager-role
-rules:
-- apiGroups:
- - ""
- resources:
- - nodes/finalizers
- verbs:
- - update
-- apiGroups:
- - ""
- resources:
- - nodes/proxy
- verbs:
- - get
-- apiGroups:
- - ""
- resources:
- - nodes/status
- verbs:
- - get
- - list
- - patch
- - update
-- apiGroups:
- - ""
- resources:
- - pods
- verbs:
- - deletecollection
-- apiGroups:
- - ""
- resources:
- - podtemplates
- verbs:
- - create
- - get
- - list
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - podtemplates/finalizers
- verbs:
- - update
-- apiGroups:
- - '*'
- resources:
- - cronjobs
- verbs:
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - '*'
- resources:
- - daemonsets
- verbs:
- - get
-- apiGroups:
- - '*'
- resources:
- - deployments
- verbs:
- - get
-- apiGroups:
- - '*'
- resources:
- - imagepolicies
- verbs:
- - delete
- - get
- - update
-- apiGroups:
- - '*'
- resources:
- - jobs
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - '*'
- resources:
- - mutatingwebhookconfigurations
- verbs:
- - get
-- apiGroups:
- - '*'
- resources:
- - pods
- verbs:
- - get
-- apiGroups:
- - '*'
- resources:
- - replicacontrollers
- verbs:
- - get
-- apiGroups:
- - '*'
- resources:
- - replicasets
- verbs:
- - get
-- apiGroups:
- - '*'
- resources:
- - statefulsets
- verbs:
- - get
-- apiGroups:
- - acme.cert-manager.io
- resources:
- - challenges
- verbs:
- - create
- - delete
- - deletecollection
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - acme.cert-manager.io
- resources:
- - challenges/finalizers
- verbs:
- - update
-- apiGroups:
- - acme.cert-manager.io
- resources:
- - challenges/status
- verbs:
- - update
-- apiGroups:
- - acme.cert-manager.io
- resources:
- - orders
- verbs:
- - create
- - delete
- - deletecollection
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - acme.cert-manager.io
- resources:
- - orders/finalizers
- verbs:
- - update
-- apiGroups:
- - acme.cert-manager.io
- resources:
- - orders/status
- verbs:
- - update
-- apiGroups:
- - admissionregistration.k8s.io
- resources:
- - mutatingwebhookconfigurations
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - admissionregistration.k8s.io
- resources:
- - validatingwebhookconfigurations
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - admissionregistration.k8s.io/v1beta1
- resources:
- - mutatingwebhookconfigurations
- verbs:
- - create
- - delete
- - list
- - update
-- apiGroups:
- - apiextensions.k8s.io
- resources:
- - customresourcedefinitions
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - apiregistration.k8s.io
- resources:
- - apiservices
- verbs:
- - get
- - list
- - update
- - watch
-- apiGroups:
- - apps
- resources:
- - daemonsets
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - apps
- resources:
- - deployments
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - apps
- resourceNames:
- - shipwright-build
- resources:
- - deployments/finalizers
- verbs:
- - update
-- apiGroups:
- - apps
- resources:
- - replicasets
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - apps
- resources:
- - statefulsets
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - auditregistration.k8s.io
- resources:
- - auditsinks
- verbs:
- - get
- - list
- - update
- - watch
-- apiGroups:
- - batch
- resources:
- - jobs
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - batch
- resources:
- - jobs/finalizers
- verbs:
- - update
-- apiGroups:
- - build.openshift.io
- resources:
- - buildconfigs
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - build.openshift.io
- resources:
- - builds
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - cert-manager.io
- resources:
- - certificaterequests
- verbs:
- - create
- - delete
- - deletecollection
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - cert-manager.io
- resources:
- - certificaterequests/finalizers
- verbs:
- - update
-- apiGroups:
- - cert-manager.io
- resources:
- - certificaterequests/status
- verbs:
- - update
-- apiGroups:
- - cert-manager.io
- resources:
- - certificates
- verbs:
- - create
- - delete
- - deletecollection
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - cert-manager.io
- resources:
- - certificates/finalizers
- verbs:
- - update
-- apiGroups:
- - cert-manager.io
- resources:
- - certificates/status
- verbs:
- - update
-- apiGroups:
- - cert-manager.io
- resources:
- - clusterissuers
- verbs:
- - deletecollection
- - get
- - list
- - update
- - watch
-- apiGroups:
- - cert-manager.io
- resources:
- - clusterissuers/status
- verbs:
- - update
-- apiGroups:
- - cert-manager.io
- resources:
- - issuers
- verbs:
- - create
- - delete
- - deletecollection
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - cert-manager.io
- resources:
- - issuers/status
- verbs:
- - update
-- apiGroups:
- - cert-manager.io
- resourceNames:
- - clusterissuers.cert-manager.io/*
- resources:
- - signers
- verbs:
- - approve
-- apiGroups:
- - cert-manager.io
- resourceNames:
- - issuers.cert-manager.io/*
- resources:
- - signers
- verbs:
- - approve
-- apiGroups:
- - certificates.k8s.io
- resources:
- - certificatesigningrequests
- verbs:
- - get
- - list
- - update
- - watch
-- apiGroups:
- - certificates.k8s.io
- resources:
- - certificatesigningrequests/status
- verbs:
- - update
-- apiGroups:
- - certificates.k8s.io
- resourceNames:
- - clusterissuers.cert-manager.io/*
- resources:
- - signers
- verbs:
- - sign
-- apiGroups:
- - certificates.k8s.io
- resourceNames:
- - issuers.cert-manager.io/*
- resources:
- - signers
- verbs:
- - sign
-- apiGroups:
- - config.openshift.io
- resources:
- - clusterversions
- verbs:
- - get
-- apiGroups:
- - config.openshift.io
- resources:
- - proxies
- verbs:
- - get
- - list
-- apiGroups:
- - connaisseur.policy
- resources:
- - imagepolicies
- verbs:
- - create
-- apiGroups:
- - coordination.k8s.io
- resources:
- - leases
- verbs:
- - create
- - delete
- - get
- - list
- - update
- - watch
-- apiGroups:
- - coordination.k8s.io
- resourceNames:
- - cert-manager-cainjector-election-core
- resources:
- - leases
- verbs:
- - patch
-- apiGroups:
- - coordination.k8s.io
- resourceNames:
- - cert-manager-cainjector-leader-election
- resources:
- - leases
- verbs:
- - patch
-- apiGroups:
- - coordination.k8s.io
- resourceNames:
- - cert-manager-cainjector-leader-election-core
- resources:
- - leases
- verbs:
- - patch
-- apiGroups:
- - coordination.k8s.io
- resourceNames:
- - cert-manager-controller
- resources:
- - leases
- verbs:
- - patch
-- apiGroups:
- - ""
- resources:
- - configmaps
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - endpoints
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - events
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - imagestreams/layers
- verbs:
- - get
-- apiGroups:
- - ""
- resources:
- - namespaces
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - nodes
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - persistentvolumeclaims
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - persistentvolumeclaims/status
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - persistentvolumes
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - pods
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - pods/log
- verbs:
- - get
-- apiGroups:
- - ""
- resources:
- - secrets
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - serviceaccounts
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - services
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - services/finalizers
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - csi.storage.k8s.io
- resources:
- - csidrivers
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - extensions
- resources:
- - jobs
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - fpga.silicom.dk
- resources:
- - '*'
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - image.openshift.io
- resources:
- - imagestreams
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - image.openshift.io
- resources:
- - imagestreams/finalizers
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - image.openshift.io
- resources:
- - imagestreams/layers
- verbs:
- - get
-- apiGroups:
- - infoscale.veritas.com
- resources:
- - infoscaleclusters
- verbs:
- - get
- - list
- - patch
- - update
-- apiGroups:
- - monitoring.coreos.com
- resources:
- - prometheusrules
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - monitoring.coreos.com
- resources:
- - servicemonitors
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - networking.k8s.io
- resources:
- - clustercidrs
- verbs:
- - list
- - watch
-- apiGroups:
- - networking.k8s.io
- resources:
- - ingresses
- verbs:
- - create
- - delete
- - get
- - list
- - update
- - watch
-- apiGroups:
- - networking.k8s.io
- resources:
- - ingresses/finalizers
- verbs:
- - update
-- apiGroups:
- - networking.x-k8s.io
- resources:
- - gateways
- verbs:
- - get
- - list
- - watch
-- apiGroups:
- - networking.x-k8s.io
- resources:
- - gateways/finalizers
- verbs:
- - update
-- apiGroups:
- - networking.x-k8s.io
- resources:
- - httproutes
- verbs:
- - create
- - delete
- - get
- - list
- - update
- - watch
-- apiGroups:
- - networking.x-k8s.io
- resources:
- - httproutes/finalisers
- verbs:
- - update
-- apiGroups:
- - nfd.k8s-sigs.io
- resources:
- - nodefeaturerules
- verbs:
- - get
- - list
- - watch
-- apiGroups:
- - nfd.k8s-sigs.io
- resources:
- - nodefeatures
- verbs:
- - create
- - delete
- - get
- - list
- - update
- - watch
-- apiGroups:
- - nvidia.com
- resources:
- - clusterpolicies
- verbs:
- - get
- - list
- - patch
- - watch
-- apiGroups:
- - operator.cert-manager.io
- resources:
- - certmanagers
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - operators.coreos.com
- resources:
- - operatorgroups
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - operators.coreos.com
- resources:
- - subscriptions
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - package.nvidia.com
- resources:
- - helmpipelines
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - package.nvidia.com
- resources:
- - helmpipelines/finalizers
- verbs:
- - update
-- apiGroups:
- - package.nvidia.com
- resources:
- - helmpipelines/status
- verbs:
- - get
- - patch
- - update
-- apiGroups:
- - rbac.authorization.k8s.io
- resources:
- - clusterrolebindings
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - rbac.authorization.k8s.io
- resources:
- - clusterroles
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - rbac.authorization.k8s.io
- resources:
- - rolebindings
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - rbac.authorization.k8s.io
- resources:
- - roles
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - route.openshift.io
- resources:
- - routes
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - route.openshift.io
- resources:
- - routes/custom-host
- verbs:
- - create
-- apiGroups:
- - security.openshift.io
- resources:
- - securitycontextconstraints
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - use
- - watch
-- apiGroups:
- - shipwright.io
- resources:
- - '*'
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - shipwright.io
- resources:
- - buildruns
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - shipwright.io
- resources:
- - buildstrategies
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - shipwright.io
- resources:
- - clusterbuildstrategies
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - snapshot.storage.k8s.io
- resources:
- - volumesnapshotclasses
- verbs:
- - get
- - list
- - watch
-- apiGroups:
- - snapshot.storage.k8s.io
- resources:
- - volumesnapshotcontents
- verbs:
- - create
- - delete
- - get
- - list
- - update
- - watch
-- apiGroups:
- - snapshot.storage.k8s.io
- resources:
- - volumesnapshotcontents/status
- verbs:
- - create
- - delete
- - get
- - list
- - update
- - watch
-- apiGroups:
- - snapshot.storage.k8s.io
- resources:
- - volumesnapshots
- verbs:
- - get
- - list
- - update
- - watch
-- apiGroups:
- - snapshot.storage.k8s.io
- resources:
- - volumesnapshots/status
- verbs:
- - create
- - delete
- - get
- - list
- - update
- - watch
-- apiGroups:
- - sro.openshift.io
- resources:
- - specialresources
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - sro.openshift.io
- resources:
- - specialresources/finalizers
- verbs:
- - get
- - patch
- - update
-- apiGroups:
- - sro.openshift.io
- resources:
- - specialresources/status
- verbs:
- - get
- - patch
- - update
-- apiGroups:
- - storage.k8s.io
- resources:
- - csidrivers
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - storage.k8s.io
- resources:
- - csinodes
- verbs:
- - get
- - list
- - watch
-- apiGroups:
- - storage.k8s.io
- resources:
- - storageclasses
- verbs:
- - get
- - list
- - watch
-- apiGroups:
- - storage.k8s.io
- resources:
- - volumeattachments
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - sts.silicom.com
- resources:
- - '*'
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - tekton.dev
- resources:
- - taskruns
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - tekton.dev
- resources:
- - tasks
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - topology.node.k8s.io
- resources:
- - noderesourcetopologies
- verbs:
- - delete
- - list
diff --git a/deploy/k8s-operator/kube-trailblazer/config/rbac/role_binding.yaml b/deploy/k8s-operator/kube-trailblazer/config/rbac/role_binding.yaml
deleted file mode 100644
index 64c93eef5..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/rbac/role_binding.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
-metadata:
- labels:
- app.kubernetes.io/name: clusterrolebinding
- app.kubernetes.io/instance: manager-rolebinding
- app.kubernetes.io/component: rbac
- app.kubernetes.io/created-by: kube-trailblazer
- app.kubernetes.io/part-of: kube-trailblazer
- app.kubernetes.io/managed-by: kustomize
- name: manager-rolebinding
-roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: ClusterRole
- name: manager-role
-subjects:
-- kind: ServiceAccount
- name: controller-manager
- namespace: system
diff --git a/deploy/k8s-operator/kube-trailblazer/config/rbac/service_account.yaml b/deploy/k8s-operator/kube-trailblazer/config/rbac/service_account.yaml
deleted file mode 100644
index b92e8b958..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/rbac/service_account.yaml
+++ /dev/null
@@ -1,12 +0,0 @@
-apiVersion: v1
-kind: ServiceAccount
-metadata:
- labels:
- app.kubernetes.io/name: serviceaccount
- app.kubernetes.io/instance: controller-manager
- app.kubernetes.io/component: rbac
- app.kubernetes.io/created-by: kube-trailblazer
- app.kubernetes.io/part-of: kube-trailblazer
- app.kubernetes.io/managed-by: kustomize
- name: controller-manager
- namespace: system
diff --git a/deploy/k8s-operator/kube-trailblazer/config/samples/kustomization.yaml b/deploy/k8s-operator/kube-trailblazer/config/samples/kustomization.yaml
deleted file mode 100644
index 828521d79..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/samples/kustomization.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-## Append samples you want in your CSV to this file as resources ##
-resources:
-- package_v1alpha1_helmpipeline.yaml
-#+kubebuilder:scaffold:manifestskustomizesamples
diff --git a/deploy/k8s-operator/kube-trailblazer/config/samples/package_v1alpha1_helmpipeline.yaml b/deploy/k8s-operator/kube-trailblazer/config/samples/package_v1alpha1_helmpipeline.yaml
deleted file mode 100644
index bdf4d4c20..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/samples/package_v1alpha1_helmpipeline.yaml
+++ /dev/null
@@ -1,12 +0,0 @@
-apiVersion: package.nvidia.com/v1alpha1
-kind: HelmPipeline
-metadata:
- labels:
- app.kubernetes.io/name: helmpipeline
- app.kubernetes.io/instance: helmpipeline-sample
- app.kubernetes.io/part-of: kube-trailblazer
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/created-by: kube-trailblazer
- name: helmpipeline-sample
-spec:
- # TODO(user): Add fields here
diff --git a/deploy/k8s-operator/kube-trailblazer/config/scorecard/bases/config.yaml b/deploy/k8s-operator/kube-trailblazer/config/scorecard/bases/config.yaml
deleted file mode 100644
index c77047841..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/scorecard/bases/config.yaml
+++ /dev/null
@@ -1,7 +0,0 @@
-apiVersion: scorecard.operatorframework.io/v1alpha3
-kind: Configuration
-metadata:
- name: config
-stages:
-- parallel: true
- tests: []
diff --git a/deploy/k8s-operator/kube-trailblazer/config/scorecard/kustomization.yaml b/deploy/k8s-operator/kube-trailblazer/config/scorecard/kustomization.yaml
deleted file mode 100644
index 50cd2d084..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/scorecard/kustomization.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-resources:
-- bases/config.yaml
-patchesJson6902:
-- path: patches/basic.config.yaml
- target:
- group: scorecard.operatorframework.io
- version: v1alpha3
- kind: Configuration
- name: config
-- path: patches/olm.config.yaml
- target:
- group: scorecard.operatorframework.io
- version: v1alpha3
- kind: Configuration
- name: config
-#+kubebuilder:scaffold:patchesJson6902
diff --git a/deploy/k8s-operator/kube-trailblazer/config/scorecard/patches/basic.config.yaml b/deploy/k8s-operator/kube-trailblazer/config/scorecard/patches/basic.config.yaml
deleted file mode 100644
index 472a98823..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/scorecard/patches/basic.config.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-- op: add
- path: /stages/0/tests/-
- value:
- entrypoint:
- - scorecard-test
- - basic-check-spec
- image: quay.io/operator-framework/scorecard-test:v1.32.0
- labels:
- suite: basic
- test: basic-check-spec-test
diff --git a/deploy/k8s-operator/kube-trailblazer/config/scorecard/patches/olm.config.yaml b/deploy/k8s-operator/kube-trailblazer/config/scorecard/patches/olm.config.yaml
deleted file mode 100644
index 343c6d8d8..000000000
--- a/deploy/k8s-operator/kube-trailblazer/config/scorecard/patches/olm.config.yaml
+++ /dev/null
@@ -1,50 +0,0 @@
-- op: add
- path: /stages/0/tests/-
- value:
- entrypoint:
- - scorecard-test
- - olm-bundle-validation
- image: quay.io/operator-framework/scorecard-test:v1.32.0
- labels:
- suite: olm
- test: olm-bundle-validation-test
-- op: add
- path: /stages/0/tests/-
- value:
- entrypoint:
- - scorecard-test
- - olm-crds-have-validation
- image: quay.io/operator-framework/scorecard-test:v1.32.0
- labels:
- suite: olm
- test: olm-crds-have-validation-test
-- op: add
- path: /stages/0/tests/-
- value:
- entrypoint:
- - scorecard-test
- - olm-crds-have-resources
- image: quay.io/operator-framework/scorecard-test:v1.32.0
- labels:
- suite: olm
- test: olm-crds-have-resources-test
-- op: add
- path: /stages/0/tests/-
- value:
- entrypoint:
- - scorecard-test
- - olm-spec-descriptors
- image: quay.io/operator-framework/scorecard-test:v1.32.0
- labels:
- suite: olm
- test: olm-spec-descriptors-test
-- op: add
- path: /stages/0/tests/-
- value:
- entrypoint:
- - scorecard-test
- - olm-status-descriptors
- image: quay.io/operator-framework/scorecard-test:v1.32.0
- labels:
- suite: olm
- test: olm-status-descriptors-test
diff --git a/deploy/k8s-operator/kube-trailblazer/controllers/helmpipeline.go b/deploy/k8s-operator/kube-trailblazer/controllers/helmpipeline.go
deleted file mode 100644
index 8f24f5bb5..000000000
--- a/deploy/k8s-operator/kube-trailblazer/controllers/helmpipeline.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package controllers
-
-import (
- "context"
-
- "github.com/nvidia/kube-trailblazer/api/v1alpha1"
- ctrl "sigs.k8s.io/controller-runtime"
- "sigs.k8s.io/controller-runtime/pkg/client"
-)
-
-func findRequestingHelmPipeline(a []v1alpha1.HelmPipeline, x string, by string) (int, bool) {
- for i, n := range a {
- if by == "Name" {
- if x == n.GetName() {
- return i, true
- }
- }
- }
- return -1, false
-}
-
-func (r *HelmPipelineReconciler) listHelmPipelines(ctx context.Context, req ctrl.Request) (*v1alpha1.HelmPipeline, *v1alpha1.HelmPipelineList, error) {
- helmPipelines := &v1alpha1.HelmPipelineList{}
-
- opts := []client.ListOption{}
- err := r.KubeClient.List(ctx, helmPipelines, opts...)
- if err != nil {
- return nil, nil, err
- }
-
- var idx int
- var found bool
- if idx, found = findRequestingHelmPipeline(helmPipelines.Items, req.Name, "Name"); !found {
- return nil, nil, nil
- }
- return &helmPipelines.Items[idx], helmPipelines, nil
-}
diff --git a/deploy/k8s-operator/kube-trailblazer/controllers/helmpipeline_controller.go b/deploy/k8s-operator/kube-trailblazer/controllers/helmpipeline_controller.go
deleted file mode 100644
index 2921041d2..000000000
--- a/deploy/k8s-operator/kube-trailblazer/controllers/helmpipeline_controller.go
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
-Copyright 2023.
-
-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.
-*/
-
-package controllers
-
-import (
- "context"
- "fmt"
-
- appsv1 "k8s.io/api/apps/v1"
- v1 "k8s.io/api/core/v1"
- rbacv1 "k8s.io/api/rbac/v1"
- storagev1 "k8s.io/api/storage/v1"
- "k8s.io/apimachinery/pkg/runtime"
- "k8s.io/client-go/rest"
- "k8s.io/klog/v2"
- ctrl "sigs.k8s.io/controller-runtime"
- "sigs.k8s.io/controller-runtime/pkg/client"
- "sigs.k8s.io/controller-runtime/pkg/log"
-
- v1alpha1 "github.com/nvidia/kube-trailblazer/api/v1alpha1"
- "github.com/nvidia/kube-trailblazer/pkg/clients"
- "github.com/nvidia/kube-trailblazer/pkg/filter"
- "github.com/nvidia/kube-trailblazer/pkg/helmer"
-)
-
-// HelmPipelineReconciler reconciles a HelmPipeline object
-type HelmPipelineReconciler struct {
- client.Client
- Scheme *runtime.Scheme
- Filter filter.Filter
- KubeClient clients.ClientsInterface
- RestConf *rest.Config
-}
-
-//+kubebuilder:rbac:groups=package.nvidia.com,resources=helmpipelines,verbs=get;list;watch;create;update;patch;delete
-//+kubebuilder:rbac:groups=package.nvidia.com,resources=helmpipelines/status,verbs=get;update;patch
-//+kubebuilder:rbac:groups=package.nvidia.com,resources=helmpipelines/finalizers,verbs=update
-
-// Reconcile is part of the main kubernetes reconciliation loop which aims to
-// move the current state of the cluster closer to the desired state.
-// TODO(user): Modify the Reconcile function to compare the state specified by
-// the HelmPipeline object against the actual cluster state, and then
-// perform operations to make the cluster state reflect the state specified by
-// the user.
-//
-// For more details, check Reconcile and its Result here:
-// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.14.1/pkg/reconcile
-func (r *HelmPipelineReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
- _ = log.FromContext(ctx)
-
- klog.Infof("%s -- reconciling -- request %s:%s", r.Filter.GetMode(), req.Namespace, req.Name)
-
- klog.Info("TODO: preflight checks")
-
- tb, _, err := r.listHelmPipelines(ctx, req)
- if err != nil {
- klog.Error(err, "[Reconcile]\tfailed to list HelmOrchards")
- return ctrl.Result{}, err
- }
-
- for {
- var ok bool
- var tb *v1alpha1.HelmPipeline
-
- item := filter.WorkStack["DELETE"].Pop()
- if item == nil {
- break
- }
- if tb, ok = item.(*v1alpha1.HelmPipeline); !ok {
- klog.Info(fmt.Sprintf("DEBUG WorkStack Item: %+v", item))
- //panic(errors.New("owned object is not a HelmPipeline"))
- continue
-
- }
- err = helmer.ReconcileDelete(tb.Spec.Pipeline, r.RestConf)
- if err != nil {
- klog.Info("SUCCESS: ReconcileDelete")
- return ctrl.Result{}, err
- }
- }
-
- // This happens if Helmer was reconciling and the HelmOrchard was deleted
- if tb == nil {
- klog.Info("SUCCESS: reconcile (tb == nil)")
- return ctrl.Result{}, nil
- }
-
- klog.Infof("[Reconcile] -- %s -- HelmPipeline %s:%s", r.Filter.GetMode(), tb.GetNamespace(), tb.GetName())
- releases, err := helmer.ReconcileCreate(tb.Spec.Pipeline, r.RestConf)
- if err != nil {
- klog.Warning(err, "[Reconcile]\trequeue request due to error")
- return ctrl.Result{Requeue: true}, nil
- }
-
- klog.Info("TODO: metrics")
- for _, release := range releases {
- klog.Infof("[Reconcile]\tRELEASES: %s:%s", release.Namespace, release.Name)
- }
-
- klog.Info("SUCCESS: reconcile")
- return ctrl.Result{}, nil
-}
-
-// SetupWithManager sets up the controller with the Manager.
-func (r *HelmPipelineReconciler) SetupWithManager(mgr ctrl.Manager) error {
- return ctrl.NewControllerManagedBy(mgr).
- For(&v1alpha1.HelmPipeline{}).
- Owns(&v1.Pod{}).
- Owns(&appsv1.DaemonSet{}).
- Owns(&appsv1.Deployment{}).
- Owns(&storagev1.CSIDriver{}).
- Owns(&v1.ConfigMap{}).
- Owns(&v1.ServiceAccount{}).
- Owns(&rbacv1.Role{}).
- Owns(&rbacv1.RoleBinding{}).
- Owns(&rbacv1.ClusterRole{}).
- Owns(&rbacv1.ClusterRoleBinding{}).
- Owns(&v1.Secret{}).
- WithEventFilter(r.Filter.GetPredicates()).
- Complete(r)
-}
diff --git a/deploy/k8s-operator/kube-trailblazer/controllers/helmpipeline_rbac.go b/deploy/k8s-operator/kube-trailblazer/controllers/helmpipeline_rbac.go
deleted file mode 100644
index d0ec76a7e..000000000
--- a/deploy/k8s-operator/kube-trailblazer/controllers/helmpipeline_rbac.go
+++ /dev/null
@@ -1,12 +0,0 @@
-package controllers
-
-//+kubebuilder:rbac:groups=package.nvidia.com,resources=helmpipelines,verbs=get;list;watch;create;update;patch;delete
-//+kubebuilder:rbac:groups=package.nvidia.com,resources=helmpipelines/status,verbs=get;update;patch
-//+kubebuilder:rbac:groups=package.nvidia.com,resources=helmpipelines/finalizers,verbs=update
-//+kubebuilder:rbac:groups="",resources=nodes/status,verbs=get;list
-//+kubebuilder:rbac:groups="",resources=nodes/proxy,verbs=get
-//+kubebuilder:rbac:groups=nfd.k8s-sigs.io,resources=nodefeaturerules,verbs=get;list;watch
-//+kubebuilder:rbac:groups=nfd.k8s-sigs.io,resources=nodefeatures,verbs=get;list;watch;delete;create;update
-//+kubebuilder:rbac:groups=topology.node.k8s.io,resources=noderesourcetopologies,verbs=delete;list
-//+kubebuilder:rbac:groups=networking.k8s.io, resources=clustercidrs, verbs=list;watch
-//+kubebuilder:rbac:groups=nvidia.com, resources=clusterpolicies, verbs=get;list;watch;patch
diff --git a/deploy/k8s-operator/kube-trailblazer/controllers/suite_test.go b/deploy/k8s-operator/kube-trailblazer/controllers/suite_test.go
deleted file mode 100644
index e8aafe4f0..000000000
--- a/deploy/k8s-operator/kube-trailblazer/controllers/suite_test.go
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
-Copyright 2023.
-
-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.
-*/
-
-package controllers
-
-import (
- "path/filepath"
- "testing"
-
- . "github.com/onsi/ginkgo/v2"
- . "github.com/onsi/gomega"
-
- "k8s.io/client-go/kubernetes/scheme"
- "k8s.io/client-go/rest"
- "sigs.k8s.io/controller-runtime/pkg/client"
- "sigs.k8s.io/controller-runtime/pkg/envtest"
- logf "sigs.k8s.io/controller-runtime/pkg/log"
- "sigs.k8s.io/controller-runtime/pkg/log/zap"
-
- packagev1alpha1 "github.com/nvidia/kube-trailblazer/api/v1alpha1"
- //+kubebuilder:scaffold:imports
-)
-
-// These tests use Ginkgo (BDD-style Go testing framework). Refer to
-// http://onsi.github.io/ginkgo/ to learn more about Ginkgo.
-
-var cfg *rest.Config
-var k8sClient client.Client
-var testEnv *envtest.Environment
-
-func TestAPIs(t *testing.T) {
- RegisterFailHandler(Fail)
-
- RunSpecs(t, "Controller Suite")
-}
-
-var _ = BeforeSuite(func() {
- logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)))
-
- By("bootstrapping test environment")
- testEnv = &envtest.Environment{
- CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")},
- ErrorIfCRDPathMissing: true,
- }
-
- var err error
- // cfg is defined in this file globally.
- cfg, err = testEnv.Start()
- Expect(err).NotTo(HaveOccurred())
- Expect(cfg).NotTo(BeNil())
-
- err = packagev1alpha1.AddToScheme(scheme.Scheme)
- Expect(err).NotTo(HaveOccurred())
-
- //+kubebuilder:scaffold:scheme
-
- k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
- Expect(err).NotTo(HaveOccurred())
- Expect(k8sClient).NotTo(BeNil())
-
-})
-
-var _ = AfterSuite(func() {
- By("tearing down the test environment")
- err := testEnv.Stop()
- Expect(err).NotTo(HaveOccurred())
-})
diff --git a/deploy/k8s-operator/kube-trailblazer/go.mod b/deploy/k8s-operator/kube-trailblazer/go.mod
deleted file mode 100644
index b675965e0..000000000
--- a/deploy/k8s-operator/kube-trailblazer/go.mod
+++ /dev/null
@@ -1,167 +0,0 @@
-module github.com/nvidia/kube-trailblazer
-
-go 1.20
-
-replace github.com/mittwald/go-helm-client => /zvonkok/github.com/zvonkok/go-helm-client
-
-require (
- github.com/golang/mock v1.6.0
- github.com/mittwald/go-helm-client v0.9.0
- github.com/onsi/ginkgo/v2 v2.11.0
- github.com/onsi/gomega v1.27.10
- github.com/openshift-psap/special-resource-operator v0.0.0-20220818111522-5e97683a2041
- github.com/openshift/api v0.0.0-20231128111040-e1845c5a7acd
- github.com/openshift/client-go v0.0.0-20231121143148-910ca30a1a9a
- github.com/pkg/errors v0.9.1
- github.com/urfave/cli/v2 v2.26.0
- golang.design/x/lockfree v0.0.1
- helm.sh/helm/v3 v3.13.2
- k8s.io/api v0.28.4
- k8s.io/apimachinery v0.28.4
- k8s.io/cli-runtime v0.28.4
- k8s.io/client-go v0.28.4
- k8s.io/klog/v2 v2.100.1
- sigs.k8s.io/controller-runtime v0.16.3
- sigs.k8s.io/yaml v1.3.0
-)
-
-require (
- github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
- github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
- github.com/BurntSushi/toml v1.3.2 // indirect
- github.com/MakeNowJust/heredoc v1.0.0 // indirect
- github.com/Masterminds/goutils v1.1.1 // indirect
- github.com/Masterminds/semver/v3 v3.2.1 // indirect
- github.com/Masterminds/sprig/v3 v3.2.3 // indirect
- github.com/Masterminds/squirrel v1.5.4 // indirect
- github.com/Microsoft/hcsshim v0.11.0 // indirect
- github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
- github.com/beorn7/perks v1.0.1 // indirect
- github.com/cespare/xxhash/v2 v2.2.0 // indirect
- github.com/chai2010/gettext-go v1.0.2 // indirect
- github.com/changkun/lockfree v0.0.1 // indirect
- github.com/containerd/containerd v1.7.6 // indirect
- github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
- github.com/cyphar/filepath-securejoin v0.2.4 // indirect
- github.com/davecgh/go-spew v1.1.1 // indirect
- github.com/docker/cli v24.0.6+incompatible // indirect
- github.com/docker/distribution v2.8.2+incompatible // indirect
- github.com/docker/docker v24.0.7+incompatible // indirect
- github.com/docker/docker-credential-helpers v0.7.0 // indirect
- github.com/docker/go-connections v0.4.0 // indirect
- github.com/docker/go-metrics v0.0.1 // indirect
- github.com/docker/go-units v0.5.0 // indirect
- github.com/emicklei/go-restful/v3 v3.11.0 // indirect
- github.com/evanphx/json-patch v5.6.0+incompatible // indirect
- github.com/evanphx/json-patch/v5 v5.6.0 // indirect
- github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
- github.com/fatih/color v1.13.0 // indirect
- github.com/fsnotify/fsnotify v1.6.0 // indirect
- github.com/go-errors/errors v1.4.2 // indirect
- github.com/go-gorp/gorp/v3 v3.1.0 // indirect
- github.com/go-logr/logr v1.2.4 // indirect
- github.com/go-logr/stdr v1.2.2 // indirect
- github.com/go-logr/zapr v1.2.4 // indirect
- github.com/go-openapi/jsonpointer v0.19.6 // indirect
- github.com/go-openapi/jsonreference v0.20.2 // indirect
- github.com/go-openapi/swag v0.22.3 // indirect
- github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
- github.com/gobwas/glob v0.2.3 // indirect
- github.com/gogo/protobuf v1.3.2 // indirect
- github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
- github.com/golang/protobuf v1.5.3 // indirect
- github.com/google/btree v1.1.2 // indirect
- github.com/google/gnostic-models v0.6.8 // indirect
- github.com/google/go-cmp v0.5.9 // indirect
- github.com/google/gofuzz v1.2.0 // indirect
- github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect
- github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
- github.com/google/uuid v1.3.0 // indirect
- github.com/gorilla/mux v1.8.0 // indirect
- github.com/gosuri/uitable v0.0.4 // indirect
- github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
- github.com/hashicorp/errwrap v1.1.0 // indirect
- github.com/hashicorp/go-multierror v1.1.1 // indirect
- github.com/huandu/xstrings v1.4.0 // indirect
- github.com/imdario/mergo v0.3.13 // indirect
- github.com/inconshreveable/mousetrap v1.1.0 // indirect
- github.com/jmoiron/sqlx v1.3.5 // indirect
- github.com/josharian/intern v1.0.0 // indirect
- github.com/json-iterator/go v1.1.12 // indirect
- github.com/klauspost/compress v1.16.0 // indirect
- github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
- github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
- github.com/lib/pq v1.10.9 // indirect
- github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
- github.com/mailru/easyjson v0.7.7 // indirect
- github.com/mattn/go-colorable v0.1.13 // indirect
- github.com/mattn/go-isatty v0.0.17 // indirect
- github.com/mattn/go-runewidth v0.0.14 // indirect
- github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
- github.com/mitchellh/copystructure v1.2.0 // indirect
- github.com/mitchellh/go-wordwrap v1.0.1 // indirect
- github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect
- github.com/mitchellh/reflectwalk v1.0.2 // indirect
- github.com/moby/locker v1.0.1 // indirect
- github.com/moby/spdystream v0.2.0 // indirect
- github.com/moby/term v0.5.0 // indirect
- github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
- github.com/modern-go/reflect2 v1.0.2 // indirect
- github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
- github.com/morikuni/aec v1.0.0 // indirect
- github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
- github.com/opencontainers/go-digest v1.0.0 // indirect
- github.com/opencontainers/image-spec v1.1.0-rc5 // indirect
- github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
- github.com/prometheus/client_golang v1.16.0 // indirect
- github.com/prometheus/client_model v0.4.0 // indirect
- github.com/prometheus/common v0.44.0 // indirect
- github.com/prometheus/procfs v0.10.1 // indirect
- github.com/rivo/uniseg v0.4.2 // indirect
- github.com/rubenv/sql-migrate v1.5.2 // indirect
- github.com/russross/blackfriday/v2 v2.1.0 // indirect
- github.com/shopspring/decimal v1.3.1 // indirect
- github.com/sirupsen/logrus v1.9.3 // indirect
- github.com/spf13/cast v1.5.0 // indirect
- github.com/spf13/cobra v1.7.0 // indirect
- github.com/spf13/pflag v1.0.5 // indirect
- github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
- github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
- github.com/xeipuuv/gojsonschema v1.2.0 // indirect
- github.com/xlab/treeprint v1.2.0 // indirect
- github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
- go.opentelemetry.io/otel v1.14.0 // indirect
- go.opentelemetry.io/otel/trace v1.14.0 // indirect
- go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
- go.uber.org/multierr v1.11.0 // indirect
- go.uber.org/zap v1.25.0 // indirect
- golang.org/x/crypto v0.15.0 // indirect
- golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect
- golang.org/x/net v0.18.0 // indirect
- golang.org/x/oauth2 v0.8.0 // indirect
- golang.org/x/sync v0.5.0 // indirect
- golang.org/x/sys v0.14.0 // indirect
- golang.org/x/term v0.14.0 // indirect
- golang.org/x/text v0.14.0 // indirect
- golang.org/x/time v0.3.0 // indirect
- golang.org/x/tools v0.15.0 // indirect
- gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
- google.golang.org/appengine v1.6.7 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect
- google.golang.org/grpc v1.56.3 // indirect
- google.golang.org/protobuf v1.31.0 // indirect
- gopkg.in/inf.v0 v0.9.1 // indirect
- gopkg.in/yaml.v2 v2.4.0 // indirect
- gopkg.in/yaml.v3 v3.0.1 // indirect
- k8s.io/apiextensions-apiserver v0.28.3 // indirect
- k8s.io/apiserver v0.28.3 // indirect
- k8s.io/component-base v0.28.4 // indirect
- k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect
- k8s.io/kubectl v0.28.4 // indirect
- k8s.io/utils v0.0.0-20230505201702-9f6742963106 // indirect
- oras.land/oras-go v1.2.4 // indirect
- sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
- sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect
- sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect
- sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
-)
diff --git a/deploy/k8s-operator/kube-trailblazer/go.sum b/deploy/k8s-operator/kube-trailblazer/go.sum
deleted file mode 100644
index b594b8361..000000000
--- a/deploy/k8s-operator/kube-trailblazer/go.sum
+++ /dev/null
@@ -1,590 +0,0 @@
-cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
-github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
-github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
-github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
-github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
-github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
-github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
-github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
-github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
-github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
-github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
-github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
-github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
-github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
-github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
-github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
-github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
-github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM=
-github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
-github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
-github.com/Microsoft/hcsshim v0.11.0 h1:7EFNIY4igHEXUdj1zXgAyU3fLc7QfOKHbkldRVTBdiM=
-github.com/Microsoft/hcsshim v0.11.0/go.mod h1:OEthFdQv/AD2RAdzR6Mm1N1KPCztGKDurW1Z8b8VGMM=
-github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs=
-github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
-github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
-github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
-github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ=
-github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
-github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
-github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
-github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
-github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
-github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
-github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
-github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70=
-github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd h1:rFt+Y/IK1aEZkEHchZRSq9OQbsSzIT/OrI8YFFmRIng=
-github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembjv71DPz3uX/V/6MMlSyD9JBQ6kQ=
-github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o=
-github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
-github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
-github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk=
-github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA=
-github.com/changkun/lockfree v0.0.1 h1:5WefVJLglY4IHRqOQmh6Ao6wkJYaJkarshKU8VUtId4=
-github.com/changkun/lockfree v0.0.1/go.mod h1:3bKiaXn/iNzIPlSvSOMSVbRQUQtAp8qUAyBUtzU11s4=
-github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
-github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
-github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
-github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
-github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
-github.com/containerd/containerd v1.7.6 h1:oNAVsnhPoy4BTPQivLgTzI9Oleml9l/+eYIDYXRCYo8=
-github.com/containerd/containerd v1.7.6/go.mod h1:SY6lrkkuJT40BVNO37tlYTSnKJnP5AXBc0fhx0q+TJ4=
-github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM=
-github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
-github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
-github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
-github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
-github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
-github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
-github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2 h1:aBfCb7iqHmDEIp6fBvC/hQUddQfg+3qdYjwzaiP9Hnc=
-github.com/docker/cli v24.0.6+incompatible h1:fF+XCQCgJjjQNIMjzaSmiKJSCcfcXb3TWTcc7GAneOY=
-github.com/docker/cli v24.0.6+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
-github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
-github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
-github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM=
-github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
-github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
-github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
-github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
-github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
-github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=
-github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8=
-github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
-github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
-github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
-github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4=
-github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
-github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
-github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
-github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U=
-github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
-github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww=
-github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4=
-github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f h1:Wl78ApPPB2Wvf/TIe2xdyJxTlb6obmF18d8QdkxNDu4=
-github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f/go.mod h1:OSYXu++VVOHnXeitef/D8n/6y4QV8uLHSFXX4NeXMGc=
-github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
-github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
-github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
-github.com/foxcpp/go-mockdns v1.0.0 h1:7jBqxd3WDWwi/6WhDvacvH1XsN3rOLXyHM1uhvIx6FI=
-github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
-github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
-github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
-github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
-github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
-github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs=
-github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw=
-github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
-github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
-github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
-github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
-github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
-github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
-github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo=
-github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA=
-github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
-github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
-github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
-github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
-github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
-github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
-github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
-github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
-github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
-github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
-github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
-github.com/gobuffalo/logger v1.0.6 h1:nnZNpxYo0zx+Aj9RfMPBm+x9zAU2OayFh/xrAWi34HU=
-github.com/gobuffalo/packd v1.0.1 h1:U2wXfRr4E9DH8IdsDLlRFwTZTK7hLfq9qT/QHXGVe/0=
-github.com/gobuffalo/packr/v2 v2.8.3 h1:xE1yzvnO56cUC0sTpKR3DIbxZgB54AftTFMhB2XEWlY=
-github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
-github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
-github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
-github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
-github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
-github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
-github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
-github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
-github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
-github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
-github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
-github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
-github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
-github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
-github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
-github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
-github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
-github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
-github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
-github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k=
-github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
-github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
-github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
-github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
-github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
-github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
-github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
-github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=
-github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
-github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
-github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
-github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
-github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
-github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
-github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
-github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY=
-github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo=
-github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA=
-github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
-github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
-github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
-github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
-github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
-github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
-github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
-github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
-github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU=
-github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
-github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
-github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
-github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
-github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
-github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
-github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
-github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
-github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
-github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=
-github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
-github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
-github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
-github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
-github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
-github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
-github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw=
-github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
-github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4=
-github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
-github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
-github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
-github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
-github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
-github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
-github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
-github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw=
-github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=
-github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk=
-github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw=
-github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
-github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
-github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
-github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=
-github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
-github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
-github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
-github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI=
-github.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY=
-github.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI=
-github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
-github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
-github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
-github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
-github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
-github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
-github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
-github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
-github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
-github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
-github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
-github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
-github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
-github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
-github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
-github.com/miekg/dns v1.1.25 h1:dFwPR6SfLtrSwgDcIq2bcU/gVutB4sNApq2HBdqcakg=
-github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
-github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
-github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
-github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
-github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
-github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4=
-github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE=
-github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
-github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
-github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
-github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
-github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
-github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
-github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
-github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78=
-github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
-github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
-github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
-github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
-github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
-github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
-github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
-github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
-github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
-github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
-github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
-github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
-github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
-github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
-github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
-github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
-github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
-github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
-github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI=
-github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8=
-github.com/openshift-psap/special-resource-operator v0.0.0-20220818111522-5e97683a2041 h1:7Hrj7tgy1phUDhXYHgzvEbwC88OAhxvuMVOwjZGTiLg=
-github.com/openshift-psap/special-resource-operator v0.0.0-20220818111522-5e97683a2041/go.mod h1:SLNy0FiA4IEd9YTCIDnydsyIV7BBKzK5D+KZuoTfyc0=
-github.com/openshift/api v0.0.0-20231128111040-e1845c5a7acd h1:bkX3IPDizf3+oYTIn10KbSIHTCsns1Ov6Ilv86Vm+Yc=
-github.com/openshift/api v0.0.0-20231128111040-e1845c5a7acd/go.mod h1:qNtV0315F+f8ld52TLtPvrfivZpdimOzTi3kn9IVbtU=
-github.com/openshift/client-go v0.0.0-20231121143148-910ca30a1a9a h1:4FVrw8hz0Wb3izbf6JfOEK+pJTYpEvteRR73mCh2g/A=
-github.com/openshift/client-go v0.0.0-20231121143148-910ca30a1a9a/go.mod h1:arApQobmOjZqtxw44TwnQdUCH+t9DgZ8geYPFqksHws=
-github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
-github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
-github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI=
-github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
-github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY=
-github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
-github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
-github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
-github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8=
-github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc=
-github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
-github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
-github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
-github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
-github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
-github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY=
-github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY=
-github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
-github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
-github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
-github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg=
-github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
-github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
-github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8=
-github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
-github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
-github.com/rubenv/sql-migrate v1.5.2 h1:bMDqOnrJVV/6JQgQ/MxOpU+AdO8uzYYA/TxFUBzFtS0=
-github.com/rubenv/sql-migrate v1.5.2/go.mod h1:H38GW8Vqf8F0Su5XignRyaRcbXbJunSWxs+kmzlg0Is=
-github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
-github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
-github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
-github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
-github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
-github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
-github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
-github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
-github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
-github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
-github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
-github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
-github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
-github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
-github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
-github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
-github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
-github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
-github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
-github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
-github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
-github.com/urfave/cli/v2 v2.26.0 h1:3f3AMg3HpThFNT4I++TKOejZO8yU55t3JnnSr4S4QEI=
-github.com/urfave/cli/v2 v2.26.0/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
-github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
-github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
-github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
-github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
-github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
-github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
-github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
-github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ=
-github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
-github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
-github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
-github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
-github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
-github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI=
-github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMztlGpl/VA+Zm1AcTPHYkHJPbHqE6WJUXE=
-github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY=
-go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
-go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM=
-go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU=
-go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M=
-go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8=
-go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY=
-go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds=
-go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
-go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
-go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
-go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
-go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
-go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
-go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
-go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c=
-go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk=
-golang.design/x/lockfree v0.0.1 h1:IHFNwZgM5bnZYWkEbzn5lWHMYr8WsRBdCJ/RBVY0xMM=
-golang.design/x/lockfree v0.0.1/go.mod h1:iaZUx6UgZaOdePjzI6wFd+seYMl1i0rsG8+xKvA8c4I=
-golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
-golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
-golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
-golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
-golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
-golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
-golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
-golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
-golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
-golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
-golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
-golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
-golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
-golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
-golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8=
-golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE=
-golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
-golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
-golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
-golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
-golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8=
-golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
-golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
-golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
-golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
-golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
-golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8=
-golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk=
-golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
-gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
-google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
-google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
-google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
-google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
-google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 h1:0nDDozoAU19Qb2HwhXadU8OcsiO/09cnTqhUtq2MEOM=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
-google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
-google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
-google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc=
-google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
-google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
-google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
-google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
-google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
-google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
-google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
-google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
-google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
-google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
-gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
-gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
-gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
-gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
-gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
-gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
-gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o=
-helm.sh/helm/v3 v3.13.2 h1:IcO9NgmmpetJODLZhR3f3q+6zzyXVKlRizKFwbi7K8w=
-helm.sh/helm/v3 v3.13.2/go.mod h1:GIHDwZggaTGbedevTlrQ6DB++LBN6yuQdeGj0HNaDx0=
-honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-k8s.io/api v0.28.4 h1:8ZBrLjwosLl/NYgv1P7EQLqoO8MGQApnbgH8tu3BMzY=
-k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0=
-k8s.io/apiextensions-apiserver v0.28.3 h1:Od7DEnhXHnHPZG+W9I97/fSQkVpVPQx2diy+2EtmY08=
-k8s.io/apiextensions-apiserver v0.28.3/go.mod h1:NE1XJZ4On0hS11aWWJUTNkmVB03j9LM7gJSisbRt8Lc=
-k8s.io/apimachinery v0.28.4 h1:zOSJe1mc+GxuMnFzD4Z/U1wst50X28ZNsn5bhgIIao8=
-k8s.io/apimachinery v0.28.4/go.mod h1:wI37ncBvfAoswfq626yPTe6Bz1c22L7uaJ8dho83mgg=
-k8s.io/apiserver v0.28.3 h1:8Ov47O1cMyeDzTXz0rwcfIIGAP/dP7L8rWbEljRcg5w=
-k8s.io/apiserver v0.28.3/go.mod h1:YIpM+9wngNAv8Ctt0rHG4vQuX/I5rvkEMtZtsxW2rNM=
-k8s.io/cli-runtime v0.28.4 h1:IW3aqSNFXiGDllJF4KVYM90YX4cXPGxuCxCVqCD8X+Q=
-k8s.io/cli-runtime v0.28.4/go.mod h1:MLGRB7LWTIYyYR3d/DOgtUC8ihsAPA3P8K8FDNIqJ0k=
-k8s.io/client-go v0.28.4 h1:Np5ocjlZcTrkyRJ3+T3PkXDpe4UpatQxj85+xjaD2wY=
-k8s.io/client-go v0.28.4/go.mod h1:0VDZFpgoZfelyP5Wqu0/r/TRYcLYuJ2U1KEeoaPa1N4=
-k8s.io/component-base v0.28.4 h1:c/iQLWPdUgI90O+T9TeECg8o7N3YJTiuz2sKxILYcYo=
-k8s.io/component-base v0.28.4/go.mod h1:m9hR0uvqXDybiGL2nf/3Lf0MerAfQXzkfWhUY58JUbU=
-k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
-k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
-k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ=
-k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM=
-k8s.io/kubectl v0.28.4 h1:gWpUXW/T7aFne+rchYeHkyB8eVDl5UZce8G4X//kjUQ=
-k8s.io/kubectl v0.28.4/go.mod h1:CKOccVx3l+3MmDbkXtIUtibq93nN2hkDR99XDCn7c/c=
-k8s.io/utils v0.0.0-20230505201702-9f6742963106 h1:EObNQ3TW2D+WptiYXlApGNLVy0zm/JIBVY9i+M4wpAU=
-k8s.io/utils v0.0.0-20230505201702-9f6742963106/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
-oras.land/oras-go v1.2.4 h1:djpBY2/2Cs1PV87GSJlxv4voajVOMZxqqtq9AB8YNvY=
-oras.land/oras-go v1.2.4/go.mod h1:DYcGfb3YF1nKjcezfX2SNlDAeQFKSXmf+qrFmrh4324=
-sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4=
-sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0=
-sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
-sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
-sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 h1:XX3Ajgzov2RKUdc5jW3t5jwY7Bo7dcRm+tFxT+NfgY0=
-sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3/go.mod h1:9n16EZKMhXBNSiUC5kSdFQJkdH3zbxS/JoO619G1VAY=
-sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 h1:W6cLQc5pnqM7vh3b7HvGNfXrJ/xL6BDMS0v1V/HHg5U=
-sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3/go.mod h1:JWP1Fj0VWGHyw3YUPjXSQnRnrwezrZSrApfX5S0nIag=
-sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
-sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
-sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
-sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
diff --git a/deploy/k8s-operator/kube-trailblazer/hack/boilerplate.go.txt b/deploy/k8s-operator/kube-trailblazer/hack/boilerplate.go.txt
deleted file mode 100644
index 65b862271..000000000
--- a/deploy/k8s-operator/kube-trailblazer/hack/boilerplate.go.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
-Copyright 2023.
-
-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.
-*/
\ No newline at end of file
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/global-values.yaml b/deploy/k8s-operator/kube-trailblazer/helm-charts/global-values.yaml
deleted file mode 100644
index e69de29bb..000000000
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/.helmignore b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/.helmignore
deleted file mode 100644
index 0e8a0eb36..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/.helmignore
+++ /dev/null
@@ -1,23 +0,0 @@
-# Patterns to ignore when building packages.
-# This supports shell glob matching, relative path matching, and
-# negation (prefixed with !). Only one pattern per line.
-.DS_Store
-# Common VCS dirs
-.git/
-.gitignore
-.bzr/
-.bzrignore
-.hg/
-.hgignore
-.svn/
-# Common backup files
-*.swp
-*.bak
-*.tmp
-*.orig
-*~
-# Various IDEs
-.project
-.idea/
-*.tmproj
-.vscode/
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/Chart.yaml b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/Chart.yaml
deleted file mode 100644
index 1dea245bb..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/Chart.yaml
+++ /dev/null
@@ -1,24 +0,0 @@
-apiVersion: v2
-name: developer-llm-operator
-description: A Helm chart for Kubernetes
-
-# A chart can be either an 'application' or a 'library' chart.
-#
-# Application charts are a collection of templates that can be packaged into versioned archives
-# to be deployed.
-#
-# Library charts provide useful utilities or functions for the chart developer. They're included as
-# a dependency of application charts to inject those utilities and functions into the rendering
-# pipeline. Library charts do not define any templates and therefore cannot be deployed.
-type: application
-
-# This is the chart version. This version number should be incremented each time you make changes
-# to the chart and its templates, including the app version.
-# Versions are expected to follow Semantic Versioning (https://semver.org/)
-version: 0.1.0
-
-# This is the version number of the application being deployed. This version number should be
-# incremented each time you make changes to the application. Versions are not expected to
-# follow Semantic Versioning. They should reflect the version the application is using.
-# It is recommended to use it with quotes.
-appVersion: "0.1.0"
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0001_operator_manifests.yaml b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0001_operator_manifests.yaml
deleted file mode 100644
index 6b945d8a2..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0001_operator_manifests.yaml
+++ /dev/null
@@ -1,201 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
- annotations:
- controller-gen.kubebuilder.io/version: v0.11.1
- creationTimestamp: null
- name: helmpipelines.package.nvidia.com
-spec:
- group: package.nvidia.com
- names:
- kind: HelmPipeline
- listKind: HelmPipelineList
- plural: helmpipelines
- singular: helmpipeline
- scope: Namespaced
- versions:
- - name: v1alpha1
- schema:
- openAPIV3Schema:
- description: HelmPipeline is the Schema for the helmpipelines API
- properties:
- apiVersion:
- description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
- type: string
- kind:
- description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
- type: string
- metadata:
- type: object
- spec:
- description: HelmPipelineSpec defines the desired state of HelmPipeline
- properties:
- managementState:
- pattern: ^(Managed|Unmanaged|Force|Removed)$
- type: string
- pipeline:
- description: 'Orchard: A planned and managed group of Helm trees.'
- items:
- description: A shelter of vines or branches or of latticework covered with climbing shrubs or vines, also latin for tree
- properties:
- chartSpec:
- properties:
- atomic:
- description: Atomic indicates whether to install resources atomically. 'Wait' will automatically be set to true when using Atomic.
- type: boolean
- chart:
- type: string
- cleanupOnFail:
- description: CleanupOnFail indicates whether to cleanup the release on failure.
- type: boolean
- createNamespace:
- description: CreateNamespace indicates whether to create the namespace if it does not exist.
- type: boolean
- dependencyUpdate:
- description: DependencyUpdate indicates whether to update the chart release if the dependencies have changed.
- type: boolean
- description:
- description: Description specifies a custom description for the uninstalled release
- type: string
- disableHooks:
- description: DisableHooks indicates whether to disable hooks.
- type: boolean
- dryRun:
- description: DryRun indicates whether to perform a dry run.
- type: boolean
- force:
- description: Force indicates whether to force the operation.
- type: boolean
- generateName:
- description: GenerateName indicates that the release name should be generated.
- type: boolean
- keepHistory:
- description: KeepHistory indicates whether to retain or purge the release history during uninstall
- type: boolean
- maxHistory:
- description: MaxHistory limits the maximum number of revisions saved per release.
- type: integer
- nameTemplate:
- description: NameTemplate is the template used to generate the release name if GenerateName is configured.
- type: string
- namespace:
- description: Namespace where the chart release is deployed. Note that helmclient.Options.Namespace should ideally match the namespace configured here.
- type: string
- recreate:
- description: Recreate indicates whether to recreate the release if it already exists.
- type: boolean
- release:
- type: string
- replace:
- description: Replace indicates whether to replace the chart release if it already exists.
- type: boolean
- resetValues:
- description: ResetValues indicates whether to reset the values.yaml file during installation.
- type: boolean
- reuseValues:
- description: ReuseValues indicates whether to reuse the values.yaml file during installation.
- type: boolean
- skipCRDs:
- description: SkipCRDs indicates whether to skip CRDs during installation.
- type: boolean
- subNotes:
- description: SubNotes indicates whether to print sub-notes.
- type: boolean
- timeout:
- description: Timeout configures the time to wait for any individual Kubernetes operation (like Jobs for hooks).
- format: int64
- type: integer
- upgradeCRDs:
- description: Upgrade indicates whether to perform a CRD upgrade during installation.
- type: boolean
- valuesOptions:
- description: Specify values similar to the cli
- properties:
- JSONValues:
- items:
- type: string
- type: array
- fileValues:
- items:
- type: string
- type: array
- strinValues:
- items:
- type: string
- type: array
- valueFiles:
- items:
- type: string
- type: array
- values:
- items:
- type: string
- type: array
- required:
- - JSONValues
- - fileValues
- - strinValues
- - valueFiles
- - values
- type: object
- valuesYaml:
- description: ValuesYaml is the values.yaml content. use string instead of map[string]interface{} https://github.com/kubernetes-sigs/kubebuilder/issues/528#issuecomment-466449483 and https://github.com/kubernetes-sigs/controller-tools/pull/317
- type: string
- version:
- description: Version of the chart release.
- type: string
- wait:
- description: Wait indicates whether to wait for the release to be deployed or not.
- type: boolean
- waitForJobs:
- description: WaitForJobs indicates whether to wait for completion of release Jobs before marking the release as successful. 'Wait' has to be specified for this to take effect. The timeout may be specified via the 'Timeout' field.
- type: boolean
- required:
- - chart
- type: object
- chartValues:
- description: TODO ChartValues json.RawMessage `json:"chartValues"`
- type: object
- x-kubernetes-preserve-unknown-fields: true
- releaseName:
- type: string
- repoEntry:
- description: Entry represents a collection of parameters for chart repository, since we cannot annotate the internal helm struct we're doing it here
- properties:
- caFile:
- type: string
- certFile:
- type: string
- insecure_skip_tls_verify:
- type: boolean
- keyFile:
- type: string
- name:
- type: string
- pass_credentials_all:
- type: boolean
- password:
- type: string
- url:
- type: string
- username:
- type: string
- required:
- - url
- type: object
- required:
- - chartSpec
- - repoEntry
- type: object
- type: array
- required:
- - pipeline
- type: object
- status:
- description: HelmPipelineStatus defines the observed state of HelmPipeline
- type: object
- type: object
- served: true
- storage: true
- subresources:
- status: {}
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0002_operator_manifests.yaml b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0002_operator_manifests.yaml
deleted file mode 100644
index 88ed3ac36..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0002_operator_manifests.yaml
+++ /dev/null
@@ -1,12 +0,0 @@
-apiVersion: v1
-kind: ServiceAccount
-metadata:
- labels:
- app.kubernetes.io/component: rbac
- app.kubernetes.io/created-by: kube-trailblazer
- app.kubernetes.io/instance: controller-manager
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: serviceaccount
- app.kubernetes.io/part-of: kube-trailblazer
- name: kube-trailblazer-controller-manager
- namespace: {{ .Release.Namespace }}
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0003_operator_manifests.yaml b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0003_operator_manifests.yaml
deleted file mode 100644
index 6080cb991..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0003_operator_manifests.yaml
+++ /dev/null
@@ -1,44 +0,0 @@
-apiVersion: rbac.authorization.k8s.io/v1
-kind: Role
-metadata:
- labels:
- app.kubernetes.io/component: rbac
- app.kubernetes.io/created-by: kube-trailblazer
- app.kubernetes.io/instance: leader-election-role
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: role
- app.kubernetes.io/part-of: kube-trailblazer
- name: kube-trailblazer-leader-election-role
- namespace: kube-trailblazer-system
-rules:
-- apiGroups:
- - ""
- resources:
- - configmaps
- verbs:
- - get
- - list
- - watch
- - create
- - update
- - patch
- - delete
-- apiGroups:
- - coordination.k8s.io
- resources:
- - leases
- verbs:
- - get
- - list
- - watch
- - create
- - update
- - patch
- - delete
-- apiGroups:
- - ""
- resources:
- - events
- verbs:
- - create
- - patch
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0004_operator_manifests.yaml b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0004_operator_manifests.yaml
deleted file mode 100644
index 6a8509e5d..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0004_operator_manifests.yaml
+++ /dev/null
@@ -1,1227 +0,0 @@
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- creationTimestamp: null
- name: kube-trailblazer-manager-role
-rules:
-- apiGroups:
- - ""
- resources:
- - nodes/finalizers
- verbs:
- - update
-- apiGroups:
- - ""
- resources:
- - nodes/proxy
- verbs:
- - get
-- apiGroups:
- - ""
- resources:
- - nodes/status
- verbs:
- - get
- - list
- - patch
- - update
-- apiGroups:
- - ""
- resources:
- - pods
- verbs:
- - deletecollection
-- apiGroups:
- - ""
- resources:
- - podtemplates
- verbs:
- - create
- - get
- - list
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - podtemplates/finalizers
- verbs:
- - update
-- apiGroups:
- - '*'
- resources:
- - cronjobs
- verbs:
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - '*'
- resources:
- - daemonsets
- verbs:
- - get
-- apiGroups:
- - '*'
- resources:
- - deployments
- verbs:
- - get
-- apiGroups:
- - '*'
- resources:
- - imagepolicies
- verbs:
- - delete
- - get
- - update
-- apiGroups:
- - '*'
- resources:
- - jobs
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - '*'
- resources:
- - mutatingwebhookconfigurations
- verbs:
- - get
-- apiGroups:
- - '*'
- resources:
- - pods
- verbs:
- - get
-- apiGroups:
- - '*'
- resources:
- - replicacontrollers
- verbs:
- - get
-- apiGroups:
- - '*'
- resources:
- - replicasets
- verbs:
- - get
-- apiGroups:
- - '*'
- resources:
- - statefulsets
- verbs:
- - get
-- apiGroups:
- - acme.cert-manager.io
- resources:
- - challenges
- verbs:
- - create
- - delete
- - deletecollection
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - acme.cert-manager.io
- resources:
- - challenges/finalizers
- verbs:
- - update
-- apiGroups:
- - acme.cert-manager.io
- resources:
- - challenges/status
- verbs:
- - update
-- apiGroups:
- - acme.cert-manager.io
- resources:
- - orders
- verbs:
- - create
- - delete
- - deletecollection
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - acme.cert-manager.io
- resources:
- - orders/finalizers
- verbs:
- - update
-- apiGroups:
- - acme.cert-manager.io
- resources:
- - orders/status
- verbs:
- - update
-- apiGroups:
- - admissionregistration.k8s.io
- resources:
- - mutatingwebhookconfigurations
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - admissionregistration.k8s.io
- resources:
- - validatingwebhookconfigurations
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - admissionregistration.k8s.io/v1beta1
- resources:
- - mutatingwebhookconfigurations
- verbs:
- - create
- - delete
- - list
- - update
-- apiGroups:
- - apiextensions.k8s.io
- resources:
- - customresourcedefinitions
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - apiregistration.k8s.io
- resources:
- - apiservices
- verbs:
- - get
- - list
- - update
- - watch
-- apiGroups:
- - apps
- resources:
- - daemonsets
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - apps
- resources:
- - deployments
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - apps
- resourceNames:
- - shipwright-build
- resources:
- - deployments/finalizers
- verbs:
- - update
-- apiGroups:
- - apps
- resources:
- - replicasets
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - apps
- resources:
- - statefulsets
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - auditregistration.k8s.io
- resources:
- - auditsinks
- verbs:
- - get
- - list
- - update
- - watch
-- apiGroups:
- - batch
- resources:
- - jobs
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - batch
- resources:
- - jobs/finalizers
- verbs:
- - update
-- apiGroups:
- - build.openshift.io
- resources:
- - buildconfigs
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - build.openshift.io
- resources:
- - builds
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - cert-manager.io
- resources:
- - certificaterequests
- verbs:
- - create
- - delete
- - deletecollection
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - cert-manager.io
- resources:
- - certificaterequests/finalizers
- verbs:
- - update
-- apiGroups:
- - cert-manager.io
- resources:
- - certificaterequests/status
- verbs:
- - update
-- apiGroups:
- - cert-manager.io
- resources:
- - certificates
- verbs:
- - create
- - delete
- - deletecollection
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - cert-manager.io
- resources:
- - certificates/finalizers
- verbs:
- - update
-- apiGroups:
- - cert-manager.io
- resources:
- - certificates/status
- verbs:
- - update
-- apiGroups:
- - cert-manager.io
- resources:
- - clusterissuers
- verbs:
- - deletecollection
- - get
- - list
- - update
- - watch
-- apiGroups:
- - cert-manager.io
- resources:
- - clusterissuers/status
- verbs:
- - update
-- apiGroups:
- - cert-manager.io
- resources:
- - issuers
- verbs:
- - create
- - delete
- - deletecollection
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - cert-manager.io
- resources:
- - issuers/status
- verbs:
- - update
-- apiGroups:
- - cert-manager.io
- resourceNames:
- - clusterissuers.cert-manager.io/*
- resources:
- - signers
- verbs:
- - approve
-- apiGroups:
- - cert-manager.io
- resourceNames:
- - issuers.cert-manager.io/*
- resources:
- - signers
- verbs:
- - approve
-- apiGroups:
- - certificates.k8s.io
- resources:
- - certificatesigningrequests
- verbs:
- - get
- - list
- - update
- - watch
-- apiGroups:
- - certificates.k8s.io
- resources:
- - certificatesigningrequests/status
- verbs:
- - update
-- apiGroups:
- - certificates.k8s.io
- resourceNames:
- - clusterissuers.cert-manager.io/*
- resources:
- - signers
- verbs:
- - sign
-- apiGroups:
- - certificates.k8s.io
- resourceNames:
- - issuers.cert-manager.io/*
- resources:
- - signers
- verbs:
- - sign
-- apiGroups:
- - config.openshift.io
- resources:
- - clusterversions
- verbs:
- - get
-- apiGroups:
- - config.openshift.io
- resources:
- - proxies
- verbs:
- - get
- - list
-- apiGroups:
- - connaisseur.policy
- resources:
- - imagepolicies
- verbs:
- - create
-- apiGroups:
- - coordination.k8s.io
- resources:
- - leases
- verbs:
- - create
- - delete
- - get
- - list
- - update
- - watch
-- apiGroups:
- - coordination.k8s.io
- resourceNames:
- - cert-manager-cainjector-election-core
- resources:
- - leases
- verbs:
- - patch
-- apiGroups:
- - coordination.k8s.io
- resourceNames:
- - cert-manager-cainjector-leader-election
- resources:
- - leases
- verbs:
- - patch
-- apiGroups:
- - coordination.k8s.io
- resourceNames:
- - cert-manager-cainjector-leader-election-core
- resources:
- - leases
- verbs:
- - patch
-- apiGroups:
- - coordination.k8s.io
- resourceNames:
- - cert-manager-controller
- resources:
- - leases
- verbs:
- - patch
-- apiGroups:
- - ""
- resources:
- - configmaps
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - endpoints
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - events
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - imagestreams/layers
- verbs:
- - get
-- apiGroups:
- - ""
- resources:
- - namespaces
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - nodes
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - persistentvolumeclaims
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - persistentvolumeclaims/status
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - persistentvolumes
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - pods
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - pods/log
- verbs:
- - get
-- apiGroups:
- - ""
- resources:
- - secrets
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - serviceaccounts
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - services
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - ""
- resources:
- - services/finalizers
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - csi.storage.k8s.io
- resources:
- - csidrivers
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - extensions
- resources:
- - jobs
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - fpga.silicom.dk
- resources:
- - '*'
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - image.openshift.io
- resources:
- - imagestreams
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - image.openshift.io
- resources:
- - imagestreams/finalizers
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - image.openshift.io
- resources:
- - imagestreams/layers
- verbs:
- - get
-- apiGroups:
- - infoscale.veritas.com
- resources:
- - infoscaleclusters
- verbs:
- - get
- - list
- - patch
- - update
-- apiGroups:
- - monitoring.coreos.com
- resources:
- - prometheusrules
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - monitoring.coreos.com
- resources:
- - servicemonitors
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - networking.k8s.io
- resources:
- - clustercidrs
- verbs:
- - list
- - watch
-- apiGroups:
- - networking.k8s.io
- resources:
- - ingresses
- verbs:
- - create
- - delete
- - get
- - list
- - update
- - watch
-- apiGroups:
- - networking.k8s.io
- resources:
- - ingresses/finalizers
- verbs:
- - update
-- apiGroups:
- - networking.x-k8s.io
- resources:
- - gateways
- verbs:
- - get
- - list
- - watch
-- apiGroups:
- - networking.x-k8s.io
- resources:
- - gateways/finalizers
- verbs:
- - update
-- apiGroups:
- - networking.x-k8s.io
- resources:
- - httproutes
- verbs:
- - create
- - delete
- - get
- - list
- - update
- - watch
-- apiGroups:
- - networking.x-k8s.io
- resources:
- - httproutes/finalisers
- verbs:
- - update
-- apiGroups:
- - nfd.k8s-sigs.io
- resources:
- - nodefeaturerules
- verbs:
- - get
- - list
- - watch
-- apiGroups:
- - nfd.k8s-sigs.io
- resources:
- - nodefeatures
- verbs:
- - create
- - delete
- - get
- - list
- - update
- - watch
-- apiGroups:
- - nvidia.com
- resources:
- - clusterpolicies
- verbs:
- - get
- - list
- - patch
- - watch
-- apiGroups:
- - operator.cert-manager.io
- resources:
- - certmanagers
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - operators.coreos.com
- resources:
- - operatorgroups
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - operators.coreos.com
- resources:
- - subscriptions
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - package.nvidia.com
- resources:
- - helmpipelines
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - package.nvidia.com
- resources:
- - helmpipelines/finalizers
- verbs:
- - update
-- apiGroups:
- - package.nvidia.com
- resources:
- - helmpipelines/status
- verbs:
- - get
- - patch
- - update
-- apiGroups:
- - rbac.authorization.k8s.io
- resources:
- - clusterrolebindings
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - rbac.authorization.k8s.io
- resources:
- - clusterroles
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - rbac.authorization.k8s.io
- resources:
- - rolebindings
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - rbac.authorization.k8s.io
- resources:
- - roles
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - route.openshift.io
- resources:
- - routes
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - route.openshift.io
- resources:
- - routes/custom-host
- verbs:
- - create
-- apiGroups:
- - security.openshift.io
- resources:
- - securitycontextconstraints
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - use
- - watch
-- apiGroups:
- - shipwright.io
- resources:
- - '*'
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - shipwright.io
- resources:
- - buildruns
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - shipwright.io
- resources:
- - buildstrategies
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - shipwright.io
- resources:
- - clusterbuildstrategies
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - snapshot.storage.k8s.io
- resources:
- - volumesnapshotclasses
- verbs:
- - get
- - list
- - watch
-- apiGroups:
- - snapshot.storage.k8s.io
- resources:
- - volumesnapshotcontents
- verbs:
- - create
- - delete
- - get
- - list
- - update
- - watch
-- apiGroups:
- - snapshot.storage.k8s.io
- resources:
- - volumesnapshotcontents/status
- verbs:
- - create
- - delete
- - get
- - list
- - update
- - watch
-- apiGroups:
- - snapshot.storage.k8s.io
- resources:
- - volumesnapshots
- verbs:
- - get
- - list
- - update
- - watch
-- apiGroups:
- - snapshot.storage.k8s.io
- resources:
- - volumesnapshots/status
- verbs:
- - create
- - delete
- - get
- - list
- - update
- - watch
-- apiGroups:
- - sro.openshift.io
- resources:
- - specialresources
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - sro.openshift.io
- resources:
- - specialresources/finalizers
- verbs:
- - get
- - patch
- - update
-- apiGroups:
- - sro.openshift.io
- resources:
- - specialresources/status
- verbs:
- - get
- - patch
- - update
-- apiGroups:
- - storage.k8s.io
- resources:
- - csidrivers
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - storage.k8s.io
- resources:
- - csinodes
- verbs:
- - get
- - list
- - watch
-- apiGroups:
- - storage.k8s.io
- resources:
- - storageclasses
- verbs:
- - get
- - list
- - watch
-- apiGroups:
- - storage.k8s.io
- resources:
- - volumeattachments
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - sts.silicom.com
- resources:
- - '*'
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - tekton.dev
- resources:
- - taskruns
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - tekton.dev
- resources:
- - tasks
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - topology.node.k8s.io
- resources:
- - noderesourcetopologies
- verbs:
- - delete
- - list
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0005_operator_manifests.yaml b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0005_operator_manifests.yaml
deleted file mode 100644
index c66e93e3f..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0005_operator_manifests.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- labels:
- app.kubernetes.io/component: kube-rbac-proxy
- app.kubernetes.io/created-by: kube-trailblazer
- app.kubernetes.io/instance: metrics-reader
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: clusterrole
- app.kubernetes.io/part-of: kube-trailblazer
- name: kube-trailblazer-metrics-reader
-rules:
-- nonResourceURLs:
- - /metrics
- verbs:
- - get
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0006_operator_manifests.yaml b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0006_operator_manifests.yaml
deleted file mode 100644
index 238d975f5..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0006_operator_manifests.yaml
+++ /dev/null
@@ -1,24 +0,0 @@
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- labels:
- app.kubernetes.io/component: kube-rbac-proxy
- app.kubernetes.io/created-by: kube-trailblazer
- app.kubernetes.io/instance: proxy-role
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: clusterrole
- app.kubernetes.io/part-of: kube-trailblazer
- name: kube-trailblazer-proxy-role
-rules:
-- apiGroups:
- - authentication.k8s.io
- resources:
- - tokenreviews
- verbs:
- - create
-- apiGroups:
- - authorization.k8s.io
- resources:
- - subjectaccessreviews
- verbs:
- - create
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0007_operator_manifests.yaml b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0007_operator_manifests.yaml
deleted file mode 100644
index 09bc970a4..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0007_operator_manifests.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-apiVersion: rbac.authorization.k8s.io/v1
-kind: RoleBinding
-metadata:
- labels:
- app.kubernetes.io/component: rbac
- app.kubernetes.io/created-by: kube-trailblazer
- app.kubernetes.io/instance: leader-election-rolebinding
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: rolebinding
- app.kubernetes.io/part-of: kube-trailblazer
- name: kube-trailblazer-leader-election-rolebinding
- namespace: {{ .Release.Namespace }}
-roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: Role
- name: kube-trailblazer-leader-election-role
-subjects:
-- kind: ServiceAccount
- name: kube-trailblazer-controller-manager
- namespace: {{ .Release.Namespace }}
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0008_operator_manifests.yaml b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0008_operator_manifests.yaml
deleted file mode 100644
index 2fd15af61..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0008_operator_manifests.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
-metadata:
- labels:
- app.kubernetes.io/component: rbac
- app.kubernetes.io/created-by: kube-trailblazer
- app.kubernetes.io/instance: manager-rolebinding
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: clusterrolebinding
- app.kubernetes.io/part-of: kube-trailblazer
- name: kube-trailblazer-manager-rolebinding
-roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: ClusterRole
- name: kube-trailblazer-manager-role
-subjects:
-- kind: ServiceAccount
- name: kube-trailblazer-controller-manager
- namespace: {{ .Release.Namespace }}
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0009_operator_manifests.yaml b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0009_operator_manifests.yaml
deleted file mode 100644
index 083907701..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0009_operator_manifests.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
-metadata:
- labels:
- app.kubernetes.io/component: kube-rbac-proxy
- app.kubernetes.io/created-by: kube-trailblazer
- app.kubernetes.io/instance: proxy-rolebinding
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: clusterrolebinding
- app.kubernetes.io/part-of: kube-trailblazer
- name: kube-trailblazer-proxy-rolebinding
-roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: ClusterRole
- name: kube-trailblazer-proxy-role
-subjects:
-- kind: ServiceAccount
- name: kube-trailblazer-controller-manager
- namespace: {{ .Release.Namespace }}
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0010_operator_manifests.yaml b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0010_operator_manifests.yaml
deleted file mode 100644
index b8c0afb53..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0010_operator_manifests.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-apiVersion: v1
-kind: Service
-metadata:
- labels:
- app.kubernetes.io/component: kube-rbac-proxy
- app.kubernetes.io/created-by: kube-trailblazer
- app.kubernetes.io/instance: controller-manager-metrics-service
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: service
- app.kubernetes.io/part-of: kube-trailblazer
- control-plane: controller-manager
- name: kube-trailblazer-controller-manager-metrics-service
- namespace: {{ .Release.Namespace }}
-spec:
- ports:
- - name: https
- port: 8443
- protocol: TCP
- targetPort: https
- selector:
- control-plane: controller-manager
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0011_operator_manifests.yaml b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0011_operator_manifests.yaml
deleted file mode 100644
index 6541ce594..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/0011_operator_manifests.yaml
+++ /dev/null
@@ -1,106 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- labels:
- app.kubernetes.io/component: manager
- app.kubernetes.io/created-by: kube-trailblazer
- app.kubernetes.io/instance: controller-manager
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: deployment
- app.kubernetes.io/part-of: kube-trailblazer
- control-plane: controller-manager
- name: kube-trailblazer-controller-manager
- namespace: {{ .Release.Namespace }}
-spec:
- replicas: 1
- selector:
- matchLabels:
- control-plane: controller-manager
- template:
- metadata:
- annotations:
- kubectl.kubernetes.io/default-container: manager
- labels:
- control-plane: controller-manager
- spec:
- affinity:
- nodeAffinity:
- requiredDuringSchedulingIgnoredDuringExecution:
- nodeSelectorTerms:
- - matchExpressions:
- - key: kubernetes.io/arch
- operator: In
- values:
- - amd64
- - arm64
- - ppc64le
- - s390x
- - key: kubernetes.io/os
- operator: In
- values:
- - linux
- containers:
- - args:
- - --secure-listen-address=0.0.0.0:8443
- - --upstream=http://127.0.0.1:8080/
- - --logtostderr=true
- - --v=0
- image: gcr.io/kubebuilder/kube-rbac-proxy:v0.13.1
- name: kube-rbac-proxy
- ports:
- - containerPort: 8443
- name: https
- protocol: TCP
- resources:
- limits:
- cpu: 500m
- memory: 128Mi
- requests:
- cpu: 5m
- memory: 64Mi
- securityContext:
- allowPrivilegeEscalation: false
- capabilities:
- drop:
- - ALL
- - args:
- - --health-probe-bind-address=:8081
- - --metrics-bind-address=127.0.0.1:8080
- - --leader-elect
- command:
- - /manager
- image: {{ include "developer-llm-operator.fullimage" . }}
- imagePullPolicy: {{ .Values.images.imagePullPolicy }}
- livenessProbe:
- httpGet:
- path: /healthz
- port: 8081
- initialDelaySeconds: 15
- periodSeconds: 20
- name: manager
- readinessProbe:
- httpGet:
- path: /readyz
- port: 8081
- initialDelaySeconds: 5
- periodSeconds: 10
- resources:
- limits:
- cpu: 500m
- memory: 512Mi
- requests:
- cpu: 100m
- memory: 128Mi
- securityContext:
- allowPrivilegeEscalation: false
- capabilities:
- drop:
- - ALL
- {{- if .Values.images.registry.imagePullSecret.name }}
- imagePullSecrets:
- - name: {{ .Values.images.registry.imagePullSecret.name }}
- {{- end }}
- securityContext:
- runAsNonRoot: true
- serviceAccountName: kube-trailblazer-controller-manager
- terminationGracePeriodSeconds: 10
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/_helpers.tpl b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/_helpers.tpl
deleted file mode 100644
index d49dd2982..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/_helpers.tpl
+++ /dev/null
@@ -1,17 +0,0 @@
-{{/*
-Create secret to access docker registry
-*/}}
-{{- define "imagePullSecret" }}
-{{- printf "{\"auths\": {\"%s\": {\"auth\": \"%s\"}}}" .Values.images.registry.name (printf "%s:%s" .Values.images.registry.imagePullSecret.username .Values.images.registry.imagePullSecret.password | b64enc) | b64enc }}
-{{- end }}
-
-{{/*
-Full image name with tag
-*/}}
-{{- define "developer-llm-operator.fullimage" -}}
-{{- if .Values.images.version }}
-{{- .Values.images.name -}}:{{- .Values.images.version -}}
-{{- else }}
-{{- .Values.images.name -}}:v{{- .Chart.AppVersion -}}
-{{- end }}
-{{- end }}
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/image-pull-secret.yaml b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/image-pull-secret.yaml
deleted file mode 100644
index e526dbe55..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/templates/image-pull-secret.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-{{ if and .Values.images.registry.imagePullSecret.name .Values.images.registry.imagePullSecret.create -}}
-apiVersion: v1
-kind: Secret
-metadata:
- name: {{ .Values.images.registry.imagePullSecret.name }}
- namespace: {{ .Release.Namespace }}
-type: kubernetes.io/dockerconfigjson
-data:
- .dockerconfigjson: {{ template "imagePullSecret" . }}
-{{- end }}
\ No newline at end of file
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/values.yaml b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/values.yaml
deleted file mode 100644
index 87b55d73b..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/developer-llm-operator/values.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
-images:
- # operator image name
- name: nvcr.io/nvidia/cloud-native/developer-llm-operator
- # operator image version. If empty then the chart's app-version is used as default
- version: ""
- imagePullPolicy: IfNotPresent
- # operator registry details for pull-secret
- registry:
- # The registry name must NOT contain a trailing slash
- name: nvcr.io
- imagePullSecret:
- # Leave blank, if no imagePullSecret is needed.
- name: ""
- # If set to false, the chart expects either a imagePullSecret
- # with the name configured above to be present on the cluster or that no
- # credentials are needed.
- create: true
- username: '$oauthtoken'
- password: ""
\ No newline at end of file
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/.helmignore b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/.helmignore
deleted file mode 100644
index 0e8a0eb36..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/.helmignore
+++ /dev/null
@@ -1,23 +0,0 @@
-# Patterns to ignore when building packages.
-# This supports shell glob matching, relative path matching, and
-# negation (prefixed with !). Only one pattern per line.
-.DS_Store
-# Common VCS dirs
-.git/
-.gitignore
-.bzr/
-.bzrignore
-.hg/
-.hgignore
-.svn/
-# Common backup files
-*.swp
-*.bak
-*.tmp
-*.orig
-*~
-# Various IDEs
-.project
-.idea/
-*.tmproj
-.vscode/
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/Chart.yaml b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/Chart.yaml
deleted file mode 100644
index b73ea5fe7..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/Chart.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-apiVersion: v2
-appVersion: 1.16.0
-description: A Helm chart for Kubernetes
-name: rag-llm-pipeline
-type: application
-version: 0.1.0
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/_helpers.tpl b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/_helpers.tpl
deleted file mode 100644
index 391efe261..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/_helpers.tpl
+++ /dev/null
@@ -1,6 +0,0 @@
-{{/*
-Create secret to access docker registry
-*/}}
-{{- define "imagePullSecret" }}
-{{- printf "{\"auths\": {\"%s\": {\"auth\": \"%s\"}}}" .Values.images.registry.name (printf "%s:%s" .Values.images.registry.ImagePullSecret.username .Values.images.registry.ImagePullSecret.password | b64enc) | b64enc }}
-{{- end }}
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/frontend.yaml b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/frontend.yaml
deleted file mode 100644
index bd1940def..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/frontend.yaml
+++ /dev/null
@@ -1,52 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: llm-playground
- labels:
- app.kubernetes.io/name: frontend
-spec:
- replicas: 1
- selector:
- matchLabels:
- app.kubernetes.io/name: frontend
- template:
- metadata:
- labels:
- app.kubernetes.io/name: frontend
- spec:
-
- imagePullSecrets:
- - name: nvcrio
- containers:
- - name: llm-playground
- imagePullPolicy: IfNotPresent
- image: {{ .Values.frontend.image }}
- command:
- - python3
- - -m
- - frontend
- - --port
- - "8090"
- env:
- - name: APP_MODELNAME
- value: {{ .Values.frontend.modelName }}
- - name: APP_SERVERPORT
- value: "8081"
- - name: APP_SERVERURL
- value: http://query
- ports:
- - containerPort: 8090
----
-apiVersion: v1
-kind: Service
-metadata:
- name: frontend-service
-spec:
- type: NodePort
- selector:
- app.kubernetes.io/name: frontend
- ports:
- - protocol: TCP
- port: 8090
- nodePort: 30001
-
\ No newline at end of file
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/image-pull-secret.yaml b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/image-pull-secret.yaml
deleted file mode 100644
index d1074724d..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/image-pull-secret.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-{{ if and .Values.images.registry.ImagePullSecret.name .Values.images.registry.ImagePullSecret.create -}}
-apiVersion: v1
-kind: Secret
-metadata:
- name: {{ .Values.images.registry.ImagePullSecret.name }}
-type: kubernetes.io/dockerconfigjson
-data:
- .dockerconfigjson: {{ template "imagePullSecret" . }}
-{{- end }}
\ No newline at end of file
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/jupyter-server.yaml b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/jupyter-server.yaml
deleted file mode 100644
index e2c71fea8..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/jupyter-server.yaml
+++ /dev/null
@@ -1,41 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: jupyter-notebook-server
- labels:
- app.kubernetes.io/name: jupyter-notebook-server
-spec:
- replicas: 1
- selector:
- matchLabels:
- app.kubernetes.io/name: jupyter-notebook-server
- template:
- metadata:
- labels:
- app.kubernetes.io/name: jupyter-notebook-server
- spec:
- imagePullSecrets:
- - name: nvcrio
- containers:
- - name: jupyter-notebook-server
- imagePullPolicy: IfNotPresent
- image: {{ .Values.jupyter.image }}
- ports:
- - containerPort: 8888
- resources:
- limits:
- {{ .Values.jupyter.gpu.type }}: {{ .Values.jupyter.gpu.count }}
----
-apiVersion: v1
-kind: Service
-metadata:
- name: jupyter-notebook-service
-spec:
- type: NodePort
-
- selector:
- app.kubernetes.io/name: jupyter-notebook-server
- ports:
- - protocol: TCP
- port: 8888
- nodePort: 30000
\ No newline at end of file
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/milvus-etcd.yaml b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/milvus-etcd.yaml
deleted file mode 100644
index dde20b762..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/milvus-etcd.yaml
+++ /dev/null
@@ -1,65 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: milvu-etcd
- labels:
- app.kubernetes.io/name: milvus-etcd
-spec:
- replicas: 1
- selector:
- matchLabels:
- app.kubernetes.io/name: milvus-etcd
- template:
- metadata:
- labels:
- app.kubernetes.io/name: milvus-etcd
- spec:
- containers:
- - name: milvus-etcd
- image: quay.io/coreos/etcd:v3.5.5
- command:
- - etcd
- - -advertise-client-urls=http://127.0.0.1:2379
- - -listen-client-urls
- - http://0.0.0.0:2379
- - --data-dir
- - /etcd
- env:
- - name: ETCD_AUTO_COMPACTION_MODE
- value: revision
- - name: ETCD_AUTO_COMPACTION_RETENTION
- value: "1000"
- - name: ETCD_QUOTA_BACKEND_BYTES
- value: "4294967296"
- - name: ETCD_SNAPSHOT_COUNT
- value: "50000"
- ports:
- - containerPort: 2379
- readinessProbe:
- exec:
- command:
- - etcdctl
- - endpoint
- - health
- initialDelaySeconds: 5
- periodSeconds: 5
- volumeMounts:
- - mountPath: /etcd
- name: etcd-data
- volumes:
- - name: etcd-data
- hostPath:
- path: /etcd
- type: DirectoryOrCreate
----
-apiVersion: v1
-kind: Service
-metadata:
- name: milvus-etcd
-spec:
- selector:
- app.kubernetes.io/name: milvus-etcd
- ports:
- - protocol: TCP
- port: 2379
- targetPort: 2379
\ No newline at end of file
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/milvus-minio.yaml b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/milvus-minio.yaml
deleted file mode 100644
index fc302398e..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/milvus-minio.yaml
+++ /dev/null
@@ -1,62 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: milvus-minio
- labels:
- app.kubernetes.io/name: milvus-minio
-spec:
- replicas: 1
- selector:
- matchLabels:
- app.kubernetes.io/name: milvus-minio
- template:
- metadata:
- labels:
- app.kubernetes.io/name: milvus-minio
- spec:
- containers:
- - name: milvus-minio
- image: minio/minio:RELEASE.2023-03-20T20-16-18Z
- command:
- - minio
- - server
- - /minio_data
- - --console-address
- - :9011
- env:
- - name: MINIO_ACCESS_KEY
- value: minioadmin
- - name: MINIO_SECRET_KEY
- value: minioadmin
- ports:
- - containerPort: 9011
- - containerPort: 9010
- volumeMounts:
- - mountPath: /minio_data
- name: minio-data
- readinessProbe:
- exec:
- command:
- - curl
- - -f
- - http://localhost:9010/minio/health/live
- initialDelaySeconds: 20
- periodSeconds: 5
- volumes:
- - name: minio-data
- hostPath:
- path: /minio_data
- type: DirectoryOrCreate
----
-apiVersion: v1
-kind: Service
-metadata:
- name: milvus-minio
-spec:
- selector:
- app.kubernetes.io/name: milvus-minio
- ports:
- - protocol: TCP
- port: 9010
- targetPort: 9010
-
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/milvus-standalone.yaml b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/milvus-standalone.yaml
deleted file mode 100644
index a52bd916a..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/milvus-standalone.yaml
+++ /dev/null
@@ -1,58 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: milvus-standalone
- labels:
- app.kubernetes.io/name: milvus-standalone
-spec:
- replicas: 1
- selector:
- matchLabels:
- app.kubernetes.io/name: milvus-standalone
- template:
- metadata:
- labels:
- app.kubernetes.io/name: milvus-standalone
- spec:
- containers:
- - name: milvus-standalone
- image: milvusdb/milvus:v2.3.1-gpu
- command:
- - /tini
- - --
- - milvus
- - run
- - standalone
- env:
- - name: ETCD_ENDPOINTS
- value: milvus-etcd:2379
- - name: KNOWHERE_GPU_MEM_POOL_SIZE
- value: 2048;4096
- - name: MINIO_ADDRESS
- value: milvus-minio:9010
- ports:
- - containerPort: 19530
- - containerPort: 9091
- readinessProbe:
- exec:
- command:
- - curl
- - -f
- - http://localhost:9091/healthz
- initialDelaySeconds: 20
- periodSeconds: 5
- resources:
- limits:
- {{ .Values.milvus.gpu.type }}: {{ .Values.milvus.gpu.count }}
----
-apiVersion: v1
-kind: Service
-metadata:
- name: milvus
-spec:
- selector:
- app.kubernetes.io/name: milvus-standalone
- ports:
- - protocol: TCP
- port: 19530
- targetPort: 19530
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/query.yaml b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/query.yaml
deleted file mode 100644
index d4ad9f3ca..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/query.yaml
+++ /dev/null
@@ -1,65 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: query-router
- labels:
- app.kubernetes.io/name: query-router
-spec:
- replicas: 1
- selector:
- matchLabels:
- app.kubernetes.io/name: query-router
- template:
- metadata:
- labels:
- app.kubernetes.io/name: query-router
- spec:
-
- imagePullSecrets:
- - name: nvcrio
- volumes:
- - name: dshm
- emptyDir:
- medium: Memory
- containers:
- - name: query-router
- imagePullPolicy: IfNotPresent
- image: {{ .Values.query.image }}
- command:
- - uvicorn
- - RetrievalAugmentedGeneration.common.server:app
- - --port
- - "8081"
- - --host
- - 0.0.0.0
- env:
- - name: APP_MILVUS_URL
- value: http://milvus:19530
- - name: APP_LLM_SERVERURL
- value: llm:8001
- - name: APP_LLM_MODELNAME
- value: ensemble
- - name: APP_LLM_MODELENGINE
- value: triton-trt-llm
-# - name: APP_CONFIG_FILE # THIS SHOULD BE A CONFIGMAP
-# value: ""
- ports:
- - containerPort: 8081
- volumeMounts:
- - mountPath: /dev/shm
- name: dshm
- resources:
- limits:
- {{ .Values.query.gpu.type }}: {{ .Values.query.gpu.count }}
----
-apiVersion: v1
-kind: Service
-metadata:
- name: query
-spec:
- selector:
- app.kubernetes.io/name: query-router
- ports:
- - protocol: TCP
- port: 8081
- targetPort: 8081
\ No newline at end of file
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/triton.yaml b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/triton.yaml
deleted file mode 100644
index 20b8ba57d..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/templates/triton.yaml
+++ /dev/null
@@ -1,86 +0,0 @@
-apiVersion: v1
-kind: ConfigMap
-metadata:
- name: triton-entrypoint
-data:
- entrypoint.sh: |-
- #!/bin/bash -x
- set -e
-
- rm -rf /usr/local/cuda-12.2/targets/x86_64-linux/lib/stubs/
- ldconfig
-
- /usr/bin/python3 -m model_server {{ .Values.triton.modelArchitecture | quote }} \
- --max-input-length {{ .Values.triton.modelMaxInputLength | quote}} \
- --max-output-length {{ .Values.triton.modelMaxOutputLength | quote}}
-
----
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: triton-inference-server
- labels:
- app.kubernetes.io/name: triton-inference-server
-spec:
- replicas: 1
- selector:
- matchLabels:
- app.kubernetes.io/name: triton-inference-server
- template:
- metadata:
- name: triton-inference-server
- labels:
- app.kubernetes.io/name: triton-inference-server
- spec:
- imagePullSecrets:
- - name: nvcrio
- containers:
- - name: triton-inference-server
- imagePullPolicy: IfNotPresent
- image: {{ .Values.triton.image }}
- command: [/bin/entrypoint.sh]
- ports:
- - containerPort: 8000
- - containerPort: 8001
- - containerPort: 8002
- readinessProbe:
- grpc:
- port: 8001
- initialDelaySeconds: 30
- periodSeconds: 10
- resources:
- limits:
- {{ .Values.triton.gpu.type }}: {{ .Values.triton.gpu.count }}
- volumeMounts:
- - mountPath: /model
- name: model
- - mountPath: /dev/shm
- name: dshm
- - name: entrypoint
- mountPath: /bin/entrypoint.sh
- readOnly: true
- subPath: entrypoint.sh
- volumes:
- - name: model
- hostPath:
- path: {{ .Values.triton.modelDirectory }}
- - name: dshm
- emptyDir:
- medium: Memory
- - name: entrypoint
- configMap:
- defaultMode: 0700
- name: triton-entrypoint
----
-apiVersion: v1
-kind: Service
-metadata:
- name: llm
-spec:
- selector:
- app.kubernetes.io/name: triton-inference-server
- ports:
- - protocol: TCP
- port: 8001
- targetPort: 8001
-
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/values.yaml b/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/values.yaml
deleted file mode 100644
index 8fa8abcf8..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-charts/staging/rag-llm-pipeline/values.yaml
+++ /dev/null
@@ -1,56 +0,0 @@
-# Default values for rag-llm-hackfest.
-# This is a YAML-formatted file.
-# Declare variables to be passed into your templates.
-triton:
- modelDirectory: "/zvonkok/model/llama2_13b_chat_hf_v1/"
- modelArchitecture: "llama"
- modelMaxInputLength: "3000"
- modelMaxOutputLength: "512"
- image: localhost:5000/llm-inference-server
- gpu:
- # MIG slice
- #type: "nvidia.com/mig-3g.40gb"
- # time-slice
- type: "nvidia.com/gpu"
- count: 1
-
-milvus:
- gpu:
- # MIG slice
- #type: "nvidia.com/mig-2g.20gb"
- type: "nvidia.com/gpu"
- count: 1
-
-jupyter:
- image: localhost:5000/notebook-server
- gpu:
- # MIG slice
- # type: "nvidia.com/mig-1g.10gb"
- type: "nvidia.com/gpu"
- count: 1
-
-query:
- image: localhost:5000/chain-server
- gpu:
- # MIG slice
- # type: "nvidia.com/mig-1g.10gb"
- type: "nvidia.com/gpu"
- count: 1
-
-frontend:
- image: localhost:5000/llm-playground
- modelName: "Llama-2-13b-chat-hf"
-
-images:
- registry:
- # The registry name must NOT contain a trailing slash
- name: nvcr.io
- ImagePullSecret:
- # Leave blank, if no ImagePullSecret is needed.
- name: nvcrio
- # If set to false, the chart expects either a ImagePullSecret
- # with the name configured above to be present on the cluster or that no
- # credentials are needed.
- create: false
- username: '$oauthtoken'
- password:
\ No newline at end of file
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-plugins/cm-getter/plugin.yaml b/deploy/k8s-operator/kube-trailblazer/helm-plugins/cm-getter/plugin.yaml
deleted file mode 100644
index 4b78c4dda..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-plugins/cm-getter/plugin.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-name: cm-getter
-version: 0.0.1
-description: cm:// Helm getter for ConfigMap charts
-downloaders:
-- command: cm-getter
- protocols: [cm, configmap]
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-plugins/file-getter/file-getter b/deploy/k8s-operator/kube-trailblazer/helm-plugins/file-getter/file-getter
deleted file mode 100755
index 216312d90..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-plugins/file-getter/file-getter
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/usr/bin/env bash
-
-# Last command-line argument is the URL of the resource
-readonly URL="${*: -1}"
-
-# Trim the scheme
-readonly FILE="${URL#file://}"
-
-cat "${FILE}"
diff --git a/deploy/k8s-operator/kube-trailblazer/helm-plugins/file-getter/plugin.yaml b/deploy/k8s-operator/kube-trailblazer/helm-plugins/file-getter/plugin.yaml
deleted file mode 100644
index b5f6983a8..000000000
--- a/deploy/k8s-operator/kube-trailblazer/helm-plugins/file-getter/plugin.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-name: file-getter
-version: 0.0.1
-description: file:// Helm getter for local filesystem charts
-downloaders:
-- command: file-getter
- protocols: [file]
diff --git a/deploy/k8s-operator/kube-trailblazer/main.go b/deploy/k8s-operator/kube-trailblazer/main.go
deleted file mode 100644
index 376134fa8..000000000
--- a/deploy/k8s-operator/kube-trailblazer/main.go
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
-Copyright 2023.
-
-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.
-*/
-
-package main
-
-import (
- "flag"
- "os"
-
- // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
- // to ensure that exec-entrypoint and run can make use of them.
- _ "k8s.io/client-go/plugin/pkg/client/auth"
- "k8s.io/klog/v2"
- "k8s.io/klog/v2/klogr"
-
- "k8s.io/apimachinery/pkg/runtime"
- utilruntime "k8s.io/apimachinery/pkg/util/runtime"
- clientgoscheme "k8s.io/client-go/kubernetes/scheme"
- ctrl "sigs.k8s.io/controller-runtime"
- "sigs.k8s.io/controller-runtime/pkg/healthz"
-
- packagev1alpha1 "github.com/nvidia/kube-trailblazer/api/v1alpha1"
- "github.com/nvidia/kube-trailblazer/controllers"
- "github.com/nvidia/kube-trailblazer/pkg/clients"
- "github.com/nvidia/kube-trailblazer/pkg/filter"
- //+kubebuilder:scaffold:imports
-)
-
-var (
- scheme = runtime.NewScheme()
- setupLog = ctrl.Log.WithName("setup")
-)
-
-func init() {
- utilruntime.Must(clientgoscheme.AddToScheme(scheme))
-
- utilruntime.Must(packagev1alpha1.AddToScheme(scheme))
- //+kubebuilder:scaffold:scheme
-}
-
-func main() {
- var metricsAddr string
- var enableLeaderElection bool
- var probeAddr string
- flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
- flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
- flag.BoolVar(&enableLeaderElection, "leader-elect", false,
- "Enable leader election for controller manager. "+
- "Enabling this will ensure there is only one active controller manager.")
-
- /*opts := zap.Options{
- Development: true,
- }
- opts.BindFlags(flag.CommandLine)
- flag.Parse()
-
- ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))*/
-
- klog.InitFlags(nil)
- flag.Parse()
-
- ctrl.SetLogger(klogr.New())
-
- mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
- Scheme: scheme,
- //MetricsBindAddress: metricsAddr,
- //Port: 9443,
- HealthProbeBindAddress: probeAddr,
- LeaderElection: enableLeaderElection,
- LeaderElectionID: "6673c020.nvidia.com",
- // LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily
- // when the Manager ends. This requires the binary to immediately end when the
- // Manager is stopped, otherwise, this setting is unsafe. Setting this significantly
- // speeds up voluntary leader transitions as the new leader don't have to wait
- // LeaseDuration time first.
- //
- // In the default scaffold provided, the program ends immediately after
- // the manager stops, so would be fine to enable this option. However,
- // if you are doing or is intended to do any operation such as perform cleanups
- // after the manager stops then its usage might be unsafe.
- // LeaderElectionReleaseOnCancel: true,
- })
- if err != nil {
- setupLog.Error(err, "unable to start manager")
- os.Exit(1)
- }
-
- kubeClient, err := clients.NewClients(mgr.GetClient(), mgr.GetConfig(), mgr.GetEventRecorderFor("specialresource"))
- if err != nil {
- setupLog.Error(err, "unable to create k8s clients")
- os.Exit(1)
- }
-
- if err = (&controllers.HelmPipelineReconciler{
- Client: mgr.GetClient(),
- Scheme: mgr.GetScheme(),
- Filter: filter.NewFilter(),
- KubeClient: kubeClient,
- RestConf: mgr.GetConfig(),
- }).SetupWithManager(mgr); err != nil {
- setupLog.Error(err, "unable to create controller", "controller", "HelmPipeline")
- os.Exit(1)
- }
- //+kubebuilder:scaffold:builder
-
- if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
- setupLog.Error(err, "unable to set up health check")
- os.Exit(1)
- }
- if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
- setupLog.Error(err, "unable to set up ready check")
- os.Exit(1)
- }
-
- setupLog.Info("starting manager")
- if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
- setupLog.Error(err, "problem running manager")
- os.Exit(1)
- }
-}
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/clients/clients.go b/deploy/k8s-operator/kube-trailblazer/pkg/clients/clients.go
deleted file mode 100644
index ca774d34b..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/clients/clients.go
+++ /dev/null
@@ -1,252 +0,0 @@
-package clients
-
-import (
- "context"
- "fmt"
-
- buildv1 "github.com/openshift/api/build/v1"
- configv1 "github.com/openshift/api/config/v1"
- clientconfigv1 "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
- "k8s.io/cli-runtime/pkg/genericclioptions"
-
- v1 "k8s.io/api/core/v1"
- apierrors "k8s.io/apimachinery/pkg/api/errors"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/runtime/schema"
- "k8s.io/client-go/discovery"
- "k8s.io/client-go/kubernetes"
- restclient "k8s.io/client-go/rest"
- "k8s.io/client-go/tools/record"
- controllerruntime "sigs.k8s.io/controller-runtime"
- "sigs.k8s.io/controller-runtime/pkg/client"
- "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
-)
-
-//go:generate mockgen -source=clients.go -package=clients -destination=mock_clients_api.go
-
-const (
- clusterVersionName = "version"
-)
-
-var (
- // TODO need to remove this global variable
- Namespace string
-)
-
-type ClientsInterface interface {
- Update(ctx context.Context, obj client.Object) error
- Get(ctx context.Context, key client.ObjectKey, obj client.Object) error
- Delete(ctx context.Context, obj client.Object) error
- List(ctx context.Context, obj client.ObjectList, opts ...client.ListOption) error
- Create(ctx context.Context, obj client.Object) error
- GetPodLogs(namespace, podName string, podLogOpts *v1.PodLogOptions) *restclient.Request
- GetNamespace(ctx context.Context, name string, opts metav1.GetOptions) (*v1.Namespace, error)
- GetSecret(ctx context.Context, namespace, name string, opts metav1.GetOptions) (*v1.Secret, error)
- ClusterVersionGet(ctx context.Context, opts metav1.GetOptions) (result *configv1.ClusterVersion, err error)
- Invalidate()
- ServerGroups() (*metav1.APIGroupList, error)
- StatusUpdate(ctx context.Context, obj client.Object) error
- CreateOrUpdate(ctx context.Context, obj client.Object, fn controllerutil.MutateFn) (controllerutil.OperationResult, error)
- HasResource(resource schema.GroupVersionResource) (bool, error)
- GetNodesByLabels(ctx context.Context, matchingLabels map[string]string) (*v1.NodeList, error)
- GetPlatform() (string, error)
-}
-
-type k8sClients struct {
- runtimeClient client.Client
- clientset kubernetes.Clientset
- configV1Client clientconfigv1.ConfigV1Client
- eventRecorder record.EventRecorder
- cachedDiscovery discovery.CachedDiscoveryInterface
- restConfig *restclient.Config
-}
-
-func NewKubeClientsFromRestConf(restConfig *restclient.Config) (ClientsInterface, error) {
- kubeClientSet, err := getKubeClientSet(restConfig)
- if err != nil {
- panic(err)
- }
- configClient, err := getConfigClient(restConfig)
- if err != nil {
- panic(err)
- }
- cachedDiscoveryClient, err := getCachedDiscoveryClient()
- if err != nil {
- panic(err)
- }
-
- runtimeClient, err := client.New(restConfig, client.Options{})
- if err != nil {
- panic(err)
- }
-
- return &k8sClients{
- runtimeClient: runtimeClient,
- clientset: *kubeClientSet,
- configV1Client: *configClient,
- eventRecorder: nil,
- cachedDiscovery: cachedDiscoveryClient,
- restConfig: restConfig,
- }, nil
-}
-
-func NewClients(runtimeClient client.Client, restConfig *restclient.Config, eventRecorder record.EventRecorder) (ClientsInterface, error) {
- kubeClientSet, err := getKubeClientSet(restConfig)
- if err != nil {
- return nil, err
- }
- configClient, err := getConfigClient(restConfig)
- if err != nil {
- return nil, err
- }
- cachedDiscoveryClient, err := getCachedDiscoveryClient()
- if err != nil {
- return nil, err
- }
- return &k8sClients{
- runtimeClient: runtimeClient,
- clientset: *kubeClientSet,
- configV1Client: *configClient,
- eventRecorder: eventRecorder,
- cachedDiscovery: cachedDiscoveryClient,
- restConfig: restConfig,
- }, nil
-}
-
-func (k *k8sClients) Update(ctx context.Context, obj client.Object) error {
- return k.runtimeClient.Update(ctx, obj)
-}
-
-func (k *k8sClients) Get(ctx context.Context, key client.ObjectKey, obj client.Object) error {
- return k.runtimeClient.Get(ctx, key, obj)
-}
-
-func (k *k8sClients) Delete(ctx context.Context, obj client.Object) error {
- return k.runtimeClient.Delete(ctx, obj)
-}
-
-func (k *k8sClients) List(ctx context.Context, obj client.ObjectList, opts ...client.ListOption) error {
- return k.runtimeClient.List(ctx, obj, opts...)
-}
-
-func (k *k8sClients) Create(ctx context.Context, obj client.Object) error {
- return k.runtimeClient.Create(ctx, obj)
-}
-
-func (k *k8sClients) GetPodLogs(namespace, podName string, podLogOpts *v1.PodLogOptions) *restclient.Request {
- return k.clientset.CoreV1().Pods(namespace).GetLogs(podName, podLogOpts)
-}
-
-func (k *k8sClients) GetNamespace(ctx context.Context, name string, opts metav1.GetOptions) (*v1.Namespace, error) {
- return k.clientset.CoreV1().Namespaces().Get(ctx, name, opts)
-}
-
-func (k *k8sClients) GetSecret(ctx context.Context, namespace, name string, opts metav1.GetOptions) (*v1.Secret, error) {
- return k.clientset.CoreV1().Secrets(namespace).Get(ctx, name, opts)
-}
-
-func (k *k8sClients) ClusterVersionGet(ctx context.Context, opts metav1.GetOptions) (result *configv1.ClusterVersion, err error) {
- return k.configV1Client.ClusterVersions().Get(ctx, clusterVersionName, opts)
-}
-
-func (k *k8sClients) Invalidate() {
- k.cachedDiscovery.Invalidate()
-}
-
-func (k *k8sClients) ServerGroups() (*metav1.APIGroupList, error) {
- return k.cachedDiscovery.ServerGroups()
-}
-
-func (k *k8sClients) StatusUpdate(ctx context.Context, obj client.Object) error {
- return k.runtimeClient.Status().Update(ctx, obj)
-}
-
-func (k *k8sClients) CreateOrUpdate(ctx context.Context, obj client.Object, fn controllerutil.MutateFn) (controllerutil.OperationResult, error) {
- return controllerruntime.CreateOrUpdate(ctx, k.runtimeClient, obj, fn)
-}
-
-func (k *k8sClients) HasResource(resource schema.GroupVersionResource) (bool, error) {
- dclient, err := discovery.NewDiscoveryClientForConfig(k.restConfig)
- if err != nil {
- return false, fmt.Errorf("Cannot retrieve a DiscoveryClient: %w", err)
- }
- if dclient == nil {
- return false, nil
- }
-
- resources, err := dclient.ServerResourcesForGroupVersion(resource.GroupVersion().String())
- if apierrors.IsNotFound(err) {
- // entire group is missing
- return false, nil
- }
- if err != nil {
- return false, fmt.Errorf("Cannot query ServerResources: %w", err)
- } else {
- for _, serverResource := range resources.APIResources {
- if serverResource.Name == resource.Resource {
- //Found it
- return true, nil
- }
- }
- }
-
- return false, nil
-}
-
-func (k *k8sClients) GetPlatform() (string, error) {
- clusterIsOCP, err := k.HasResource(buildv1.SchemeGroupVersion.WithResource("buildconfigs"))
- if err != nil {
- return "", err
- }
- if clusterIsOCP {
- return "OCP", nil
- } else {
- return "K8S", nil
- }
-}
-
-func (k *k8sClients) GetNodesByLabels(ctx context.Context, matchingLabels map[string]string) (*v1.NodeList, error) {
- opts := []client.ListOption{
- client.MatchingLabels(matchingLabels),
- }
- nodes := v1.NodeList{}
- err := k.runtimeClient.List(ctx, &nodes, opts...)
- if err != nil {
- return nil, err
- }
-
- // filter nodes by taints
- nodesWithoutTaints := nodes.Items[:0]
- for _, node := range nodes.Items {
- if k.isNodeNotExecOrSchedule(&node) {
- continue
- }
- nodesWithoutTaints = append(nodesWithoutTaints, node)
- }
- nodes.Items = nodesWithoutTaints
- return &nodes, nil
-}
-
-func (k *k8sClients) isNodeNotExecOrSchedule(node *v1.Node) bool {
- for _, taint := range node.Spec.Taints {
- if taint.Effect == v1.TaintEffectNoSchedule || taint.Effect == v1.TaintEffectNoExecute {
- return true
- }
- }
- return false
-}
-
-// getKubeClientSet returns a native non-caching client for advanced CRUD operations
-func getKubeClientSet(restConfig *restclient.Config) (*kubernetes.Clientset, error) {
- return kubernetes.NewForConfig(restConfig)
-}
-
-// getConfigClient returns a configv1 client to the reconciler
-func getConfigClient(restConfig *restclient.Config) (*clientconfigv1.ConfigV1Client, error) {
- return clientconfigv1.NewForConfig(restConfig)
-}
-
-func getCachedDiscoveryClient() (discovery.CachedDiscoveryInterface, error) {
- var config genericclioptions.ConfigFlags
- return config.ToDiscoveryClient()
-}
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/clients/clients_test.go b/deploy/k8s-operator/kube-trailblazer/pkg/clients/clients_test.go
deleted file mode 100644
index b3821fe63..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/clients/clients_test.go
+++ /dev/null
@@ -1,72 +0,0 @@
-package clients
-
-import (
- "context"
- "testing"
-
- . "github.com/onsi/ginkgo/v2"
- . "github.com/onsi/gomega"
- corev1 "k8s.io/api/core/v1"
- "k8s.io/apimachinery/pkg/runtime"
-
- "github.com/openshift-psap/special-resource-operator/pkg/utils"
- "sigs.k8s.io/controller-runtime/pkg/client/fake"
-)
-
-func TestPkgClients(t *testing.T) {
- RegisterFailHandler(Fail)
- RunSpecs(t, "Clients Suite")
-}
-
-var _ = Describe("GetNodesByLabels", func() {
- type testInput struct {
- numNodes int
- labels map[string]string
- addTaint bool
- taintEffect corev1.TaintEffect
- expectedNumNodes int
- }
-
- DescribeTable(
- "should return correct number of nodes",
- func(test testInput) {
- nodesList := utils.CreateNodesList(test.numNodes, test.labels)
- if test.addTaint {
- utils.SetTaint(&nodesList.Items[0], "taintKey", "taintValue", test.taintEffect)
- }
- objs := []runtime.Object{nodesList}
- clientsStruct := k8sClients{runtimeClient: fake.NewClientBuilder().WithRuntimeObjects(objs...).Build()}
- res, _ := clientsStruct.GetNodesByLabels(context.TODO(), test.labels)
- Expect(res.Items).To(HaveLen(test.expectedNumNodes))
- },
- Entry(
- "all nodes without taint",
- testInput{
- numNodes: 3,
- labels: map[string]string{"key1": "label1"},
- addTaint: false,
- expectedNumNodes: 3,
- },
- ),
- Entry(
- "a node with NoExecute taint",
- testInput{
- numNodes: 3,
- labels: map[string]string{"key1": "label1"},
- addTaint: true,
- taintEffect: corev1.TaintEffectNoExecute,
- expectedNumNodes: 2,
- },
- ),
- Entry(
- "a node with NoSchedule taint",
- testInput{
- numNodes: 3,
- labels: map[string]string{"key1": "label1"},
- addTaint: true,
- taintEffect: corev1.TaintEffectNoSchedule,
- expectedNumNodes: 2,
- },
- ),
- )
-})
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/clients/mock_clients_api.go b/deploy/k8s-operator/kube-trailblazer/pkg/clients/mock_clients_api.go
deleted file mode 100644
index 30c04b745..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/clients/mock_clients_api.go
+++ /dev/null
@@ -1,277 +0,0 @@
-// Code generated by MockGen. DO NOT EDIT.
-// Source: clients.go
-
-// Package clients is a generated GoMock package.
-package clients
-
-import (
- context "context"
- reflect "reflect"
-
- gomock "github.com/golang/mock/gomock"
- v1 "github.com/openshift/api/config/v1"
- v10 "k8s.io/api/core/v1"
- v11 "k8s.io/apimachinery/pkg/apis/meta/v1"
- schema "k8s.io/apimachinery/pkg/runtime/schema"
- rest "k8s.io/client-go/rest"
- client "sigs.k8s.io/controller-runtime/pkg/client"
- controllerutil "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
-)
-
-// MockClientsInterface is a mock of ClientsInterface interface.
-type MockClientsInterface struct {
- ctrl *gomock.Controller
- recorder *MockClientsInterfaceMockRecorder
-}
-
-// MockClientsInterfaceMockRecorder is the mock recorder for MockClientsInterface.
-type MockClientsInterfaceMockRecorder struct {
- mock *MockClientsInterface
-}
-
-// NewMockClientsInterface creates a new mock instance.
-func NewMockClientsInterface(ctrl *gomock.Controller) *MockClientsInterface {
- mock := &MockClientsInterface{ctrl: ctrl}
- mock.recorder = &MockClientsInterfaceMockRecorder{mock}
- return mock
-}
-
-// EXPECT returns an object that allows the caller to indicate expected use.
-func (m *MockClientsInterface) EXPECT() *MockClientsInterfaceMockRecorder {
- return m.recorder
-}
-
-// ClusterVersionGet mocks base method.
-func (m *MockClientsInterface) ClusterVersionGet(ctx context.Context, opts v11.GetOptions) (*v1.ClusterVersion, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "ClusterVersionGet", ctx, opts)
- ret0, _ := ret[0].(*v1.ClusterVersion)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// ClusterVersionGet indicates an expected call of ClusterVersionGet.
-func (mr *MockClientsInterfaceMockRecorder) ClusterVersionGet(ctx, opts interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClusterVersionGet", reflect.TypeOf((*MockClientsInterface)(nil).ClusterVersionGet), ctx, opts)
-}
-
-// Create mocks base method.
-func (m *MockClientsInterface) Create(ctx context.Context, obj client.Object) error {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "Create", ctx, obj)
- ret0, _ := ret[0].(error)
- return ret0
-}
-
-// Create indicates an expected call of Create.
-func (mr *MockClientsInterfaceMockRecorder) Create(ctx, obj interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockClientsInterface)(nil).Create), ctx, obj)
-}
-
-// CreateOrUpdate mocks base method.
-func (m *MockClientsInterface) CreateOrUpdate(ctx context.Context, obj client.Object, fn controllerutil.MutateFn) (controllerutil.OperationResult, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "CreateOrUpdate", ctx, obj, fn)
- ret0, _ := ret[0].(controllerutil.OperationResult)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// CreateOrUpdate indicates an expected call of CreateOrUpdate.
-func (mr *MockClientsInterfaceMockRecorder) CreateOrUpdate(ctx, obj, fn interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateOrUpdate", reflect.TypeOf((*MockClientsInterface)(nil).CreateOrUpdate), ctx, obj, fn)
-}
-
-// Delete mocks base method.
-func (m *MockClientsInterface) Delete(ctx context.Context, obj client.Object) error {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "Delete", ctx, obj)
- ret0, _ := ret[0].(error)
- return ret0
-}
-
-// Delete indicates an expected call of Delete.
-func (mr *MockClientsInterfaceMockRecorder) Delete(ctx, obj interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockClientsInterface)(nil).Delete), ctx, obj)
-}
-
-// Get mocks base method.
-func (m *MockClientsInterface) Get(ctx context.Context, key client.ObjectKey, obj client.Object) error {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "Get", ctx, key, obj)
- ret0, _ := ret[0].(error)
- return ret0
-}
-
-// Get indicates an expected call of Get.
-func (mr *MockClientsInterfaceMockRecorder) Get(ctx, key, obj interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockClientsInterface)(nil).Get), ctx, key, obj)
-}
-
-// GetNamespace mocks base method.
-func (m *MockClientsInterface) GetNamespace(ctx context.Context, name string, opts v11.GetOptions) (*v10.Namespace, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetNamespace", ctx, name, opts)
- ret0, _ := ret[0].(*v10.Namespace)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetNamespace indicates an expected call of GetNamespace.
-func (mr *MockClientsInterfaceMockRecorder) GetNamespace(ctx, name, opts interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNamespace", reflect.TypeOf((*MockClientsInterface)(nil).GetNamespace), ctx, name, opts)
-}
-
-// GetNodesByLabels mocks base method.
-func (m *MockClientsInterface) GetNodesByLabels(ctx context.Context, matchingLabels map[string]string) (*v10.NodeList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetNodesByLabels", ctx, matchingLabels)
- ret0, _ := ret[0].(*v10.NodeList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetNodesByLabels indicates an expected call of GetNodesByLabels.
-func (mr *MockClientsInterfaceMockRecorder) GetNodesByLabels(ctx, matchingLabels interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNodesByLabels", reflect.TypeOf((*MockClientsInterface)(nil).GetNodesByLabels), ctx, matchingLabels)
-}
-
-// GetPlatform mocks base method.
-func (m *MockClientsInterface) GetPlatform() (string, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetPlatform")
- ret0, _ := ret[0].(string)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetPlatform indicates an expected call of GetPlatform.
-func (mr *MockClientsInterfaceMockRecorder) GetPlatform() *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPlatform", reflect.TypeOf((*MockClientsInterface)(nil).GetPlatform))
-}
-
-// GetPodLogs mocks base method.
-func (m *MockClientsInterface) GetPodLogs(namespace, podName string, podLogOpts *v10.PodLogOptions) *rest.Request {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetPodLogs", namespace, podName, podLogOpts)
- ret0, _ := ret[0].(*rest.Request)
- return ret0
-}
-
-// GetPodLogs indicates an expected call of GetPodLogs.
-func (mr *MockClientsInterfaceMockRecorder) GetPodLogs(namespace, podName, podLogOpts interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPodLogs", reflect.TypeOf((*MockClientsInterface)(nil).GetPodLogs), namespace, podName, podLogOpts)
-}
-
-// GetSecret mocks base method.
-func (m *MockClientsInterface) GetSecret(ctx context.Context, namespace, name string, opts v11.GetOptions) (*v10.Secret, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetSecret", ctx, namespace, name, opts)
- ret0, _ := ret[0].(*v10.Secret)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetSecret indicates an expected call of GetSecret.
-func (mr *MockClientsInterfaceMockRecorder) GetSecret(ctx, namespace, name, opts interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSecret", reflect.TypeOf((*MockClientsInterface)(nil).GetSecret), ctx, namespace, name, opts)
-}
-
-// HasResource mocks base method.
-func (m *MockClientsInterface) HasResource(resource schema.GroupVersionResource) (bool, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "HasResource", resource)
- ret0, _ := ret[0].(bool)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// HasResource indicates an expected call of HasResource.
-func (mr *MockClientsInterfaceMockRecorder) HasResource(resource interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasResource", reflect.TypeOf((*MockClientsInterface)(nil).HasResource), resource)
-}
-
-// Invalidate mocks base method.
-func (m *MockClientsInterface) Invalidate() {
- m.ctrl.T.Helper()
- m.ctrl.Call(m, "Invalidate")
-}
-
-// Invalidate indicates an expected call of Invalidate.
-func (mr *MockClientsInterfaceMockRecorder) Invalidate() *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Invalidate", reflect.TypeOf((*MockClientsInterface)(nil).Invalidate))
-}
-
-// List mocks base method.
-func (m *MockClientsInterface) List(ctx context.Context, obj client.ObjectList, opts ...client.ListOption) error {
- m.ctrl.T.Helper()
- varargs := []interface{}{ctx, obj}
- for _, a := range opts {
- varargs = append(varargs, a)
- }
- ret := m.ctrl.Call(m, "List", varargs...)
- ret0, _ := ret[0].(error)
- return ret0
-}
-
-// List indicates an expected call of List.
-func (mr *MockClientsInterfaceMockRecorder) List(ctx, obj interface{}, opts ...interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- varargs := append([]interface{}{ctx, obj}, opts...)
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockClientsInterface)(nil).List), varargs...)
-}
-
-// ServerGroups mocks base method.
-func (m *MockClientsInterface) ServerGroups() (*v11.APIGroupList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "ServerGroups")
- ret0, _ := ret[0].(*v11.APIGroupList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// ServerGroups indicates an expected call of ServerGroups.
-func (mr *MockClientsInterfaceMockRecorder) ServerGroups() *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ServerGroups", reflect.TypeOf((*MockClientsInterface)(nil).ServerGroups))
-}
-
-// StatusUpdate mocks base method.
-func (m *MockClientsInterface) StatusUpdate(ctx context.Context, obj client.Object) error {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "StatusUpdate", ctx, obj)
- ret0, _ := ret[0].(error)
- return ret0
-}
-
-// StatusUpdate indicates an expected call of StatusUpdate.
-func (mr *MockClientsInterfaceMockRecorder) StatusUpdate(ctx, obj interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StatusUpdate", reflect.TypeOf((*MockClientsInterface)(nil).StatusUpdate), ctx, obj)
-}
-
-// Update mocks base method.
-func (m *MockClientsInterface) Update(ctx context.Context, obj client.Object) error {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "Update", ctx, obj)
- ret0, _ := ret[0].(error)
- return ret0
-}
-
-// Update indicates an expected call of Update.
-func (mr *MockClientsInterfaceMockRecorder) Update(ctx, obj interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockClientsInterface)(nil).Update), ctx, obj)
-}
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/filter/filter.go b/deploy/k8s-operator/kube-trailblazer/pkg/filter/filter.go
deleted file mode 100644
index 8f43519fa..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/filter/filter.go
+++ /dev/null
@@ -1,151 +0,0 @@
-package filter
-
-import (
- "github.com/nvidia/kube-trailblazer/api/v1alpha1"
- operatorv1 "github.com/openshift/api/operator/v1"
- "golang.design/x/lockfree"
- "k8s.io/klog/v2"
- "sigs.k8s.io/controller-runtime/pkg/client"
- "sigs.k8s.io/controller-runtime/pkg/event"
- "sigs.k8s.io/controller-runtime/pkg/predicate"
-)
-
-const (
- Kind = "HelmPipeline"
- OwnedLabel = "app.trailblazer.nvidia.com/owned-by"
-)
-
-var (
- WorkStack = make(map[string]*lockfree.Stack)
-)
-
-type Filter interface {
- GetPredicates() predicate.Predicate
- GetMode() string
-}
-
-func NewFilter() Filter {
- WorkStack["DELETE"] = lockfree.NewStack()
- return &filter{
- //log: log.WithName("filter"),
- //lifecycle: lifecycle,
- //storage: storage,
- //kernelData: kernelData,
- }
-}
-
-type filter struct {
- mode string
-}
-
-func (f *filter) GetMode() string {
- return f.mode
-}
-
-func (f *filter) isTrailblazerUnmanaged(obj client.Object) bool {
- tb, ok := obj.(*v1alpha1.HelmPipeline)
- if !ok {
- return false
- }
- return tb.Spec.ManagementState == operatorv1.Unmanaged
-}
-
-func (f *filter) isHelmPipelineObject(obj client.Object) bool {
-
- _, ok := obj.(*v1alpha1.HelmPipeline)
- return ok
-}
-
-func (f *filter) isOwned(obj client.Object) bool {
-
- for _, owner := range obj.GetOwnerReferences() {
- if owner.Kind == Kind {
- return true
- }
- }
-
- var labels map[string]string
-
- if labels = obj.GetLabels(); labels != nil {
- if _, found := labels[OwnedLabel]; found {
- return true
- }
- }
- return false
-}
-
-func (f *filter) selectOnlyOwnedObjects(obj client.Object) bool {
-
- if f.isHelmPipelineObject(obj) {
- if f.isTrailblazerUnmanaged(obj) {
- return false
- }
- klog.Infof("%s - isHelmPipeline - %s -- %s:%s", f.mode, obj.GetNamespace(), obj.GetObjectKind(), obj.GetName())
- if f.mode == "DELETE" {
- WorkStack[f.mode].Push(obj)
- }
- return true
- }
-
- if f.isOwned(obj) {
- klog.Infof("%s - isOwned - %s -- %s:%s", f.mode, obj.GetNamespace(), obj.GetObjectKind(), obj.GetName())
- return true
- }
- return false
-}
-
-func (f *filter) GetPredicates() predicate.Predicate {
- return predicate.Funcs{
- CreateFunc: func(e event.CreateEvent) bool {
-
- f.mode = "CREATE"
- return f.selectOnlyOwnedObjects(e.Object)
- },
-
- UpdateFunc: func(e event.UpdateEvent) bool {
- // Ignore updates if the resourceVersion does not change
- // resourceVersion is updated when the object is modified
-
- /* UPDATING THE STATUS WILL INCREASE THE RESOURCEVERSION DISABLING
- * BUT KEEPING FOR REFERENCE
- if e.MetaOld.GetResourceVersion() == e.MetaNew.GetResourceVersion() {
- return false
- }*/
- f.mode = "UPDATE"
-
- ownedObject := f.selectOnlyOwnedObjects(e.ObjectNew)
- if !ownedObject {
- return false
- }
-
- // Ignore updates to CR status in which case metadata.Generation does not change
- if e.ObjectOld.GetGeneration() == e.ObjectNew.GetGeneration() {
- klog.Infof("UPDATE Generation Equal %s ", e.ObjectNew.GetName())
- //return false
- }
- // Some objects will increase generation on update ...
- if e.ObjectOld.GetResourceVersion() == e.ObjectNew.GetResourceVersion() {
- klog.Infof("UPDATE ResourceVersion Equal %s", e.ObjectNew.GetName())
- //return false
- }
-
- // If a trailblazer dependency is updated we
- // want to reconcile it, handle the update event
- return f.selectOnlyOwnedObjects(e.ObjectNew)
- },
- DeleteFunc: func(e event.DeleteEvent) bool {
-
- f.mode = "DELETE"
- // If an owned object is deleted we
- // want to recreate it so handle the delete event
- return f.selectOnlyOwnedObjects(e.Object)
- },
- GenericFunc: func(e event.GenericEvent) bool {
-
- f.mode = "GENERIC"
- // If a owned object is modified we
- // want to reconcile it, handle the generic event
- return f.selectOnlyOwnedObjects(e.Object)
- },
- }
-}
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/filter/filter_test.go b/deploy/k8s-operator/kube-trailblazer/pkg/filter/filter_test.go
deleted file mode 100644
index 7d2736816..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/filter/filter_test.go
+++ /dev/null
@@ -1,476 +0,0 @@
-package filter
-
-import (
- "context"
- "testing"
-
- "github.com/golang/mock/gomock"
- . "github.com/onsi/ginkgo/v2"
- . "github.com/onsi/gomega"
- "github.com/onsi/gomega/types"
- appsv1 "k8s.io/api/apps/v1"
- "sigs.k8s.io/controller-runtime/pkg/event"
-
- "github.com/openshift-psap/special-resource-operator/api/v1beta1"
- "github.com/openshift-psap/special-resource-operator/pkg/kernel"
- "github.com/openshift-psap/special-resource-operator/pkg/lifecycle"
- "github.com/openshift-psap/special-resource-operator/pkg/storage"
- operatorv1 "github.com/openshift/api/operator/v1"
- corev1 "k8s.io/api/core/v1"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
- "sigs.k8s.io/controller-runtime/pkg/client"
-)
-
-var (
- ctrl *gomock.Controller
- mockLifecycle *lifecycle.MockLifecycle
- mockStorage *storage.MockStorage
- mockKernel *kernel.MockKernelData
- f filter
-)
-
-func TestFilter(t *testing.T) {
- RegisterFailHandler(Fail)
-
- BeforeEach(func() {
- ctrl = gomock.NewController(GinkgoT())
- mockLifecycle = lifecycle.NewMockLifecycle(ctrl)
- mockStorage = storage.NewMockStorage(ctrl)
- mockKernel = kernel.NewMockKernelData(ctrl)
- f = filter{
- //log: zap.New(zap.WriteTo(ioutil.Discard)),
- //lifecycle: mockLifecycle,
- //storage: mockStorage,
- //kernelData: mockKernel,
- }
- })
-
- AfterEach(func() {
- ctrl.Finish()
- })
-
- RunSpecs(t, "Filter Suite")
-}
-
-var _ = Describe("IsTrailblazer", func() {
- DescribeTable(
- "should return the correct value",
- func(obj client.Object, m types.GomegaMatcher) {
- Expect(f.isHelmPipelineObject(obj)).To(m)
- },
- Entry(
- Kind,
- &v1beta1.SpecialResource{
- TypeMeta: metav1.TypeMeta{Kind: Kind},
- },
- BeTrue(),
- ),
- Entry(
- "Pod owned by SRO",
- &corev1.Pod{
- ObjectMeta: metav1.ObjectMeta{
- Labels: map[string]string{OwnedLabel: "true"},
- },
- },
- BeFalse(),
- ),
- Entry(
- "valid selflink",
- func() *unstructured.Unstructured {
- uo := &unstructured.Unstructured{}
- uo.SetSelfLink("/apis/sro.openshift.io/v1")
-
- return uo
- }(),
- BeTrue(),
- ),
- Entry(
- "selflink in Label",
- func() *unstructured.Unstructured {
- uo := &unstructured.Unstructured{}
- uo.SetLabels(map[string]string{"some-label": "/apis/sro.openshift.io/v1"})
-
- return uo
- }(),
- BeTrue(),
- ),
- Entry(
- "no selflink",
- &unstructured.Unstructured{},
- BeFalse(),
- ),
- )
-})
-
-var _ = Describe("Owned", func() {
- DescribeTable(
- "should return the expected value",
- func(obj client.Object, m types.GomegaMatcher) {
- Expect(f.isOwned(obj)).To(m)
- },
- Entry(
- "via ownerReferences",
- &corev1.Pod{
- ObjectMeta: metav1.ObjectMeta{
- OwnerReferences: []metav1.OwnerReference{
- {Kind: Kind},
- },
- },
- },
- BeTrue(),
- ),
- Entry(
- "via labels",
- &corev1.Pod{
- ObjectMeta: metav1.ObjectMeta{
- Labels: map[string]string{OwnedLabel: "whatever"},
- },
- },
- BeTrue(),
- ),
- Entry(
- "not owned",
- &corev1.Pod{},
- BeFalse(),
- ),
- )
-})
-
-var _ = Describe("Predicate", func() {
- Context("CreateFunc", func() {
- DescribeTable(
- "should work as expected",
- func(obj client.Object, m types.GomegaMatcher) {
- ret := f.GetPredicates().Create(event.CreateEvent{Object: obj})
-
- Expect(ret).To(m)
- Expect(f.GetMode()).To(Equal("CREATE"))
- },
- Entry(
- "special resource",
- &v1beta1.SpecialResource{},
- BeTrue(),
- ),
- Entry(
- "owned",
- &corev1.Pod{
- ObjectMeta: metav1.ObjectMeta{
- OwnerReferences: []metav1.OwnerReference{
- {Kind: Kind},
- },
- },
- },
- BeTrue(),
- ),
- Entry(
- "random pod",
- &corev1.Pod{},
- BeFalse(),
- ),
- Entry(
- "unmanaged special resource",
- &v1beta1.SpecialResource{
- TypeMeta: metav1.TypeMeta{Kind: Kind},
- Spec: v1beta1.SpecialResourceSpec{
- ManagementState: operatorv1.Unmanaged,
- },
- },
- BeFalse(),
- ),
- )
- })
-
- Context("UpdateFunc", func() {
- DescribeTable(
- "should work as expected",
- func(mockSetup func(), old client.Object, new client.Object, m types.GomegaMatcher) {
- mockSetup()
-
- ret := f.GetPredicates().Update(event.UpdateEvent{
- ObjectOld: old,
- ObjectNew: new,
- })
-
- Expect(ret).To(m)
- Expect(f.GetMode()).To(Equal("UPDATE"))
- },
- Entry(
- "No change to object's Generation or ResourceVersion",
- func() {
- mockKernel.EXPECT().IsObjectAffine(gomock.Any()).Return(false)
- },
- &corev1.Pod{
- ObjectMeta: metav1.ObjectMeta{
- OwnerReferences: []metav1.OwnerReference{
- {Kind: Kind},
- },
- Generation: 1,
- ResourceVersion: "dummy1",
- },
- },
- &corev1.Pod{
- ObjectMeta: metav1.ObjectMeta{
- OwnerReferences: []metav1.OwnerReference{
- {Kind: Kind},
- },
- Generation: 1,
- ResourceVersion: "dummy1",
- },
- },
- BeFalse(),
- ),
- Entry(
- "Object's Generation changed, no change to ResourceVersion",
- func() {
- mockKernel.EXPECT().IsObjectAffine(gomock.Any()).Return(false)
- },
- &corev1.Pod{
- ObjectMeta: metav1.ObjectMeta{
- OwnerReferences: []metav1.OwnerReference{
- {Kind: Kind},
- },
- Generation: 1,
- ResourceVersion: "dummy1",
- },
- },
- &corev1.Pod{
- ObjectMeta: metav1.ObjectMeta{
- OwnerReferences: []metav1.OwnerReference{
- {Kind: Kind},
- },
- Generation: 2,
- ResourceVersion: "dummy1",
- },
- },
- BeFalse(),
- ),
- Entry(
- "Object has changed but is not owned by SRO",
- func() {},
- &corev1.Pod{
- ObjectMeta: metav1.ObjectMeta{
- Generation: 1,
- ResourceVersion: "dummy1",
- },
- },
- &corev1.Pod{
- ObjectMeta: metav1.ObjectMeta{
- Generation: 2,
- ResourceVersion: "dummy2",
- },
- },
- BeFalse(),
- ),
- Entry(
- "Object has changed and it's a SRO owned DaemonSet",
- func() {
- mockKernel.EXPECT().IsObjectAffine(gomock.Any()).Return(true)
- mockLifecycle.EXPECT().UpdateDaemonSetPods(context.TODO(), gomock.Any())
- },
- &appsv1.DaemonSet{
- ObjectMeta: metav1.ObjectMeta{
- OwnerReferences: []metav1.OwnerReference{
- {Kind: Kind},
- },
- Generation: 1,
- ResourceVersion: "dummy1",
- },
- },
- &appsv1.DaemonSet{
- ObjectMeta: metav1.ObjectMeta{
- OwnerReferences: []metav1.OwnerReference{
- {Kind: Kind},
- },
- Generation: 2,
- ResourceVersion: "dummy2",
- },
- },
- BeTrue(),
- ),
- Entry(
- "Object is a SRO owned & kernel affine DaemonSet, but did not change",
- func() {
- mockKernel.EXPECT().IsObjectAffine(gomock.Any()).Return(true)
- },
- &appsv1.DaemonSet{
- ObjectMeta: metav1.ObjectMeta{
- OwnerReferences: []metav1.OwnerReference{
- {Kind: Kind},
- },
- Annotations: map[string]string{
- "specialresource.openshift.io/kernel-affine": "true",
- },
- Generation: 0,
- ResourceVersion: "dummy",
- },
- },
- &appsv1.DaemonSet{
- ObjectMeta: metav1.ObjectMeta{
- OwnerReferences: []metav1.OwnerReference{
- {Kind: Kind},
- },
- Annotations: map[string]string{
- "specialresource.openshift.io/kernel-affine": "true",
- },
- Generation: 0,
- ResourceVersion: "dummy",
- },
- },
- BeFalse(),
- ),
- Entry(
- "Object is a SRO owned & kernel affine DaemonSet",
- func() {
- mockKernel.EXPECT().IsObjectAffine(gomock.Any()).Return(true)
- mockLifecycle.EXPECT().UpdateDaemonSetPods(context.TODO(), gomock.Any())
- },
- &appsv1.DaemonSet{
- ObjectMeta: metav1.ObjectMeta{
- OwnerReferences: []metav1.OwnerReference{
- {Kind: Kind},
- },
- Annotations: map[string]string{
- "specialresource.openshift.io/kernel-affine": "true",
- },
- Generation: 0,
- ResourceVersion: "dummy",
- },
- },
- &appsv1.DaemonSet{
- ObjectMeta: metav1.ObjectMeta{
- OwnerReferences: []metav1.OwnerReference{
- {Kind: Kind},
- },
- Annotations: map[string]string{
- "specialresource.openshift.io/kernel-affine": "true",
- },
- Generation: 1,
- ResourceVersion: "dummy",
- },
- },
- BeTrue(),
- ),
- Entry(
- "Object is a SpecialResource with both Generation and ResourceVersion changed",
- func() {
- mockKernel.EXPECT().IsObjectAffine(gomock.Any()).Return(false)
- },
- &v1beta1.SpecialResource{
- ObjectMeta: metav1.ObjectMeta{
- OwnerReferences: []metav1.OwnerReference{
- {Kind: Kind},
- },
- Generation: 1,
- ResourceVersion: "dummy1",
- },
- },
- &v1beta1.SpecialResource{
- ObjectMeta: metav1.ObjectMeta{
- OwnerReferences: []metav1.OwnerReference{
- {Kind: Kind},
- },
- Generation: 2,
- ResourceVersion: "dummy2",
- },
- },
- BeTrue(),
- ),
- Entry(
- "Object is a SpecialResource with both Generation and ResourceVersion changed but unmanaged state",
- func() {
- mockKernel.EXPECT().IsObjectAffine(gomock.Any()).Return(false)
- },
- &v1beta1.SpecialResource{
- ObjectMeta: metav1.ObjectMeta{
- OwnerReferences: []metav1.OwnerReference{
- {Kind: Kind},
- },
- Generation: 1,
- ResourceVersion: "dummy1",
- },
- },
- &v1beta1.SpecialResource{
- ObjectMeta: metav1.ObjectMeta{
- OwnerReferences: []metav1.OwnerReference{
- {Kind: Kind},
- },
- Generation: 2,
- ResourceVersion: "dummy2",
- },
- Spec: v1beta1.SpecialResourceSpec{
- ManagementState: operatorv1.Unmanaged,
- },
- },
- BeFalse(),
- ),
- )
- })
-
- Context("DeleteFunc", func() {
- DescribeTable(
- "should work as expected",
- func(obj client.Object, m types.GomegaMatcher) {
- ret := f.GetPredicates().Delete(event.DeleteEvent{Object: obj})
-
- Expect(ret).To(m)
- Expect(f.GetMode()).To(Equal("DELETE"))
- },
- Entry(
- "special resource",
- &v1beta1.SpecialResource{},
- BeTrue(),
- ),
- // TODO(qbarrand) testing this function requires injecting a fake pkg/storage
- //Entry("owned", ...),
- Entry(
- "random pod",
- &corev1.Pod{},
- BeFalse(),
- ),
- )
- })
-
- Context("GenericFunc", func() {
- DescribeTable(
- "should return the correct value",
- func(obj client.Object, m types.GomegaMatcher) {
- ret := f.GetPredicates().Generic(event.GenericEvent{Object: obj})
-
- Expect(ret).To(m)
- Expect(f.GetMode()).To(Equal("GENERIC"))
- },
- Entry(
- "special resource",
- &v1beta1.SpecialResource{},
- BeTrue(),
- ),
- Entry(
- "owned",
- &corev1.Pod{
- ObjectMeta: metav1.ObjectMeta{
- OwnerReferences: []metav1.OwnerReference{
- {Kind: Kind},
- },
- },
- },
- BeTrue(),
- ),
- Entry(
- "random pod",
- &corev1.Pod{},
- BeFalse(),
- ),
- Entry(
- "unmanaged special resource",
- &v1beta1.SpecialResource{
- TypeMeta: metav1.TypeMeta{Kind: Kind},
- Spec: v1beta1.SpecialResourceSpec{
- ManagementState: operatorv1.Unmanaged,
- },
- },
- BeFalse(),
- ),
- )
- })
-})
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/LICENSE b/deploy/k8s-operator/kube-trailblazer/pkg/helmer/LICENSE
deleted file mode 100644
index 261eeb9e9..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- 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.
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/README.md b/deploy/k8s-operator/kube-trailblazer/pkg/helmer/README.md
deleted file mode 100644
index e86bd4b74..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/README.md
+++ /dev/null
@@ -1 +0,0 @@
-# helmer
\ No newline at end of file
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/chart.go b/deploy/k8s-operator/kube-trailblazer/pkg/helmer/chart.go
deleted file mode 100644
index 1502167ec..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/chart.go
+++ /dev/null
@@ -1,72 +0,0 @@
-package helmer
-
-import helmclient "github.com/mittwald/go-helm-client"
-
-func (in *chartSpec) DeepCopyInto(out *helmclient.ChartSpec) {
-
- // copy all chartSpec fields from out to in
- out.ReleaseName = in.ReleaseName
- out.ChartName = in.ChartName
- out.Namespace = in.Namespace
- out.ValuesYaml = in.ValuesYaml
- out.ValuesOptions = in.ValuesOptions
- out.Version = in.Version
- out.CreateNamespace = in.CreateNamespace
- out.DisableHooks = in.DisableHooks
- out.Replace = in.Replace
- out.Wait = in.Wait
- out.WaitForJobs = in.WaitForJobs
- out.DependencyUpdate = in.DependencyUpdate
- out.Timeout = in.Timeout
- out.GenerateName = in.GenerateName
- out.NameTemplate = in.NameTemplate
- out.Atomic = in.Atomic
- out.SkipCRDs = in.SkipCRDs
- out.UpgradeCRDs = in.UpgradeCRDs
- out.SubNotes = in.SubNotes
- out.Force = in.Force
- out.ResetValues = in.ResetValues
- out.ReuseValues = in.ReuseValues
- out.Recreate = in.Recreate
- out.MaxHistory = in.MaxHistory
- out.CleanupOnFail = in.CleanupOnFail
- out.DryRun = in.DryRun
- out.Description = in.Description
- out.KeepHistory = in.KeepHistory
-}
-
-func (in *chartSpec) DeepCopy() *helmclient.ChartSpec {
-
- var out helmclient.ChartSpec
- // copy all chartSpec fields from out to in
- out.ReleaseName = in.ReleaseName
- out.ChartName = in.ChartName
- out.Namespace = in.Namespace
- out.ValuesYaml = in.ValuesYaml
- out.ValuesOptions = in.ValuesOptions
- out.Version = in.Version
- out.CreateNamespace = in.CreateNamespace
- out.DisableHooks = in.DisableHooks
- out.Replace = in.Replace
- out.Wait = in.Wait
- out.WaitForJobs = in.WaitForJobs
- out.DependencyUpdate = in.DependencyUpdate
- out.Timeout = in.Timeout
- out.GenerateName = in.GenerateName
- out.NameTemplate = in.NameTemplate
- out.Atomic = in.Atomic
- out.SkipCRDs = in.SkipCRDs
- out.UpgradeCRDs = in.UpgradeCRDs
- out.SubNotes = in.SubNotes
- out.Force = in.Force
- out.ResetValues = in.ResetValues
- out.ReuseValues = in.ReuseValues
- out.Recreate = in.Recreate
- out.MaxHistory = in.MaxHistory
- out.CleanupOnFail = in.CleanupOnFail
- out.DryRun = in.DryRun
- out.Description = in.Description
- out.KeepHistory = in.KeepHistory
-
- return &out
-}
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/controller/Makefile b/deploy/k8s-operator/kube-trailblazer/pkg/helmer/controller/Makefile
deleted file mode 100644
index 4d9772c1a..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/controller/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-helm:
- ../hack/helmer.sh
-
-GRAPH ?= ${HOME}/github.com/zvonkok/helmer/graphs/helmer-nfd.yaml
-
-run: helm
- go mod tidy
- go mod vendor
- cp patches/root.go vendor/helm.sh/helm/v3/pkg/chart/.
- go run . -g $(GRAPH)
-
-
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/controller/controller.go b/deploy/k8s-operator/kube-trailblazer/pkg/helmer/controller/controller.go
deleted file mode 100644
index 8951956c1..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/controller/controller.go
+++ /dev/null
@@ -1,133 +0,0 @@
-package main
-
-import (
- "flag"
- "log"
- "os"
-
- cli "github.com/urfave/cli/v2"
-
- "github.com/nvidia/kube-trailblazer/pkg/helmer"
- klog "k8s.io/klog/v2"
-)
-
-func init() {
- flags := flag.FlagSet{
- Usage: func() {
- },
- }
- // Default is logtostderr
- klog.InitFlags(&flags)
-}
-
-func main() {
-
- var err error
- var graphs cli.StringSlice
- var kubeConfig string
-
- app := &cli.App{
- Name: "helmer",
- Usage: "reconcile a helm graph",
- Flags: []cli.Flag{
- &cli.StringFlag{
- Name: "kubeConfig",
- Aliases: []string{"k"},
- DefaultText: "${HOME}/.kube/config",
- Value: "${HOME}/.kube/config",
- Destination: &kubeConfig,
- },
- &cli.StringSliceFlag{
- Name: "graphs",
- Aliases: []string{"g"},
- Required: true,
- DefaultText: "None",
- Destination: &graphs,
- },
- },
- Action: func(c *cli.Context) error {
- return nil
- },
- }
-
- app.Run(os.Args)
- if err != nil {
- log.Fatal(err)
- }
-
- os.Setenv("HELMER_DEBUG", "1")
-
- for _, fromFile := range graphs.Value() {
-
- var orchard helmer.Pipeline
- // We're providing Helmer a Graph as the interface what to create
- // In an operator we would have a go struct but for testing we can
- // also load a Graph from file.
- orchard, err = helmer.LoadPipeline(fromFile)
- if err != nil {
- panic(err)
- }
-
- // RECONCILE LOOP
- for _, arbor := range orchard {
-
- // For each chart we create an Helmer instance with its own settings
- // this makes it easier to decouple each chart for processing and clients
- // that do not interfere with each other.
- h, err := helmer.NewWithPackage(&arbor)
- if err != nil {
- panic(err)
- }
-
- err = h.GetClientsWithKubeConf("", "default")
- if err != nil {
- panic(err)
- }
-
- err = h.AddOrUpdateRepo()
- if err != nil {
- panic(err)
- }
-
- err = h.Lint()
- if err != nil {
- panic(err)
- }
-
- // klog.Info("TEMPLATE")
- // err = h.Template()
- // if err != nil {
- // panic(err)
- // }
-
- reconcile(h)
- }
-
- }
- return
-}
-
-func reconcile(h *helmer.Helmer) {
-
- for {
- err := h.InstallOrUpgradePackage()
- if err != nil {
- klog.Info(err)
- }
- if err == nil {
- break
- }
- }
-}
-
-/*
-func OpenShiftInstallOrder() {
- // Mutates helm package exported variables
- idx := utils.StringSliceFind(releaseutil.InstallOrder, "Service")
- releaseutil.InstallOrder = utils.StringSliceInsert(releaseutil.InstallOrder, idx, "BuildConfig")
- releaseutil.InstallOrder = utils.StringSliceInsert(releaseutil.InstallOrder, idx, "ImageStream")
- releaseutil.InstallOrder = utils.StringSliceInsert(releaseutil.InstallOrder, idx, "SecurityContextConstraints")
- releaseutil.InstallOrder = utils.StringSliceInsert(releaseutil.InstallOrder, idx, "Issuer")
- releaseutil.InstallOrder = utils.StringSliceInsert(releaseutil.InstallOrder, idx, "Certificates")
-}
-*/
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/controller/patches/root.go b/deploy/k8s-operator/kube-trailblazer/pkg/helmer/controller/patches/root.go
deleted file mode 100644
index fa1eb832a..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/controller/patches/root.go
+++ /dev/null
@@ -1,8 +0,0 @@
-package chart
-
-// NotRoot not root
-func (ch *Chart) NotRoot() {
- ch.parent = nil
- ch.dependencies = nil
- ch.Metadata.Dependencies = nil
-}
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/controller/test.yaml b/deploy/k8s-operator/kube-trailblazer/pkg/helmer/controller/test.yaml
deleted file mode 100644
index 7c6f21f26..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/controller/test.yaml
+++ /dev/null
@@ -1,34 +0,0 @@
-
- - repoEntry:
- name: "zvonkok"
- url: "https://zvonkok.github.io/helm-charts/"
- chartSpec:
- release: "flannel"
- chart: "zvonkok/flannel"
- namespace: "flannel"
- version: "v0.23.0"
-
- - repoEntry:
- name: "nfd"
- url: "https://kubernetes-sigs.github.io/node-feature-discovery/charts"
- chartSpec:
- release: "node-feature-discovery"
- chart: "nfd/node-feature-discovery"
- namespace: "node-feature-discovery"
- version: "0.14.3"
- chartValues:
- kernelVersion: "{{ tpl .Values.runtime.kernelVersiosn }}" # {{ tpl .Values.chartValues.kernelVersion . }}
-
- - repoEntry:
- name: "nvidia"
- url: "https://helm.ngc.nvidia.com/nvidia"
- chartSpec:
- release: "gpu-operator"
- chart: "nvidia/gpu-operator"
- namespace: "gpu-operator"
- version: "v23.9.0"
- chartValues:
- nfd:
- enabled: false
- mig:
- strategy: "single"
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/graphs/helmer-kubevirt.yaml b/deploy/k8s-operator/kube-trailblazer/pkg/helmer/graphs/helmer-kubevirt.yaml
deleted file mode 100644
index 6715eed13..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/graphs/helmer-kubevirt.yaml
+++ /dev/null
@@ -1,41 +0,0 @@
-repoEntry:
- name: "nvidia"
- url: "file:///home/zvonkok/helm-charts/nvidia"
- username: ""
- password: ""
- certFile: ""
- keyFile: ""
- caFile: ""
- insecure_skip_tls_verify: false
- pass_credentials_all: false
-
-chartSpec:
- release: "nvidia-kubevirt"
- chart: "nvidia/kata-device-plugin"
- namespace: "nvidia"
- valuesYaml: ""
- version: "1.1.1"
- createNamespace: true
- disableHooks: false
- replace: true
- wait: true
- waitForJobs: true
- dependencyUpdate: false
- timeout: 10000000000
- generateName: true
- NameTemplate: ""
- atomic: false
- skipCRDs: false
- upgradeCRDs: true
- subNotes: false
- force: false
- resetValues: false
- reuseValues: false
- recreate: false
- maxHistory: 0
- cleanupOnFail: false
- dryRun: false
- # postRenderer: "setN"
-
-chartValues:
- kernelVersion: "{{ tpl .Values.runtime.kernelVersion }}" # {{ tpl .Values.chartValues.kernelVersion . }}
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/graphs/helmer-nfd.yaml b/deploy/k8s-operator/kube-trailblazer/pkg/helmer/graphs/helmer-nfd.yaml
deleted file mode 100644
index 96eded613..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/graphs/helmer-nfd.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-- repoEntry:
- name: "nfd"
- url: "https://kubernetes-sigs.github.io/node-feature-discovery/charts"
- chartSpec:
- release: "node-feature-discovery"
- chart: "nfd/node-feature-discovery"
- namespace: "node-feature-discovery"
- version: "0.14.3"
- chartValues:
- kernelVersion: "{{ tpl .Values.runtime.kernelVersion }}" # {{ tpl .Values.chartValues.kernelVersion . }}
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/graphs/helmer-nvidia-kata.yaml b/deploy/k8s-operator/kube-trailblazer/pkg/helmer/graphs/helmer-nvidia-kata.yaml
deleted file mode 100644
index f96b8f820..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/graphs/helmer-nvidia-kata.yaml
+++ /dev/null
@@ -1,41 +0,0 @@
-repoEntry:
- name: "nvidia"
- url: "file:///home/zvonkok/helm-charts/nvidia"
- username: ""
- password: ""
- certFile: ""
- keyFile: ""
- caFile: ""
- insecure_skip_tls_verify: false
- pass_credentials_all: false
-
-chartSpec:
- release: "nvidia-kata"
- chart: "nvidia/nvidia-kata"
- namespace: "nvidia"
- valuesYaml: ""
- version: "0.3.0"
- createNamespace: true
- disableHooks: false
- replace: true
- wait: true
- waitForJobs: true
- dependencyUpdate: false
- timeout: 10000000000
- generateName: true
- NameTemplate: ""
- atomic: false
- skipCRDs: false
- upgradeCRDs: true
- subNotes: false
- force: false
- resetValues: false
- reuseValues: false
- recreate: false
- maxHistory: 0
- cleanupOnFail: false
- dryRun: false
- # postRenderer: "setN"
-
-chartValues:
- kernelVersion: "{{ tpl .Values.runtime.kernelVersion }}" # {{ tpl .Values.chartValues.kernelVersion . }}
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/graphs/helmer-nvidia-vgpu.yaml b/deploy/k8s-operator/kube-trailblazer/pkg/helmer/graphs/helmer-nvidia-vgpu.yaml
deleted file mode 100644
index 67e0c6117..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/graphs/helmer-nvidia-vgpu.yaml
+++ /dev/null
@@ -1,41 +0,0 @@
-repoEntry:
- name: "nvidia"
- url: "file:///home/zvonkok/helm-charts/nvidia"
- username: ""
- password: ""
- certFile: ""
- keyFile: ""
- caFile: ""
- insecure_skip_tls_verify: false
- pass_credentials_all: false
-
-chartSpec:
- release: "nvidia-vgpu"
- chart: "nvidia/nvidia-vgpu"
- namespace: "nvidia"
- valuesYaml: ""
- version: "0.2.0"
- createNamespace: true
- disableHooks: false
- replace: true
- wait: true
- waitForJobs: true
- dependencyUpdate: false
- timeout: 10000000000
- generateName: true
- NameTemplate: ""
- atomic: false
- skipCRDs: false
- upgradeCRDs: true
- subNotes: false
- force: false
- resetValues: false
- reuseValues: false
- recreate: false
- maxHistory: 0
- cleanupOnFail: false
- dryRun: false
- # postRenderer: "setN"
-
-chartValues:
- kernelVersion: "{{ tpl .Values.runtime.kernelVersion }}" # {{ tpl .Values.chartValues.kernelVersion . }}
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/hack/helmer.sh b/deploy/k8s-operator/kube-trailblazer/pkg/helmer/hack/helmer.sh
deleted file mode 100755
index 471e93820..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/hack/helmer.sh
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/bin/bash
-
-HELM_PLUGINS=$(realpath ../plugins)
-export HELM_PLUGINS
-
-HELM_CHARTS_DIR=${HOME}/helm-charts
-HELM_REPOS=$(ls -d ${HELM_CHARTS_DIR}/*)
-HELM_TMP_DIR=$(mktemp -d)
-
-function lint {
- helm lint --with-subcharts --strict "${CHARTS}"
-}
-
-function package {
- helm package "${CHARTS}" --destination "${REPO}"
-}
-
-function repo_index {
- helm repo index "${REPO}" --url=file:///${REPO}
-}
-
-function dependency_update {
- for CHART in ${CHARTS}
- do
- helm dependency update "${CHART}"
- done
-}
-
-function template {
- for CHART in ${CHARTS}
- do
- MANIFESTS=${HELM_TMP_DIR}/$(basename "${CHART}").yaml
- echo "==> Templating ${CHART}"
- echo "[INFO] ${MANIFESTS}"
- echo ""
- helm template --name-template=nvidia "${CHART}" > "${MANIFESTS}"
- done
-}
-
-
-function kube_linter {
- echo "kube-linter"
-}
-
-function helmer_prereq {
- ln -sf "${HELM_PLUGINS}" /tmp/.helmplugins
-}
-
-function helmer {
- COMMAND=$1
- for REPO in ${HELM_REPOS}
- do
- CHARTS=$(ls -d "${REPO}"/*/)
- ${COMMAND}
- done
-}
-
-
-helmer_prereq
-
-#helmer lint
-helmer dependency_update
-helmer package
-helmer repo_index
-helmer lint
-helmer template
-helmer kube_linter
-
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/helmer.go b/deploy/k8s-operator/kube-trailblazer/pkg/helmer/helmer.go
deleted file mode 100644
index 5207ae77b..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/helmer.go
+++ /dev/null
@@ -1,599 +0,0 @@
-package helmer
-
-import (
- "bytes"
- "context"
- "encoding/json"
- "log"
- "os"
- "reflect"
-
- apierrors "k8s.io/apimachinery/pkg/api/errors"
-
- helmclient "github.com/mittwald/go-helm-client"
- "github.com/nvidia/kube-trailblazer/pkg/clients"
- "github.com/nvidia/kube-trailblazer/pkg/utils"
- "github.com/pkg/errors"
- "helm.sh/helm/v3/pkg/action"
- "helm.sh/helm/v3/pkg/chart"
- "helm.sh/helm/v3/pkg/chartutil"
- "helm.sh/helm/v3/pkg/release"
- "helm.sh/helm/v3/pkg/repo"
- "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
- "k8s.io/client-go/rest"
- "k8s.io/client-go/tools/clientcmd"
- "k8s.io/klog/v2"
- "sigs.k8s.io/controller-runtime/pkg/client"
- "sigs.k8s.io/yaml"
-)
-
-const (
- FilterKind = "HelmPipeline"
- FilterOwnedLabel = "app.trailblazer.nvidia.com/owned-by"
-)
-
-func (h *Helmer) GetClientsWithRestConf(restConf *rest.Config) error {
-
- var err error
-
- opt := &helmclient.RestConfClientOptions{
- Options: &helmclient.Options{
- Namespace: h.Package.ChartSpec.Namespace, // Change this to the namespace you wish to install the chart in.
- RepositoryCache: "/tmp/.helmcache",
- RepositoryConfig: "/tmp/.helmrepo",
- Debug: true,
- Linting: false, // Change this to false if you don't want linting.
- DebugLog: klog.Infof,
- },
- RestConfig: restConf,
- }
-
- h.Client, err = helmclient.NewClientFromRestConf(opt)
- if err != nil {
- return errors.Wrap(err, "\n[GGetClientWithRestConf]\tcannot create client from restConfig")
- }
- h.KubeClient, err = clients.NewKubeClientsFromRestConf(restConf)
- if err != nil {
- return errors.Wrapf(err, "\n[GGetClientWithRestConf]\tcannot create kubeClients from restConfig")
- }
- return nil
-}
-
-// GetClientWithKubeConf create a Helmer with a supplied KubeConf
-func (h *Helmer) GetClientsWithKubeConf(path string, kubeContext string) error {
-
- if path == "" {
- homeDir, err := os.UserHomeDir()
- if err != nil {
- return errors.Wrapf(err, "\n[GetClientWithKubeConf]\tcannot read user home dir")
- }
- path = homeDir + "/.kube/config"
- }
-
- kubeConfig, err := os.ReadFile(path)
- if err != nil {
- return errors.Wrapf(err, "\n[GetClientWithKubeConf]\tcannot read kubeConfig from path %s:%v", path, err)
- }
-
- opt := &helmclient.KubeConfClientOptions{
- Options: &helmclient.Options{
- Namespace: h.Package.ChartSpec.Namespace, // Change this to the namespace you wish to install the chart in.
- RepositoryCache: "/tmp/.helmcache",
- RepositoryConfig: "/tmp/.helmrepo",
- Debug: true,
- Linting: false, // Change this to false if you don't want linting.
- DebugLog: klog.Infof,
- },
- KubeContext: kubeContext,
- KubeConfig: kubeConfig,
- }
-
- h.Client, err = helmclient.NewClientFromKubeConf(opt)
- if err != nil {
- return errors.Wrap(err, "\n[GetClientWithKubeConf]\tcannot create client from kubeConfig")
- }
-
- clientCfg, err := clientcmd.NewClientConfigFromBytes(kubeConfig)
- if err != nil {
- log.Fatal(err)
- }
-
- restConf, err := clientCfg.ClientConfig()
- if err != nil {
- log.Fatal(err)
- }
- h.KubeClient, err = clients.NewKubeClientsFromRestConf(restConf)
- if err != nil {
- return errors.Wrapf(err, "\n[GGetClientWithRestConf]\tcannot create kubeClients from restConfig")
- }
- return nil
-}
-
-// New creates a simple Helmer object with debugging flag set
-func New() (*Helmer, error) {
-
- h := &Helmer{
- Debug: false,
- }
-
- os.Setenv("HELM_DEBUG", "1")
- //os.Setenv("HELM_PLUGINS", "/tmp/.helmplugins")
-
- if debug := os.Getenv("HELMER_DEBUG"); debug == "1" {
- h.Debug = true
- }
-
- h.Options = helmclient.GenericHelmOptions{
- PostRenderer: h,
- RollBack: nil,
- }
-
- return h, nil
-}
-
-// NewWithPackage creates a very simple Helmer object
-func NewWithPackage(pkg *HelmPackage) (*Helmer, error) {
-
- h, _ := New()
- h.Package = *pkg
-
- // TODO: Is there a better place to have this logic? BEGIN
- hash, err := utils.FNV64a(h.Package.RepoEntry.URL)
- if err != nil {
- return nil, errors.Wrapf(err, "[NewWithPackage] cannot create hash for repo ")
- }
-
- if h.Package.RepoEntry.Name == "" {
- h.Package.RepoEntry.Name = hash
- }
-
- if h.Package.ChartSpec.Namespace == "" {
- h.Package.ChartSpec.Namespace = h.Package.ChartSpec.ChartName
- h.Package.ChartSpec.CreateNamespace = true
- }
-
- if h.Package.ChartSpec.ReleaseName == "" {
- h.Package.ChartSpec.ReleaseName = h.Package.ChartSpec.ChartName + "-" + hash
- }
- // Replace the chart name with the full chart name
- h.Package.ChartSpec.ChartName = h.Package.RepoEntry.Name + "/" + h.Package.ChartSpec.ChartName
- // TODO: Is there a better place to have this logic? END
-
- // This is needed for housekeeping between rootChart and childChart
- h.Package.ReleaseName = h.Package.ChartSpec.ReleaseName
-
- return h, nil
-}
-
-// LoadPipeline loads an Pipeline from various sources
-func LoadPipeline(object interface{}) (Pipeline, error) {
-
- var err error
- var pipeline Pipeline
- switch t := object.(type) {
- case string:
-
- klog.Info("Pipeline:", object)
- if pipeline, err = LoadPipelineFromFile(t); err != nil {
- return nil, errors.Wrapf(err, "\n[LoadPipeline]\tfailed loading Package from file: %s", t)
- }
- return pipeline, nil
-
- case map[string]interface{}:
-
- klog.Info("Pipeline:", object)
- if pipeline, err = LoadPipelineFromObject(t); err != nil {
- return nil, errors.Wrapf(err, "\n[LoadPipeline]\tfailed loading Package from map: %v", t)
- }
-
- return pipeline, nil
-
- default:
- return nil, errors.New("\n[Load]\tcannot construct Package from type: " + reflect.TypeOf(object).String())
- }
-}
-
-// LoadPipelineFromFile reads an Pipeline object from provided YANL file
-func LoadPipelineFromFile(file string) (Pipeline, error) {
-
- var orhcard Pipeline
-
- yamlText, err := os.ReadFile(file)
- if err != nil {
- return nil, errors.Wrapf(err, "\n[LoadPackageFromFile]\tcannot read %s from path %s:%v", yamlText, file, err)
- }
-
- jsonText, err := yaml.YAMLToJSON(yamlText)
- if err != nil {
- return nil, errors.Wrapf(err, "\n[LoadPackageFromFile]\tfailed on %s", yamlText)
- }
- dec := json.NewDecoder(bytes.NewReader(jsonText))
- dec.DisallowUnknownFields()
-
- if err := dec.Decode(&orhcard); err != nil {
- return nil, errors.Wrapf(err, "\n[LoadPackageFromFile]\tfailed on %s", jsonText)
- }
- return UpdatePipelineWithDefaultChartSpec(orhcard), err
-}
-
-// LoadPipelineFromObject loads an Pipeline from a CR or any other YAML like object
-func LoadPipelineFromObject(object map[string]interface{}) (Pipeline, error) {
-
- var pipeline Pipeline
-
- UpdatePipelineWithDefaultChartSpec(pipeline)
- return pipeline, nil
-}
-
-// GetChart loads the chart from the repo
-func (h *Helmer) GetChart(chartSpec *helmclient.ChartSpec) (*chart.Chart, error) {
-
- chart, _, err := h.Client.GetChart(chartSpec.ChartName, &action.ChartPathOptions{})
- return chart, err
-
-}
-
-// InstallOrUpgradePackage implements HelmHelper
-func (h *Helmer) InstallOrUpgradePackage() error {
-
- // The graph chart values can override chart.Values
- rootValues := h.Package.ChartValues
-
- chartSpec := h.Package.ChartSpec.DeepCopy()
- rootChart, err := h.GetChart(chartSpec)
- if err != nil {
- return errors.Wrapf(err, "\n[InstallOrUpgradePackage]\tcannot get Chart from Package %s", h.Package.ChartSpec.ReleaseName)
- }
- err = h.install(rootChart, &rootValues)
- if err != nil {
- return errors.Wrapf(err, "\n[InstallOrUpgradePackage]\tcannot install Chart from Package %s", h.Package.ChartSpec.ReleaseName)
- }
-
- return nil
-}
-
-func checkKubeAPIErrors(err error, msg string) error {
- if apierrors.IsNotFound(err) {
- return errors.Wrapf(err, "[checkKubeAPIErrors]\t%s not found", msg)
-
- }
- if apierrors.IsForbidden(err) {
- return errors.Wrapf(err, "[checkKubeAPIErrors]\tforbidden, check Role, ClusterRole and Bindings for operator")
- }
-
- if err != nil {
- return errors.Wrapf(err, "[checkKubeAPIErrors]\tunexpected error")
- }
- return nil
-}
-
-func (h *Helmer) setReleaseOwnerReference(chartRelease *release.Release) error {
-
- matchingLabels := map[string]string{
- "owner": "helm",
- "name": chartRelease.Name,
- "status": "deployed",
- }
-
- opts := []client.ListOption{
- client.InNamespace(chartRelease.Namespace),
- client.MatchingLabels(matchingLabels),
- }
-
- secrets := unstructured.UnstructuredList{}
- secrets.SetAPIVersion("v1")
- secrets.SetKind("SecretList")
-
- err := h.KubeClient.List(context.TODO(), &secrets, opts...)
- if checkKubeAPIErrors(err, "SecretList"); err != nil {
- return errors.Wrapf(err, "[setReleaseOwnerReference]\tcannot list secrets for chartRelease: ", chartRelease.Name)
- }
-
- for _, secret := range secrets.Items {
- labels := secret.GetLabels()
- labels[FilterOwnedLabel] = FilterKind
-
- secret.SetLabels(labels)
- klog.Infof("[setReleaseOwnerReference]\tupdating release %s:%s", secret.GetNamespace(), secret.GetName())
- err := h.KubeClient.Update(context.Background(), &secret)
- if checkKubeAPIErrors(err, "Secret"); err != nil {
- return errors.Wrapf(err, "[setReleaseOwnerReference]\tcannot update secret for chartRelease: ", chartRelease.Name)
- }
- }
-
- return nil
-}
-
-func (h *Helmer) install(rootChart *chart.Chart, rootValues *chartutil.Values) error {
-
- var err error
- // TODO: Sharing Templates with Subcharts
- // Parent charts and subcharts can share templates.
- // Any defined block in any chart is available to other charts.
- //for _, childChart := range rootChart {
- // id := childChart.ChartFullPath()
- //}
-
- // rootValues will hold the value overrides for the child chart
- *rootValues, err = chartutil.CoalesceValues(rootChart, rootValues.AsMap())
- if err != nil {
- return errors.Wrapf(err, "\n[Install]\tcoalesce values failed %v", rootChart.Name())
- }
-
- err = chartutil.ProcessDependencies(rootChart, *rootValues)
- if err != nil {
- return errors.Wrapf(err, "\n[Install]\tprocess dependencies failed for %v", rootChart.Name())
- }
-
- // We need the initial releaseName since we're updating each child chart
- // with a new releaseName, this way we are not concat relase + child0 + child1
- h.installDependencies(rootChart.Dependencies(), rootValues)
-
- // Reset the releasename if we are the original root chart
- if rootChart.IsRoot() {
- h.Package.ChartSpec.ReleaseName = h.Package.ReleaseName
- }
- // Need to reset the root flag, helm aggregates all Values and templates
- // if it is a root chart it will only populate the child values with
- // the root .Value.childChart not the actual child values
- rootChart.NotRoot()
-
- vals, err := rootValues.YAML()
- if err != nil {
- return errors.Wrapf(err, "\n[Install]\tcannot convert rootValues to YAML")
- }
-
- h.Package.ChartSpec.ValuesYaml = vals
-
- chartSpec := h.Package.ChartSpec.DeepCopy()
- chartRelease, err := h.Client.InstallOrUpgradeChart(context.TODO(), chartSpec, &h.Options)
- if err != nil {
- return errors.Wrapf(err, "\n[Install]\tchart failed with %v", rootChart.Name())
- }
-
- err = h.setReleaseOwnerReference(chartRelease)
- if err != nil {
- return errors.Wrapf(err, "\n[Install]\tcannot setReleaseOwnerReference for charRelease %s", chartRelease.Name)
- }
-
- return nil
-}
-
-func (h *Helmer) installDependencies(rootChart []*chart.Chart, rootValues *chartutil.Values) error {
-
- childValues := chartutil.Values{}
-
- for _, childChart := range rootChart {
-
- // Overriding Values from a Parent Values
- // The value at the top level can override the
- // value of the subchart.
- if rootOverride, err := rootValues.Table(childChart.Name()); err == nil {
- childValues = chartutil.CoalesceTables(childValues, rootOverride)
- }
-
- // Global Chart Values
- // Global values are values that can be accessed from any
- // chart or subchart by exactly the same name.
- if rootGlobal, err := rootValues.Table("global"); err == nil {
- childGlobal, err := childValues.Table("global")
- if err != nil {
- return errors.Wrap(err, "\n[installDependencies]\tcannot extract global from childValues")
- }
- childValues["global"] = chartutil.CoalesceTables(childGlobal, rootGlobal)
- }
-
- h.installDependency(childChart, &childValues)
- }
- return nil
-}
-
-func (h *Helmer) updateChildPackage(childChart *chart.Chart) {
- h.Package.ChartSpec.ReleaseName = h.Package.ReleaseName + "-" + childChart.Name()
- h.Package.ChartSpec.ChartName = h.Package.RepoEntry.Name + "/" + childChart.Name()
- h.Package.ChartSpec.Version = childChart.Metadata.Version
-}
-
-func (h *Helmer) installDependency(childChart *chart.Chart, childValues *chartutil.Values) error {
-
- // For each chart we create an Helmer instance with its own settings
- // this makes it easier to decouple each chart for processing and clients
- // that do not interfere with each other.
-
- // Copy root definitions and apply to child charts, we may think of
- // own graph definitions for child charts
- h.updateChildPackage(childChart)
-
- klog.Info(h.Package.ChartSpec)
-
- c, err := NewWithPackage(&h.Package)
- if err != nil {
- return errors.Wrapf(err, "\n[installDependency]\tcannot create new Helmer with Package %s", h.Package.ChartSpec.ReleaseName)
- }
-
- // TODO: add generic client which can handle "all" situations
- err = c.GetClientsWithKubeConf("", "default")
- if err != nil {
- return errors.Wrapf(err, "\n[installDependency]\tcannot get client with kubeConf")
- }
-
- klog.Info("[InstallChildChart]: ", childChart.Name())
-
- err = c.install(childChart, childValues)
- if err != nil {
- return errors.Wrapf(err, "\n[installDependency]\tcannot install chart: %s", childChart.Name())
- }
- return nil
-}
-
-// Upgrade implements HelmHelper
-func (h *Helmer) Upgrade() error {
- panic("unimplemented")
-}
-
-// Lint implement HelmHelper
-func (h *Helmer) Lint() error {
- chartSpec := h.Package.ChartSpec.DeepCopy()
- if err := h.Client.LintChart(chartSpec); err != nil {
- return errors.Wrap(err, "[Lint] failed linting chart")
- }
- return nil
-}
-
-// Template implement HelmHelper
-func (h *Helmer) Template() error {
- var err error
- yamls := []byte{}
- chartSpec := h.Package.ChartSpec.DeepCopy()
- if yamls, err = h.Client.TemplateChart(chartSpec, nil); err != nil {
- return errors.Wrap(err, "[Template] templating failed")
- }
- if h.Debug {
- klog.Info(string(yamls))
- }
-
- return nil
-}
-
-// AddOrUpdateRepo implements HelmHelper
-func (h *Helmer) AddOrUpdateRepo() error {
-
- var repoEntry repo.Entry
-
- h.Package.RepoEntry.DeepCopyInto(&repoEntry)
- if err := h.Client.AddOrUpdateChartRepo(repoEntry); err != nil {
- return errors.Wrapf(err, "[AddOrUpdateChartRepo] failed with repo entry %v", h.Package.RepoEntry)
- }
-
- return nil
-}
-
-func (h *Helmer) RunChartTests() (bool, error) {
- return h.Client.RunChartTests(h.Package.ChartSpec.ReleaseName)
-}
-
-func ReconcileDelete(pipeline Pipeline, restConf *rest.Config) error {
- for _, pkg := range UpdatePipelineWithDefaultChartSpec(pipeline) {
-
- // For each chart we create an Helmer instance with its own settings
- // this makes it easier to decouple each chart for processing and clients
- // that do not interfere with each other.
- h, err := NewWithPackage(&pkg)
- if err != nil {
- panic(err)
- }
-
- err = h.GetClientsWithRestConf(restConf)
- if err != nil {
- panic(err)
- }
- chartSpec := h.Package.ChartSpec.DeepCopy()
- err = h.UninstallRelease(chartSpec)
- if err != nil {
- return errors.Wrapf(err, "\n[ReconcileDelete]\tcannot uninstall release %s", h.Package.ChartSpec.ReleaseName)
- }
- }
- return nil
-}
-
-func ReconcileCreate(pipeline Pipeline, restConf *rest.Config) ([]*release.Release, error) {
-
- var releases []*release.Release
-
- for _, pkg := range UpdatePipelineWithDefaultChartSpec(pipeline) {
- // For each chart we create an Helmer instance with its own settings
- // this makes it easier to decouple each chart for processing and clients
- // that do not interfere with each other.
- h, err := NewWithPackage(&pkg)
- if err != nil {
- panic(err)
- }
-
- err = h.GetClientsWithRestConf(restConf)
- if err != nil {
- panic(err)
- }
- err = h.AddOrUpdateRepo()
- if err != nil {
- return nil, err
- }
-
- err = h.Lint()
- if err != nil {
- return nil, err
- }
- err = h.InstallOrUpgradePackage()
- if err != nil {
- return nil, err
- }
- ok, err := h.RunChartTests()
- if !ok {
- klog.Infof("[Reconcile]\tchart tests failed for %s", h.Package.ChartSpec.ReleaseName)
- return nil, err
- }
- if err != nil {
- klog.Infof("[Reconcile]\terror executing tests for %s", h.Package.ChartSpec.ReleaseName)
-
- }
- if err == nil {
- releases, err = h.ListDeployedReleases()
- if err != nil {
- return nil, err
- }
- }
- }
- return releases, nil
-}
-
-// UpdateGrapshWithDefaultChartSpec updates a HelmPackage with default ChartSpec values
-func UpdatePipelineWithDefaultChartSpec(in Pipeline) Pipeline {
- var out Pipeline
- for _, pkg := range in {
- pkg.ChartSpec.CreateNamespace = true
- pkg.ChartSpec.DisableHooks = false
- pkg.ChartSpec.Replace = true
- pkg.ChartSpec.Wait = true
- pkg.ChartSpec.WaitForJobs = true
- pkg.ChartSpec.DependencyUpdate = false
- pkg.ChartSpec.Timeout = 10000000000
- pkg.ChartSpec.GenerateName = false
- pkg.ChartSpec.NameTemplate = ""
- pkg.ChartSpec.Atomic = false
- pkg.ChartSpec.SkipCRDs = false
- pkg.ChartSpec.UpgradeCRDs = true
- pkg.ChartSpec.SubNotes = false
- pkg.ChartSpec.Force = false
- pkg.ChartSpec.ResetValues = false
- pkg.ChartSpec.ReuseValues = false
- pkg.ChartSpec.Recreate = false
- // Keep this at one, otherwise we will have a lot of
- // incomplete releases because of reconciliation
- pkg.ChartSpec.MaxHistory = 0
- pkg.ChartSpec.CleanupOnFail = false
- pkg.ChartSpec.DryRun = false
- pkg.ChartSpec.Description = ""
- pkg.ChartSpec.KeepHistory = false
- out = append(out, pkg)
- }
- return out
-}
-
-func (h *Helmer) UninstallRelease(spec *helmclient.ChartSpec) error {
- return h.Client.UninstallRelease(spec)
-}
-func (h *Helmer) ListDeployedReleases() ([]*release.Release, error) {
-
- ownedReleases := make([]*release.Release, 0)
-
- chartReleases, err := h.Client.ListDeployedReleases()
- if err != nil {
-
- }
- for _, chartRelease := range chartReleases {
- if chartRelease.Labels[FilterOwnedLabel] == FilterKind {
- ownedReleases = append(ownedReleases, chartRelease)
- }
-
- }
- return ownedReleases, nil
-}
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/interface.go b/deploy/k8s-operator/kube-trailblazer/pkg/helmer/interface.go
deleted file mode 100644
index d11494451..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/interface.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package helmer
-
-import (
- helmclient "github.com/mittwald/go-helm-client"
- "helm.sh/helm/v3/pkg/chart"
- "helm.sh/helm/v3/pkg/release"
- "k8s.io/client-go/rest"
-)
-
-// Interface a helm hepler Helper
-type Interface interface {
- InstallOrUpgradePackage() error
- Upgrade() error
- Lint() error
- Template() error
- AddOrUpdateRepo() error
- GetClientsWithKubeConf(path string, kubeContext string) error
- GetClientsWithRestConf(restConf *rest.Config) error
- GetChart(char *helmclient.ChartSpec) (*chart.Chart, error)
- RunChartTests() (bool, error)
- UninstallRelease(spec *helmclient.ChartSpec) error
- ListDeployedReleases() ([]*release.Release, error)
-}
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/package.go b/deploy/k8s-operator/kube-trailblazer/pkg/helmer/package.go
deleted file mode 100644
index 8abae9f4a..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/package.go
+++ /dev/null
@@ -1,62 +0,0 @@
-package helmer
-
-import (
- "github.com/mittwald/go-helm-client/values"
-)
-
-// NewHelmPackageWithDefaultChartSpec creates a new HelmPackage with default ChartSpec values
-// that trailblazer things may be usefull
-func NewHelmPackageWithDefaultChartSpec() *HelmPackage {
- pipeline := &HelmPackage{
- RepoEntry: repoEntry{},
- ChartSpec: chartSpec{
- ReleaseName: "",
- ChartName: "",
- Namespace: "",
- ValuesYaml: "",
- ValuesOptions: values.Options{},
- Version: "",
- CreateNamespace: true,
- DisableHooks: false,
- Replace: true,
- Wait: true,
- WaitForJobs: true,
- DependencyUpdate: false,
- Timeout: 90000000000,
- GenerateName: true,
- NameTemplate: "",
- Atomic: false,
- SkipCRDs: false,
- UpgradeCRDs: true,
- SubNotes: false,
- Force: false,
- ResetValues: false,
- ReuseValues: false,
- Recreate: false,
- MaxHistory: 1,
- CleanupOnFail: false,
- DryRun: false,
- Description: "",
- KeepHistory: false,
- },
- ChartValues: make(map[string]interface{}),
- ReleaseName: "",
- }
- return pipeline
-}
-
-func (in *HelmPackage) DeepCopyInto(out *HelmPackage) {
- *out = *in
- out.RepoEntry = in.RepoEntry
- out.ChartSpec = in.ChartSpec
- out.ChartValues = in.ChartValues
-}
-
-func (in *HelmPackage) DeepCopy() *HelmPackage {
- if in == nil {
- return nil
- }
- out := new(HelmPackage)
- in.DeepCopyInto(out)
- return out
-}
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/plugins/file-proto/file-downloader.sh b/deploy/k8s-operator/kube-trailblazer/pkg/helmer/plugins/file-proto/file-downloader.sh
deleted file mode 100755
index 8066b4e06..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/plugins/file-proto/file-downloader.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-
-# [~/helm-charts/nvidia]$ helm package kvm-driver-container-0.1.0
-# Successfully packaged chart and saved it to: /home/zvonkok/helm-charts/nvidia/kvm-driver-container-0.1.0.tgz
-# [~/helm-charts/nvidia]$ helm repo index . --url=file:///$PWD
-
-FILE=${4/file:\/\//}
-
-echo $FILE >> /tmp/log.txt
-
-cat $FILE
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/plugins/file-proto/file-helper.sh b/deploy/k8s-operator/kube-trailblazer/pkg/helmer/plugins/file-proto/file-helper.sh
deleted file mode 100644
index f355d4e52..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/plugins/file-proto/file-helper.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash
-
-# See e.g. https://github.com/viglesiasce/helm-gcs/tree/master/bin
\ No newline at end of file
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/plugins/file-proto/plugin.yaml b/deploy/k8s-operator/kube-trailblazer/pkg/helmer/plugins/file-proto/plugin.yaml
deleted file mode 100644
index 400f78c7c..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/plugins/file-proto/plugin.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-name: "file"
-version: "0.1.0"
-usage: "file:// protocol for charts and repositories."
-description: "file:// protocol for charts and repositories."
-command: "$HELM_PLUGIN_DIR/file-helper.sh"
-downloaders:
-- command: "file-downloader.sh"
- protocols:
- - "file"
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/plugins/plugins b/deploy/k8s-operator/kube-trailblazer/pkg/helmer/plugins/plugins
deleted file mode 120000
index 83aedfc9d..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/plugins/plugins
+++ /dev/null
@@ -1 +0,0 @@
-/zvonkok/github.com/zvonkok/helmer/plugins
\ No newline at end of file
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/postrenderer.go b/deploy/k8s-operator/kube-trailblazer/pkg/helmer/postrenderer.go
deleted file mode 100644
index 8f31df684..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/postrenderer.go
+++ /dev/null
@@ -1,68 +0,0 @@
-package helmer
-
-import (
- "bytes"
- "errors"
- "fmt"
- "os"
- "os/exec"
-)
-
-func check(e error) {
- if e != nil {
- panic(e)
- }
-}
-
-func mkdir(path string) error {
- if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) {
- err := os.MkdirAll(path, os.ModePerm)
- if err != nil {
- return err
- }
- }
- return nil
-}
-
-func (h *Helmer) Run(renderedManifests *bytes.Buffer) (modifiedManifests *bytes.Buffer, err error) {
-
- kustomizePath := "/kustomize/"
- chart := h.Package.ReleaseName + "-" + h.Package.ChartSpec.Version
- basePath := kustomizePath + chart + "/base/"
-
- err = mkdir(basePath)
- check(err)
-
- var kustomization bytes.Buffer
-
- manifests := bytes.Split(renderedManifests.Bytes(), []byte("---"))
- if len(manifests[0]) == 0 {
- manifests = manifests[1:]
- }
-
- kustomization.WriteString("resources:\n")
- for i, manifest := range manifests {
- // this cannot error per docs
- name := fmt.Sprintf("resource-%d.yaml", i)
- err := os.WriteFile(basePath+name, manifest, 0644)
- check(err)
- fmt.Fprintf(&kustomization, " - %s\n", name)
- }
-
- kustomization.WriteString("\n")
- kustomization.WriteString("commonLabels:\n")
- kustomization.WriteString(" app.trailblazer.nvidia.com/owned-by: HelmOrchard\n")
-
- err = os.WriteFile(basePath+"kustomization.yaml", kustomization.Bytes(), 0644)
- check(err)
-
- kustomize := exec.Command("kustomize", "build", basePath)
- out, err := kustomize.Output()
- check(err)
-
- // otherwise, print the output from running the command
- //klog.Info("Output: ", string(out))
- renderedManifests = bytes.NewBuffer(out)
-
- return renderedManifests, nil
-}
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/repo.go b/deploy/k8s-operator/kube-trailblazer/pkg/helmer/repo.go
deleted file mode 100644
index d6dc642fe..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/repo.go
+++ /dev/null
@@ -1,17 +0,0 @@
-package helmer
-
-import "helm.sh/helm/v3/pkg/repo"
-
-func (in *repoEntry) DeepCopyInto(out *repo.Entry) *repo.Entry {
- out.Name = in.Name
- out.URL = in.URL
- out.Username = in.Username
- out.Password = in.Password
- out.CertFile = in.CertFile
- out.KeyFile = in.KeyFile
- out.CAFile = in.CAFile
- out.InsecureSkipTLSverify = in.InsecureSkipTLSverify
- out.PassCredentialsAll = in.PassCredentialsAll
-
- return out
-}
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/types.go b/deploy/k8s-operator/kube-trailblazer/pkg/helmer/types.go
deleted file mode 100644
index cac21c615..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/helmer/types.go
+++ /dev/null
@@ -1,150 +0,0 @@
-package helmer
-
-import (
- "time"
-
- helmclient "github.com/mittwald/go-helm-client"
- "github.com/mittwald/go-helm-client/values"
- "github.com/nvidia/kube-trailblazer/pkg/clients"
- "helm.sh/helm/v3/pkg/chartutil"
-)
-
-// Type Guard asserting that Helmer satisfies the Helmer interface.
-var _ Interface = &Helmer{}
-
-// Helmer describes the resource to be built
-type Helmer struct {
- Package HelmPackage `json:"helmArbor"`
- Client helmclient.Client `json:"helmClient"`
- Options helmclient.GenericHelmOptions `json:"helmOptions"`
- KubeClient clients.ClientsInterface `json:"kubeClient"`
- Debug bool `json:"debug"`
-}
-
-// Entry represents a collection of parameters for chart repository, since
-// we cannot annotate the internal helm struct we're doing it here
-type repoEntry struct {
- // +kubebuilder:validation:Optional
- Name string `json:"name"`
- URL string `json:"url"`
- // +kubebuilder:validation:Optional
- Username string `json:"username"`
- // +kubebuilder:validation:Optional
- Password string `json:"password"`
- // +kubebuilder:validation:Optional
- CertFile string `json:"certFile"`
- // +kubebuilder:validation:Optional
- KeyFile string `json:"keyFile"`
- // +kubebuilder:validation:Optional
- CAFile string `json:"caFile"`
- // +kubebuilder:validation:Optional
- InsecureSkipTLSverify bool `json:"insecure_skip_tls_verify"`
- // +kubebuilder:validation:Optional
- PassCredentialsAll bool `json:"pass_credentials_all"`
-}
-type chartSpec struct {
- // +kubebuilder:validation:Optional
- ReleaseName string `json:"release"`
- ChartName string `json:"chart"`
- // Namespace where the chart release is deployed.
- // Note that helmclient.Options.Namespace should ideally match the namespace configured here.
- // +kubebuilder:validation:Optional
- Namespace string `json:"namespace"`
- // ValuesYaml is the values.yaml content.
- // use string instead of map[string]interface{}
- // https://github.com/kubernetes-sigs/kubebuilder/issues/528#issuecomment-466449483
- // and https://github.com/kubernetes-sigs/controller-tools/pull/317
- // +optional
- ValuesYaml string `json:"valuesYaml,omitempty"`
- // Specify values similar to the cli
- // +optional
- ValuesOptions values.Options `json:"valuesOptions,omitempty"`
- // Version of the chart release.
- // +optional
- Version string `json:"version,omitempty"`
- // CreateNamespace indicates whether to create the namespace if it does not exist.
- // +optional
- CreateNamespace bool `json:"createNamespace,omitempty"`
- // DisableHooks indicates whether to disable hooks.
- // +optional
- DisableHooks bool `json:"disableHooks,omitempty"`
- // Replace indicates whether to replace the chart release if it already exists.
- // +optional
- Replace bool `json:"replace,omitempty"`
- // Wait indicates whether to wait for the release to be deployed or not.
- // +optional
- Wait bool `json:"wait,omitempty"`
- // WaitForJobs indicates whether to wait for completion of release Jobs before marking the release as successful.
- // 'Wait' has to be specified for this to take effect.
- // The timeout may be specified via the 'Timeout' field.
- WaitForJobs bool `json:"waitForJobs,omitempty"`
- // DependencyUpdate indicates whether to update the chart release if the dependencies have changed.
- // +optional
- DependencyUpdate bool `json:"dependencyUpdate,omitempty"`
- // Timeout configures the time to wait for any individual Kubernetes operation (like Jobs for hooks).
- // +optional
- Timeout time.Duration `json:"timeout,omitempty"`
- // GenerateName indicates that the release name should be generated.
- // +optional
- GenerateName bool `json:"generateName,omitempty"`
- // NameTemplate is the template used to generate the release name if GenerateName is configured.
- // +optional
- NameTemplate string `json:"nameTemplate,omitempty"`
- // Atomic indicates whether to install resources atomically.
- // 'Wait' will automatically be set to true when using Atomic.
- // +optional
- Atomic bool `json:"atomic,omitempty"`
- // SkipCRDs indicates whether to skip CRDs during installation.
- // +optional
- SkipCRDs bool `json:"skipCRDs,omitempty"`
- // Upgrade indicates whether to perform a CRD upgrade during installation.
- // +optional
- UpgradeCRDs bool `json:"upgradeCRDs,omitempty"`
- // SubNotes indicates whether to print sub-notes.
- // +optional
- SubNotes bool `json:"subNotes,omitempty"`
- // Force indicates whether to force the operation.
- // +optional
- Force bool `json:"force,omitempty"`
- // ResetValues indicates whether to reset the values.yaml file during installation.
- // +optional
- ResetValues bool `json:"resetValues,omitempty"`
- // ReuseValues indicates whether to reuse the values.yaml file during installation.
- // +optional
- ReuseValues bool `json:"reuseValues,omitempty"`
- // Recreate indicates whether to recreate the release if it already exists.
- // +optional
- Recreate bool `json:"recreate,omitempty"`
- // MaxHistory limits the maximum number of revisions saved per release.
- // +optional
- MaxHistory int `json:"maxHistory,omitempty"`
- // CleanupOnFail indicates whether to cleanup the release on failure.
- // +optional
- CleanupOnFail bool `json:"cleanupOnFail,omitempty"`
- // DryRun indicates whether to perform a dry run.
- // +optional
- DryRun bool `json:"dryRun,omitempty"`
- // Description specifies a custom description for the uninstalled release
- // +optional
- Description string `json:"description,omitempty"`
- // KeepHistory indicates whether to retain or purge the release history during uninstall
- // +optional
- KeepHistory bool `json:"keepHistory,omitempty"`
-}
-
-// A shelter of vines or branches or of latticework covered with climbing
-// shrubs or vines, also latin for tree
-type HelmPackage struct {
- RepoEntry repoEntry `json:"repoEntry"`
- ChartSpec chartSpec `json:"chartSpec"`
- // +kubebuilder:validation:Optional
- // +kubebuilder:validation:Schemaless
- // +kubebuilder:pruning:PreserveUnknownFields
- // +kubebuilder:validation:Type=object
- // TODO ChartValues json.RawMessage `json:"chartValues"`
- ChartValues chartutil.Values `json:"chartValues"`
- // +kubebuilder:validation:Optional
- ReleaseName string `json:"releaseName"`
-}
-
-type Pipeline []HelmPackage
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/storage/mock_storage_api.go b/deploy/k8s-operator/kube-trailblazer/pkg/storage/mock_storage_api.go
deleted file mode 100644
index 14004b58e..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/storage/mock_storage_api.go
+++ /dev/null
@@ -1,79 +0,0 @@
-// Code generated by MockGen. DO NOT EDIT.
-// Source: storage.go
-
-// Package storage is a generated GoMock package.
-package storage
-
-import (
- context "context"
- reflect "reflect"
-
- gomock "github.com/golang/mock/gomock"
- types "k8s.io/apimachinery/pkg/types"
-)
-
-// MockStorage is a mock of Storage interface.
-type MockStorage struct {
- ctrl *gomock.Controller
- recorder *MockStorageMockRecorder
-}
-
-// MockStorageMockRecorder is the mock recorder for MockStorage.
-type MockStorageMockRecorder struct {
- mock *MockStorage
-}
-
-// NewMockStorage creates a new mock instance.
-func NewMockStorage(ctrl *gomock.Controller) *MockStorage {
- mock := &MockStorage{ctrl: ctrl}
- mock.recorder = &MockStorageMockRecorder{mock}
- return mock
-}
-
-// EXPECT returns an object that allows the caller to indicate expected use.
-func (m *MockStorage) EXPECT() *MockStorageMockRecorder {
- return m.recorder
-}
-
-// CheckConfigMapEntry mocks base method.
-func (m *MockStorage) CheckConfigMapEntry(arg0 context.Context, arg1 string, arg2 types.NamespacedName) (string, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "CheckConfigMapEntry", arg0, arg1, arg2)
- ret0, _ := ret[0].(string)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// CheckConfigMapEntry indicates an expected call of CheckConfigMapEntry.
-func (mr *MockStorageMockRecorder) CheckConfigMapEntry(arg0, arg1, arg2 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckConfigMapEntry", reflect.TypeOf((*MockStorage)(nil).CheckConfigMapEntry), arg0, arg1, arg2)
-}
-
-// DeleteConfigMapEntry mocks base method.
-func (m *MockStorage) DeleteConfigMapEntry(arg0 context.Context, arg1 string, arg2 types.NamespacedName) error {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "DeleteConfigMapEntry", arg0, arg1, arg2)
- ret0, _ := ret[0].(error)
- return ret0
-}
-
-// DeleteConfigMapEntry indicates an expected call of DeleteConfigMapEntry.
-func (mr *MockStorageMockRecorder) DeleteConfigMapEntry(arg0, arg1, arg2 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteConfigMapEntry", reflect.TypeOf((*MockStorage)(nil).DeleteConfigMapEntry), arg0, arg1, arg2)
-}
-
-// UpdateConfigMapEntry mocks base method.
-func (m *MockStorage) UpdateConfigMapEntry(arg0 context.Context, arg1, arg2 string, arg3 types.NamespacedName) error {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "UpdateConfigMapEntry", arg0, arg1, arg2, arg3)
- ret0, _ := ret[0].(error)
- return ret0
-}
-
-// UpdateConfigMapEntry indicates an expected call of UpdateConfigMapEntry.
-func (mr *MockStorageMockRecorder) UpdateConfigMapEntry(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateConfigMapEntry", reflect.TypeOf((*MockStorage)(nil).UpdateConfigMapEntry), arg0, arg1, arg2, arg3)
-}
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/storage/storage.go b/deploy/k8s-operator/kube-trailblazer/pkg/storage/storage.go
deleted file mode 100644
index 82624ffde..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/storage/storage.go
+++ /dev/null
@@ -1,97 +0,0 @@
-package storage
-
-import (
- "context"
-
- "github.com/openshift-psap/special-resource-operator/pkg/clients"
- v1 "k8s.io/api/core/v1"
- apierrors "k8s.io/apimachinery/pkg/api/errors"
- "k8s.io/apimachinery/pkg/types"
- ctrl "sigs.k8s.io/controller-runtime"
- "sigs.k8s.io/controller-runtime/pkg/client"
-)
-
-//go:generate mockgen -source=storage.go -package=storage -destination=mock_storage_api.go
-
-type Storage interface {
- CheckConfigMapEntry(context.Context, string, types.NamespacedName) (string, error)
- UpdateConfigMapEntry(context.Context, string, string, types.NamespacedName) error
- DeleteConfigMapEntry(context.Context, string, types.NamespacedName) error
-}
-
-type storage struct {
- kubeClient clients.ClientsInterface
-}
-
-func NewStorage(kubeClient clients.ClientsInterface) Storage {
- return &storage{kubeClient: kubeClient}
-}
-
-func (s *storage) CheckConfigMapEntry(ctx context.Context, key string, ins types.NamespacedName) (string, error) {
- cm, err := s.getConfigMap(ctx, ins.Namespace, ins.Name)
- if err != nil {
- return "", err
- }
-
- return cm.Data[key], nil
-}
-
-func (s *storage) UpdateConfigMapEntry(ctx context.Context, key string, value string, ins types.NamespacedName) error {
- cm, err := s.getConfigMap(ctx, ins.Namespace, ins.Name)
- if err != nil {
- ctrl.LoggerFrom(ctx).Error(err, "Failed to get configmap to update an entry", "namespacedName", ins, "key", key, "value", value)
- return err
- }
-
- if cm.Data == nil {
- cm.Data = make(map[string]string)
- }
-
- if cm.Data[key] != value {
- cm.Data[key] = value
-
- if err = s.updateObject(ctx, cm); err != nil {
- ctrl.LoggerFrom(ctx).Error(err, "Failed to update configmap to update an entry", "namespacedName", ins, "key", key, "value", value)
- return err
- }
- }
-
- return nil
-}
-
-func (s *storage) DeleteConfigMapEntry(ctx context.Context, key string, ins types.NamespacedName) error {
- cm, err := s.getConfigMap(ctx, ins.Namespace, ins.Name)
- if err != nil {
- ctrl.LoggerFrom(ctx).Error(err, "Failed to get configmap to remove an entry", "namespacedName", ins, "key", key)
- return err
- }
-
- if _, ok := cm.Data[key]; ok {
- delete(cm.Data, key)
-
- if err = s.updateObject(ctx, cm); err != nil {
- ctrl.LoggerFrom(ctx).Error(err, "Failed to update configmap to remove an entry", "namespacedName", ins, "key", key)
- return err
- }
- }
-
- return nil
-}
-
-func (s *storage) getConfigMap(ctx context.Context, namespace string, name string) (*v1.ConfigMap, error) {
- cm := &v1.ConfigMap{}
- dep := types.NamespacedName{Namespace: namespace, Name: name}
-
- err := s.kubeClient.Get(ctx, dep, cm)
-
- if apierrors.IsNotFound(err) {
- ctrl.LoggerFrom(ctx).Error(err, "Failed to get configmap", "cmNamespace", namespace, "cmName", name)
- return nil, err
- }
-
- return cm, err
-}
-
-func (s *storage) updateObject(ctx context.Context, cm client.Object) error {
- return s.kubeClient.Update(ctx, cm)
-}
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/storage/storage_test.go b/deploy/k8s-operator/kube-trailblazer/pkg/storage/storage_test.go
deleted file mode 100644
index bf05495eb..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/storage/storage_test.go
+++ /dev/null
@@ -1,184 +0,0 @@
-package storage_test
-
-import (
- "context"
- "testing"
-
- "github.com/golang/mock/gomock"
- . "github.com/onsi/ginkgo/v2"
- . "github.com/onsi/gomega"
- "github.com/openshift-psap/special-resource-operator/pkg/clients"
- "github.com/openshift-psap/special-resource-operator/pkg/storage"
- v1 "k8s.io/api/core/v1"
- k8serrors "k8s.io/apimachinery/pkg/api/errors"
- "k8s.io/apimachinery/pkg/types"
-)
-
-const (
- namespaceName = "test-ns"
- resourceName = "test-resource"
-)
-
-var (
- ctrl *gomock.Controller
- mockClient *clients.MockClientsInterface
- notFound = k8serrors.NewNotFound(v1.Resource("configmap"), resourceName)
- nsn = types.NamespacedName{Namespace: namespaceName, Name: resourceName}
- cmMatcher = gomock.AssignableToTypeOf(&v1.ConfigMap{})
-)
-
-func TestStorage(t *testing.T) {
- RegisterFailHandler(Fail)
-
- BeforeEach(func() {
- ctrl = gomock.NewController(GinkgoT())
- mockClient = clients.NewMockClientsInterface(ctrl)
- })
-
- AfterEach(func() {
- ctrl.Finish()
- })
-
- RunSpecs(t, "Storage Suite")
-}
-
-var _ = Describe("storage_CheckConfigMapEntry", func() {
- const key = "test-key"
-
- It("should return an error with no ConfigMap present", func() {
- mockClient.
- EXPECT().
- Get(context.TODO(), nsn, &v1.ConfigMap{}).
- Return(notFound)
-
- _, err := storage.NewStorage(mockClient).CheckConfigMapEntry(context.TODO(), key, nsn)
- Expect(err).To(HaveOccurred())
- })
-
- It("should not return an error with an empty ConfigMap", func() {
- mockClient.
- EXPECT().
- Get(context.TODO(), nsn, &v1.ConfigMap{})
-
- _, err := storage.NewStorage(mockClient).CheckConfigMapEntry(context.TODO(), key, nsn)
- Expect(err).NotTo(HaveOccurred())
- })
-
- It("should return the expected value with a good ConfigMap", func() {
- const data = "test-data"
-
- mockClient.
- EXPECT().
- Get(context.TODO(), nsn, &v1.ConfigMap{}).
- Do(func(_ context.Context, _ types.NamespacedName, cm *v1.ConfigMap) {
- cm.Data = map[string]string{key: data}
- })
-
- v, err := storage.NewStorage(mockClient).CheckConfigMapEntry(context.TODO(), key, nsn)
-
- Expect(err).NotTo(HaveOccurred())
- Expect(v).To(Equal(data))
- })
-})
-
-var _ = Describe("UpdateConfigMapEntry", func() {
- It("should return an error when the ConfigMap does not exist", func() {
- mockClient.
- EXPECT().
- Get(context.TODO(), nsn, &v1.ConfigMap{}).
- Return(notFound)
-
- err := storage.NewStorage(mockClient).UpdateConfigMapEntry(context.TODO(), "any-key", "any-value", nsn)
- Expect(err).To(HaveOccurred())
- })
-
- It("set a key that does not already exist", func() {
- const (
- key = "key"
- value = "value"
- )
-
- gomock.InOrder(
- mockClient.EXPECT().Get(context.TODO(), nsn, &v1.ConfigMap{}),
- mockClient.EXPECT().
- Update(context.TODO(), cmMatcher).
- Do(func(_ context.Context, cm *v1.ConfigMap) {
- Expect(cm.Data).To(HaveKeyWithValue(key, value))
- }),
- )
-
- err := storage.NewStorage(mockClient).UpdateConfigMapEntry(context.TODO(), key, value, nsn)
- Expect(err).NotTo(HaveOccurred())
- })
-
- It("set a key that already exists", func() {
- const (
- key = "key"
- newValue = "new-value"
- )
-
- gomock.InOrder(
- mockClient.EXPECT().
- Get(context.TODO(), nsn, &v1.ConfigMap{}).
- Do(func(_ context.Context, _ types.NamespacedName, cm *v1.ConfigMap) {
- cm.Data = map[string]string{key: "oldvalue"}
- }),
- mockClient.EXPECT().
- Update(context.TODO(), cmMatcher).
- Do(func(_ context.Context, cm *v1.ConfigMap) {
- Expect(cm.Data).To(HaveKeyWithValue(key, newValue))
- }),
- )
-
- err := storage.NewStorage(mockClient).UpdateConfigMapEntry(context.TODO(), key, newValue, nsn)
- Expect(err).NotTo(HaveOccurred())
- })
-})
-
-var _ = Describe("DeleteConfigMapEntry", func() {
- It("should return an error when the ConfigMap does not exist", func() {
- mockClient.
- EXPECT().
- Get(context.TODO(), nsn, &v1.ConfigMap{}).
- Return(notFound)
-
- err := storage.NewStorage(mockClient).DeleteConfigMapEntry(context.TODO(), "any-key", nsn)
- Expect(err).To(HaveOccurred())
- })
-
- It("should not return an error when the key does not exist", func() {
- mockClient.
- EXPECT().
- Get(context.TODO(), nsn, &v1.ConfigMap{})
-
- err := storage.NewStorage(mockClient).DeleteConfigMapEntry(context.TODO(), "some-other-key", nsn)
- Expect(err).NotTo(HaveOccurred())
- })
-
- It("should delete the key when the key exists", func() {
- const (
- key = "key"
- otherKey = "other-key"
- value = "value"
- )
-
- data := map[string]string{key: value, otherKey: "other-value"}
-
- gomock.InOrder(
- mockClient.EXPECT().
- Get(context.TODO(), nsn, &v1.ConfigMap{}).
- Do(func(_ context.Context, _ types.NamespacedName, cm *v1.ConfigMap) {
- cm.Data = data
- }),
- mockClient.EXPECT().
- Update(context.TODO(), cmMatcher).
- Do(func(_ context.Context, cm *v1.ConfigMap) {
- Expect(cm.Data).NotTo(HaveKey(otherKey))
- Expect(cm.Data).To(HaveKeyWithValue(key, value))
- }),
- )
-
- err := storage.NewStorage(mockClient).DeleteConfigMapEntry(context.TODO(), otherKey, nsn)
- Expect(err).NotTo(HaveOccurred())
- })
-})
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/utils/hash.go b/deploy/k8s-operator/kube-trailblazer/pkg/utils/hash.go
deleted file mode 100644
index a00f33d3d..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/utils/hash.go
+++ /dev/null
@@ -1,17 +0,0 @@
-package utils
-
-import (
- "fmt"
- "hash/fnv"
-
- "github.com/pkg/errors"
-)
-
-// FNV64a returns a 64bit hash
-func FNV64a(s string) (string, error) {
- h := fnv.New64a()
- if _, err := h.Write([]byte(s)); err != nil {
- return "", errors.Wrap(err, "[FNV64a]\tcould not create hash")
- }
- return fmt.Sprintf("%x", h.Sum64()), nil
-}
diff --git a/deploy/k8s-operator/kube-trailblazer/pkg/utils/rbac.go b/deploy/k8s-operator/kube-trailblazer/pkg/utils/rbac.go
deleted file mode 100644
index 4e68c9b04..000000000
--- a/deploy/k8s-operator/kube-trailblazer/pkg/utils/rbac.go
+++ /dev/null
@@ -1,128 +0,0 @@
-package utils
-
-// +kubebuilder:rbac:groups=sro.openshift.io,resources=specialresources,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=sro.openshift.io,resources=specialresources/status,verbs=get;update;patch
-// +kubebuilder:rbac:groups=sro.openshift.io,resources=specialresources/finalizers,verbs=get;update;patch
-// +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=core,resources=pods/log,verbs=get
-// +kubebuilder:rbac:groups=apps,resources=daemonsets,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=core,resources=namespaces,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=core,resources=nodes,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=core,resources=configmaps,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=core,resources=serviceaccounts,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=roles,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=rolebindings,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=config.openshift.io,resources=clusterversions,verbs=get
-// +kubebuilder:rbac:groups=config.openshift.io,resources=proxies,verbs=get;list
-// +kubebuilder:rbac:groups=core,resources=secrets,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=security.openshift.io,resources=securitycontextconstraints,verbs=use;get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=image.openshift.io,resources=imagestreams,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=image.openshift.io,resources=imagestreams/finalizers,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=image.openshift.io,resources=imagestreams/layers,verbs=get
-// +kubebuilder:rbac:groups=core,resources=imagestreams/layers,verbs=get
-// +kubebuilder:rbac:groups=build.openshift.io,resources=buildconfigs,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=build.openshift.io,resources=builds,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterroles,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterrolebindings,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=core,resources=events,verbs=list;watch;create;update;patch;delete;get
-// +kubebuilder:rbac:groups=core,resources=persistentvolumeclaims,verbs=get;list;watch;update;
-// +kubebuilder:rbac:groups=core,resources=persistentvolumes,verbs=get;list;watch;create;delete;update;patch
-// +kubebuilder:rbac:groups=coordination.k8s.io,resources=leases,verbs=get;list;watch;create;update;delete
-// +kubebuilder:rbac:groups=storage.k8s.io,resources=csinodes,verbs=get;list;watch
-// +kubebuilder:rbac:groups=storage.k8s.io,resources=storageclasses,verbs=watch;get;list
-// +kubebuilder:rbac:groups=storage.k8s.io,resources=csidrivers,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=core,resources=endpoints,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=core,resources=services,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=monitoring.coreos.com,resources=servicemonitors,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=monitoring.coreos.com,resources=prometheusrules,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=route.openshift.io,resources=routes,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=cert-manager.io,resources=issuers,verbs=get;list;watch;create;update;patch;delete;deletecollection
-// +kubebuilder:rbac:groups=cert-manager.io,resources=certificates,verbs=get;list;watch;create;update;patch;delete;deletecollection
-// +kubebuilder:rbac:groups=apiextensions.k8s.io,resources=customresourcedefinitions,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=core,resources=persistentvolumeclaims,verbs=create;patch;delete
-// +kubebuilder:rbac:groups=core,resources=services/finalizers,verbs=create;delete;get;list;update;patch;delete;watch
-// +kubebuilder:rbac:groups=apps,resources=deployments/finalizers,resourceNames=shipwright-build,verbs=update
-// +kubebuilder:rbac:groups=apps,resources=replicasets,verbs=create;delete;get;list;patch;update;watch;get
-// +kubebuilder:rbac:groups=apps,resources=statefulsets,verbs=create;delete;get;list;patch;update;watch
-// +kubebuilder:rbac:groups=shipwright.io,resources=*,verbs=create;delete;get;list;patch;update;watch
-// +kubebuilder:rbac:groups=shipwright.io,resources=buildruns,verbs=create;delete;get;list;patch;update;watch
-// +kubebuilder:rbac:groups=shipwright.io,resources=buildstrategies,verbs=create;delete;get;list;patch;update;watch
-// +kubebuilder:rbac:groups=shipwright.io,resources=clusterbuildstrategies,verbs=create;delete;get;list;patch;update;watch
-// +kubebuilder:rbac:groups=tekton.dev,resources=taskruns,verbs=create;delete;get;list;patch;update;watch
-// +kubebuilder:rbac:groups=tekton.dev,resources=tasks,verbs=create;delete;get;list;patch;update;watch
-// +kubebuilder:rbac:groups=storage.k8s.io,resources=volumeattachments,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=snapshot.storage.k8s.io,resources=volumesnapshotclasses,verbs=get;list;watch
-// +kubebuilder:rbac:groups=snapshot.storage.k8s.io,resources=volumesnapshots,verbs=get;list;watch;update
-// +kubebuilder:rbac:groups=snapshot.storage.k8s.io,resources=volumesnapshotcontents,verbs=create;get;list;watch;update;delete
-// +kubebuilder:rbac:groups=snapshot.storage.k8s.io,resources=volumesnapshots/status,verbs=create;get;list;watch;update;delete
-// +kubebuilder:rbac:groups=snapshot.storage.k8s.io,resources=volumesnapshotcontents/status,verbs=create;get;list;watch;update;delete
-// +kubebuilder:rbac:groups=csi.storage.k8s.io,resources=csidrivers,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=apiextensions.k8s.io,resources=customresourcedefinitions,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=apps,resources=statefulsets,verbs=get;list;watch;create;update;patch;delete
-// +kubebuilder:rbac:groups=core,resources=persistentvolumeclaims/status,verbs=get;list;watch;create;delete;update;patch
-// +kubebuilder:rbac:groups=operators.coreos.com,resources=operatorgroups,verbs=get;list;watch;create;delete;update;patch
-// +kubebuilder:rbac:groups=operators.coreos.com,resources=subscriptions,verbs=get;list;watch;create;delete;update;patch
-// +kubebuilder:rbac:groups=operator.cert-manager.io,resources=certmanagers,verbs=get;list;watch;create;delete;update;patch
-// +kubebuilder:rbac:groups=admissionregistration.k8s.io,resources=mutatingwebhookconfigurations,verbs=get;list;watch;update
-// +kubebuilder:rbac:groups=admissionregistration.k8s.io,resources=validatingwebhookconfigurations,verbs=get;list;watch;update
-// +kubebuilder:rbac:groups=apiregistration.k8s.io,resources=apiservices,verbs=get;list;watch;update
-// +kubebuilder:rbac:groups=auditregistration.k8s.io,resources=auditsinks,verbs=get;list;watch;update
-// +kubebuilder:rbac:groups=cert-manager.io,resources=issuers/status,verbs=update
-// +kubebuilder:rbac:groups=cert-manager.io,resources=clusterissuers/status,verbs=update
-// +kubebuilder:rbac:groups=cert-manager.io,resources=clusterissuers,verbs=get;update;list;watch;deletecollection
-// +kubebuilder:rbac:groups=cert-manager.io,resources=certificaterequests,verbs=get;update;list;watch;delete
-// +kubebuilder:rbac:groups=cert-manager.io,resources=certificaterequests/finalizers,verbs=update
-// +kubebuilder:rbac:groups=cert-manager.io,resources=certificaterequests/status,verbs=update
-// +kubebuilder:rbac:groups=cert-manager.io,resources=certificates/finalizers,verbs=update
-// +kubebuilder:rbac:groups=cert-manager.io,resources=certificates/status,verbs=update
-// +kubebuilder:rbac:groups=acme.cert-manager.io,resources=orders,verbs=create;delete;get;list;watch;update;patch;deletecollection
-// +kubebuilder:rbac:groups=acme.cert-manager.io,resources=challenges,verbs=create;delete;get;list;watch;update;patch;deletecollection
-// +kubebuilder:rbac:groups=acme.cert-manager.io,resources=orders/finalizers,verbs=update
-// +kubebuilder:rbac:groups=acme.cert-manager.io,resources=orders/status,verbs=update
-// +kubebuilder:rbac:groups=acme.cert-manager.io,resources=challenges/finalizers,verbs=update
-// +kubebuilder:rbac:groups=acme.cert-manager.io,resources=challenges/status,verbs=update
-// +kubebuilder:rbac:groups=networking.k8s.io,resources=ingresses,verbs=get;list;watch;create;delete;update
-// +kubebuilder:rbac:groups=networking.k8s.io,resources=ingresses/finalizers,verbs=update
-// +kubebuilder:rbac:groups=route.openshift.io,resources=routes/custom-host,verbs=create
-// +kubebuilder:rbac:groups=cert-manager.io,resources=certificaterequests,verbs=create;patch;deletecollection
-// +kubebuilder:rbac:groups=cert-manager.io,resources=signers,resourceNames=clusterissuers.cert-manager.io/*,verbs=approve
-// +kubebuilder:rbac:groups=cert-manager.io,resources=signers,resourceNames=issuers.cert-manager.io/*,verbs=approve
-// +kubebuilder:rbac:groups=certificates.k8s.io,resources=certificatesigningrequests,verbs=get;list;watch;update
-// +kubebuilder:rbac:groups=certificates.k8s.io,resources=certificatesigningrequests/status,verbs=update
-// +kubebuilder:rbac:groups=certificates.k8s.io,resources=signers,resourceNames=clusterissuers.cert-manager.io/*,verbs=sign
-// +kubebuilder:rbac:groups=certificates.k8s.io,resources=signers,resourceNames=issuers.cert-manager.io/*,verbs=sign
-// +kubebuilder:rbac:groups=coordination.k8s.io,resources=leases,resourceNames=cert-manager-cainjector-leader-election,verbs=patch
-// +kubebuilder:rbac:groups=coordination.k8s.io,resources=leases,resourceNames=cert-manager-cainjector-election-core,verbs=patch
-// +kubebuilder:rbac:groups=coordination.k8s.io,resources=leases,resourceNames=cert-manager-cainjector-leader-election-core,verbs=patch
-// +kubebuilder:rbac:groups=coordination.k8s.io,resources=leases,resourceNames=cert-manager-controller,verbs=patch
-// +kubebuilder:rbac:groups=admissionregistration.k8s.io,resources=mutatingwebhookconfigurations,verbs=create;get;list;watch;update;delete;patch
-// +kubebuilder:rbac:groups=admissionregistration.k8s.io,resources=validatingwebhookconfigurations,verbs=create;get;list;watch;update;delete;patch
-// +kubebuilder:rbac:groups=*,resources=cronjobs,verbs=get;delete;update;list;watch;patch
-// +kubebuilder:rbac:groups=*,resources=daemonsets,verbs=get
-// +kubebuilder:rbac:groups=*,resources=deployments,verbs=get
-// +kubebuilder:rbac:groups=*,resources=imagepolicies,verbs=get;update;delete
-// +kubebuilder:rbac:groups=*,resources=jobs,verbs=get;create;delete;update;list;watch;patch
-// +kubebuilder:rbac:groups=*,resources=mutatingwebhookconfigurations,verbs=get
-// +kubebuilder:rbac:groups=*,resources=pods,verbs=get
-// +kubebuilder:rbac:groups=*,resources=replicacontrollers,verbs=get
-// +kubebuilder:rbac:groups=*,resources=replicasets,verbs=get
-// +kubebuilder:rbac:groups=*,resources=statefulsets,verbs=get
-// +kubebuilder:rbac:groups=connaisseur.policy,resources=imagepolicies,verbs=create
-// +kubebuilder:rbac:groups=admissionregistration.k8s.io/v1beta1,resources=mutatingwebhookconfigurations,verbs=create;delete;update;list
-// +kubebuilder:rbac:groups=batch,resources=jobs,verbs=watch;list
-// +kubebuilder:rbac:groups="",resources=nodes/finalizers,verbs=update
-// +kubebuilder:rbac:groups="",resources=nodes/status,verbs=update;patch
-// +kubebuilder:rbac:groups="",resources=pods,verbs=deletecollection
-// +kubebuilder:rbac:groups="",resources=podtemplates,verbs=list;watch;get;create;update
-// +kubebuilder:rbac:groups="",resources=podtemplates/finalizers,verbs=update
-// +kubebuilder:rbac:groups=batch,resources=jobs,verbs=list;watch;get;create;update;patch;delete
-// +kubebuilder:rbac:groups=batch,resources=jobs/finalizers,verbs=update
-// +kubebuilder:rbac:groups=extensions,resources=jobs,verbs=list;watch;get;create;update;patch;delete
-// +kubebuilder:rbac:groups=networking.x-k8s.io,resources=httproutes,verbs=get;list;watch;create;update;delete
-// +kubebuilder:rbac:groups=networking.x-k8s.io,resources=gateways,verbs=get;list;watch
-// +kubebuilder:rbac:groups=networking.x-k8s.io,resources=gateways/finalizers,verbs=update
-// +kubebuilder:rbac:groups=networking.x-k8s.io,resources=httproutes/finalisers,verbs=update
-// +kubebuilder:rbac:groups=infoscale.veritas.com,resources=infoscaleclusters,verbs=update;patch;get;list
-// +kubebuilder:rbac:groups=fpga.silicom.dk,resources=*,verbs=list;watch;get;create;update;patch;delete
-// +kubebuilder:rbac:groups=sts.silicom.com,resources=*,verbs=list;watch;get;create;update;patch;delete
diff --git a/deploy/k8s-operator/kube-trailblazer/rag-llm-pipeline.yaml b/deploy/k8s-operator/kube-trailblazer/rag-llm-pipeline.yaml
deleted file mode 100644
index f2267975d..000000000
--- a/deploy/k8s-operator/kube-trailblazer/rag-llm-pipeline.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-apiVersion: package.nvidia.com/v1alpha1
-kind: HelmPipeline
-metadata:
- name: rag-llm-pipeline
-spec:
- pipeline:
- - repoEntry:
- url: "file:///helm-charts/staging"
- chartSpec:
- chart: "rag-llm-pipeline"
- chartValues:
- triton:
- modelDirectory: "/zvonkok/model/llama2_13b_chat_hf_v1/"
- images:
- registry:
- ImagePullSecret:
- password: ${NVCR_TOKEN}
diff --git a/docs/api-catalog.md b/docs/api-catalog.md
index feb5d371a..8a8028d76 100644
--- a/docs/api-catalog.md
+++ b/docs/api-catalog.md
@@ -28,7 +28,7 @@ backlinks: none
## Example Features
This example deploys a developer RAG pipeline for chat Q&A and serves inferencing from an NVIDIA API Catalog endpoint
-instead of NVIDIA Triton Inference Server, a local Llama 2 model, or local GPUs.
+instead of a local inference server, a local model, or local GPUs.
Developers get free credits for 10K requests to any of the available models.
@@ -42,12 +42,22 @@ Developers get free credits for 10K requests to any of the available models.
- Multi-GPU
- TRT-LLM
- Model Location
- - Triton
+ - NIM for LLMs
- Vector Database
-* - ai-mixtral-8x7b-instruct
- - ai-embed-qa-4
- - Langchain
+* - ai-llama3-70b
+ - snowflake/arctic-embed-l
+ - LangChain
+ - QA chatbot
+ - NO
+ - NO
+ - API Catalog
+ - NO
+ - Milvus
+
+* - ai-llama3-8b
+ - snowflake/arctic-embed-l
+ - LlamaIndex
- QA chatbot
- NO
- NO
@@ -81,6 +91,14 @@ The following figure shows the sample topology:
- Install Docker Engine and Docker Compose.
Refer to the instructions for [Ubuntu](https://docs.docker.com/engine/install/ubuntu/).
+- Login to Nvidia's docker registry. Please refer to [instructions](https://docs.nvidia.com/ngc/gpu-cloud/ngc-overview/index.html) to create account and generate NGC API key. This is needed for pulling in the secure base container used by all the examples.
+
+ ```console
+ $ docker login nvcr.io
+ Username: $oauthtoken
+ Password:
+ ```
+
- Optional: Enable NVIDIA Riva automatic speech recognition (ASR) and text to speech (TTS).
- To launch a Riva server locally, refer to the [Riva Quick Start Guide](https://docs.nvidia.com/deeplearning/riva/user-guide/docs/quick-start-guide.html).
@@ -101,7 +119,7 @@ The following figure shows the sample topology:
% end-prerequisites
-## Get an API Key for the Mixtral 8x7B Instruct API Endpoint
+## Get an API Key for the Accessing Models on the API Catalog
% api-key-start
@@ -110,13 +128,13 @@ You can use different model API endpoints with the same API key.
1. Navigate to .
-2. Find the **Mixtral 8x7B Instruct** card and click the card.
+2. Find the **Llama 3 70B Instruct** card and click the card.
- 
+ 
3. Click **Get API Key**.
- 
+ 
4. Click **Generate Key**.
@@ -125,7 +143,7 @@ You can use different model API endpoints with the same API key.
5. Click **Copy Key** and then save the API key.
The key begins with the letters nvapi-.
- 
+ 
% api-key-end
@@ -143,13 +161,19 @@ You can use different model API endpoints with the same API key.
2. From the root of the repository, build the containers:
```console
- $ docker compose --env-file deploy/compose/compose.env -f deploy/compose/rag-app-api-catalog-text-chatbot.yaml build
+ $ docker compose \
+ --env-file deploy/compose/compose.env \
+ -f deploy/compose/rag-app-api-catalog-text-chatbot.yaml \
+ build
```
3. Start the containers:
```console
- $ docker compose --env-file deploy/compose/compose.env -f deploy/compose/rag-app-api-catalog-text-chatbot.yaml up -d
+ $ docker compose \
+ --env-file deploy/compose/compose.env \
+ -f deploy/compose/rag-app-api-catalog-text-chatbot.yaml \
+ up -d
```
*Example Output*
@@ -163,7 +187,11 @@ You can use different model API endpoints with the same API key.
4. Start the Milvus vector database:
```console
- $ docker compose --env-file deploy/compose/compose.env -f deploy/compose/docker-compose-vectordb.yaml up -d milvus
+ $ docker compose \
+ --env-file deploy/compose/compose.env \
+ -f deploy/compose/docker-compose-vectordb.yaml \
+ --profile llm-embedding \
+ up -d milvus
```
*Example Output*
@@ -191,10 +219,64 @@ You can use different model API endpoints with the same API key.
57a068d62fbb milvus-etcd Up 3 minutes (healthy)
```
+## Using an Alternative Inference Model
+
+You can specify the model to use in the `APP_LLM_MODELNAME` environment variable when you start the Chain Server.
+The following sample command uses the Mistral AI Mixtral 8x7B Instruct model.
+
+```console
+$ APP_LLM_MODELNAME='mistralai/mixtral-8x7b-instruct-v0.1' docker compose \
+ --env-file deploy/compose/compose.env \
+ -f deploy/compose/rag-app-api-catalog-text-chatbot.yaml \
+ up -d
+```
+
+You can determine the available model names using one of the following methods:
+
+- Browse the models at .
+ View the sample Python code and get the model name from the `model` argument to the `client.chat.completions.create` method.
+- Install the [langchain-nvidia-ai-endpoints](https://pypi.org/project/langchain-nvidia-ai-endpoints/) Python package from PyPi.
+ Use the `get_available_models()` method to list the models.
+ Refer to the preceding web page for sample code to list the models.
+
+## Using the LlamaIndex Data Framework
+
+As an alternative to the LangChain based Chain Server, you can build and run a LlamaIndex based Chain Server.
+
+This example also starts a JupyterLab server on port 8888.
+
+1. After meeting the [](#prerequisites), build the containers:
+
+ ```console
+ $ docker compose \
+ --env-file deploy/compose/compose.env \
+ -f deploy/compose/rag-app-text-chatbot.yaml \
+ build
+ ```
+
+1. Start the containers:
+
+ ```console
+ $ docker compose \
+ --env-file deploy/compose/compose.env \
+ -f deploy/compose/rag-app-text-chatbot.yaml \
+ up -d
+ ```
+
+1. Start the Milvus vector database:
+
+ ```console
+ $ docker compose \
+ --env-file deploy/compose/compose.env \
+ -f deploy/compose/docker-compose-vectordb.yaml \
+ --profile llm-embedding \
+ up -d milvus
+ ```
+
## Next Steps
- Access the web interface for the chat server.
Refer to [](./using-sample-web-application.md) for information about using the web interface.
- [](./vector-database.md)
- Stop the containers by running `docker compose -f deploy/compose/rag-app-api-catalog-text-chatbot.yaml down` and
- `docker compose -f deploy/compose/docker-compose-vectordb.yaml down`.
+ `docker compose -f deploy/compose/docker-compose-vectordb.yaml --profile llm-embedding down`.
diff --git a/docs/architecture.md b/docs/architecture.md
index 71f4f7a82..198bac04f 100644
--- a/docs/architecture.md
+++ b/docs/architecture.md
@@ -29,66 +29,72 @@ backlinks: none
The default sample deployment contains:
-- [NVIDIA NeMo Framework Inference Server](https://docs.nvidia.com/nemo-framework/user-guide/latest/index.html) - part of NVIDIA AI Enterprise solution
-- [NVIDIA TensorRT-LLM](https://developer.nvidia.com/tensorrt) - for low latency and high throughput inference for LLMs
-- [LangChain](https://github.com/langchain-ai/langchain/) and [LlamaIndex](https://www.llamaindex.ai/) for combining language model components and easily constructing question-answering from a company's database
-- [Sample Jupyter Notebooks](jupyter-server.md) and [chat bot web application/API calls](./frontend.md) so that you can test the chat system in an interactive manner
-- [Milvus](https://milvus.io/docs/install_standalone-docker.md) - Generated embeddings are stored in a vector database. The vector DB used in this workflow is Milvus. Milvus is an open-source vector database capable of NVIDIA GPU-accelerated vector searches.
-- [UAE-Large-V1 model](https://huggingface.co/WhereIsAI/UAE-Large-V1) from Hugging Face to generate the embeddings.
-- [Llama2](https://github.com/facebookresearch/llama/), an open source model from Meta, to formulate natural responses.
+- Inference and embedding are performed by accessing model endpoints running on NVIDIA API Catalog.
-This sample deployment is a reference for you to build your own enterprise AI solution with minimal effort.
-The software components are used to deploy models and inference pipeline, integrated together with the additional components as indicated in the following diagram:
+ Most examples use the [Meta Llama 3 70B Instruct](https://build.ngc.nvidia.com/meta/llama3-70b) model
+ for inference and the [Snowflake Arctic Embed L](https://build.ngc.nvidia.com/snowflake/arctic-embed-l)
+ model for embedding.
-
+ Alternatively, you can deploy NVIDIA NIM for LLMs and NVIDIA NeMo Retriever Embedding microservice
+ to use local models and local GPUs.
+ Refer to the [](nim-llms.md) example for more information.
+
+- A Chain Server uses [LangChain](https://github.com/langchain-ai/langchain/) and [LlamaIndex](https://www.llamaindex.ai/) for combining language model components and easily constructing question-answering from a company's database.
+
+- [Sample Jupyter Notebooks](jupyter-server.md) and [](./frontend.md) so that you can test the chat system in an interactive manner.
+
+- [Milvus](https://milvus.io/docs/install_standalone-docker.md) or [pgvector](https://github.com/pgvector/pgvector) - Embeddings are stored in a vector database. Milvus is an open-source vector database capable of NVIDIA GPU-accelerated vector searches.
+
+The sample deployment is a reference for you to build your own enterprise AI solution with minimal effort.
## NVIDIA AI Components
The sample deployment uses a variety of NVIDIA AI components to customize and deploy the RAG-based chat bot example.
- [NVIDIA TensorRT-LLM](https://github.com/NVIDIA/TensorRT-LLM)
-- [NVIDIA NeMo Inference Container](https://developer.nvidia.com/nemo)
+- [NVIDIA NIM for LLMs](https://docs.nvidia.com/nim/large-language-models/latest/index.html)
### NVIDIA TensorRT-LLM Optimization
-An LLM can be optimized using TensorRT-LLM. NVIDIA NeMo uses TensorRT for LLMs (TensorRT-LLM), for deployment which accelerates and maximizes inference performance on the latest LLMs.
-The sample deployment leverages a Llama 2 (13B parameters) chat model.
-The foundational model is converted to TensorRT format using TensorRT-LLM for optimized inference.
+An LLM can be optimized using TensorRT-LLM.
+NVIDIA NIM for LLMs uses TensorRT for LLMs (TensorRT-LLM) to accelerate and maximize inference performance on the latest LLMs.
+The sample deployment deploys a Llama 3 8B parameter chat model that TensorRT-LLM optimizes for inference.
-### NVIDIA NeMo Framework Inference Container
+### NVIDIA NIM for LLMs Container
-With NeMo Framework Inference Container, the optimized LLM can be deployed for high-performance, cost-effective, and low-latency inference. NeMo Framework Inference Container contains modules and scripts to help exporting LLM models to [TensorRT-LLM](https://github.com/NVIDIA/TensorRT-LLM) and deploying them to [Triton Inference Server](https://docs.nvidia.com/deeplearning/triton-inference-server/user-guide/docs/index.html) with easy-to-use APIs.
+The NVIDIA NIM for LLMs container simplifies deployment and provides high-performance, cost-effective, and low-latency inference.
+Software in the container determines your GPU hardware and determines whether to use the TensorRT-LLM backend or the vLLM backend.
## Inference Pipeline
-To get started with the inferencing pipeline, we connect the customized LLM to a sample proprietary data source.
-This knowledge can come in many forms: product specifications, HR documents, or finance spreadsheets.
+To get started with the inferencing pipeline, we connect the LLM to a sample vector database.
+You can upload documents and embeddings of the documents are stored in the vector database to augment the responses to your queries.
+The knowledge in the vector database can come in many forms: product specifications, HR documents, or finance spreadsheets.
Enhancing the model’s capabilities with this knowledge can be done with RAG.
Because foundational LLMs are not trained on your proprietary enterprise data and are only trained up to a fixed point in time, they need to be augmented with additional data.
RAG consists of two processes.
First, *retrieval* of data from document repositories, databases, or APIs that are all outside of the foundational model’s knowledge.
Second, *generation* of responses via inference.
-The following graphic describes an overview of this inference pipeline:
-
-
## Document Ingestion and Retrieval
RAG begins with a knowledge base of relevant up-to-date information.
Because data within an enterprise is frequently updated, the ingestion of documents into a knowledge base is a recurring process and could be scheduled as a job.
-Next, content from the knowledge base is passed to an embedding model such as UAE-Large-V1 that the sample deployment uses.
+Next, content from the knowledge base is passed to an embedding model such as Snowflake Arctic Embedding L that the sample deployment uses.
The embedding model converts the content to vectors, referred to as *embeddings*.
Generating embeddings is a critical step in RAG.
The embeddings provide dense numerical representations of textual information.
-These embeddings are stored in a vector database, in this case Milvus, which is [RAFT accelerated](https://developer.nvidia.com/blog/accelerating-vector-search-using-gpu-powered-indexes-with-rapids-raft).
+These embeddings are stored in a vector database.
+The default database is Milvus, which is [RAFT accelerated](https://developer.nvidia.com/blog/accelerating-vector-search-using-gpu-powered-indexes-with-rapids-raft).
+An alternative vector database is pgvector.
## User Query and Response Generation
When a user query is sent to the inference server, it is converted to an embedding using the embedding model.
-This is the same embedding model that is used to convert the documents in the knowledge base, UAE-Large-V1, in the case of this sample deployment.
+This is the same embedding model that is used to convert the documents in the knowledge base.
The database performs a similarity/semantic search to find the vectors that most closely resemble the user’s intent and provides them to the LLM as enhanced context.
-Because Milvus is RAFT accelerated, the similarity serach is optimized on the GPU.
+Because Milvus is RAFT accelerated, the similarity search is optimized on the GPU.
Lastly, the LLM generates a full answer that is streamed to the user.
This is all done with ease using [LangChain](https://github.com/langchain-ai/langchain/) and [LlamaIndex](https://www.llamaindex.ai).
@@ -97,8 +103,8 @@ The following diagram illustrates the ingestion of documents and generation of r

LangChain enables you to write LLM wrappers for your own custom LLMs.
-NVIDIA provides a sample wrapper for streaming responses from a TensorRT-LLM Llama 2 model running on Triton Inference Server.
-This wrapper enables us to leverage LangChain’s standard interface for interacting with LLMs while still achieving vast performance speedup from TensorRT-LLM and scalable and flexible inference from Triton Inference Server.
+NVIDIA provides a sample wrapper for streaming responses from an LLM running in NVIDIA NIM for LLMs.
+This wrapper enables us to leverage LangChain’s standard interface for interacting with LLMs while still achieving vast performance speedup from TensorRT-LLM and scalable and flexible inference from NIM for LLMs.
A sample chat bot web application is provided in the sample deployment so that you can test the chat system in an interactive manner.
Requests to the chat system are wrapped in API calls, so these can be abstracted to other applications.
@@ -111,23 +117,18 @@ In our sample deployment, we prompt our model to generate safe and polite respon
## LLM Inference Server
-The LLM Inference Server uses models that are stored in a model repository.
+The NVIDIA NIM for LLMs container downloads a model that is cached in a model repository.
This repository is available locally to serve inference requests.
-After they are available in Triton Inference Server, inference requests are sent from a client application.
+After the container downloads the model, inference requests are sent from a client application.
Python and C++ libraries provide APIs to simplify communication.
-Clients send HTTP/REST requests directly to Triton Inference Server using HTTP/REST or gRPC protocols.
-
-Within the sample deployment, the Llama2 LLM was optimized using NVIDIA TensorRT for LLMs (TRT-LLM).
-This software accelerates and maximizes inference performance on the latest LLMs.
+Clients send HTTP/REST requests to NIM for LLMs using HTTP/REST or gRPC protocols.
## Vector DB
Milvus is an open-source vector database built to power embedding similarity search and AI applications.
The database makes unstructured data from API calls, PDFs, and other documents more accessible by storing them as embeddings.
-When content from the knowledge base is passed to an embedding model, UAE-Large-V1, the model converts the content to vectors--referred to as *embeddings*.
+When content from the knowledge base is passed to an embedding model, the model converts the content to vectors--referred to as *embeddings*.
These embeddings are stored in the vector database.
The sample deployment uses Milvus as the vector database.
Milvus is an open-source vector database capable of NVIDIA GPU-accelerated vector searches.
-
-If needed, see Milvus's [documentation](https://milvus.io/docs/install_standalone-docker.md/) for how to configure a Docker Compose file for Milvus.
diff --git a/docs/conf.py b/docs/conf.py
index 4c39f6f2f..c568d1b29 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -26,7 +26,7 @@
this_year = date.today().year
copyright = f"2023-{this_year}, NVIDIA Corporation"
author = "NVIDIA Corporation"
-release = "24.4.0"
+release = "24.6.0"
extensions = [
"sphinx_rtd_theme",
diff --git a/docs/configuration.md b/docs/configuration.md
index 4d14d1b64..00905d33c 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -31,18 +31,6 @@ The following sections identify the environment variables and parameters that ar
You can set environment variables in the `deploy/compose/compose.env` file.
-### LLM Server Configuration
-
-LLM Inference server hosts the Large Language Model (LLM) with Triton Inference Server backend.
-
-You can configure the server using the following environment variables:
-
-:MODEL_DIRECTORY: Specifies the path to the model directory where model checkpoints are stored.
-:MODEL_ARCHITECTURE: Defines the architecture of the model used for deployment.
-:MODEL_MAX_INPUT_LENGTH: Maximum allowed input length, with a default value of 3000.
-:QUANTIZATION: Specifies to enable activation-aware quantization for the LLM. By default, quantization is not enabled.
-:INFERENCE_GPU_COUNT: Specifies the GPUs to be used by Triton for model deployment, with the default setting being "all."
-
### Milvus
Milvus is the default vector database server.
@@ -74,13 +62,10 @@ You can configure the server using the following environment variable:
:APP_VECTORSTORE_URL: Specifies the URL of the vector database server.
:APP_VECTORSTORE_NAME: Specifies the vendor name of the vector database. Values are `milvus` or `pgvector`.
:COLLECTION_NAME: Specifies the example-specific collection in the vector database.
-:APP_LLM_SERVERURL: Specifies the URL of Triton Inference Server.
-:APP_LLM_MODELNAME: The model name used by the Triton server.
+:APP_LLM_SERVERURL: Specifies the URL of NVIDIA NIM for LLMs.
+:APP_LLM_MODELNAME: The model name used by NIM for LLMs.
:APP_LLM_MODELENGINE: An enum that specifies the backend name hosting the model. Supported values are as follows:
-
- `triton-trt-llm` to use locally deployed LLM models.
-
- `nvidia-ai-endpoints` to use models hosted from NVIDIA API Catalog.
+ `nvidia-ai-endpoints` to use models hosted using NIM for LLMs in cloud based API Catalog or locally.
:APP_RETRIEVER_TOPK: Number of relevant results to retrieve. The default value is `4`.
:APP_RETRIEVER_SCORETHRESHOLD: The minimum confidence score for the retrieved values to be considered. The default value is `0.25`.
:APP_PROMPTS_CHATTEMPLATE: Specifies the instructions to provide to the model.
@@ -89,7 +74,7 @@ You can configure the server using the following environment variable:
:APP_PROMPTS_RAGTEMPLATE: Specifies the instructions to provide to the model.
The prompt is combined with the user-supplied query and then presented to the model.
The chain server uses this prompt when the query uses a knowledge base.
-
+:LOGLEVEL: Set the logging verbosity level for the logs printed by container. Chain server uses the standard python logging module. Possible values are NOTSET, DEBUG, INFO, WARN, ERROR, CRITICAL.
### RAG Playground
diff --git a/docs/developer-llm-operator/README.md b/docs/developer-llm-operator/README.md
deleted file mode 100644
index 5ac398b2a..000000000
--- a/docs/developer-llm-operator/README.md
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-# NVIDIA Developer LLM Operator
-
-The NVIDIA Developer LLM Operator enables developers to
-build RAG-LLM pipelines on Kubernetes and manage the lifecycle of the
-components for a sample pipeline.
-
-The Operator manages the lifecycle of the following components:
-
-- **Jupyter Notebook server**:
- The container includes sample notebooks to demonstrate a sample pipeline.
-
-- **Chatbot web application**:
- The sample web application enables you to perform question and answering with the chatbot
- and to upload PDF documents to form a knowledge base.
-
-- **Vector database**:
- The sample pipeline uses Milvus to manage the embeddings generated by the LLM.
-
-- **NVIDIA Triton Inference Server**:
- The server is configured with the NVIDIA Nemo Framework for working with LLMs.
-
-Refer to [Installing the Operator](./install.md) to get started.
\ No newline at end of file
diff --git a/docs/developer-llm-operator/install.md b/docs/developer-llm-operator/install.md
deleted file mode 100644
index ba3df5169..000000000
--- a/docs/developer-llm-operator/install.md
+++ /dev/null
@@ -1,309 +0,0 @@
-
-
-# Installing the Operator
-
-## Prerequisites
-
-- You have a machine with one or more NVIDIA A100 80 GB or NVIDIA H100 GPUs.
- If you have fewer than four GPUs, you can configure GPU time-slicing.
- Time-slicing oversubscribes the GPUs to simulate the four GPUs that are required,
- though at lower performance.
-
-- You have access to Docker and Docker Compose to build container images.
- Refer to the [installation documentation](https://docs.docker.com/engine/install/ubuntu/)
- for Ubuntu from the Docker documentation.
-
-- You have Kubernetes installed and running on the machine with Ubuntu 22.04 or 20.04.
- Refer to the [Kubernetes documentation](https://kubernetes.io/docs/setup/) or
- the [NVIDIA Cloud Native Stack repository](https://github.com/NVIDIA/cloud-native-stack/)
- for more information.
-
-- You have access to Git and Git LFS to clone the repository to get access to the Dockerfile
- and software for container images.
-
-- You downloaded a Llama2 chat model weights from Meta or HuggingFace.
- Get the 13 billion or 7 billion parameter model.
-
- Request access to the model from [Meta](https://ai.meta.com/resources/models-and-libraries/llama-downloads/)
- or refer to the [meta-llama/LLama-2-13b-chat-hf](https://huggingface.co/meta-llama/Llama-2-13b-chat-hf)
- page from HuggingFace.
-
- The directory with the model is shared as a host path volume mount with the Triton Inference Server pod.
-
-
-## Install the NVIDIA GPU Operator
-
-Use the NVIDIA GPU Operator to install, configure, and manage the NVIDIA GPU driver and
-NVIDIA container runtime on the Kubernetes node.
-
-1. Add the NVIDIA Helm repository:
-
- ```console
- $ helm repo add nvidia https://helm.ngc.nvidia.com/nvidia \
- && helm repo update
- ```
-
-1. Install the Operator:
-
- ```console
- $ helm install --wait --generate-name \
- -n gpu-operator --create-namespace \
- nvidia/gpu-operator
- ```
-
-1. Optional: Configure GPU time-slicing if you have fewer than four GPUs.
-
- - Create a file, `time-slicing-config-all.yaml`, with the following content:
-
- ```yaml
- apiVersion: v1
- kind: ConfigMap
- metadata:
- name: time-slicing-config-all
- data:
- any: |-
- version: v1
- flags:
- migStrategy: none
- sharing:
- timeSlicing:
- resources:
- - name: nvidia.com/gpu
- replicas: 4
- ```
-
- The sample configuration creates four *replicas* from each GPU on the node.
-
- - Add the config map to the Operator namespace:
-
- ```console
- $ kubectl create -n gpu-operator -f time-slicing-config-all.yaml
- ```
-
- - Configure the device plugin with the config map and set the default time-slicing configuration:
-
- ```console
- $ kubectl patch clusterpolicy/cluster-policy \
- -n gpu-operator --type merge \
- -p '{"spec": {"devicePlugin": {"config": {"name": "time-slicing-config-all", "default": "any"}}}}'
- ```
-
- - Verify that at least `4` GPUs are allocatable:
-
- ```console
- $ kubectl get nodes -l nvidia.com/gpu.present -o json | jq '.items[0].status.allocatable | with_entries(select(.key | startswith("nvidia.com/"))) | with_entries(select(.value != "0"))'
- ```
-
- *Example Output*
-
- ```json
- {
- "nvidia.com/gpu": "4"
- }
- ```
-
-For more information or to adjust the configuration, refer to
-[Install NVIDIA GPU Operator](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/getting-started.html#install-nvidia-gpu-operator) and
-[Time-Slicing GPUs in Kubernetes](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/gpu-sharing.html)
-in the NVIDIA GPU Operator documentation.
-
-## Install the Developer LLM Operator
-
-1. Get the Helm chart for the Operator:
-
- ```console
- $ helm fetch https://helm.ngc.nvidia.com/nvidia/cloud-native/charts/developer-llm-operator-0.1.0.tgz
- ```
-
-1. Install the Operator:
-
- ```console
- $ helm install --generate-name ./developer-llm-operator-0.1.0.tgz \
- -n kube-trailblazer-system --create-namespace
- ```
-
-1. Optional: Confirm the controller pod is running:
-
- ```console
- $ kubectl get pods -n kube-trailblazer-system
- ```
-
- *Example Output*
-
- ```output
- NAME READY STATUS RESTARTS AGE
- kube-trailblazer-controller-manager-868bf8dc84-p2zgc 2/2 Running 2 (20h ago) 21h
- ```
-
-## Build the Container Images
-
-1. Clone the repository if you haven't already:
-
- ```console
- $ git lfs clone https://github.com/NVIDIA/GenerativeAIExamples.git
- ```
-
-1. Build the container images:
-
- ```console
- $ cd GenerativeAIExamples/deploy/compose
- $ docker compose --env-file compose.env build
- ```
-
- Building the images requires several minutes.
-
-1. Start a local registry, tag the images, and push the images to the registry.
-
- - Start a local registry:
-
- ```console
- $ docker run -d -p 5000:5000 --name registry registry:2.7
- ```
-
- - Tag and push the images that are not publicly available:
-
- ```console
- $ docker tag llm-inference-server localhost:5000/llm-inference-server
- $ docker push localhost:5000/llm-inference-server
-
- $ docker tag chain-server localhost:5000/chain-server
- $ docker push localhost:5000/chain-server
-
- $ docker tag llm-playground localhost:5000/llm-playground
- $ docker push localhost:5000/llm-playground
-
- $ docker tag notebook-server localhost:5000/notebook-server
- $ docker push localhost:5000/notebook-server
- ```
-
- - Optional: Confirm the images are available from the local registry:
-
- ```console
- $ curl -sSL "http://localhost:5000/v2/_catalog"
- ```
-
- *Example Output*
-
- ```json
- {"repositories":["chain-server","llm-inference-server","llm-playground","notebook-server"]}
- ```
-
-## Create a RAG-LLM Pipeline
-
-1. Create a file, such as `rag-llm-pipeline.yaml`, with contents like the following example:
-
- ```yaml
- apiVersion: package.nvidia.com/v1alpha1
- kind: HelmPipeline
- metadata:
- name: rag-llm-pipeline
- spec:
- pipeline:
- - repoEntry:
- url: "file:///helm-charts/staging"
- chartSpec:
- chart: "rag-llm-pipeline"
- chartValues:
- triton:
- modelDirectory: "/llama2_13b_chat_hf_v1/"
- ```
-
- Modify the `modelDirectory` value to match the location and name of the model directory
- on the Kubernetes node.
-
-1. Apply the manifest:
-
- ```console
- $ kubectl apply -n kube-trailblazer-system -f rag-llm-pipeline.yaml
- ```
-
- The Operator creates the `rag-llm-pipeline` namespace and creates deployments and services in the namespace.
- Downloading the container images and starting the pods can require a few minutes.
-
-1. Optional: Monitor progress.
-
- - View the logs from the Operator controller pod:
-
- ```console
- $ kubectl logs -n kube-trailblazer-system $(kubectl get pod -n kube-trailblazer-system -o=jsonpath='{.items[0].metadata.name}')
- ```
-
- - View the pods in the pipeline namespace:
-
- ```console
- $ kubectl get pods -n rag-llm-pipeline
- ```
-
- *Example Output*
-
- ```output
- NAME READY STATUS RESTARTS AGE
- jupyter-notebook-server-6d6b46578d-98xdq 1/1 Running 0 21h
- llm-playground-6fd649ff8f-r2hp6 1/1 Running 0 22h
- milvu-etcd-6559759884-9rvpz 1/1 Running 0 22h
- milvus-minio-6fc5b9bdd4-d7l4z 1/1 Running 0 22h
- milvus-standalone-9bfb5d974-tsjtp 1/1 Running 0 22h
- query-router-77499f5459-6jjr9 1/1 Running 0 22h
- triton-inference-server-79d5c499b-26nqq 0/1 Running 0 22h
- ```
-
-1. View the services and node ports:
-
- ```console
- $ kubectl get svc -n rag-llm-pipeline
- ```
-
- *Example Output*
-
- ```output
- NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
- frontend-service NodePort 10.111.66.10 8090:30001/TCP 22h
- jupyter-notebook-service NodePort 10.110.101.174 8888:30000/TCP 22h
- llm ClusterIP 10.107.213.112 8001/TCP 22h
- milvus ClusterIP 10.102.86.183 19530/TCP 22h
- milvus-etcd ClusterIP 10.109.74.142 2379/TCP 22h
- milvus-minio ClusterIP 10.103.238.28 9010/TCP 22h
- query ClusterIP 10.110.199.69 8081/TCP 22h
- ```
-
- The output shows that the chat web application, `frontend-service`, is mapped to port `30001`
- on the Kubernetes host through a node port.
- The output also shows the Jupyter Notebook server is mapped to port `30000` on the host.
-
-## Access the Chat Web Application
-
-- Open a browser and access `http://localhost:30001` or replace localhost with the IP address
- of the Kubernetes node.
-
- 
-
-- Upload a PDF file as a knowledge base for retrieval.
-
- - Access `http://localhost:30001/converse` and click **Knowledge Base**.
-
- - Browse to a local file and upload it to the web application.
-
- - When you return to the **Converse** tab to ask a question, enable the **Use knowledge base** checkbox.
-
-## Access the Jupyter Notebooks
-
-- Open a browser and access `http://localhost:30000` or replace localhost with the IP address
- of the Kubernetes node.
-
- Browse and run the notebooks that are part of the container image.
-
diff --git a/docs/developer-llm-operator/uninstall.md b/docs/developer-llm-operator/uninstall.md
deleted file mode 100644
index 5cd096a70..000000000
--- a/docs/developer-llm-operator/uninstall.md
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
-# Uninstalling the Operator
-
-To uninstall the Operator, perform the following steps:
-
-1. Delete the RAG pipeline:
-
- ```console
- $ kubectl delete helmpipeline -n kube-trailblazer-system rag-llm-pipeline
- ```
-
- *Example Output*
-
- ```output
- helmpipeline.package.nvidia.com "rag-llm-pipeline" deleted
- ```
-
-1. Optional: Delete the namespace for the RAG pipeline:
-
- ```console
- $ kubectl delete namespace rag-llm-pipeline
- ```
-
-1. Uninstall the Operator:
-
- ```console
- $ helm delete -n kube-trailblazer-system $(helm list -n kube-trailblazer-system | grep developer-llm-operator | awk '{print $1}')
- ```
-
- *Example Output*
-
- ```output
- release "developer-llm-operator-0-1705070979" uninstalled
- ```
diff --git a/docs/evaluation.md b/docs/evaluation.md
index 075f3f769..b7377e2c4 100644
--- a/docs/evaluation.md
+++ b/docs/evaluation.md
@@ -203,7 +203,7 @@ You can use different model API endpoints with the same API key.
$ docker compose --env-file deploy/compose/compose.env -f deploy/compose/rag-app-text-chatbot.yaml build
```
-4. Start the milvus container:
+4. Start the Milvus container:
```console
$ docker compose -f deploy/compose/docker-compose-vectordb.yaml up -d milvus
@@ -214,7 +214,8 @@ You can use different model API endpoints with the same API key.
```console
$ docker compose --env-file deploy/compose/compose.env -f deploy/compose/rag-app-text-chatbot.yaml up -d
```
- NVIDIA Triton Inference Server can require 5 minutes to start. The `-d` flag starts the services in the background.
+
+ The inference server can require 5 minutes to start. The `-d` flag starts the services in the background.
*Example Output*
diff --git a/docs/hf_model_download.md b/docs/hf_model_download.md
deleted file mode 100644
index 216020c9b..000000000
--- a/docs/hf_model_download.md
+++ /dev/null
@@ -1,59 +0,0 @@
-## Downloading Model from huggingface
-
-- Visit the Hugging Face Models Hub at https://huggingface.co/models
-
-- Search for the "llama-2" model in search bar.
-
-
-- Choose the specific model you wish to download; for instance, let's select "llama-2-13b-chat-hf."
-
-- If you haven't already, sign up or log in to your Hugging Face account.
-
-
-- Agree to the terms and conditions provided.
-
-
-
-- Confirm that your request to access the repository is successful.
-
-
-- Complete the meta form by clicking on the link `Meta website` link mentioned in the previous steps.
-
-
-- Navigate to the "Files" section, which displays the available files. If you don't have access, it will be indicated like below.
-
-
-- Upon obtaining the necessary permissions, you will see all the files associated with the model on Hugging Face.
-
-
-- Click on the three dots (...) next to the train.
-
-
-- Select "Clone repository," which will prompt the following:
-
-
-- Execute the provided command in your terminal. When prompted, enter your Hugging Face username and token.
-
-
-- In the password section, insert your token. If you haven't generated a token, you can do so in the Hugging Face settings.
-
-
-- Access the "Access Tokens" section in the right panel.
-
-
-- Generate a new token or copy an existing one.
-
-
-- Paste the token into your terminal.
-
-
-- You may be asked for your username and password multiple times; provide the required information.
-
-- The terminal will initiate the download process for the model. This may take some time as it involves downloading checkpoints.
-
-- Once the download is complete, you will be able to view the contents of the downloaded model.
-
-
-
-
-
diff --git a/docs/images/llama3-70b-instruct-get-api-key.png b/docs/images/llama3-70b-instruct-get-api-key.png
new file mode 100644
index 000000000..4e186b0b1
Binary files /dev/null and b/docs/images/llama3-70b-instruct-get-api-key.png differ
diff --git a/docs/images/llama3-70b-instruct-model-card.png b/docs/images/llama3-70b-instruct-model-card.png
new file mode 100644
index 000000000..427ce27a9
Binary files /dev/null and b/docs/images/llama3-70b-instruct-model-card.png differ
diff --git a/docs/images/llama3-8b-instruct-get-api-key.png b/docs/images/llama3-8b-instruct-get-api-key.png
new file mode 100644
index 000000000..c59234952
Binary files /dev/null and b/docs/images/llama3-8b-instruct-get-api-key.png differ
diff --git a/docs/images/llama3-8b-instruct-model-card.png b/docs/images/llama3-8b-instruct-model-card.png
new file mode 100644
index 000000000..e0bdd4a61
Binary files /dev/null and b/docs/images/llama3-8b-instruct-model-card.png differ
diff --git a/docs/images/local-gpus-topology.png b/docs/images/local-gpus-topology.png
deleted file mode 100644
index c33a14eda..000000000
Binary files a/docs/images/local-gpus-topology.png and /dev/null differ
diff --git a/docs/images/nim-llms-topology.png b/docs/images/nim-llms-topology.png
new file mode 100644
index 000000000..f8ba2f971
Binary files /dev/null and b/docs/images/nim-llms-topology.png differ
diff --git a/docs/index.md b/docs/index.md
index ff493eca9..567ce7f18 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -43,100 +43,66 @@ The chat bot also supports uploading documents to create a knowledge base.
- | Embedding
- | Framework
- | Description
- - | Multi-GPU
- - | TensorRT-LLM
- | Model
| Location
- - | Triton
- | Inference
- | Server
+ - | NIM
+ | for
+ | LLMs
- | Vector
| Database
- * - ai-mixtral-8x7b-instruct
- - ai-embed-qa-4
+ * - ai-llama3-70b
+ - snowflake-arctic-embed-l
- LangChain
- :doc:`api-catalog`
- - NO
- - NO
- API Catalog
- - NO
+ - No
- Milvus or pgvector
- * - llama-2
- - UAE-Large-V1
- - LlamaIndex
- - :doc:`local-gpu`
- - NO
- - YES
- - Local Model
- - YES
- - Milvus or pgvector
-
- * - llama-2
- - UAE-Large-V1
- - LlamaIndex
- - :doc:`multi-gpu`
- - YES
- - YES
- - Local Model
- - YES
- - Milvus or pgvector
-
- * - ai-llama2-70b
- - ai-embed-qa-4
+ * - ai-llama3-70b
+ - snowflake-arctic-embed-l
- LangChain
- :doc:`query-decomposition`
- - NO
- - NO
- API Catalog
- - NO
+ - No
- Milvus or pgvector
- * - llama2-7b
- - UAE-Large-V1
- - LlamaIndex
- - :doc:`quantized-llm-model`
- - NO
- - YES
- - Local Model
- - YES
- - Milvus or pgvector
+ * - meta/llama3-70b-instruct for response generation
- * - ai-llama3-70b for response generation
-
- ai-llama3-70b for PandasAI
+ meta/llama3-70b-instruct for PandasAI
- Not Applicable
- PandasAI
- :doc:`structured-data`
- - NO
- - NO
- API Catalog
- - NO
+ - No
- Not Applicable
- * - ai-mixtral-8x7b-instruct for response generation
+ * - ai-llama3-8b for response generation
ai-google-Deplot for graph to text conversion
ai-Neva-22B for image to text conversion
- - ai-embed-qa-4
+ - snowflake-arctic-embed-l
- Custom Python
- :doc:`multimodal-data`
- - NO
- - NO
- API Catalog
- - NO
+ - No
- Milvus or pgvector
- * - ai-llama2-70b
- - ai-embed-qa-4
+ * - ai-llama3-8b
+ - snowflake-arctic-embed-l
- LangChain
- :doc:`multi-turn`
- - NO
- - NO
- API Catalog
- - NO
+ - No
+ - Milvus or pgvector
+
+ * - meta-llama3-8b-instruct
+ - nv-embed-qa:4
+ - LangChain
+ - :doc:`nim-llms`
+ - Local LLM
+ - Yes
- Milvus or pgvector
```
@@ -145,7 +111,7 @@ The chat bot also supports uploading documents to create a knowledge base.
```{include} ../README.md
:start-after: '## Open Source Integrations'
-:end-before: '## Support, Feedback, and Contributing'
+:end-before: '## Related NVIDIA Projects'
```
```{toctree}
@@ -156,10 +122,7 @@ The chat bot also supports uploading documents to create a knowledge base.
About the RAG Pipelines
support-matrix
API Catalog Models
-Local GPUs
-Multi-GPU for Inference
Query Decomposition
-Quantized Model
Structured Data
Multimodal Data
Multi-turn
@@ -193,7 +156,6 @@ notebooks/*
:hidden:
architecture
-llm-inference-server
frontend
jupyter-server
chain-server
diff --git a/docs/jupyter-server.md b/docs/jupyter-server.md
index 94e7aee36..02042508f 100644
--- a/docs/jupyter-server.md
+++ b/docs/jupyter-server.md
@@ -31,60 +31,49 @@ The Jupyter notebooks provide guidance to building knowledge-augmented chat bots
The following Jupyter notebooks are provided with the AI workflow for the default canonical RAG example:
-- [LLM Streaming Client](../../notebooks/01-llm-streaming-client.ipynb)
-
- This notebook demonstrates how to use a client to stream responses from an LLM deployed to NVIDIA Triton Inference Server with NVIDIA TensorRT-LLM (TRT-LLM). This deployment format optimizes the model for low latency and high throughput inference.
-
-- [Document Question-Answering with LangChain](../../notebooks/02_langchain_simple.ipynb)
-
- This notebook demonstrates how to use LangChain to build a chat bot that references a custom knowledge base. LangChain provides a simple framework for connecting LLMs to your own data sources. It shows how to integrate a TensorRT-LLM to LangChain using a custom wrapper.
-
-- [Document Question-Answering with LlamaIndex](../../notebooks/03_llama_index_simple.ipynb)
-
- This notebook demonstrates how to use LlamaIndex to build a chat bot that references a custom knowledge base. It contains the same functionality as the preceding notebook, but uses some LlamaIndex components instead of LangChain components. It also shows how the two frameworks can be used together.
-
-- [Advanced Document Question-Answering with LlamaIndex](../../notebooks/04_llamaindex_hier_node_parser.ipynb)
-
- This notebook demonstrates how to use LlamaIndex to build a more complex retrieval for a chat bot. The retrieval method shown in this notebook works well for code documentation. The method retrieves more contiguous document blocks that preserve both code snippets and explanations of code.
-
-- [Upload Press Releases and Interact with REST FastAPI Server](../../notebooks/05_dataloader.ipynb)
+- [Upload Press Releases and Interact with REST FastAPI Server](../../notebooks/01_dataloader.ipynb)
This notebook demonstrates how to use the REST FastAPI server to upload the knowledge base and then ask a question without and with the knowledge base.
-- [NVIDIA AI Endpoint Integration with LangChain](../../notebooks/07_Option(1)_NVIDIA_AI_endpoint_simple.ipynb)
+- [NVIDIA AI Endpoint Integration with LangChain](../../notebooks/02_Option(1)_NVIDIA_AI_endpoint_simple.ipynb)
This notebook demonstrates how to build a Retrieval Augmented Generation (RAG) example using the NVIDIA AI endpoint integrated with Langchain, with FAISS as the vector store.
-- [RAG with LangChain and local LLM model](../../notebooks/07_Option(2)_minimalistic_RAG_with_langchain_local_HF_LLM.ipynb)
+- [RAG with LangChain and local LLM model](../../notebooks/02_Option(2)_minimalistic_RAG_with_langchain_local_HF_LLM.ipynb)
This notebook demonstrates how to plug in a local LLM from Hugging Face Hub and build a simple RAG app using LangChain.
-- [NVIDIA AI Endpoint with LlamaIndex and LangChain](../../notebooks/08_Option(1)_llama_index_with_NVIDIA_AI_endpoint.ipynb)
+- [NVIDIA AI Endpoint with LlamaIndex and LangChain](../../notebooks/03_Option(1)_llama_index_with_NVIDIA_AI_endpoint.ipynb)
- This notebook demonstrates how to plug in an NVIDIA AI Endpoint mixtral_8x7b and embedding nvolveqa_40k, bind these into LlamaIndex with these customizations.
+ This notebook demonstrates how to plug in an NVIDIA AI Endpoint ai-mixtral-8x7b-instruct and embedding ai-embed-qa-4, bind these into LlamaIndex with these customizations.
-- [Locally deployed model from Hugging Face integration with LlamaIndex and LangChain](../../notebooks/08_Option(2)_llama_index_with_HF_local_LLM.ipynb)
+- [Locally deployed model from Hugging Face integration with LlamaIndex and LangChain](../../notebooks/03_Option(2)_llama_index_with_HF_local_LLM.ipynb)
This notebook demonstrates how to plug in a local LLM from Hugging Face Hub Llama-2-13b-chat-hf and all-MiniLM-L6-v2 embedding from Hugging Face, bind these to into LlamaIndex with these customizations.
-- [LangChain agent with tools plug in multiple models from NVIDIA AI Endpoints](../../notebooks/09_Agent_use_tools_leveraging_NVIDIA_AI_endpoints.ipynb)
+- [LangChain agent with tools plug in multiple models from NVIDIA AI Endpoints](../../notebooks/04_Agent_use_tools_leveraging_NVIDIA_AI_endpoints.ipynb)
- This notebook demonstrates how to use multiple NVIDIA AI Endpoint models such as mixtral_8x7b, Deplot, and Neva.
+ This notebook demonstrates how to use multiple NVIDIA AI Endpoint models such as ai-mixtral-8x7b-instruct, Deplot, and Neva.
-- [LangChain with HTML documents and NVIDIA AI Endpoints](../../notebooks/10_RAG_for_HTML_docs_with_Langchain_NVIDIA_AI_Endpoints.ipynb)
+- [LangChain with HTML documents and NVIDIA AI Endpoints](../../notebooks/05_RAG_for_HTML_docs_with_Langchain_NVIDIA_AI_Endpoints.ipynb)
This notebook demonstrates how to build a RAG using NVIDIA AI Endpoints for LangChain.
The notebook creates a vector store by downloading web pages and generating their embeddings using FAISS.
The notebook shows two different chat chains for querying the vector store.
-- [LangChain with HTML documents and NVIDIA AI Endpoints](../../notebooks/11_LangGraph_HandlingAgent_IntermediateSteps.ipynb)
+- [LangChain with HTML documents and NVIDIA AI Endpoints](../../notebooks/06_LangGraph_HandlingAgent_IntermediateSteps.ipynb)
This notebook guides you through creating a basic agent executor using LangGraph. We demonstrate how to handle the logic of the intermediate steps from the agent leveraging different provided tools within langGraph.
-- [LangChain with HTML documents and NVIDIA AI Endpoints](../../notebooks/12_Chat_wtih_nvidia_financial_reports.ipynb)
+- [LangChain with HTML documents and NVIDIA AI Endpoints](../../notebooks/07_Chat_with_nvidia_financial_reports.ipynb)
+
+ In this notebook, we are going to use milvus as vectorstore, the ai-mixtral-8x7b-instruct as LLM and ai-embed-qa-4 embedding provided by NVIDIA_AI_Endpoint as LLM and embedding model, and build a simply RAG example for chatting with NVIDIA Financial Reports.
+
+- [RAG with locally deployed models using NIMS](../../notebooks/08_RAG_Langchain_with_Local_NIM.ipynb)
- In this notebook, we are going to use milvus as vectorstore, the mixtral_8x7b as LLM and ai-embed-qa-4 embedding provided by NVIDIA_AI_Endpoint as LLM and embedding model, and build a simply RAG example for chatting with NVIDIA Financial Reports.
+ In this notebook we demonstrate how to build a RAG using [NVIDIA Inference Microservices (NIM)](https://build.nvidia.com/explore/discover). We locally host a `Llama3-8b-instruct` using the NIM LLM container and deploy it using [ NVIDIA AI Endpoints for LangChain](https://python.langchain.com/docs/integrations/chat/nvidia_ai_endpoints/).
+ In order to run this notebook in a virtual environment, you need to launch the NIM Docker container in the background outside of the notebook environment prior to running the LangChain code in the notebook cells. Run the commands in the first 3 cells from a terminal then begin with the 4th cell (curl inference command) within the notebook environment.
## Running JupyterLab Server Individually
diff --git a/docs/llm-inference-server.md b/docs/llm-inference-server.md
deleted file mode 100644
index a9298be2f..000000000
--- a/docs/llm-inference-server.md
+++ /dev/null
@@ -1,61 +0,0 @@
-
-
-# NeMo Framework Inference Server
-
-```{contents}
----
-depth: 2
-local: true
-backlinks: none
----
-```
-
-## About the Inference Server
-
-The generative AI examples use [NeMo Framework Inference Server](https://docs.nvidia.com/nemo-framework/user-guide/latest/index.html) container.
-NeMo can create optimized LLM using TensorRT-LLM and can deploy models using NVIDIA Triton Inference Server for high-performance, cost-effective, and low-latency inference.
-Many examples use Llama 2 models and LLM Inference Server container contains modules and scripts that are required for TRT-LLM conversion of the Llama 2 models and deployment using NVIDIA Triton Inference Server.
-
-The inference server is used with examples that deploy a model on-premises.
-The examples that use [NVIDIA AI foundation models](https://www.nvidia.com/en-in/ai-data-science/foundation-models/) or NVIDIA AI Endpoints do not use this component.
-
-
-## Running the Inference Server Individually
-
-The following steps describe how a Llama 2 model deployment.
-
-- Download Llama 2 Chat Model Weights from [Meta](https://ai.meta.com/resources/models-and-libraries/llama-downloads/) or [HuggingFace](https://huggingface.co/meta-llama/Llama-2-13b-chat-hf/). You can check [support matrix](support-matrix.md) for GPU requirements for the deployment.
-
-- Update the `deploy/compose/compose.env` file with `MODEL_DIRECTORY` as the downloaded Llama 2 model path and other model parameters as needed.
-
-- Build the LLM inference server container from source:
-
- ```console
- $ source deploy/compose/compose.env
- $ docker compose -f deploy/compose/rag-app-text-chatbot.yaml build llm
- ```
-
-- Run the container. The container starts Triton Inference Server with TRT-LLM optimized Llama 2 model:
-
- ```console
- $ source deploy/compose/compose.env
- $ docker compose -f deploy/compose/rag-app-text-chatbot.yaml up llm
- ```
-
-After the optimized Llama 2 model is deployed in Triton Inference Server, clients can send HTTP/REST or gRPC requests directly to the server.
-A sample implementation of a client can be found in the `triton_trt_llm.py` file of GitHub repository at [integrations/langchain/llms/](https://github.com/NVIDIA/GenerativeAIExamples/tree/main/integrations/langchain/llms).
diff --git a/docs/local-gpu.md b/docs/local-gpu.md
deleted file mode 100644
index c620fbacc..000000000
--- a/docs/local-gpu.md
+++ /dev/null
@@ -1,328 +0,0 @@
-
-
-# Using Local GPUs for a Q&A Chatbot
-
-```{contents}
----
-depth: 2
-local: true
-backlinks: none
----
-```
-
-## Example Features
-
-This example deploys a developer RAG pipeline for chat Q&A and serves inferencing with the NeMo Framework Inference container.
-
-This example uses a local host with an NVIDIA A100, H100, or L40S GPU.
-
-```{list-table}
-:header-rows: 1
-
-* - Model
- - Embedding
- - Framework
- - Description
- - Multi-GPU
- - TRT-LLM
- - Model Location
- - Triton
- - Vector Database
-
-* - llama-2
- - UAE-Large-V1
- - LlamaIndex
- - QA chatbot
- - NO
- - YES
- - Local Model
- - YES
- - Milvus
-
-* - llama-2
- - UAE-Large-V1
- - LlamaIndex
- - QA chatbot
- - NO
- - YES
- - Local Model
- - YES
- - pgvector
-```
-
-The following figure shows the sample topology:
-
-- The sample chat bot web application communicates with the local chain server.
-
-- The local chain server sends inference requests to NVIDIA Triton Inference Server (TIS).
- TIS uses TensorRT-LLM and NVIDIA GPUs with the LLama 2 model for generative AI.
-
-- The sample chat bot supports uploading documents to create a knowledge base.
- The uploaded documents are parsed by the chain server and embeddings are stored
- in the vector database, Milvus or pgvector.
- When you submit a question and request to use the knowledge base, the chain server
- retrieves the most relevant documents and submits them with the question to
- TIS to perform retrieval-augumented generation.
-
-- Optionally, you can deploy NVIDIA Riva. Riva can use automatic speech recognition to
- transcribe your questions and use text-to-speech to speak the answers aloud.
-
-
-
-
-## Prerequisites
-
-- Clone the Generative AI examples Git repository using Git LFS:
-
- ```console
- $ sudo apt -y install git-lfs
- $ git clone git@github.com:NVIDIA/GenerativeAIExamples.git
- $ cd GenerativeAIExamples/
- $ git lfs pull
- ```
-
-- A host with an NVIDIA A100, H100, or L40S GPU.
-
-- Verify NVIDIA GPU driver version 535 or later is installed and that the GPU is in compute mode:
-
- ```console
- $ nvidia-smi -q -d compute
- ```
-
- *Example Output*
-
- ```{code-block} output
- ---
- emphasize-lines: 4,9
- ---
- ==============NVSMI LOG==============
-
- Timestamp : Sun Nov 26 21:17:25 2023
- Driver Version : 535.129.03
- CUDA Version : 12.2
-
- Attached GPUs : 1
- GPU 00000000:CA:00.0
- Compute Mode : Default
- ```
-
- If the driver is not installed or below version 535, refer to the [*NVIDIA Driver Installation Quickstart Guide*](https://docs.nvidia.com/datacenter/tesla/tesla-installation-notes/index.html).
-
-- Install Docker Engine and Docker Compose.
- Refer to the instructions for [Ubuntu](https://docs.docker.com/engine/install/ubuntu/).
-
-- Install the NVIDIA Container Toolkit.
-
- 1. Refer to the [installation documentation](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html).
-
- 1. When you configure the runtime, set the NVIDIA runtime as the default:
-
- ```console
- $ sudo nvidia-ctk runtime configure --runtime=docker --set-as-default
- ```
-
- If you did not set the runtime as the default, you can reconfigure the runtime by running the preceding command.
-
- 1. Verify the NVIDIA container toolkit is installed and configured as the default container runtime:
-
- ```console
- $ cat /etc/docker/daemon.json
- ```
-
- *Example Output*
-
- ```json
- {
- "default-runtime": "nvidia",
- "runtimes": {
- "nvidia": {
- "args": [],
- "path": "nvidia-container-runtime"
- }
- }
- }
- ```
-
- 1. Run the `nvidia-smi` command in a container to verify the configuration:
-
- ```console
- $ sudo docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi -L
- ```
-
- *Example Output*
-
- ```output
- GPU 0: NVIDIA A100 80GB PCIe (UUID: GPU-d8ce95c1-12f7-3174-6395-e573163a2ace)
- ```
-
-- Optional: Enable NVIDIA Riva automatic speech recognition (ASR) and text to speech (TTS).
-
- - To launch a Riva server locally, refer to the [Riva Quick Start Guide](https://docs.nvidia.com/deeplearning/riva/user-guide/docs/quick-start-guide.html).
-
- - In the provided `config.sh` script, set `service_enabled_asr=true` and `service_enabled_tts=true`, and select the desired ASR and TTS languages by adding the appropriate language codes to `asr_language_code` and `tts_language_code`.
-
- - After the server is running, assign its IP address (or hostname) and port (50051 by default) to `RIVA_API_URI` in `deploy/compose/compose.env`.
-
- - Alternatively, you can use a hosted Riva API endpoint. You might need to obtain an API key and/or Function ID for access.
-
- In `deploy/compose/compose.env`, make the following assignments as necessary:
-
- ```bash
- export RIVA_API_URI=":"
- export RIVA_API_KEY=""
- export RIVA_FUNCTION_ID=""
- ```
-
-## Download the Llama 2 Model and Weights
-
-1. Fill out Meta's [Llama request access form](https://ai.meta.com/resources/models-and-libraries/llama-downloads/).
-
- - Select the **Llama 2 & Llama Chat** checkbox.
- - After verifying your email, Meta will email you a download link.
-
-1. Clone the Llama repository:
-
- ```console
- $ git clone https://github.com/facebookresearch/llama.git
- $ cd llama/
- ```
-
-1. Run the `download.sh` script. When prompted, specify `13B-chat` to download the llama-2-13b-chat model:
-
- ```console
- $ ./download.sh
- Enter the URL from email: < https://download.llamameta.net/...>
-
- Enter the list of models to download without spaces (7B,13B,70B,7B-chat,13B-chat,70B-chat), or press Enter for all: 13B-chat
- ```
-
-1. Copy the tokenizer to the model directory.
-
- ```console
- $ mv tokenizer* llama-2-13b-chat/
- $ ls llama-2-13b-chat/
- ```
-
- *Example Output*
-
- ```output
- checklist.chk consolidated.00.pth consolidated.01.pth params.json tokenizer.model tokenizer_checklist.chk
- ```
-
-## Build and Start the Containers
-
-1. In the Generative AI Examples repository, edit the `deploy/compose/compose.env` file.
-
- Specify the absolute path to the model location, model architecture, and model name.
-
- ```bash
- # full path to the local copy of the model weights
- # NOTE: This should be an absolute path and not relative path
- export MODEL_DIRECTORY="/path/to/llama/llama-2-13b_chat/"
-
- # the architecture of the model. eg: llama
- export MODEL_ARCHITECTURE="llama"
-
- # the name of the model being used - only for displaying on frontend
- export MODEL_NAME="Llama-2-13b-chat"
- ...
- ```
-
-1. From the root of the repository, build the containers:
-
- ```console
- $ docker compose --env-file deploy/compose/compose.env -f deploy/compose/rag-app-text-chatbot.yaml build
- ```
-
-1. Start the containers:
-
- ```console
- $ docker compose --env-file deploy/compose/compose.env -f deploy/compose/rag-app-text-chatbot.yaml up -d
- ```
-
- NVIDIA Triton Inference Server can require 5 minutes to start. The `-d` flag starts the services in the background.
-
- *Example Output*
-
- ```output
- ✔ Network nvidia-rag Created
- ✔ Container notebook-server Started
- ✔ Container llm-inference-server Started
- ✔ Container chain-server Started
- ✔ Container rag-playground Started
- ```
-
-1. Start the Milvus vector database:
-
- ```console
- $ docker compose --env-file deploy/compose/compose.env -f deploy/compose/docker-compose-vectordb.yaml up -d milvus
- ```
-
- *Example Output*
-
- ```output
- ✔ Container milvus-minio Started
- ✔ Container milvus-etcd Started
- ✔ Container milvus-standalone Started
- ```
-
-1. Confirm the containers are running:
-
- ```console
- $ docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Status}}"
- ```
-
- *Example Output*
-
- ```output
- CONTAINER ID NAMES STATUS
- 256da0ecdb7b rag-playground Up 48 minutes
- 2974aa4fb2ce chain-server Up 48 minutes
- 4a8c4aebe4ad notebook-server Up 48 minutes
- 5be2b57bb5c1 milvus-standalone Up 48 minutes (healthy)
- ecf674c8139c llm-inference-server Up 48 minutes (healthy)
- a6609c22c171 milvus-minio Up 48 minutes (healthy)
- b23c0858c4d4 milvus-etcd Up 48 minutes (healthy)
- ```
-
-
-### Related Information
-
-- [Meta Llama README](https://github.com/facebookresearch/llama/blob/main/README.md)
-- [Meta Llama request access form](https://ai.meta.com/resources/models-and-libraries/llama-downloads/)
-
-
-## Stopping the Containers
-
-1. Stop the vector database:
-
- ```console
- $ docker compose -f deploy/compose/docker-compose-vectordb.yaml down
- ```
-
-1. Stop and remove the application containers:
-
- ```console
- $ docker compose --env-file deploy/compose/compose.env -f deploy/compose/rag-app-text-chatbot.yaml down
- ```
-
-## Next Steps
-
-- Use the [](./using-sample-web-application.md).
-- [](./vector-database.md)
-- Run the sample Jupyter notebooks to learn about optional features.
diff --git a/docs/multi-gpu.md b/docs/multi-gpu.md
deleted file mode 100644
index 19cd390f2..000000000
--- a/docs/multi-gpu.md
+++ /dev/null
@@ -1,404 +0,0 @@
-
-
-# Multi-GPU for Inference
-
-```{contents}
----
-depth: 2
-local: true
-backlinks: none
----
-```
-
-## Comparison with the Local GPUs Example
-
-This example is very similar to the example that uses local GPUs.
-The key difference is to modify the `deploy/compose/rag-app-text-chatbot.yaml` file to specify the GPU device IDs for the services.
-If you performed all the steps in [](local-gpu.md), consider skipping to
-step 1 of [](#build-and-start-the-containers) on this page.
-
-
-## Special Considerations for Tensor Parallelism
-
-When you use more than two GPUs for the inference server, you might need to specify additional command-line arguments.
-
-The special consideration is that the attention head size for the model must be a multiple of the tensor parallelism size.
-For the Llama-2-13B chat model, the model attention head size is 40.
-You can view this value in the `n_heads: 40` field in the `llama-2-13b-chat/params.json` file after you download the model or from the Hugging Face Model Hub: .
-
-The tensor parallelism is calculated as {math}`\mbox{tensor-parallelism} = \mbox{world-size} \div \mbox{pipeline-parallelism}`
-where $\mbox{world-size}$ is the number of GPUs and $\mbox{pipeline-parallelism}$ has a default value of 1.
-
-With 1, 2, 4, 5, or any number of GPUs that divide 40 into equally, no action is required.
-
-For 3, 6, or any other number that does not divide equally into 40, you can specify a pipeline parallelism value so that the tensor parallelism is a whole number.
-For example, to use 6 GPUs, you can specify `--pipeline-parallelism 3` on the inference server command line so that tensor parallelism is 2.
-
-If you use a different model, refer to the `params.json` file.
-For example, the Llama-2-7B chat model has `n_heads: 32` and the Llama-2-70B chat model has `n_heads: 64`.
-
-
-## Example Features
-
-This example deploys a developer RAG pipeline for chat Q&A and serves inferencing with the NeMo Framework Inference container across multiple local GPUs.
-
-This example uses a local host with an NVIDIA A100, H100, or L40S GPU.
-
-```{list-table}
-:header-rows: 1
-
-* - Model
- - Embedding
- - Framework
- - Description
- - Multi-GPU
- - TRT-LLM
- - Model Location
- - Triton
- - Vector Database
-
-* - llama-2
- - UAE-Large-V1
- - LlamaIndex
- - QA chatbot
- - YES
- - YES
- - Local Model
- - YES
- - Milvus
-
-* - llama-2
- - UAE-Large-V1
- - LlamaIndex
- - QA chatbot
- - YES
- - YES
- - Local Model
- - YES
- - pgvector
-```
-
-The following figure shows the sample topology:
-
-- The sample chat bot web application communicates with the local chain server.
-
-- The chain server sends inference requests to NVIDIA Triton Inference Server (TIS).
- TIS uses TensorRT-LLM and NVIDIA GPUs with the LLama 2 model for generative AI.
-
-- The sample chat bot supports uploading documents to create a knowledge base.
- The uploaded documents are parsed by the chain server and embeddings are stored
- in the vector database, Milvus or pgvector.
- When you submit a question and request to use the knowledge base, the chain server
- retrieves the most relevant documents and submits them with the question to
- TIS to perform retrieval-augumented generation.
-
-- Optionally, you can deploy NVIDIA Riva. Riva can use automatic speech recognition to
- transcribe your questions and use text-to-speech to speak the answers aloud.
-
-
-
-
-## Prerequisites
-
-- Clone the Generative AI examples Git repository using Git LFS:
-
- ```console
- $ sudo apt -y install git-lfs
- $ git clone git@github.com:NVIDIA/GenerativeAIExamples.git
- $ cd GenerativeAIExamples/
- $ git lfs pull
- ```
-
-- A host with one or more NVIDIA A100, H100, or L40S GPU.
-
-- Verify NVIDIA GPU driver version 535 or later is installed and that the GPU is in compute mode:
-
- ```console
- $ nvidia-smi -q -d compute
- ```
-
- *Example Output*
-
- ```{code-block} output
- ---
- emphasize-lines: 4,9
- ---
- ==============NVSMI LOG==============
-
- Timestamp : Sun Nov 26 21:17:25 2023
- Driver Version : 535.129.03
- CUDA Version : 12.2
-
- Attached GPUs : 2
- GPU 00000000:CA:00.0
- Compute Mode : Default
-
- GPU 00000000:FA:00.0
- Compute Mode : Default
- ```
-
- If the driver is not installed or below version 535, refer to the [*NVIDIA Driver Installation Quickstart Guide*](https://docs.nvidia.com/datacenter/tesla/tesla-installation-notes/index.html).
-
-- Install Docker Engine and Docker Compose.
- Refer to the instructions for [Ubuntu](https://docs.docker.com/engine/install/ubuntu/).
-
-- Install the NVIDIA Container Toolkit.
-
- 1. Refer to the [installation documentation](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html).
-
- 1. When you configure the runtime, set the NVIDIA runtime as the default:
-
- ```console
- $ sudo nvidia-ctk runtime configure --runtime=docker --set-as-default
- ```
-
- If you did not set the runtime as the default, you can reconfigure the runtime by running the preceding command.
-
- 1. Verify the NVIDIA container toolkit is installed and configured as the default container runtime:
-
- ```console
- $ cat /etc/docker/daemon.json
- ```
-
- *Example Output*
-
- ```json
- {
- "default-runtime": "nvidia",
- "runtimes": {
- "nvidia": {
- "args": [],
- "path": "nvidia-container-runtime"
- }
- }
- }
- ```
-
- 1. Run the `nvidia-smi` command in a container to verify the configuration:
-
- ```console
- $ sudo docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi -L
- ```
-
- *Example Output*
-
- ```output
- GPU 0: NVIDIA A100 80GB PCIe (UUID: GPU-d8ce95c1-12f7-3174-6395-e573163a2ace)
- GPU 1: NVIDIA A100 80GB PCIe (UUID: GPU-1d37ef30-0861-de64-a06d-73257e247a0d)
- ```
-
-- Optional: Enable NVIDIA Riva automatic speech recognition (ASR) and text to speech (TTS).
-
- - To launch a Riva server locally, refer to the [Riva Quick Start Guide](https://docs.nvidia.com/deeplearning/riva/user-guide/docs/quick-start-guide.html).
-
- - In the provided `config.sh` script, set `service_enabled_asr=true` and `service_enabled_tts=true`, and select the desired ASR and TTS languages by adding the appropriate language codes to `asr_language_code` and `tts_language_code`.
-
- - After the server is running, assign its IP address (or hostname) and port (50051 by default) to `RIVA_API_URI` in `deploy/compose/compose.env`.
-
- - Alternatively, you can use a hosted Riva API endpoint. You might need to obtain an API key and/or Function ID for access.
-
- In `deploy/compose/compose.env`, make the following assignments as necessary:
-
- ```bash
- export RIVA_API_URI=":"
- export RIVA_API_KEY=""
- export RIVA_FUNCTION_ID=""
- ```
-
-## Download the Llama 2 Model and Weights
-
-1. Fill out Meta's [Llama request access form](https://ai.meta.com/resources/models-and-libraries/llama-downloads/).
-
- - Select the **Llama 2 & Llama Chat** checkbox.
- - After verifying your email, Meta will email you a download link.
-
-1. Clone the Llama repository:
-
- ```console
- $ git clone https://github.com/facebookresearch/llama.git
- $ cd llama/
- ```
-
-1. Run the `download.sh` script. When prompted, specify `13B-chat` to download the llama-2-13b-chat model:
-
- ```console
- $ ./download.sh
- Enter the URL from email: < https://download.llamameta.net/...>
-
- Enter the list of models to download without spaces (7B,13B,70B,7B-chat,13B-chat,70B-chat), or press Enter for all: 13B-chat
- ```
-
-1. Copy the tokenizer to the model directory.
-
- ```console
- $ mv tokenizer* llama-2-13b-chat/
- $ ls llama-2-13b-chat/
- ```
-
- *Example Output*
-
- ```output
- checklist.chk consolidated.00.pth consolidated.01.pth params.json tokenizer.model tokenizer_checklist.chk
- ```
-
-## Build and Start the Containers
-
-1. In the Generative AI Examples repository, edit the `deploy/compose/rag-app-text-chatbot.yaml` file.
-
- Specify the GPU device IDs to assign to the services.
- Refer to [](#special-considerations-for-tensor-parallelism) when specifying more than two GPUs.
-
- ```yaml
- services:
- llm:
- // ...
- command: # Add --pipeline-parallelism if you need to specify a value.
- deploy:
- resources:
- reservations:
- devices:
- - driver: nvidia
- # count: ${INFERENCE_GPU_COUNT:-all} # Comment this out
- device_ids: ["0", "1"]
- capabilities: [gpu]
-
- jupyter-server:
- // ...
- deploy:
- resources:
- reservations:
- devices:
- - driver: nvidia
- # count: 1 # Comment this out
- device_ids: ["2"]
- capabilities: [gpu]
- ```
-
-1. Edit the `deploy/compose/docker-compose-vectordb.yaml` file.
-
- Specify the GPU device IDs to assign to the services:
-
- ```yaml
- services:
- milvus:
- // ...
- deploy:
- resources:
- reservations:
- devices:
- - driver: nvidia
- # count: 1 # Comment this out
- device_ids: ["3"]
- capabilities: [gpu]
- ```
-
- You can share device IDs between vector database and Jupyter Server.
-
-1. Edit the `deploy/compose/compose.env` file.
-
- Specify the absolute path to the model location, model architecture, and model name.
-
- ```bash
- # full path to the local copy of the model weights
- # NOTE: This should be an absolute path and not relative path
- export MODEL_DIRECTORY="/path/to/llama/llama-2-13b_chat/"
-
- # the architecture of the model. eg: llama
- export MODEL_ARCHITECTURE="llama"
-
- # the name of the model being used - only for displaying on frontend
- export MODEL_NAME="Llama-2-13b-chat"
- ...
- ```
-
-1. From the root of the repository, build the containers:
-
- ```console
- $ docker compose --env-file deploy/compose/compose.env -f deploy/compose/rag-app-text-chatbot.yaml build
- ```
-
-1. Start the containers:
-
- ```console
- $ docker compose --env-file deploy/compose/compose.env -f deploy/compose/rag-app-text-chatbot.yaml up -d
- ```
-
- NVIDIA Triton Inference Server can require 5 minutes to start. The `-d` flag starts the services in the background.
-
- *Example Output*
-
- ```output
- ✔ Network nvidia-rag Created
- ✔ Container llm-inference-server Started
- ✔ Container notebook-server Started
- ✔ Container chain-server Started
- ✔ Container rag-playground Started
- ```
-
-1. Start the Milvus vector database:
-
- ```console
- $ docker compose --env-file deploy/compose/compose.env -f deploy/compose/docker-compose-vectordb.yaml up -d milvus
- ```
-
- *Example Output*
-
- ```output
- ✔ Container milvus-minio Started
- ✔ Container milvus-etcd Started
- ✔ Container milvus-standalone Started
- ```
-
-1. Confirm the containers are running:
-
- ```console
- $ docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Status}}"
- ```
-
- *Example Output*
-
- ```output
- CONTAINER ID NAMES STATUS
- 256da0ecdb7b rag-playground Up 48 minutes
- 2974aa4fb2ce chain-server Up 48 minutes
- 4a8c4aebe4ad notebook-server Up 48 minutes
- 5be2b57bb5c1 milvus-standalone Up 48 minutes (healthy)
- ecf674c8139c llm-inference-server Up 48 minutes (healthy)
- a6609c22c171 milvus-minio Up 48 minutes (healthy)
- b23c0858c4d4 milvus-etcd Up 48 minutes (healthy)
- ```
-
-### Related Information
-
-- [Meta Llama README](https://github.com/facebookresearch/llama/blob/main/README.md)
-- [Meta Llama request access form](https://ai.meta.com/resources/models-and-libraries/llama-downloads/)
-
-
-## Stopping the Containers
-
-- To uninstall, stop and remove the running containers from the root of the Generative AI Examples repository:
-
- ```console
- $ docker compose -f deploy/compose/rag-app-text-chatbot.yaml down
- ```
-
-## Next Steps
-
-- Use the [](./using-sample-web-application.md).
-- [](./vector-database.md)
-- Run the sample Jupyter notebooks to learn about optional features.
diff --git a/docs/multi-turn.md b/docs/multi-turn.md
index a7592c3b5..bd1a7738b 100644
--- a/docs/multi-turn.md
+++ b/docs/multi-turn.md
@@ -53,11 +53,11 @@ This example uses models from the NVIDIA API Catalog.
- Multi-GPU
- TRT-LLM
- Model Location
- - Triton
+ - NIM for LLMs
- Vector Database
-* - ai-llama2-70b
- - ai-embed-qa-4
+* - meta/llama3-8b-instruct
+ - snowflake-arctic-embed-l
- LangChain
- QA chatbot
- NO
@@ -90,6 +90,14 @@ The following figure shows the sample topology:
- Install Docker Engine and Docker Compose.
Refer to the instructions for [Ubuntu](https://docs.docker.com/engine/install/ubuntu/).
+- Login to Nvidia's docker registry. Please refer to [instructions](https://docs.nvidia.com/ngc/gpu-cloud/ngc-overview/index.html) to create account and generate NGC API key. This is needed for pulling in the secure base container used by all the examples.
+
+ ```console
+ $ docker login nvcr.io
+ Username: $oauthtoken
+ Password:
+ ```
+
- Optional: Enable NVIDIA Riva automatic speech recognition (ASR) and text to speech (TTS).
- To launch a Riva server locally, refer to the [Riva Quick Start Guide](https://docs.nvidia.com/deeplearning/riva/user-guide/docs/quick-start-guide.html).
@@ -108,9 +116,9 @@ The following figure shows the sample topology:
export RIVA_FUNCTION_ID=""
```
-## Get an API Key for the Llama 2 70B API Endpoint
+## Get an API Key for the Llama 3 8B API Endpoint
-```{include} query-decomposition.md
+```{include} multimodal-data.md
:start-after: api-key-start
:end-before: api-key-end
```
@@ -148,7 +156,11 @@ The following figure shows the sample topology:
1. Start the Milvus vector database:
```console
- $ docker compose --env-file deploy/compose/compose.env -f deploy/compose/docker-compose-vectordb.yaml up -d milvus
+ $ docker compose \
+ --env-file deploy/compose/compose.env \
+ -f deploy/compose/docker-compose-vectordb.yaml \
+ --profile llm-embedding \
+ up -d milvus
```
*Example Output*
@@ -184,4 +196,4 @@ The following figure shows the sample topology:
- Enable the **Use knowledge base** checkbox when you submit a question.
- [](./vector-database.md)
- Stop the containers by running `docker compose -f deploy/compose/rag-app-multiturn-chatbot.yaml down` and
- `docker compose -f deploy/compose/docker-compose-vectordb.yaml down`.
+ `docker compose -f deploy/compose/docker-compose-vectordb.yaml --profile llm-embedding down`.
diff --git a/docs/multimodal-data.md b/docs/multimodal-data.md
index 32eabcd8c..0215d234c 100644
--- a/docs/multimodal-data.md
+++ b/docs/multimodal-data.md
@@ -28,12 +28,12 @@ backlinks: none
## Example Features
This example deploys a developer RAG pipeline for chat Q&A and serves inferencing from NVIDIA API Catalog endpoints
-instead of NVIDIA Triton Inference Server, a local Llama 2 model, or local GPUs.
+instead of a local inference server, a local LLM, or local GPUs.
Developers get free credits for 10K requests to any of the available models.
The key difference from the [](./api-catalog.md) example is that this example demonstrates how work with multimodal data.
-The model works with any kind of image in PDF, such as graphs and plots, as well as text and tables.
+The model works with any kind of image in PDF or PPTX, such as graphs and plots, as well as text and tables.
This example uses models from the NVIDIA API Catalog.
@@ -48,15 +48,15 @@ This example uses models from the NVIDIA API Catalog.
- Multi-GPU
- TRT-LLM
- Model Location
- - Triton
+ - NIM for LLMs
- Vector Database
-* - ai-mixtral-8x7b-instruct for response generation
+* - meta/llama3-8b-instruct for response generation
ai-google-Deplot for graph to text conversion
ai-Neva-22B for image to text conversion
- - ai-embed-qa-4
+ - snowflake-arctic-embed-l
- Custom Python
- QA chatbot
- NO
@@ -79,7 +79,7 @@ The following figure shows the sample topology:
## Limitations
Although the AI Foundation Models endpoint uses the Neva_22B model for processing images, this example
-supports uploading images that are part of PDF files only.
+supports uploading images that are part of PDF and PPTX files only.
For example, after deploying the services, you cannot upload a PNG, JPEG, TIFF, or any other image format file.
@@ -97,6 +97,14 @@ For example, after deploying the services, you cannot upload a PNG, JPEG, TIFF,
- Install Docker Engine and Docker Compose.
Refer to the instructions for [Ubuntu](https://docs.docker.com/engine/install/ubuntu/).
+- Login to Nvidia's docker registry. Please refer to [instructions](https://docs.nvidia.com/ngc/gpu-cloud/ngc-overview/index.html) to create account and generate NGC API key. This is needed for pulling in the secure base container used by all the examples.
+
+ ```console
+ $ docker login nvcr.io
+ Username: $oauthtoken
+ Password:
+ ```
+
- Optional: Enable NVIDIA Riva automatic speech recognition (ASR) and text to speech (TTS).
- To launch a Riva server locally, refer to the [Riva Quick Start Guide](https://docs.nvidia.com/deeplearning/riva/user-guide/docs/quick-start-guide.html).
@@ -115,12 +123,33 @@ For example, after deploying the services, you cannot upload a PNG, JPEG, TIFF,
export RIVA_FUNCTION_ID=""
```
-## Get an API Key for the Mixtral 8x7B Instruct API Endpoint
+## Get an API Key for the Meta Llama 3 8B Instruct API Endpoint
-```{include} api-catalog.md
-:start-after: api-key-start
-:end-before: api-key-end
-```
+% api-key-start
+
+Perform the following steps if you do not already have an API key.
+You can use different model API endpoints with the same API key.
+
+1. Navigate to .
+
+2. Find the **Llama 3 8B Instruct** card and click the card.
+
+ 
+
+3. Click **Get API Key**.
+
+ 
+
+4. Click **Generate Key**.
+
+ 
+
+5. Click **Copy Key** and then save the API key.
+ The key begins with the letters nvapi-.
+
+ 
+
+% api-key-end
## Build and Start the Containers
@@ -155,7 +184,11 @@ For example, after deploying the services, you cannot upload a PNG, JPEG, TIFF,
1. Start the Milvus vector database:
```console
- $ docker compose --env-file deploy/compose/compose.env -f deploy/compose/docker-compose-vectordb.yaml up -d milvus
+ $ docker compose \
+ --env-file deploy/compose/compose.env \
+ -f deploy/compose/docker-compose-vectordb.yaml \
+ --profile llm-embedding \
+ up -d milvus
```
*Example Output*
@@ -187,7 +220,7 @@ For example, after deploying the services, you cannot upload a PNG, JPEG, TIFF,
- Access the web interface for the chat server.
Refer to [](./using-sample-web-application.md) for information about using the web interface.
-- Upload one or more PDF files with graphics, plots, and tables.
+- Upload one or more PDF and PPTX files with graphics, plots, and tables.
- Enable the **Use knowledge base** checkbox when you submit a question.
- Stop the containers by running `docker compose -f deploy/compose/rag-app-multimodal-chatbot.yaml down` and
- `docker compose -f deploy/compose/docker-compose-vectordb.yaml down`.
+ `docker compose -f deploy/compose/docker-compose-vectordb.yaml --profile llm-embedding down`.
diff --git a/docs/nim-llms.md b/docs/nim-llms.md
index ed06c756a..cf3d2d94e 100644
--- a/docs/nim-llms.md
+++ b/docs/nim-llms.md
@@ -31,6 +31,15 @@ NVIDIA NIM for LLMs provides the enterprise-ready approach for deploying large l
If you are approved for [early access to NVIDIA NeMo Microservices](https://developer.nvidia.com/nemo-microservices), you can run the examples with NIM for LLMs.
+The following figure shows the sample topology:
+
+- The sample chat bot web application communicates with the chain server.
+ The chain server sends inference requests to a local NVIDIA NIM for LLMs microservice.
+- Optionally, you can deploy NVIDIA Riva. Riva can use automatic speech recognition to transcribe
+ your questions and use text-to-speech to speak the answers aloud.
+
+
+
## Prerequisites
@@ -137,41 +146,39 @@ If you are approved for [early access to NVIDIA NeMo Microservices](https://deve
```
-## Deploy NIM for LLMs and NeMo Retriever Embedding
-
-- Deploy an LLM with NIM for LLMs, such as Llama-2-13b-chat-hf or Mixtral 8x7b Instruct.
- Refer to the [Llama 2 70B Chat](https://docs.nvidia.com/ai-enterprise/nim-llm/latest/quickstart/llama2-70b-chat.html) quick start, or another quick start in the _NVIDIA NIM for LLMs_ documentation.
+## Build and Start the Containers
-- Deploy a text embedding model, such as NV-Embed-QA.
- Refer to [Deploying Text Embedding Models](https://developer.nvidia.com/docs/nemo-microservices/embedding/source/deploy.html)
- in the _NVIDIA NeMo Retriever Embedding_ documentation.
-
-
-## Build and Start the Chain Server and RAG Playground
+1. Create a `model-cache` directory to download and store the models
+ ```bash
+ mkdir -p model-cache
+ ```
1. In the Generative AI Examples repository, edit the `deploy/compose/compose.env` file.
- Add the following environment variables.
+ Add or update the following environment variables.
```bash
- # Name of the deployed LLM model.
- export APP_LLM_MODELNAME=
-
- export APP_LLM_MODELENGINE=nvidia-ai-endpoints
+ # full path to the `model-cache` directory
+ # NOTE: This should be an absolute path and not relative path
+ export MODEL_DIRECTORY="/path/to/model/cache/directory/"
# IP of system where llm is deployed.
- export APP_LLM_SERVERURL=":"
+ export APP_LLM_SERVERURL="nemollm-inference:8000"
# Name of the deployed embedding model (NV-Embed-QA)
- export APP_EMBEDDINGS_MODELNAME=
+ export APP_EMBEDDINGS_MODELNAME="NV-Embed-QA"
export APP_EMBEDDINGS_MODELENGINE=nvidia-ai-endpoints
+
# IP of system where embedding model is deployed.
- export APP_EMBEDDINGS_SERVERURL=":"
+ export APP_EMBEDDINGS_SERVERURL="nemollm-embedding:9080" # Or ranking-ms:8080 for the reranking example.
+
+ # GPU for use by Milvus
+ export VECTORSTORE_GPU_DEVICE_ID=
...
```
-1. From the root of the repository, build the containers:
+1. Build the Chain Server and RAG Playground containers:
```console
$ docker compose \
@@ -180,20 +187,10 @@ If you are approved for [early access to NVIDIA NeMo Microservices](https://deve
build chain-server rag-playground
```
+ Avoid GPU memory errors by assigning a GPU to the Chain Server.
+ Update `device_ids` in the `chain-server` service of `deploy/compose/rag-app-text-chatbot.yaml` manifest to specify a unique GPU ID.
You can specify a different Docker Compose file, such as `deploy/compose/rag-app-multiturn-chatbot.yaml`.
-1. Start the Chain Server and RAG Playground:
-
- ```console
- $ docker compose \
- --env-file deploy/compose/compose.env \
- -f deploy/compose/rag-app-text-chatbot.yaml \
- up -d --no-deps chain-server rag-playground
- ```
-
- The `-d` argument starts the services in the background and the `--no-deps` argument avoids starting a second inference server.
-
- `Note`: To avoid memory issues, deploy the chain server on a separate GPU from the LLM. Update `device_ids` in `chain-server` service of `deploy/compose/rag-app-text-chatbot.yaml` (or relevant Docker Compose file) to specify a different GPU
```yaml
deploy:
resources:
@@ -204,14 +201,45 @@ If you are approved for [early access to NVIDIA NeMo Microservices](https://deve
capabilities: [gpu]
```
-1. Start the Milvus vector database:
+1. Start the Chain Server and RAG Playground:
```console
- $ docker compose --env-file deploy/compose/compose.env -f deploy/compose/docker-compose-vectordb.yaml up -d milvus
+ $ docker compose \
+ --env-file deploy/compose/compose.env \
+ -f deploy/compose/rag-app-text-chatbot.yaml \
+ up -d --no-deps chain-server rag-playground
```
- `Note`: To avoid memory issues, deploy the milvus on a separate GPU from the LLM. Update `VECTORSTORE_GPU_DEVICE_ID` in `deploy/compose/compose.env`
+
+ The `-d` argument starts the services in the background and the `--no-deps` argument avoids starting the JupyterLab server.
+
+1. Start the NIM for LLMs and NeMo Embedding Microservices containers.
+
+ 1. Export the `NGC_API_KEY` environment variable that the containers use to download models from NVIDIA NGC:
+
+ ```console
+ export NGC_API_KEY=M2...
+ ```
+
+ The NGC API key has a different value than the NVIDIA API key that the API catalog examples use.
+
+ 1. Start the containers:
+
+ ```console
+ $ DOCKER_USER=$(id -u) docker compose \
+ --env-file deploy/compose/compose.env \
+ -f deploy/compose/docker-compose-nim-ms.yaml \
+ --profile llm-embedding \
+ up -d
+ ```
+
+1. Start the Milvus vector database:
+
```console
- export VECTORSTORE_GPU_DEVICE_ID=
+ $ docker compose \
+ --env-file deploy/compose/compose.env \
+ -f deploy/compose/docker-compose-vectordb.yaml \
+ --profile llm-embedding \
+ up -d milvus
```
1. Confirm the containers are running:
@@ -239,7 +267,17 @@ If you are approved for [early access to NVIDIA NeMo Microservices](https://deve
1. Stop the vector database:
```console
- $ docker compose -f deploy/compose/docker-compose-vectordb.yaml down
+ $ docker compose -f deploy/compose/docker-compose-vectordb.yaml --profile llm-embedding down
+ ```
+
+1. Stop the NIM for LLMs and NeMo Retriever Embedding Microservices:
+
+ ```console
+ $ DOCKER_USER=$(id -u) docker compose \
+ --env-file deploy/compose/compose.env \
+ -f deploy/compose/docker-compose-nim-ms.yaml \
+ --profile llm-embedding \
+ down
```
1. Stop and remove the application containers:
@@ -251,7 +289,17 @@ If you are approved for [early access to NVIDIA NeMo Microservices](https://deve
1. Stop the NIM for LLMs container and NeMo Retriever Embedding container by pressing Ctrl+C in each terminal.
+## Related Information
+
+- [_NVIDIA NIM for LLMs_](https://docs.nvidia.com/nim/large-language-models/latest/index.html)
+
+- [_NVIDIA NeMo Retriever Embedding_](https://developer.nvidia.com/docs/nemo-microservices/embedding/source/overview.html)
+
+- [_NVIDIA NeMo Retriever Reranking_](https://developer.nvidia.com/docs/nemo-microservices/reranking/source/overview.html)
+
+
## Next Steps
- Use the [](./using-sample-web-application.md).
- [](./vector-database.md)
+
diff --git a/docs/project.json b/docs/project.json
index 4939983c8..fa9aa38b4 100644
--- a/docs/project.json
+++ b/docs/project.json
@@ -1 +1 @@
-{"name": "generative-ai-examples", "version": "0.5.0"}
\ No newline at end of file
+{"name": "generative-ai-examples", "version": "0.7.0"}
\ No newline at end of file
diff --git a/docs/quantized-llm-model.md b/docs/quantized-llm-model.md
deleted file mode 100644
index 7b76d6b70..000000000
--- a/docs/quantized-llm-model.md
+++ /dev/null
@@ -1,349 +0,0 @@
-
-
-# Quantized LLM Inference Model
-
-```{contents}
----
-depth: 2
-local: true
-backlinks: none
----
-```
-
-
-## Example Features
-
-This example deploys a developer RAG pipeline for chat Q&A and serves inferencing with the NeMo Framework Inference container across multiple local GPUs with a
-quantized version of the Llama 7B chat model.
-
-This example uses a local host with an NVIDIA A100, H100, or L40S GPU.
-
-```{list-table}
-:header-rows: 1
-
-* - Model
- - Embedding
- - Framework
- - Description
- - Multi-GPU
- - TRT-LLM
- - Model Location
- - Triton
- - Vector Database
-
-* - llama-2-7b-chat
- - UAE-Large-V1
- - LlamaIndex
- - QA chatbot
- - YES
- - YES
- - Local Model
- - YES
- - Milvus
-```
-
-## Prerequisites
-
-- Clone the Generative AI examples Git repository using Git LFS:
-
- ```console
- $ sudo apt -y install git-lfs
- $ git clone git@github.com:NVIDIA/GenerativeAIExamples.git
- $ cd GenerativeAIExamples/
- $ git lfs pull
- ```
-
-- A host with one or more NVIDIA A100, H100, or L40S GPU.
-
-- Verify NVIDIA GPU driver version 535 or later is installed and that the GPU is in compute mode:
-
- ```console
- $ nvidia-smi -q -d compute
- ```
-
- *Example Output*
-
- ```{code-block} output
- ---
- emphasize-lines: 4,9
- ---
- ==============NVSMI LOG==============
-
- Timestamp : Sun Nov 26 21:17:25 2023
- Driver Version : 535.129.03
- CUDA Version : 12.2
-
- Attached GPUs : 2
- GPU 00000000:CA:00.0
- Compute Mode : Default
-
- GPU 00000000:FA:00.0
- Compute Mode : Default
- ```
-
- If the driver is not installed or below version 535, refer to the [*NVIDIA Driver Installation Quickstart Guide*](https://docs.nvidia.com/datacenter/tesla/tesla-installation-notes/index.html).
-
-- Install Docker Engine and Docker Compose.
- Refer to the instructions for [Ubuntu](https://docs.docker.com/engine/install/ubuntu/).
-
-- Install the NVIDIA Container Toolkit.
-
- 1. Refer to the [installation documentation](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html).
-
- 1. When you configure the runtime, set the NVIDIA runtime as the default:
-
- ```console
- $ sudo nvidia-ctk runtime configure --runtime=docker --set-as-default
- ```
-
- If you did not set the runtime as the default, you can reconfigure the runtime by running the preceding command.
-
- 1. Verify the NVIDIA container toolkit is installed and configured as the default container runtime:
-
- ```console
- $ cat /etc/docker/daemon.json
- ```
-
- *Example Output*
-
- ```json
- {
- "default-runtime": "nvidia",
- "runtimes": {
- "nvidia": {
- "args": [],
- "path": "nvidia-container-runtime"
- }
- }
- }
- ```
-
- 1. Run the `nvidia-smi` command in a container to verify the configuration:
-
- ```console
- $ sudo docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi -L
- ```
-
- *Example Output*
-
- ```output
- GPU 0: NVIDIA A100 80GB PCIe (UUID: GPU-d8ce95c1-12f7-3174-6395-e573163a2ace)
- GPU 1: NVIDIA A100 80GB PCIe (UUID: GPU-1d37ef30-0861-de64-a06d-73257e247a0d)
- ```
-
-- Optional: Enable NVIDIA Riva automatic speech recognition (ASR) and text to speech (TTS).
-
- - To launch a Riva server locally, refer to the [Riva Quick Start Guide](https://docs.nvidia.com/deeplearning/riva/user-guide/docs/quick-start-guide.html).
-
- - In the provided `config.sh` script, set `service_enabled_asr=true` and `service_enabled_tts=true`, and select the desired ASR and TTS languages by adding the appropriate language codes to `asr_language_code` and `tts_language_code`.
-
- - After the server is running, assign its IP address (or hostname) and port (50051 by default) to `RIVA_API_URI` in `deploy/compose/compose.env`.
-
- - Alternatively, you can use a hosted Riva API endpoint. You might need to obtain an API key and/or Function ID for access.
-
- In `deploy/compose/compose.env`, make the following assignments as necessary:
-
- ```bash
- export RIVA_API_URI=":"
- export RIVA_API_KEY=""
- export RIVA_FUNCTION_ID=""
- ```
-
-## Download the Llama 2 Model and Weights
-
-1. Go to .
-
- - Locate the model to download, such as [Llama 2 7B chat HF](https://huggingface.co/meta-llama/Llama-2-7b-chat-hf).
- - Follow the information about accepting the license terms from Meta.
- - Log in or sign up for an account with Hugging Face.
-
-1. After you are granted access, clone the repository by clicking the vertical ellipses button and selecting **Clone repository**.
-
- During the clone, you might be asked for your username and password multiple times.
- Provide the information until the clone is complete.
-
-
-## Download TensorRT-LLM and Quantize the Model
-
-The following steps summarize downloading the TensorRT-LLM repository,
-building a container image, and quantizing the model.
-
-1. Clone the NVIDIA TensorRT-LLM repository:
-
- ```console
- $ git clone https://github.com/NVIDIA/TensorRT-LLM.git
- $ cd TensorRT-LLM
- $ git checkout release/0.5.0
- $ git submodule update --init --recursive
- $ git lfs install
- $ git lfs pull
- ```
-
-1. Build the TensorRT-LLM Docker image:
-
- ```console
- $ make -C docker release_build
- ```
-
- Building the image can require more than 30 minutes and requires approximately 30 GB.
- The image is named tensorrt_llm/release:latest.
-
-1. Start the container.
- Ensure that the container has one volume mount to the model directory and one volume mount to the TensorRT-LLM repository:
-
- ```console
- $ docker run --rm -it --gpus all --ipc=host \
- -v :/model-store \
- -v $(pwd):/repo -w /repo \
- --ulimit memlock=-1 --shm-size=20g \
- tensorrt_llm/release:latest bash
- ```
-
-1. Install NVIDIA AMMO Toolkit in the container:
-
- ```console
- # Obtain the cuda version from the system. Assuming nvcc is available in path.
- $ cuda_version=$(nvcc --version | grep 'release' | awk '{print $6}' | awk -F'[V.]' '{print $2$3}')
- # Obtain the python version from the system.
- $ python_version=$(python3 --version 2>&1 | awk '{print $2}' | awk -F. '{print $1$2}')
- # Download and install the AMMO package from the DevZone.
- $ wget https://developer.nvidia.com/downloads/assets/cuda/files/nvidia-ammo/nvidia_ammo-0.3.0.tar.gz
- $ tar -xzf nvidia_ammo-0.3.0.tar.gz
- $ pip install nvidia_ammo-0.3.0/nvidia_ammo-0.3.0+cu$cuda_version-cp$python_version-cp$python_version-linux_x86_64.whl
- # Install the additional requirements
- $ pip install -r examples/quantization/requirements.txt
- ```
-
-1. Install version `0.25.0` of the accelerate Python package:
-
- ```console
- $ pip install accelerate==0.25.0
- ```
-
-1. Run the quantization with the container:
-
- ```console
- $ python3 examples/llama/quantize.py --model_dir /model-store \
- --dtype float16 --qformat int4_awq \
- --export_path ./llama-2-7b-4bit-gs128-awq.pt --calib_size 32
- ```
-
- Quantization can require more than 15 minutes to complete.
- The sample command creates a `llama-2-7b-4bit-gs128-awq.pt`
- quantized checkpoint.
-
-1. Copy the quantized checkpoint directory to the model directory:
-
- ```console
- $ cp .pt
- ```
-
-The preceding steps summarize several documents from the NVIDIA TensorRT-LLM GitHub repository.
-Refer to the repository for more detail about the following topics:
-
-- Building the TensorRT-LLM image, refer to the [installation.md](https://github.com/NVIDIA/TensorRT-LLM/blob/release/0.5.0/docs/source/installation.md) file in the release/0.5.0 branch.
-
-- Installing NVIDIA AMMO Toolkit, refer to the [README](https://github.com/NVIDIA/TensorRT-LLM/blob/release/0.5.0/examples/quantization/README.md) file in the `examples/quantization` directory.
-
-- Running the `quantize.py` command, refer to [AWQ](https://github.com/NVIDIA/TensorRT-LLM/blob/release/0.5.0/examples/llama/README.md#awq) in the `examples/llama` directory.
-
-
-## Build and Start the Containers
-
-1. In the Generative AI Examples repository, edit the `deploy/compose/compose.env` file.
-
- - Update the `MODEL_DIRECTORY` variable to identify the Llama 2 model directory that contains the quantized checkpoint.
-
- - Uncomment the `QUANTIZATION` variable:
-
- ```text
- export QUANTIZATION="int4_awq"
- ```
-
-1. From the root of the repository, build the containers:
-
- ```console
- $ docker compose --env-file deploy/compose/compose.env -f deploy/compose/rag-app-text-chatbot.yaml build
- ```
-
-1. Start the containers:
-
- ```console
- $ docker compose --env-file deploy/compose/compose.env -f deploy/compose/rag-app-text-chatbot.yaml up -d
- ```
-
- NVIDIA Triton Inference Server can require 5 minutes to start. The `-d` flag starts the services in the background.
-
- *Example Output*
-
- ```output
- ✔ Network nvidia-rag Created
- ✔ Container llm-inference-server Started
- ✔ Container notebook-server Started
- ✔ Container chain-server Started
- ✔ Container rag-playground Started
- ```
-
-1. Start the Milvus vector database:
-
- ```console
- $ docker compose --env-file deploy/compose/compose.env -f deploy/compose/docker-compose-vectordb.yaml up -d milvus
- ```
-
- *Example Output*
-
- ```output
- ✔ Container milvus-minio Started
- ✔ Container milvus-etcd Started
- ✔ Container milvus-standalone Started
- ```
-
-1. Confirm the containers are running:
-
- ```console
- $ docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Status}}"
- ```
-
- *Example Output*
-
- ```output
- CONTAINER ID NAMES STATUS
- 256da0ecdb7b rag-playground Up 48 minutes
- 2974aa4fb2ce chain-server Up 48 minutes
- 4a8c4aebe4ad notebook-server Up 48 minutes
- 5be2b57bb5c1 milvus-standalone Up 48 minutes (healthy)
- ecf674c8139c llm-inference-server Up 48 minutes (healthy)
- a6609c22c171 milvus-minio Up 48 minutes (healthy)
- b23c0858c4d4 milvus-etcd Up 48 minutes (healthy)
- ```
-
-## Stopping the Containers
-
-- To uninstall, stop and remove the running containers from the root of the Generative AI Examples repository:
-
- ```console
- $ docker compose --env-file deploy/compose/compose.env -f deploy/compose/rag-app-text-chatbot.yaml down
- $ docker compose -f deploy/compose/docker-compose-vectordb.yaml down
-
- ```
-
-## Next Steps
-
-- Use the [](./using-sample-web-application.md).
-- [](./vector-database.md)
-- Run the sample Jupyter notebooks to learn about optional features.
diff --git a/docs/query-decomposition.md b/docs/query-decomposition.md
index 2781dd1ab..42af1760c 100644
--- a/docs/query-decomposition.md
+++ b/docs/query-decomposition.md
@@ -28,7 +28,7 @@ backlinks: none
## Example Features
This example deploys a recursive query decomposition example for chat Q&A.
-The example uses the llama2-70b chat model from an NVIDIA API Catalog endpoint for inference.
+The example uses the Meta Llama 3 70B Instruct model from an NVIDIA API Catalog endpoint for inference.
Query decomposition can perform RAG when the agent needs to access information from several different documents
(also referred to as _chunks_) or to perform some computation on the answers.
@@ -52,11 +52,11 @@ The agent continues to break down the question into subquestions until it has th
- Multi-GPU
- TRT-LLM
- Model Location
- - Triton
+ - NIM for LLMs
- Vector Database
-* - ai-llama2-70b
- - ai-embed-qa-4
+* - meta/llama3-70b-instruct
+ - snowflake-arctic-embed-l
- LangChain
- QA chatbot
- NO
@@ -89,6 +89,14 @@ The following figure shows the sample topology:
- Install Docker Engine and Docker Compose.
Refer to the instructions for [Ubuntu](https://docs.docker.com/engine/install/ubuntu/).
+- Login to Nvidia's docker registry. Please refer to [instructions](https://docs.nvidia.com/ngc/gpu-cloud/ngc-overview/index.html) to create account and generate NGC API key. This is needed for pulling in the secure base container used by all the examples.
+
+ ```console
+ $ docker login nvcr.io
+ Username: $oauthtoken
+ Password:
+ ```
+
- Optional: Enable NVIDIA Riva automatic speech recognition (ASR) and text to speech (TTS).
- To launch a Riva server locally, refer to the [Riva Quick Start Guide](https://docs.nvidia.com/deeplearning/riva/user-guide/docs/quick-start-guide.html).
@@ -107,33 +115,12 @@ The following figure shows the sample topology:
export RIVA_FUNCTION_ID=""
```
-## Get an API Key for the Llama 2 70B API Endpoint
-
-% api-key-start
-
-Perform the following steps if you do not already have an API key.
-You can use different model API endpoints with the same API key.
-
-1. Navigate to .
-
-1. Find the **Llama 2 70B** card and click the card.
+## Get an API Key for the Llama 3 70B API Endpoint
- 
-
-1. Click **Get API Key**.
-
- 
-
-1. Click **Generate Key**.
-
- 
-
-1. Click **Copy Key** and then save the API key.
- The key begins with the letters nvapi-.
-
- 
-
-% api-key-end
+```{include} ./api-catalog.md
+:start-after: api-key-start
+:end-before: api-key-end
+```
## Build and Start the Containers
@@ -168,7 +155,11 @@ You can use different model API endpoints with the same API key.
4. Start the Milvus vector database:
```console
- $ docker compose --env-file deploy/compose/compose.env -f deploy/compose/docker-compose-vectordb.yaml up -d milvus
+ $ docker compose \
+ --env-file deploy/compose/compose.env \
+ -f deploy/compose/docker-compose-vectordb.yaml \
+ --profile llm-embedding \
+ up -d milvus
```
*Example Output*
@@ -204,4 +195,4 @@ You can use different model API endpoints with the same API key.
Ensure that you upload documents and use the knowledge base to answer queries.
- [](./vector-database.md)
- Stop the containers by running `docker compose -f deploy/compose/rag-app-query-decomposition-agent.yaml down` and
- `docker compose -f deploy/compose/docker-compose-vectordb.yaml down`.
+ `docker compose -f deploy/compose/docker-compose-vectordb.yaml --profile llm-embedding down`.
diff --git a/docs/simple-example/code/api-catalog/boilerplate/simple-rag-api-catalog.yaml b/docs/simple-example/code/api-catalog/boilerplate/simple-rag-api-catalog.yaml
index 074bc2cfc..7447ca614 100644
--- a/docs/simple-example/code/api-catalog/boilerplate/simple-rag-api-catalog.yaml
+++ b/docs/simple-example/code/api-catalog/boilerplate/simple-rag-api-catalog.yaml
@@ -11,7 +11,7 @@ services:
environment:
APP_LLM_MODELNAME: ai-mixtral-8x7b-instruct
APP_LLM_MODELENGINE: nvidia-ai-endpoints
- APP_EMBEDDINGS_MODELNAME: ai-embed-qa-4
+ APP_EMBEDDINGS_MODELNAME: snowflake/arctic-embed-l
APP_EMBEDDINGS_MODELENGINE: nvidia-ai-endpoints
APP_TEXTSPLITTER_CHUNKSIZE: 1200
APP_TEXTSPLITTER_CHUNKOVERLAP: 200
diff --git a/docs/simple-example/code/api-catalog/documents/chains.py b/docs/simple-example/code/api-catalog/documents/chains.py
index c9299b2aa..4b7c2f79c 100644
--- a/docs/simple-example/code/api-catalog/documents/chains.py
+++ b/docs/simple-example/code/api-catalog/documents/chains.py
@@ -90,8 +90,10 @@ def delete_documents(self, filenames: List[str]):
ids_list = [doc_id for doc_id, doc_data in in_memory_docstore.items() if extract_filename(doc_data.metadata) == filename]
if vector_store.delete(ids_list):
logger.info(f"Deleted document with file name: {filename}")
+ return True
else:
logger.error(f"Failed to delete document: {filename}")
+ return False
except Exception as e:
logger.error(f"Vector store not initialized. Error details: {e}")
diff --git a/docs/simple-example/code/api-catalog/ingest/chains.py b/docs/simple-example/code/api-catalog/ingest/chains.py
index 17a141a92..7b66462d3 100644
--- a/docs/simple-example/code/api-catalog/ingest/chains.py
+++ b/docs/simple-example/code/api-catalog/ingest/chains.py
@@ -17,7 +17,6 @@
import os
from langchain.vectorstores import FAISS
-DOCS_DIR = os.path.abspath("./uploaded_files")
vector_store_path = "vectorstore.pkl"
vector_store = None
# end-ingest-faiss
@@ -31,10 +30,8 @@ def ingest_docs(self, data_dir: str, filename: str):
"""Code to ingest documents"""
try:
global vector_store
- # Files are copied to DOCS_DIR in the common.server:upload_document method.
- _path = os.path.join(DOCS_DIR, filename)
- raw_documents = UnstructuredFileLoader(_path).load()
+ raw_documents = UnstructuredFileLoader(data_dir).load()
if raw_documents:
text_splitter = CharacterTextSplitter(chunk_size=settings.text_splitter.chunk_size,
chunk_overlap=settings.text_splitter.chunk_overlap)
diff --git a/docs/simple-example/output/api-catalog/search/response.json b/docs/simple-example/output/api-catalog/search/response.json
index ac580eeeb..2782ba3b3 100644
--- a/docs/simple-example/output/api-catalog/search/response.json
+++ b/docs/simple-example/output/api-catalog/search/response.json
@@ -6,7 +6,7 @@
"score": 0
},
{
- "content": "Model Embedding Framework Description Multi-GPU TRT-LLM NVIDIA Endpoints Triton Vector Database mixtral_8x7b nvolveqa_40k LangChain NVIDIA API Catalog endpoints chat bot [ code , docs ] No No Yes Yes Milvus or pgvector llama-2 e5-large-v2 LlamaIndex Canonical QA Chatbot [ code , docs ] Yes Yes No Yes Milvus or pgvector llama-2 all-MiniLM-L6-v2 LlamaIndex Chat bot, GeForce, Windows [ repo ] No Yes No No FAISS llama-2 nvolveqa_40k LangChain Chat bot with query decomposition agent [ code , docs ] No No Yes Yes Milvus or pgvector mixtral_8x7b nvolveqa_40k LangChain Minimilastic example: RAG with NVIDIA AI Foundation Models [ code , README ] No No Yes Yes FAISS mixtral_8x7b Deplot Neva-22b nvolveqa_40k Custom Chat bot with multimodal data [ code , docs ] No No Yes No Milvus or pvgector llama-2 e5-large-v2 LlamaIndex Chat bot with quantized LLM model [ docs ] Yes Yes No Yes Milvus or pgvector mixtral_8x7b none PandasAI Chat bot with structured data [ code , docs ] No No Yes No none llama-2 nvolveqa_40k LangChain Chat bot with multi-turn conversation [ code , docs ] No No Yes No Milvus or pgvector",
+ "content": "Model Embedding Framework Description Multi-GPU TRT-LLM NVIDIA Endpoints Triton Vector Database mixtral_8x7b ai-embed-qa-4 LangChain NVIDIA API Catalog endpoints chat bot [ code , docs ] No No Yes Yes Milvus or pgvector llama-2 e5-large-v2 LlamaIndex Canonical QA Chatbot [ code , docs ] Yes Yes No Yes Milvus or pgvector llama-2 all-MiniLM-L6-v2 LlamaIndex Chat bot, GeForce, Windows [ repo ] No Yes No No FAISS llama-2 nvolveqa_40k LangChain Chat bot with query decomposition agent [ code , docs ] No No Yes Yes Milvus or pgvector mixtral_8x7b nvolveqa_40k LangChain Minimilastic example: RAG with NVIDIA AI Foundation Models [ code , README ] No No Yes Yes FAISS mixtral_8x7b Deplot Neva-22b nvolveqa_40k Custom Chat bot with multimodal data [ code , docs ] No No Yes No Milvus or pvgector llama-2 e5-large-v2 LlamaIndex Chat bot with quantized LLM model [ docs ] Yes Yes No Yes Milvus or pgvector mixtral_8x7b none PandasAI Chat bot with structured data [ code , docs ] No No Yes No none llama-2 nvolveqa_40k LangChain Chat bot with multi-turn conversation [ code , docs ] No No Yes No Milvus or pgvector",
"filename": "README.md",
"score": 0
},
diff --git a/docs/structured-data.md b/docs/structured-data.md
index 051144d0c..48a6a4d78 100644
--- a/docs/structured-data.md
+++ b/docs/structured-data.md
@@ -28,7 +28,7 @@ backlinks: none
## Example Features
This example deploys a developer RAG pipeline for chat Q&A and serves inferencing from an NVIDIA API Catalog endpoint
-instead of NVIDIA Triton Inference Server, a local Llama 2 model, or local GPUs.
+instead of a local inference server, local LLM, or local GPUs.
Developers get free credits for 10K requests to any of the available models.
@@ -64,12 +64,12 @@ Customization of the CSV data retrieval prompt is not supported.
- Multi-GPU
- TRT-LLM
- Model Location
- - Triton
+ - NIM for LLMs
- Vector Database
-* - ai-llama3-70b for response generation
+* - meta/llama3-70b-instruct for response generation
- ai-llama3-70b for PandasAI
+ meta/llama3-70b-instruct for PandasAI
- Not Applicable
- PandasAI
- QA chatbot
@@ -103,6 +103,14 @@ The following figure shows the sample topology:
- Install Docker Engine and Docker Compose.
Refer to the instructions for [Ubuntu](https://docs.docker.com/engine/install/ubuntu/).
+- Login to Nvidia's docker registry. Please refer to [instructions](https://docs.nvidia.com/ngc/gpu-cloud/ngc-overview/index.html) to create account and generate NGC API key. This is needed for pulling in the secure base container used by all the examples.
+
+ ```console
+ $ docker login nvcr.io
+ Username: $oauthtoken
+ Password:
+ ```
+
- Optional: Enable NVIDIA Riva automatic speech recognition (ASR) and text to speech (TTS).
- To launch a Riva server locally, refer to the [Riva Quick Start Guide](https://docs.nvidia.com/deeplearning/riva/user-guide/docs/quick-start-guide.html).
@@ -121,7 +129,7 @@ The following figure shows the sample topology:
export RIVA_FUNCTION_ID=""
```
-## Get an API Key for the Mixtral 8x7B Instruct API Endpoint
+## Get an API Key for the Llama 3 70B API Endpoint
```{include} api-catalog.md
:start-after: api-key-start
diff --git a/docs/support-matrix.md b/docs/support-matrix.md
index bf8426dd7..74be347f1 100644
--- a/docs/support-matrix.md
+++ b/docs/support-matrix.md
@@ -29,9 +29,8 @@ backlinks: none
Large Language Models are a heavily GPU-limited workflow.
All LLMs are defined by the number of billions of parameters that make up their networks.
-These generative AI examples focus on the Llama 2 Chat models from Meta.
-These models are available in three different sizes: 7B, 13B, and 70B.
-All three models perform well, but the 13B model is a good balance of performance and GPU memory utilization.
+These generative AI examples focus on the Llama 3 Instruct models from Meta.
+These models are available in two sizes: 8B and 70B.
```{list-table}
:header-rows: 1
@@ -39,20 +38,12 @@ All three models perform well, but the 13B model is a good balance of performanc
* - Model
- GPU Memory Requirement
-* - Llama-2-7B-Chat
+* - Meta Llama 3 8B Instruct
- 30 GB
-* - Llama-2-13B-Chat
- - 50 GB
-
-* - Llama-2-70B-Chat
+* - Meta Llama 3 70B Instruct
- 320 GB
-* - Llama-2-7B-Chat AWQ Quantized
- - 30 GB
-
-* - Nemotron-8B-Chat-SFT
- - 100 GB
```
These resources can be provided by multiple GPUs on the same machine.
@@ -80,17 +71,12 @@ The file size of the model varies according to the number of parameters in the m
* - Model
- Disk Storage
-* - Llama-2-7B-Chat
+* - Llama 3 8B Instruct
- 30 GB
-* - Llama-2-13B-Chat
- - 50 GB
-
-* - Llama-2-70B-Chat
- - 150 GB
+* - Llama 3 70B Instruct
+ - 140 GB
-* - Nemotron-8B-Chat-SFT
- - 50 GB
```
The file space needed for the vector database varies by how many documents that you upload.
diff --git a/docs/using-sample-web-application.md b/docs/using-sample-web-application.md
index d4391e538..96e7fcbfc 100644
--- a/docs/using-sample-web-application.md
+++ b/docs/using-sample-web-application.md
@@ -27,7 +27,7 @@ backlinks: none
## Prerequisites
-- You deployed one of the samples, such as [](./api-catalog.md) or [](./local-gpu.md).
+- You deployed one of the samples, such as [](./api-catalog.md).
## Access the Web Application
diff --git a/docs/vector-database.md b/docs/vector-database.md
index 910618ba4..ea6638b7b 100644
--- a/docs/vector-database.md
+++ b/docs/vector-database.md
@@ -51,7 +51,7 @@ Alternatively, you can deploy pgvector.
The preceding example shows the default values for the database user, password, and database.
To override the defaults, edit the values in the Docker Compose file, or set the values in the `compose.env` file.
- `Note`: If you have existing setup remove `deploy/compose/volumes` directory to avoid pgvector crash.
+ If you have existing setup remove `deploy/compose/volumes` directory to avoid pgvector crash.
1. Optional: If a container for a vector database is running, stop the container:
@@ -86,7 +86,6 @@ Alternatively, you can deploy pgvector.
1. Confirm the log output includes the vector database:
```output
- INFO:example:Ingesting .pdf in vectorDB
INFO:RetrievalAugmentedGeneration.common.utils:Using pgvector as vector store
INFO:RetrievalAugmentedGeneration.common.utils:Using PGVector collection:
```
@@ -139,7 +138,6 @@ Alternatively, you can deploy pgvector.
1. Confirm the log output includes the vector database:
```output
- INFO:example:Ingesting .pdf in vectorDB
INFO:RetrievalAugmentedGeneration.common.utils:Using milvus as vector store
INFO:RetrievalAugmentedGeneration.common.utils:Using milvus collection:
```
diff --git a/docs/versions.json b/docs/versions.json
index d29a613c2..e36ec4d18 100644
--- a/docs/versions.json
+++ b/docs/versions.json
@@ -1,6 +1,9 @@
{
- "latest": "0.5.0",
+ "latest": "0.7.0",
"versions": [
+ {
+ "version": "0.7.0"
+ },
{
"version": "0.5.0"
}
diff --git a/examples/5_mins_rag_no_gpu/main.py b/examples/5_mins_rag_no_gpu/main.py
index 0c4207bcc..5640f8f59 100644
--- a/examples/5_mins_rag_no_gpu/main.py
+++ b/examples/5_mins_rag_no_gpu/main.py
@@ -47,17 +47,17 @@
from langchain_nvidia_ai_endpoints import ChatNVIDIA, NVIDIAEmbeddings
# make sure to export your NVIDIA AI Playground key as NVIDIA_API_KEY!
-llm = ChatNVIDIA(model="mixtral_8x7b")
-document_embedder = NVIDIAEmbeddings(model="nvolveqa_40k", model_type="passage")
-query_embedder = NVIDIAEmbeddings(model="nvolveqa_40k", model_type="query")
+llm = ChatNVIDIA(model="ai-llama3-70b")
+document_embedder = NVIDIAEmbeddings(model="ai-embed-qa-4", model_type="passage")
+query_embedder = NVIDIAEmbeddings(model="ai-embed-qa-4", model_type="query")
############################################
# Component #3 - Vector Database Store
############################################
from langchain.text_splitter import CharacterTextSplitter
-from langchain.document_loaders import DirectoryLoader
-from langchain.vectorstores import FAISS
+from langchain_community.document_loaders import DirectoryLoader
+from langchain_community.vectorstores import FAISS
import pickle
with st.sidebar:
@@ -116,14 +116,14 @@
[("system", "You are a helpful AI assistant named Envie. You will reply to questions only based on the context that you are provided. If something is out of context, you will refrain from replying and politely decline to respond to the user."), ("user", "{input}")]
)
user_input = st.chat_input("Can you tell me what NVIDIA is known for?")
-llm = ChatNVIDIA(model="mixtral_8x7b")
+llm = ChatNVIDIA(model="ai-llama3-70b")
chain = prompt_template | llm | StrOutputParser()
if user_input and vectorstore!=None:
st.session_state.messages.append({"role": "user", "content": user_input})
retriever = vectorstore.as_retriever()
- docs = retriever.get_relevant_documents(user_input)
+ docs = retriever.invoke(user_input)
with st.chat_message("user"):
st.markdown(user_input)
diff --git a/examples/5_mins_rag_no_gpu/requirements.txt b/examples/5_mins_rag_no_gpu/requirements.txt
index a82c08db2..abd21ba65 100644
--- a/examples/5_mins_rag_no_gpu/requirements.txt
+++ b/examples/5_mins_rag_no_gpu/requirements.txt
@@ -1,5 +1,5 @@
streamlit==1.30.0
-langchain-nvidia-ai-endpoints==0.0.1
faiss-cpu==1.7.4
-langchain==0.0.352
+langchain==0.1.20
unstructured[all-docs]==0.11.2
+langchain-nvidia-ai-endpoints==0.0.19
diff --git a/experimental/README.md b/experimental/README.md
index 14a4dc9d5..e7e5279f4 100644
--- a/experimental/README.md
+++ b/experimental/README.md
@@ -47,3 +47,11 @@ Experimental examples are sample code and deployments for RAG pipelines that are
This example shows the configuration changes to using Docker containers and local GPUs that are required
to run the RAG-LLM pipelines in Azure Machine Learning.
+
+* [NVIDIA Developer RAG Chatbot](./rag-developer-chatbot)
+
+ This example shows how to create a developer-focused RAG chatbot using RAPIDS cuDF source code and API documentation as a representative example of a typical codebase.
+
+* [NVIDIA Event Driven RAG for CVE Analysis with NVIDIA Morpheus](./event-driven-rag-cve-analysis/)
+
+ This example demonstrates how NVIDIA Morpheus, NIMs, and RAG pipelines can be integrated to create LLM-based agent pipelines. These pipelines will be used to automatically and scalably traige and detect Common Vulnerabilities and Exposures (CVEs) in Docker containers using references to source code, dependencies, and information about the CVEs.
\ No newline at end of file
diff --git a/experimental/event-driven-rag-cve-analysis/Dockerfile b/experimental/event-driven-rag-cve-analysis/Dockerfile
new file mode 100755
index 000000000..c7dc661d8
--- /dev/null
+++ b/experimental/event-driven-rag-cve-analysis/Dockerfile
@@ -0,0 +1,70 @@
+# syntax=docker/dockerfile:1.3
+
+# SPDX-FileCopyrightText: Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+# SPDX-License-Identifier: Apache-2.0
+#
+# 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.
+
+ARG MORPHEUS_CONTAINER=nvcr.io/nvidia/morpheus/morpheus
+ARG MORPHEUS_CONTAINER_VERSION=v24.03.00-dev
+
+FROM ${MORPHEUS_CONTAINER}:${MORPHEUS_CONTAINER_VERSION} as base
+
+WORKDIR /workspace
+
+# # Use a separate build directory to avoid clashes on the host
+# ENV BUILD_DIR=build-docker
+
+# Make it easier to run commands in the container
+ENV SHELL=/bin/bash
+
+# Copy over just the environment file to install the dependencies without busting the cache from source file changes
+COPY ./requirements.yaml .
+
+# Install the example's dependencies
+RUN source activate morpheus \
+ && mamba env update -n morpheus -f ./requirements.yaml
+
+# Copy everything over to the container to build
+COPY . ./
+
+RUN chmod +x /workspace/entrypoint.sh
+
+# # If any changes have been made from the base image, recopy the sources
+# COPY ./examples/cyber_dev_day /workspace/examples/cyber_dev_day/
+
+# ===== Setup for running unattended =====
+FROM base as runtime
+
+# # Install the Workflow package
+# RUN source activate morpheus \
+# && pip install -e .
+
+# # Keep the container running indefinitely
+# CMD ["sleep", "infinity"]
+
+# ===== Setup for running Jupyter =====
+FROM base as jupyter
+
+# Install the jupyter specific requirements
+RUN source activate morpheus &&\
+ mamba install -y -c conda-forge \
+ ipywidgets \
+ jupyter_contrib_nbextensions \
+ # notebook v7 is incompatible with jupyter_contrib_nbextensions
+ notebook=6 &&\
+ jupyter contrib nbextension install --user &&\
+ pip install jupyterlab_nvdashboard==0.9
+
+# Launch jupyter
+CMD ["jupyter-lab", "--ip=0.0.0.0", "--no-browser", "--allow-root"]
diff --git a/experimental/event-driven-rag-cve-analysis/README.md b/experimental/event-driven-rag-cve-analysis/README.md
new file mode 100644
index 000000000..1bf2d83c9
--- /dev/null
+++ b/experimental/event-driven-rag-cve-analysis/README.md
@@ -0,0 +1,110 @@
+
+
+# Event Driven RAG and Agents with NVIDIA Morpheus
+Determining the impact of a documented CVE on a specific project or container is a labor-intensive and manual task. This intricate process involves the collection, comprehension, and synthesis of various pieces of information to ascertain whether immediate remediation, such as patching, is necessary upon the identification of a new CVE.
+
+Our team developed a cybersecurity vulnerability analysis tool to aid in assessing the exploitability of CVEs in specific projects and containers. This tutorial will guide you step-by-step through the process of using LLMs, Retrieval-Augmented Generation (RAG), and agents to create both a toy version and a microservice running LLM-powered CVE exploitability analysis.
+
+## Prerequisites
+
+To run this example, you will need to have the access to `build.nvidia.com` and API credits to access the hosted LLMs. These are necessary to support running LLMs which are the focus of the Cyber Developer Day.
+
+You will also need to have a `Morpheus 24.03` docker container built and present in the environment.
+
+### NVIDIA GPU Cloud
+
+To access the NVIDIA hosted Inference Service, you will need to have the following environment variables set: `OPENAI_API_KEY`. To obtain the API key, please visit the [NVIDIA website](https://build.nvidia.com/) for instructions on generating your API key.
+
+It's important to note here that although we store the NGC API Key under the `OPENAI_API_KEY` variable, we will be interacting with NVIDIA hosted LLMs and not OpenAI LLMs.
+
+NVIDIA NIMs are OpenAI API compliant to maximize usability, so we will be using the `openai` with package as a wrapped to make API calls.
+### Building a Morpheus Container
+
+This notebook has originally been designed to run with the NVIDIA AI Enterprise Morpheus container from NGC:
+
+```bash
+nvcr.io/nvidia/morpheus/morpheus:v24.03.02-runtime
+```
+
+If you do not have access to NVIDIA AI Enterprise containers, you can follow instructions to build from source at the [Morpheus Repository](https://github.com/nv-morpheus/Morpheus/tree/branch-24.03).
+
+If you are using a Morpheus version that is not `v24.03.02-runtime`, please update the version argument in the `docker-compose.yml` file as follows:
+
+```bash
+ args:
+ - MORPHEUS_CONTAINER=${MORPHEUS_CONTAINER:-nvcr.io/nvidia/morpheus/morpheus}
+ - MORPHEUS_CONTAINER_VERSION=${MORPHEUS_CONTAINER_VERSION:-v24.03.02-runtime}
+```
+### Creating an Environment File
+
+To automatically use these API keys, you can set the `OPENAI_API_KEY` value in the `docker-compose.yml` file in this directory as follows:
+
+```bash
+ environment:
+ - TERM=${TERM:-}
+ # Workaround until this is working: https://github.com/docker/compose/issues/9181#issuecomment-1996016211
+ - OPENAI_API_KEY=
+ # Overwrite any environment variables in the .env file with URLs needed in the network
+ - OPENAI_API_BASE=https://integrate.api.nvidia.com/v1
+ - OPENAI_BASE_URL=https://integrate.api.nvidia.com/v1
+```
+
+### Pulling Large Files from GIT LFS
+
+If you do not have Git LFS installed, install it using instructions at this [link](https://docs.github.com/en/repositories/working-with-files/managing-large-files/installing-git-large-file-storage).
+
+Run the following command from inside this repository's directory to pull down large files using Git LFS.
+
+```bash
+git lfs pull
+```
+## Build Instructions
+You can build the required containers to run the workflow by running the following command in your terminal from this directory.
+ ```bash
+ docker compose build cyber-dev-day
+ ```
+## Running the Cyber Developer Day Content
+
+The Cyber Developer Day content is designed to be run using the `docker compose` command. The main entry point is the `cyber-dev-day` container, which is built in the previous step. This container launches a JupyterLab server with the necessary environment variables set to access the NeMo Inference Service and NVIDIA AI Foundation Models API. From there, the pipelines and all content can be run from JupyterLab.
+
+### Launching the Container and Connecting to JupyterLab
+
+To run the Cyber Developer Day content, use the following command:
+```bash
+docker compose up cyber-dev-day
+```
+
+Once launched, you should see a link in the output to connect to the JupyterLab server. Open this link in your web browser to access the content. For example:
+```
+cyber-dev-day-1 | To access the server, open this file in a browser:
+cyber-dev-day-1 | file:///root/.local/share/jupyter/runtime/jpserver-7-open.html
+cyber-dev-day-1 | Or copy and paste one of these URLs:
+cyber-dev-day-1 | http://localhost:8888/lab?token=a2d7504f70a2f5407236be5897ee266dc24bf19b01c222bc
+cyber-dev-day-1 | http://127.0.0.1:8888/lab?token=a2d7504f70a2f5407236be5897ee266dc24bf19b01c222bc
+```
+
+### Running the Notebook
+
+Once connected to the JupyterLab server, you can navigate to the `notebooks` directory and open the `cyber-dev-day.ipynb` Notebook. The notebook contains the instructions and all of the necessary content to run the Cyber Developer Day.
+
+### Stopping the Container
+
+To stop the container, use the following command:
+```bash
+docker compose down
+```
diff --git a/experimental/event-driven-rag-cve-analysis/cyber_dev_day/__init__.py b/experimental/event-driven-rag-cve-analysis/cyber_dev_day/__init__.py
new file mode 100644
index 000000000..f6aa0d20f
--- /dev/null
+++ b/experimental/event-driven-rag-cve-analysis/cyber_dev_day/__init__.py
@@ -0,0 +1,35 @@
+# Copyright (c) 2023-2024, NVIDIA CORPORATION.
+#
+# 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.
+
+
+import logging
+import sys
+
+morpheus_logger = logging.getLogger("morpheus")
+
+if (not getattr(morpheus_logger, "_configured_by_morpheus", False)):
+
+ # Set the morpheus logger to propagate upstream
+ morpheus_logger.propagate = False
+
+ # Add a default handler to the morpheus logger to print to screen
+ morpheus_logger.addHandler(logging.StreamHandler(stream=sys.stdout))
+
+ # Set a flag to indicate that the logger has been configured by Morpheus
+ setattr(morpheus_logger, "_configured_by_morpheus", True)
+
+logger = logging.getLogger(__name__)
+
+# Set the parent logger for the entire package to use morpheus so we can take advantage of configure_logging
+logger.parent = morpheus_logger
diff --git a/experimental/event-driven-rag-cve-analysis/cyber_dev_day/checklist_node.py b/experimental/event-driven-rag-cve-analysis/cyber_dev_day/checklist_node.py
new file mode 100644
index 000000000..15d117b88
--- /dev/null
+++ b/experimental/event-driven-rag-cve-analysis/cyber_dev_day/checklist_node.py
@@ -0,0 +1,266 @@
+# Copyright (c) 2023-2024, NVIDIA CORPORATION.
+#
+# 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.
+
+import ast
+import logging
+import re
+from textwrap import dedent
+
+from morpheus.llm import LLMLambdaNode
+from morpheus.llm import LLMNode
+from morpheus.llm.nodes.llm_generate_node import LLMGenerateNode
+from morpheus.llm.nodes.prompt_template_node import PromptTemplateNode
+from cyber_dev_day.llm_service import LLMService
+
+from .config import EngineChecklistConfig
+
+logger = logging.getLogger(__name__)
+
+# checklist_prompt_template = dedent("""
+# This is an example of CVE information and a checklist produced to determine if the given CVE is exploitable in a containerized environment:
+# (1) CVE information: The email module of Python through 3.11.3 incorrectly parses e-mail addresses that contain a special character. The wrong portion of an RFC2822 header is identified as the value of the addr-spec. In some applications, an attacker can bypass a protection mechanism in which application access is granted only after verifying receipt of e-mail to a specific domain (e.g., only @company.example.com addresses may be used for signup). This occurs in email/_parseaddr.py in recent versions of Python.
+# (2) Checklist:
+# 1. Check the version of python. The vulnerability affects python through 3.11.3.
+# 2. Check if the code base uses email functionality in python.
+
+# Given the following cve information, make a checklist for security analysts to follow to determine whether a Docker container is vulnerable to this exploit.
+# CVE information: {{cve_info}}
+
+# Checklist:
+
+# """).strip("\n")
+
+checklist_prompt_template = dedent(
+ """You are an expert security analyst. Your objective is to add a "Checklist" section containing steps to use when assessing the exploitability of a specific CVE within a containerized environment. \
+For each checklist item, start with an action verb, making it clear and actionable
+
+**Context**:
+Not all CVEs are exploitable in a given container. By making a checklist specific to the information available for a given CVE analysts can execute the checklist to determine exploitability.
+
+**Example Format**:
+Below is a format for examples that illustrate transforming CVE information into an exploitability assessment checklist.
+
+Example 1 CVE Details:
+- CVE ID: CVE-2022-2309
+- Description: NULL Pointer Dereference allows attackers to cause a denial of service (or application crash). This only applies when lxml up to version 4.9.1 \
+is used together with libxml2 2.9.10 through 2.9.14. libxml2 2.9.9 and earlier are not affected. It allows triggering crashes through forged input data, given a \
+vulnerable code sequence in the application. The vulnerability is caused by the iterwalk function (also used by the canonicalize function). Such code shouldn't be \
+in wide-spread use, given that parsing + iterwalk would usually be replaced with the more efficient iterparse function. However, an XML converter that serialises to \
+C14N would also be vulnerable, for example, and there are legitimate use cases for this code sequence. If untrusted input is received (also remotely) and processed via \
+iterwalk function, a crash can be triggered.
+- Vulnerable Package Name: lxml, libxml2
+- Vulnerable Package Version: lxml: up to 4.9.1, libxml2: 2.91.0 through 2.9.14
+- CVSS3 Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
+
+Example 1 Exploitability Assessment Checklist:
+[
+"Check for lxml: Verify if your project uses the lxml library, which is the affected package. If lxml is not a dependency in your project, then your code is not vulnerable to this CVE.",
+"Review Affected Versions: If lxml is used, checked the version that your project depends on. According to the vulnerability details, versions 4.9.0 and earlier are vulnerable.",
+"Review Versions of Connected Dependencies: The package is only vulnerable if libxml 2.9.10 through 2.9.14 is also present. Check the version of libxml in the project.",
+"Check for use of vulnerable functions: The library is vulnerable through its `iterwalk` function, which is also utilized by the `canonicalize` function. Check if either of these functions are used in your code base."
+]
+
+Example 2 CVE Details:
+- CVE ID: CVE-2024-23334
+- Description: aiohttp is an asynchronous HTTP client/server framework for asyncio and Python. When using aiohttp as a web server and configuring static routes, \
+it is necessary to specify the root path for static files. Additionally, the option 'follow_symlinks' can be used to determine whether to follow symbolic links \
+outside the static root directory. When 'follow_symlinks' is set to True, there is no validation to check if reading a file is within the root directory. This can \
+lead to directory traversal vulnerabilities, resulting in unauthorized access to arbitrary files on the system, even when symlinks are not present. \
+Disabling `follow_symlinks` by setting `follow_symlinks = False` and using a reverse proxy are encouraged mitigations. Version 3.9.2 fixes this issue.
+- Vulnerable Package Name: aiohttp
+- Vulnerable Package Version: from 1.0.5 up to (excluding) 3.9.2
+- CVSS3 Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
+
+Example 2 Exploitability Assessment Checklist:
+[
+ "Check for aiohttp: Verify if your project uses the aiohttp library, which is the affected package. If aiohttp is not a dependency in your project, then your code is not vulnerable to this CVE.",
+ "Review Affected Versions: If aiohttp is used, check the version that your project depends on. According to the vulnerability details, versions from 1.0.5 up to (excluding) 3.9.2 are affected by this vulnerability.",
+ "Review Code To Check for Vulnerability Mitigation: Check if the 'follow_symlinks' option is set to False to mitigate the risk of directory traversal vulnerabilities."
+]
+
+**Criteria**:
+- Exploitability assessment checklists must relate to the information in the specific CVE Details.
+- Exploitability assessment checklists must include checks for mitigating conditions when present in the CVE Details.
+
+**Procedure**:
+[
+"Understand the CVE Details, description, and CVSS3 attack vector string.",
+"Produce a CVE exploitability assessment checklist.",
+"Format the checklist as comma separated list surrounded by square braces.",
+"Output the checklist."
+]
+
+**CVE Details:**
+{{cve_details}}
+
+**Checklist**:
+
+Please only provide the comma separated, python formatted list, no other text. """).strip("\n")
+
+parselist_prompt_template = dedent("""
+Parse the following numbered checklist's contents into a python list in the format ['x', 'y', 'z'], a comma separated list surrounded by square braces. For example, the following checklist:
+
+1. Check for notable vulnerable software vendors
+2. Consider the network exposure of your Docker container
+
+Should generate: ["Check for notable vulnerable software vendors", "Consider the network exposure of your Docker container"]
+
+Checklist:
+{{template}}
+
+Please only provide the comma separated, python formatted, list.""").strip("\n")
+
+# Find all substrings that start and end with quotes, allowing for spaces before a comma or closing bracket
+re_quote_capture = re.compile(
+ r"""
+ (['"]) # Opening quote
+ ( # Start capturing the quoted content
+ (?:\\.|[^\\])*? # Non-greedy match for any escaped character or non-backslash character
+ ) # End capturing the quoted content
+ \1 # Matching closing quote
+ (?=\s*,|\s*\]) # Lookahead for whitespace followed by a comma or closing bracket, without including it in the match
+ """,
+ re.VERBOSE)
+
+
+def attempt_fix_list_string(s: str) -> str:
+ """
+ Attempt to fix unescaped quotes in a string that represents a list to make it parsable.
+
+ Parameters
+ ----------
+ s : str
+ A string representation of a list that potentially contains unescaped quotes.
+
+ Returns
+ -------
+ str
+ The corrected string where internal quotes are properly escaped, ensuring it can be parsed as a list.
+
+ Notes
+ -----
+ This function is useful for preparing strings to be parsed by `ast.literal_eval` by ensuring that quotes inside
+ the string elements of the list are properly escaped. It adds brackets at the beginning and end if they are missing.
+ """
+ # Check if the input starts with '[' and ends with ']'
+ s = s.strip()
+ if (not s.startswith('[')):
+ s = "[" + s
+ if (not s.endswith(']')):
+ s = s + "]"
+
+ def fix_quotes(match):
+ # Extract the captured groups
+ quote_char, content = match.group(1), match.group(2)
+ # Escape quotes inside the string content
+ fixed_content = re.sub(r"(? list[list[str]]:
+ """
+ Asynchronously parse a list of strings, each representing a list, into a list of lists.
+
+ Parameters
+ ----------
+ text : list of str
+ A list of strings, each intended to be parsed into a list.
+
+ Returns
+ -------
+ list of lists of str
+ A list of lists, parsed from the input strings.
+
+ Raises
+ ------
+ ValueError
+ If the string cannot be parsed into a list or if the parsed object is not a list.
+
+ Notes
+ -----
+ This function tries to fix strings that represent lists with unescaped quotes by calling
+ `attempt_fix_list_string` and then uses `ast.literal_eval` for safe parsing of the string into a list.
+ It ensures that each element of the parsed list is actually a list and will raise an error if not.
+ """
+ return_val = []
+
+ for x in text:
+ try:
+ # Try to do some very basic string cleanup to fix unescaped quotes
+ x = attempt_fix_list_string(x)
+
+ # Only proceed if the input is a valid Python literal
+ # This isn't really dangerous, literal_eval only evaluates a small subset of python
+ current = ast.literal_eval(x)
+
+ # Ensure that the parsed data is a list
+ if not isinstance(current, list):
+ raise ValueError(f"Input is not a list: {x}")
+
+ # Process the list items
+ for i in range(len(current)):
+ if (isinstance(current[i], list) and len(current[i]) == 1):
+ current[i] = current[i][0]
+
+ return_val.append(current)
+ except (ValueError, SyntaxError) as e:
+ # Handle the error, log it, or re-raise it with additional context
+ raise ValueError(f"Failed to parse input {x}: {e}")
+
+ return return_val
+
+
+class CVEChecklistNode(LLMNode):
+ """
+ A node that orchestrates the process of generating a checklist for CVE (Common Vulnerabilities and Exposures) items.
+ It integrates various nodes that handle CVE lookup, prompting, generation, and parsing to produce an actionable checklist.
+ """
+
+ def __init__(self, *, config: EngineChecklistConfig):
+ """
+ Initialize the CVEChecklistNode with optional caching and a vulnerability endpoint retriever.
+
+ Parameters
+ ----------
+ model_name : str, optional
+ The name of the language model to be used for generating text, by default "gpt-3.5-turbo".
+ cache_dir : str, optional
+ The directory where the node's cache should be stored. If None, caching is not used.
+ vuln_endpoint_retriever : object, optional
+ An instance of a vulnerability endpoint retriever. If None, defaults to `NISTCVERetriever`.
+ """
+ super().__init__()
+
+ self._config = config
+
+ llm_service = LLMService.create(config.model.service.type, **config.model.service.model_dump(exclude={"type"}))
+
+ # Add a node to create a prompt for CVE checklist generation based on the CVE details obtained from the lookup
+ # node
+ self.add_node("checklist_prompt",
+ inputs=[("*", "*")],
+ node=PromptTemplateNode(template=checklist_prompt_template, template_format="jinja"))
+
+ # Instantiate a chat service and configure a client for generating responses to the checklist prompt
+ llm_client_1 = llm_service.get_client(**config.model.model_dump(exclude={"service"}))
+ self.add_node("generate_checklist", inputs=["/checklist_prompt"], node=LLMGenerateNode(llm_client=llm_client_1))
+
+ # Add an output parser node to process the final generated checklist into a structured list
+ self.add_node("output_parser", inputs=["/generate_checklist"], node=LLMLambdaNode(_parse_list), is_output=True)
diff --git a/experimental/event-driven-rag-cve-analysis/cyber_dev_day/config.py b/experimental/event-driven-rag-cve-analysis/cyber_dev_day/config.py
new file mode 100644
index 000000000..30249e4a1
--- /dev/null
+++ b/experimental/event-driven-rag-cve-analysis/cyber_dev_day/config.py
@@ -0,0 +1,127 @@
+# Copyright (c) 2023-2024, NVIDIA CORPORATION.
+#
+# 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
+
+import typing
+from pydantic import BaseModel
+from pydantic import Discriminator
+from pydantic import Field
+from pydantic import Tag
+
+
+def _llm_discriminator(v: typing.Any) -> str:
+ if isinstance(v, dict):
+ return v.get("service").get("type")
+ return getattr(getattr(v, "service"), "type")
+
+
+class NeMoLLMServiceConfig(BaseModel):
+ type: typing.Literal["nemo"] = "nemo"
+
+ api_key: str | None = None
+ org_id: str | None = None
+
+
+class NeMoLLMModelConfig(BaseModel):
+ service: NeMoLLMServiceConfig
+
+ model_name: str
+ customization_id: str | None = None
+ temperature: float = 0.0
+ top_k: int = 0
+ tokens_to_generate: int = 300
+
+
+class NVFoundationLLMServiceConfig(BaseModel):
+ type: typing.Literal["nvfoundation"] = "nvfoundation"
+
+ api_key: str | None = None
+
+
+class NVFoundationLLMModelConfig(BaseModel):
+ service: NVFoundationLLMServiceConfig
+
+ model_name: str
+ temperature: float = 0.0
+
+
+class OpenAIServiceConfig(BaseModel):
+ type: typing.Literal["openai"] = "openai"
+
+
+class OpenAIMModelConfig(BaseModel):
+ service: OpenAIServiceConfig
+
+ model_name: str
+
+
+class NIMServiceConfig(BaseModel):
+ type: typing.Literal["NIM"] = "NIM"
+
+
+class NIMModelConfig(BaseModel):
+ service: NIMServiceConfig
+
+ model_name: str
+ base_url: str
+ temperature: float = 0.0
+ top_p: float = 1
+
+
+LLMModelConfig = typing.Annotated[typing.Annotated[NeMoLLMModelConfig, Tag("nemo")]
+ | typing.Annotated[OpenAIMModelConfig, Tag("openai")]
+ | typing.Annotated[NVFoundationLLMModelConfig, Tag("nvfoundation")]
+ | typing.Annotated[NIMModelConfig, Tag("NIM")],
+Discriminator(_llm_discriminator)]
+
+
+class HttpServerInputConfig(BaseModel):
+ type: typing.Literal["http_server"] = "http_server"
+
+
+class NspectFileInputConfig(BaseModel):
+ type: typing.Literal["nspect_file"] = "nspect_file"
+
+
+class CveFileInputConfig(BaseModel):
+ type: typing.Literal["cve_file"] = "cve_file"
+
+
+class EngineChecklistConfig(BaseModel):
+ model: LLMModelConfig
+
+
+class EngineSBOMConfig(BaseModel):
+ data_file: str
+
+
+class EngineCodeRepoConfig(BaseModel):
+ faiss_dir: str
+
+ embedding_model_name: str = "sentence-transformers/all-mpnet-base-v2"
+
+
+class EngineAgentConfig(BaseModel):
+ model: LLMModelConfig
+
+ sbom: EngineSBOMConfig
+
+ code_repo: EngineCodeRepoConfig
+
+ verbose: bool = True
+
+
+class EngineConfig(BaseModel):
+ checklist: EngineChecklistConfig
+
+ agent: EngineAgentConfig
diff --git a/experimental/event-driven-rag-cve-analysis/cyber_dev_day/embeddings.py b/experimental/event-driven-rag-cve-analysis/cyber_dev_day/embeddings.py
new file mode 100644
index 000000000..c9635ff91
--- /dev/null
+++ b/experimental/event-driven-rag-cve-analysis/cyber_dev_day/embeddings.py
@@ -0,0 +1,152 @@
+# Copyright (c) 2024, NVIDIA CORPORATION.
+#
+# 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.
+
+import logging
+import os
+import pathlib
+
+import nbformat
+from langchain.docstore.document import Document
+from langchain.document_loaders.parsers import LanguageParser
+from langchain.text_splitter import Language
+from langchain.text_splitter import RecursiveCharacterTextSplitter
+from langchain.vectorstores.faiss import FAISS
+from langchain_community.document_loaders.blob_loaders.schema import Blob
+from langchain_core.embeddings import Embeddings
+
+logger = logging.getLogger(f"__name__")
+
+
+def _extract_python_code_from_ipynb(notebook_content: str, cell_type: str = "code"):
+ """Extract python code from jupyter notebook
+
+ Parameters
+ ----------
+ notebook_content : str
+ notebook content location
+ cell_type : str, optional
+ _description_, by default "code"
+
+ Returns
+ -------
+ str
+ python codes
+ """
+
+ notebook = nbformat.read(notebook_content, as_version=nbformat.NO_CONVERT)
+
+ python_code = []
+ for cell in notebook.cells:
+ if cell.cell_type == cell_type:
+ python_code.append(cell.source)
+
+ return "\n".join(python_code)
+
+
+def _read_gitignore_exclusions(gitignore_file: str, base_dir: str) -> list[str]:
+ exclusions = []
+
+ # Load the gitignore file
+ with open(os.path.join(base_dir, ".gitignore"), "r") as ignore_file:
+ for line in ignore_file:
+ # Remove any leading or trailing whitespace
+ line = line.strip()
+
+ # Ignore comments and empty lines
+ if not line or line.startswith("#"):
+ continue
+
+ # Unescape # characters
+ if line[0] == '\\' and line[1] in ('#', '!'):
+ line = line[1:]
+
+ # Add the line to the list of exclusions
+ if ("/" in line):
+ exclusions.append(os.path.normpath(os.path.join(base_dir, line.removeprefix("/"))))
+ else:
+ exclusions.append(line)
+
+ return exclusions
+
+
+def create_code_embedding(code_dir: str,
+ embedding: Embeddings,
+ include: str = "**/*.py",
+ exclude: list[str] = None,
+ include_notebooks: bool = False):
+ """
+ Create code embedding from specified code directory.
+ """
+ documents: list[Document] = []
+ logger.info(f"Generating embedding for source code in {code_dir}")
+
+ # include notebooks
+ if include_notebooks:
+
+ for nb in pathlib.Path(code_dir).glob("**/[!.]*.ipynb"):
+ content = _extract_python_code_from_ipynb(str(nb))
+ if content:
+ documents.append(Document(page_content=content, metadata={'source': nb, 'language': Language.PYTHON}))
+
+ final_exclusions = exclude or []
+
+ # # Load the gitignore file to pre-populate the exclude list
+ # if (os.path.exists(os.path.join(code_dir, ".gitignore"))):
+ # # Load the gitignore file
+ # final_exclusions.extend(_read_gitignore_exclusions(os.path.join(code_dir, ".gitignore"), code_dir))
+
+ code_path = pathlib.Path(code_dir)
+
+ parser = LanguageParser(language=Language.PYTHON.value, parser_threshold=500)
+
+ positive_matches = set(code_path.glob(include))
+
+ for exclusion in final_exclusions:
+ negative_matches = set(code_path.glob(exclusion))
+ positive_matches -= negative_matches
+
+ def build_documents(matches):
+
+ for path in matches:
+
+ blob = Blob.from_path(path)
+
+ yield from parser.lazy_parse(blob)
+
+ documents.extend(build_documents(sorted(positive_matches)))
+
+ logger.info(f"Total {len(documents)} source code documents in {len(positive_matches)} files.")
+
+ debug_file_path = f"{os.getenv('MORPHEUS_ROOT', '.')}/.tmp/embedding_file_list.txt"
+
+ # Ensure the directory exists
+ os.makedirs(os.path.dirname(debug_file_path), exist_ok=True)
+
+ # Write out the list of files to disk to analyze
+ with open(debug_file_path, mode="w", encoding="utf-8") as f:
+ f.writelines([f".{doc.metadata['source'].removeprefix(code_dir)}\n" for doc in documents])
+
+ python_splitter = RecursiveCharacterTextSplitter.from_language(language=Language.PYTHON,
+ chunk_size=1000,
+ chunk_overlap=200)
+ code_documents = python_splitter.split_documents(documents)
+
+ logger.info("Creating embeddings...")
+
+ # create embeddings
+ db = FAISS.from_documents(code_documents, embedding)
+
+ logger.info("Creating embeddings... Complete")
+
+ return db
diff --git a/experimental/event-driven-rag-cve-analysis/cyber_dev_day/faiss_vdb_service.py b/experimental/event-driven-rag-cve-analysis/cyber_dev_day/faiss_vdb_service.py
new file mode 100644
index 000000000..81f63aef5
--- /dev/null
+++ b/experimental/event-driven-rag-cve-analysis/cyber_dev_day/faiss_vdb_service.py
@@ -0,0 +1,765 @@
+# Copyright (c) 2023-2024, NVIDIA CORPORATION.
+#
+# 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.
+
+import asyncio
+import copy
+import json
+import logging
+import threading
+import time
+import typing
+from functools import wraps
+
+import pandas as pd
+
+import cudf
+
+from morpheus.service.vdb.vector_db_service import VectorDBResourceService
+from morpheus.service.vdb.vector_db_service import VectorDBService
+
+logger = logging.getLogger(__name__)
+
+IMPORT_EXCEPTION = None
+IMPORT_ERROR_MESSAGE = "MilvusVectorDBResourceService requires the milvus and pymilvus packages to be installed."
+
+try:
+ from langchain.vectorstores.faiss import FAISS
+except ImportError as import_exc:
+ IMPORT_EXCEPTION = import_exc
+
+
+class FaissVectorDBResourceService(VectorDBResourceService):
+ """
+ Represents a service for managing resources in a Milvus Vector Database.
+
+ Parameters
+ ----------
+ name : str
+ Name of the resource.
+ client : MilvusClient
+ An instance of the MilvusClient for interaction with the Milvus Vector Database.
+ """
+
+ def __init__(self, parent: "FaissVectorDBService", *, name: str) -> None:
+ if IMPORT_EXCEPTION is not None:
+ raise ImportError(IMPORT_ERROR_MESSAGE) from IMPORT_EXCEPTION
+
+ super().__init__()
+
+ self._parent = parent
+ self._name = name
+
+ self._index = FAISS.load_local(folder_path=self._parent._local_dir,
+ embeddings=self._parent._embeddings,
+ index_name=self._name,
+ allow_dangerous_deserialization=True)
+
+ def insert(self, data: list[list] | list[dict], **kwargs: dict[str, typing.Any]) -> dict:
+ """
+ Insert data into the vector database.
+
+ Parameters
+ ----------
+ data : list[list] | list[dict]
+ Data to be inserted into the collection.
+ **kwargs : dict[str, typing.Any]
+ Extra keyword arguments specific to the vector database implementation.
+
+ Returns
+ -------
+ dict
+ Returns response content as a dictionary.
+ """
+ raise NotImplementedError("Insert operation is not supported in FAISS")
+
+ def insert_dataframe(self, df: typing.Union[cudf.DataFrame, pd.DataFrame], **kwargs: dict[str, typing.Any]) -> dict:
+ """
+ Insert a dataframe entires into the vector database.
+
+ Parameters
+ ----------
+ df : typing.Union[cudf.DataFrame, pd.DataFrame]
+ Dataframe to be inserted into the collection.
+ **kwargs : dict[str, typing.Any]
+ Extra keyword arguments specific to the vector database implementation.
+
+ Returns
+ -------
+ dict
+ Returns response content as a dictionary.
+ """
+ raise NotImplementedError("Insert operation is not supported in FAISS")
+
+ def describe(self, **kwargs: dict[str, typing.Any]) -> dict:
+ """
+ Provides a description of the collection.
+
+ Parameters
+ ----------
+ **kwargs : dict[str, typing.Any]
+ Extra keyword arguments specific to the vector database implementation.
+
+ Returns
+ -------
+ dict
+ Returns response content as a dictionary.
+ """
+ raise NotImplementedError("Describe operation is not supported in FAISS")
+
+ def query(self, query: str, **kwargs: dict[str, typing.Any]) -> typing.Any:
+ """
+ Query data in a collection in the Milvus vector database.
+
+ This method performs a search operation in the specified collection/partition in the Milvus vector database.
+
+ Parameters
+ ----------
+ query : str, optional
+ The search query, which can be a filter expression, by default None.
+ **kwargs : dict
+ Additional keyword arguments for the search operation.
+
+ Returns
+ -------
+ typing.Any
+ The search result, which can vary depending on the query and options.
+
+ Raises
+ ------
+ RuntimeError
+ If an error occurs during the search operation.
+ If query argument is `None` and `data` keyword argument doesn't exist.
+ If `data` keyword arguement is `None`.
+ """
+ raise NotImplementedError("Query operation is not supported in FAISS")
+
+ async def similarity_search(self,
+ embeddings: list[list[float]],
+ k: int = 4,
+ **kwargs: dict[str, typing.Any]) -> list[list[dict]]:
+ """
+ Perform a similarity search within the collection.
+
+ Parameters
+ ----------
+ embeddings : list[list[float]]
+ Embeddings for which to perform the similarity search.
+ k : int, optional
+ The number of nearest neighbors to return, by default 4.
+ **kwargs : dict[str, typing.Any]
+ Extra keyword arguments specific to the vector database implementation.
+
+ Returns
+ -------
+ list[dict]
+ Returns a list of dictionaries representing the results of the similarity search.
+ """
+
+ async def single_search(single_embedding):
+ docs = await self._index.asimilarity_search_by_vector(embedding=single_embedding, k=k)
+
+ return [d.dict() for d in docs]
+
+ return list(await asyncio.gather(*[single_search(embedding) for embedding in embeddings]))
+
+ def update(self, data: list[typing.Any], **kwargs: dict[str, typing.Any]) -> dict[str, typing.Any]:
+ """
+ Update data in the collection.
+
+ Parameters
+ ----------
+ data : list[typing.Any]
+ Data to be updated in the collection.
+ **kwargs : dict[str, typing.Any]
+ Extra keyword arguments specific to upsert operation.
+
+ Returns
+ -------
+ dict[str, typing.Any]
+ Returns result of the updated operation stats.
+ """
+ raise NotImplementedError("Update operation is not supported in FAISS")
+
+ def delete_by_keys(self, keys: int | str | list, **kwargs: dict[str, typing.Any]) -> typing.Any:
+ """
+ Delete vectors by keys from the collection.
+
+ Parameters
+ ----------
+ keys : int | str | list
+ Primary keys to delete vectors.
+ **kwargs : dict[str, typing.Any]
+ Extra keyword arguments specific to the vector database implementation.
+
+ Returns
+ -------
+ typing.Any
+ Returns result of the given keys that are deleted from the collection.
+ """
+ raise NotImplementedError("Delete by keys operation is not supported in FAISS")
+
+ def delete(self, expr: str, **kwargs: dict[str, typing.Any]) -> dict[str, typing.Any]:
+ """
+ Delete vectors from the collection using expressions.
+
+ Parameters
+ ----------
+ expr : str
+ Delete expression.
+ **kwargs : dict[str, typing.Any]
+ Extra keyword arguments specific to the vector database implementation.
+
+ Returns
+ -------
+ dict[str, typing.Any]
+ Returns result of the given keys that are deleted from the collection.
+ """
+ raise NotImplementedError("Delete operation is not supported in FAISS")
+
+ def retrieve_by_keys(self, keys: int | str | list, **kwargs: dict[str, typing.Any]) -> list[typing.Any]:
+ """
+ Retrieve the inserted vectors using their primary keys.
+
+ Parameters
+ ----------
+ keys : int | str | list
+ Primary keys to get vectors for. Depending on pk_field type it can be int or str
+ or a list of either.
+ **kwargs : dict[str, typing.Any]
+ Additional keyword arguments for the retrieval operation.
+
+ Returns
+ -------
+ list[typing.Any]
+ Returns result rows of the given keys from the collection.
+ """
+ raise NotImplementedError("Retrieve by keys operation is not supported in FAISS")
+
+ def count(self, **kwargs: dict[str, typing.Any]) -> int:
+ """
+ Returns number of rows/entities.
+
+ Parameters
+ ----------
+ **kwargs : dict[str, typing.Any]
+ Additional keyword arguments for the count operation.
+
+ Returns
+ -------
+ int
+ Returns number of entities in the collection.
+ """
+ raise NotImplementedError("Count operation is not supported in FAISS")
+
+ def drop(self, **kwargs: dict[str, typing.Any]) -> None:
+ """
+ Drop a collection, index, or partition in the Milvus vector database.
+
+ This function allows you to drop a collection.
+
+ Parameters
+ ----------
+ **kwargs : dict
+ Additional keyword arguments for specifying the type and partition name (if applicable).
+ """
+ raise NotImplementedError("Drop operation is not supported in FAISS")
+
+
+class FaissVectorDBService(VectorDBService):
+ """
+ Service class for Milvus Vector Database implementation. This class provides functions for interacting
+ with a Milvus vector database.
+
+ Parameters
+ ----------
+ host : str
+ The hostname or IP address of the Milvus server.
+ port : str
+ The port number for connecting to the Milvus server.
+ alias : str, optional
+ Alias for the Milvus connection, by default "default".
+ **kwargs : dict
+ Additional keyword arguments specific to the Milvus connection configuration.
+ """
+
+ _collection_locks = {}
+ _cleanup_interval = 600 # 10mins
+ _last_cleanup_time = time.time()
+
+ def __init__(self, local_dir: str, embeddings, **kwargs: dict[str, typing.Any]):
+
+ if IMPORT_EXCEPTION is not None:
+ raise ImportError(IMPORT_ERROR_MESSAGE) from IMPORT_EXCEPTION
+
+ self._local_dir = local_dir
+ self._embeddings = embeddings
+
+ def load_resource(self, name: str = "index", **kwargs: dict[str, typing.Any]) -> FaissVectorDBResourceService:
+
+ return FaissVectorDBResourceService(self, name=name, **kwargs)
+
+ def has_store_object(self, name: str) -> bool:
+ """
+ Check if a collection exists in the Milvus vector database.
+
+ Parameters
+ ----------
+ name : str
+ Name of the collection to check.
+
+ Returns
+ -------
+ bool
+ True if the collection exists, False otherwise.
+ """
+ return self._client.has_collection(collection_name=name)
+
+ def list_store_objects(self, **kwargs: dict[str, typing.Any]) -> list[str]:
+ """
+ List the names of all collections in the Milvus vector database.
+
+ Returns
+ -------
+ list[str]
+ A list of collection names.
+ """
+ return self._client.list_collections(**kwargs)
+
+ def _create_schema_field(self, field_conf: dict) -> "pymilvus.FieldSchema":
+
+ field_schema = pymilvus.FieldSchema.construct_from_dict(field_conf)
+
+ return field_schema
+
+ def create(self, name: str, overwrite: bool = False, **kwargs: dict[str, typing.Any]):
+ """
+ Create a collection in the Milvus vector database with the specified name and configuration. This method
+ creates a new collection in the Milvus vector database with the provided name and configuration options.
+ If the collection already exists, it can be overwritten if the `overwrite` parameter is set to True.
+
+ Parameters
+ ----------
+ name : str
+ Name of the collection to be created.
+ overwrite : bool, optional
+ If True, the collection will be overwritten if it already exists, by default False.
+ **kwargs : dict
+ Additional keyword arguments containing collection configuration.
+
+ Raises
+ ------
+ ValueError
+ If the provided schema fields configuration is empty.
+ """
+ logger.debug("Creating collection: %s, overwrite=%s, kwargs=%s", name, overwrite, kwargs)
+
+ # Preserve original configuration.
+ collection_conf = copy.deepcopy(kwargs)
+
+ auto_id = collection_conf.get("auto_id", False)
+ index_conf = collection_conf.get("index_conf", None)
+ partition_conf = collection_conf.get("partition_conf", None)
+
+ schema_conf = collection_conf.get("schema_conf")
+ schema_fields_conf = schema_conf.pop("schema_fields")
+
+ if not self.has_store_object(name) or overwrite:
+ if overwrite and self.has_store_object(name):
+ self.drop(name)
+
+ if len(schema_fields_conf) == 0:
+ raise ValueError("Cannot create collection as provided empty schema_fields configuration")
+
+ schema_fields = [FieldSchemaEncoder.from_dict(field_conf) for field_conf in schema_fields_conf]
+
+ schema = pymilvus.CollectionSchema(fields=schema_fields, **schema_conf)
+
+ self._client.create_collection_with_schema(collection_name=name,
+ schema=schema,
+ index_params=index_conf,
+ auto_id=auto_id,
+ shards_num=collection_conf.get("shards", 2),
+ consistency_level=collection_conf.get(
+ "consistency_level", "Strong"))
+
+ if partition_conf:
+ timeout = partition_conf.get("timeout", 1.0)
+ # Iterate over each partition configuration
+ for part in partition_conf["partitions"]:
+ self._client.create_partition(collection_name=name, partition_name=part["name"], timeout=timeout)
+
+ def create_from_dataframe(self,
+ name: str,
+ df: typing.Union[cudf.DataFrame, pd.DataFrame],
+ overwrite: bool = False,
+ **kwargs: dict[str, typing.Any]) -> None:
+ """
+ Create collections in the vector database.
+
+ Parameters
+ ----------
+ name : str
+ Name of the collection.
+ df : Union[cudf.DataFrame, pd.DataFrame]
+ The dataframe to create the collection from.
+ overwrite : bool, optional
+ Whether to overwrite the collection if it already exists. Default is False.
+ **kwargs : dict[str, typing.Any]
+ Extra keyword arguments specific to the vector database implementation.
+ """
+
+ fields = self._build_schema_conf(df=df)
+
+ create_kwargs = {
+ "schema_conf": {
+ "description": "Auto generated schema from DataFrame in Morpheus",
+ "schema_fields": fields,
+ }
+ }
+
+ if (kwargs.get("index_field", None) is not None):
+ # Check to make sure the column name exists in the fields
+ create_kwargs["index_conf"] = {
+ "field_name": kwargs.get("index_field"), # Default index type
+ "metric_type": "L2",
+ "index_type": "HNSW",
+ "params": {
+ "M": 8,
+ "efConstruction": 64,
+ },
+ }
+
+ self.create(name=name, overwrite=overwrite, **create_kwargs)
+
+ def insert(self, name: str, data: list[list] | list[dict], **kwargs: dict[str,
+ typing.Any]) -> dict[str, typing.Any]:
+ """
+ Insert a collection specific data in the Milvus vector database.
+
+ Parameters
+ ----------
+ name : str
+ Name of the collection to be inserted.
+ data : list[list] | list[dict]
+ Data to be inserted in the collection.
+ **kwargs : dict[str, typing.Any]
+ Additional keyword arguments containing collection configuration.
+
+ Returns
+ -------
+ dict
+ Returns response content as a dictionary.
+
+ Raises
+ ------
+ RuntimeError
+ If the collection not exists exists.
+ """
+
+ resource = self.load_resource(name)
+ return resource.insert(data, **kwargs)
+
+ def insert_dataframe(self,
+ name: str,
+ df: typing.Union[cudf.DataFrame, pd.DataFrame],
+ **kwargs: dict[str, typing.Any]) -> dict[str, typing.Any]:
+ """
+ Converts dataframe to rows and insert to a collection in the Milvus vector database.
+
+ Parameters
+ ----------
+ name : str
+ Name of the collection to be inserted.
+ df : typing.Union[cudf.DataFrame, pd.DataFrame]
+ Dataframe to be inserted in the collection.
+ **kwargs : dict[str, typing.Any]
+ Additional keyword arguments containing collection configuration.
+
+ Returns
+ -------
+ dict
+ Returns response content as a dictionary.
+
+ Raises
+ ------
+ RuntimeError
+ If the collection not exists exists.
+ """
+ resource = self.load_resource(name)
+
+ return resource.insert_dataframe(df=df, **kwargs)
+
+ def query(self, name: str, query: str = None, **kwargs: dict[str, typing.Any]) -> typing.Any:
+ """
+ Query data in a collection in the Milvus vector database.
+
+ This method performs a search operation in the specified collection/partition in the Milvus vector database.
+
+ Parameters
+ ----------
+ name : str
+ Name of the collection to search within.
+ query : str
+ The search query, which can be a filter expression.
+ **kwargs : dict
+ Additional keyword arguments for the search operation.
+
+ Returns
+ -------
+ typing.Any
+ The search result, which can vary depending on the query and options.
+ """
+
+ resource = self.load_resource(name)
+
+ return resource.query(query, **kwargs)
+
+ async def similarity_search(self, name: str, **kwargs: dict[str, typing.Any]) -> list[dict]:
+ """
+ Perform a similarity search within the collection.
+
+ Parameters
+ ----------
+ name : str
+ Name of the collection.
+ **kwargs : dict[str, typing.Any]
+ Extra keyword arguments specific to the vector database implementation.
+
+ Returns
+ -------
+ list[dict]
+ Returns a list of dictionaries representing the results of the similarity search.
+ """
+
+ resource = self.load_resource(name)
+
+ return resource.similarity_search(**kwargs)
+
+ def update(self, name: str, data: list[typing.Any], **kwargs: dict[str, typing.Any]) -> dict[str, typing.Any]:
+ """
+ Update data in the vector database.
+
+ Parameters
+ ----------
+ name : str
+ Name of the collection.
+ data : list[typing.Any]
+ Data to be updated in the collection.
+ **kwargs : dict[str, typing.Any]
+ Extra keyword arguments specific to upsert operation.
+
+ Returns
+ -------
+ dict[str, typing.Any]
+ Returns result of the updated operation stats.
+ """
+
+ if not isinstance(data, list):
+ raise RuntimeError("Data is not of type list.")
+
+ resource = self.load_resource(name)
+
+ return resource.update(data=data, **kwargs)
+
+ def delete_by_keys(self, name: str, keys: int | str | list, **kwargs: dict[str, typing.Any]) -> typing.Any:
+ """
+ Delete vectors by keys from the collection.
+
+ Parameters
+ ----------
+ name : str
+ Name of the collection.
+ keys : int | str | list
+ Primary keys to delete vectors.
+ **kwargs : dict[str, typing.Any]
+ Extra keyword arguments specific to the vector database implementation.
+
+ Returns
+ -------
+ typing.Any
+ Returns result of the given keys that are delete from the collection.
+ """
+
+ resource = self.load_resource(name)
+
+ return resource.delete_by_keys(keys=keys, **kwargs)
+
+ def delete(self, name: str, expr: str, **kwargs: dict[str, typing.Any]) -> dict[str, typing.Any]:
+ """
+ Delete vectors from the collection using expressions.
+
+ Parameters
+ ----------
+ name : str
+ Name of the collection.
+ expr : str
+ Delete expression.
+ **kwargs : dict[str, typing.Any]
+ Extra keyword arguments specific to the vector database implementation.
+
+ Returns
+ -------
+ dict[str, typing.Any]
+ Returns result of the given keys that are delete from the collection.
+ """
+
+ resource = self.load_resource(name)
+ result = resource.delete(expr=expr, **kwargs)
+
+ return result
+
+ def retrieve_by_keys(self, name: str, keys: int | str | list, **kwargs: dict[str, typing.Any]) -> list[typing.Any]:
+ """
+ Retrieve the inserted vectors using their primary keys from the Collection.
+
+ Parameters
+ ----------
+ name : str
+ Name of the collection.
+ keys : int | str | list
+ Primary keys to get vectors for. Depending on pk_field type it can be int or str
+ or a list of either.
+ **kwargs : dict[str, typing.Any]
+ Additional keyword arguments for the retrieval operation.
+
+ Returns
+ -------
+ list[typing.Any]
+ Returns result rows of the given keys from the collection.
+ """
+
+ resource = self.load_resource(name)
+
+ result = resource.retrieve_by_keys(keys=keys, **kwargs)
+
+ return result
+
+ def count(self, name: str, **kwargs: dict[str, typing.Any]) -> int:
+ """
+ Returns number of rows/entities in the given collection.
+
+ Parameters
+ ----------
+ name : str
+ Name of the collection.
+ **kwargs : dict[str, typing.Any]
+ Additional keyword arguments for the count operation.
+
+ Returns
+ -------
+ int
+ Returns number of entities in the collection.
+ """
+ resource = self.load_resource(name)
+
+ return resource.count(**kwargs)
+
+ def drop(self, name: str, **kwargs: dict[str, typing.Any]) -> None:
+ """
+ Drop a collection, index, or partition in the Milvus vector database.
+
+ This method allows you to drop a collection, an index within a collection,
+ or a specific partition within a collection in the Milvus vector database.
+
+ Parameters
+ ----------
+ name : str
+ Name of the collection, index, or partition to be dropped.
+ **kwargs : dict
+ Additional keyword arguments for specifying the type and partition name (if applicable).
+
+ Notes on Expected Keyword Arguments:
+ ------------------------------------
+ - 'collection' (str, optional):
+ Specifies the type of collection to drop. Possible values: 'collection' (default), 'index', 'partition'.
+
+ - 'partition_name' (str, optional):
+ Required when dropping a specific partition within a collection. Specifies the partition name to be dropped.
+
+ - 'field_name' (str, optional):
+ Required when dropping an index within a collection. Specifies the field name for which the index is created.
+
+ - 'index_name' (str, optional):
+ Required when dropping an index within a collection. Specifies the name of the index to be dropped.
+
+ Raises
+ ------
+ ValueError
+ If mandatory arguments are missing or if the provided 'collection' value is invalid.
+ """
+
+ logger.debug("Dropping collection: %s, kwargs=%s", name, kwargs)
+
+ if self.has_store_object(name):
+ resource = kwargs.get("resource", "collection")
+ if resource == "collection":
+ self._client.drop_collection(collection_name=name)
+ elif resource == "partition":
+ if "partition_name" not in kwargs:
+ raise ValueError("Mandatory argument 'partition_name' is required when resource='partition'")
+ partition_name = kwargs["partition_name"]
+ if self._client.has_partition(collection_name=name, partition_name=partition_name):
+ # Collection need to be released before dropping the partition.
+ self._client.release_collection(collection_name=name)
+ self._client.drop_partition(collection_name=name, partition_name=partition_name)
+ elif resource == "index":
+ if "field_name" in kwargs and "index_name" in kwargs:
+ self._client.drop_index(collection_name=name,
+ field_name=kwargs["field_name"],
+ index_name=kwargs["index_name"])
+ else:
+ raise ValueError(
+ "Mandatory arguments 'field_name' and 'index_name' are required when resource='index'")
+
+ def describe(self, name: str, **kwargs: dict[str, typing.Any]) -> dict:
+ """
+ Describe the collection in the vector database.
+
+ Parameters
+ ----------
+ name : str
+ Name of the collection.
+ **kwargs : dict[str, typing.Any]
+ Additional keyword arguments specific to the Milvus vector database.
+
+ Returns
+ -------
+ dict
+ Returns collection information.
+ """
+
+ resource = self.load_resource(name)
+
+ return resource.describe(**kwargs)
+
+ def release_resource(self, name: str) -> None:
+ """
+ Release a loaded collection from the memory.
+
+ Parameters
+ ----------
+ name : str
+ Name of the collection to release.
+ """
+
+ self._client.release_collection(collection_name=name)
+
+ def close(self) -> None:
+ """
+ Close the connection to the Milvus vector database.
+
+ This method disconnects from the Milvus vector database by removing the connection.
+
+ """
+ self._client.close()
diff --git a/experimental/event-driven-rag-cve-analysis/cyber_dev_day/langchain_llm_client_wrapper.py b/experimental/event-driven-rag-cve-analysis/cyber_dev_day/langchain_llm_client_wrapper.py
new file mode 100644
index 000000000..18589f9b5
--- /dev/null
+++ b/experimental/event-driven-rag-cve-analysis/cyber_dev_day/langchain_llm_client_wrapper.py
@@ -0,0 +1,61 @@
+# Copyright (c) 2024, NVIDIA CORPORATION.
+#
+# 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.
+
+import typing
+
+from cyber_dev_day.llm_service import LLMClient
+
+IMPORT_EXCEPTION = None
+IMPORT_ERROR_MESSAGE = ("LangchainLLMClientWrapper require the langchain package to be installed. "
+ "Install it by running the following command:\n"
+ "`conda env update --solver=libmamba -n morpheus "
+ "--file morpheus/conda/environments/examples_cuda-121_arch-x86_64.yaml --prune`")
+
+try:
+ from langchain_core.callbacks import AsyncCallbackManagerForLLMRun
+ from langchain_core.callbacks import CallbackManagerForLLMRun
+ from langchain_core.language_models.llms import LLM
+except ImportError as import_exc:
+ IMPORT_EXCEPTION = import_exc
+
+
+class LangchainLLMClientWrapper(LLM):
+
+ client: LLMClient
+
+ @property
+ def _llm_type(self) -> str:
+ """Return type of llm."""
+ return "morpheus"
+
+ def _call(
+ self,
+ prompt: str,
+ stop: typing.Optional[list[str]] = None,
+ run_manager: typing.Optional[CallbackManagerForLLMRun] = None,
+ **kwargs: typing.Any,
+ ) -> str:
+ """Run the LLM on the given prompt and input."""
+
+ return self.client.generate(prompt=prompt, stop=stop)
+
+ async def _acall(
+ self,
+ prompt: str,
+ stop: typing.Optional[list[str]] = None,
+ run_manager: typing.Optional[AsyncCallbackManagerForLLMRun] = None,
+ **kwargs: typing.Any,
+ ) -> str:
+ """Run the LLM on the given prompt and input."""
+ return await self.client.generate_async(prompt=prompt, stop=stop)
diff --git a/experimental/event-driven-rag-cve-analysis/cyber_dev_day/llm_service.py b/experimental/event-driven-rag-cve-analysis/cyber_dev_day/llm_service.py
new file mode 100644
index 000000000..7777d7ea0
--- /dev/null
+++ b/experimental/event-driven-rag-cve-analysis/cyber_dev_day/llm_service.py
@@ -0,0 +1,186 @@
+# Copyright (c) 2023-2024, NVIDIA CORPORATION.
+#
+# 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.
+
+import importlib
+import logging
+import typing
+from abc import ABC
+from abc import abstractmethod
+
+logger = logging.getLogger(__name__)
+
+
+class LLMClient(ABC):
+ """
+ Abstract interface for clients which are able to interact with LLM models. Concrete implementations of this class
+ will have an associated implementation of `LLMService` which is able to construct instances of this class.
+ """
+
+ @abstractmethod
+ def get_input_names(self) -> list[str]:
+ """
+ Returns the names of the inputs to the model.
+ """
+ pass
+
+ @abstractmethod
+ def generate(self, **input_dict) -> str:
+ """
+ Issue a request to generate a response based on a given prompt.
+
+ Parameters
+ ----------
+ input_dict : dict
+ Input containing prompt data.
+ """
+ pass
+
+ @abstractmethod
+ async def generate_async(self, **input_dict) -> str:
+ """
+ Issue an asynchronous request to generate a response based on a given prompt.
+
+ Parameters
+ ----------
+ input_dict : dict
+ Input containing prompt data.
+ """
+ pass
+
+ @typing.overload
+ @abstractmethod
+ def generate_batch(self,
+ inputs: dict[str, list],
+ return_exceptions: typing.Literal[True] = True) -> list[str | BaseException]:
+ ...
+
+ @typing.overload
+ @abstractmethod
+ def generate_batch(self, inputs: dict[str, list], return_exceptions: typing.Literal[False] = False) -> list[str]:
+ ...
+
+ @abstractmethod
+ def generate_batch(self, inputs: dict[str, list], return_exceptions=False) -> list[str] | list[str | BaseException]:
+ """
+ Issue a request to generate a list of responses based on a list of prompts.
+
+ Parameters
+ ----------
+ inputs : dict
+ Inputs containing prompt data.
+ return_exceptions : bool
+ Whether to return exceptions in the output list or raise them immediately.
+ """
+ pass
+
+ @typing.overload
+ @abstractmethod
+ async def generate_batch_async(self,
+ inputs: dict[str, list],
+ return_exceptions: typing.Literal[True] = True) -> list[str | BaseException]:
+ ...
+
+ @typing.overload
+ @abstractmethod
+ async def generate_batch_async(self,
+ inputs: dict[str, list],
+ return_exceptions: typing.Literal[False] = False) -> list[str]:
+ ...
+
+ @abstractmethod
+ async def generate_batch_async(self,
+ inputs: dict[str, list],
+ return_exceptions=False) -> list[str] | list[str | BaseException]:
+ """
+ Issue an asynchronous request to generate a list of responses based on a list of prompts.
+
+ Parameters
+ ----------
+ inputs : dict
+ Inputs containing prompt data.
+ return_exceptions : bool
+ Whether to return exceptions in the output list or raise them immediately.
+ """
+ pass
+
+
+class LLMService(ABC):
+ """
+ Abstract interface for services which are able to construct clients for interacting with LLM models.
+ """
+
+ @abstractmethod
+ def get_client(self, *, model_name: str, **model_kwargs) -> LLMClient:
+ """
+ Returns a client for interacting with a specific model.
+
+ Parameters
+ ----------
+ model_name : str
+ The name of the model to create a client for.
+
+ model_kwargs : dict[str, typing.Any]
+ Additional keyword arguments to pass to the model.
+ """
+ pass
+
+ @typing.overload
+ @staticmethod
+ def create(service_type: typing.Literal["nemo"], *service_args,
+ **service_kwargs) -> "morpheus.llm.services.nemo_llm_service.NeMoLLMService":
+ pass
+
+ @typing.overload
+ @staticmethod
+ def create(service_type: typing.Literal["openai"], *service_args,
+ **service_kwargs) -> "morpheus.llm.services.nemo_llm_service.OpenAILLMService":
+ pass
+
+ @typing.overload
+ @staticmethod
+ def create(service_type: str, *service_args, **service_kwargs) -> "LLMService":
+ pass
+
+ @staticmethod
+ def create(service_type: str | typing.Literal["nemo"] | typing.Literal["openai"], *service_args, **service_kwargs):
+ """
+ Returns a service for interacting with LLM models.
+
+ Parameters
+ ----------
+ service_type : str
+ The type of the service to create
+
+ service_kwargs : dict[str, typing.Any]
+ Additional keyword arguments to pass to the service.
+ """
+ module_name = f"cyber_dev_day.{service_type.lower()}_llm_service"
+ module = importlib.import_module(module_name)
+
+ # Get all of the classes in the module to find the correct service class
+ mod_classes = dict([(name, cls) for name, cls in module.__dict__.items() if isinstance(cls, type)])
+
+ class_name_lower = f"{service_type}LLMService".lower()
+
+ # Find case-insensitive match for the class name
+ matching_classes = [name for name in mod_classes if name.lower() == class_name_lower]
+
+ assert len(matching_classes) == 1, f"Expected to find exactly one class with name {class_name_lower} in module {module_name}, but found {matching_classes}"
+
+ # Create the class
+ class_ = getattr(module, matching_classes[0])
+
+ instance = class_(*service_args, **service_kwargs)
+
+ return instance
diff --git a/experimental/event-driven-rag-cve-analysis/cyber_dev_day/nim_llm_service.py b/experimental/event-driven-rag-cve-analysis/cyber_dev_day/nim_llm_service.py
new file mode 100644
index 000000000..621befbef
--- /dev/null
+++ b/experimental/event-driven-rag-cve-analysis/cyber_dev_day/nim_llm_service.py
@@ -0,0 +1,165 @@
+# Copyright (c) 2023-2024, NVIDIA CORPORATION.
+#
+# 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.
+import asyncio
+import copy
+import logging
+import os
+import time
+import typing
+from contextlib import contextmanager
+from textwrap import dedent
+import re
+
+import appdirs
+
+from cyber_dev_day.llm_service import LLMClient
+from cyber_dev_day.llm_service import LLMService
+from cyber_dev_day.openai_chat_service import OpenAIChatService, OpenAIChatClient
+
+logger = logging.getLogger(__name__)
+
+IMPORT_EXCEPTION = None
+IMPORT_ERROR_MESSAGE = ("OpenAIChatService & OpenAIChatClient require the openai package to be installed. "
+ "Install it by running the following command:\n"
+ "`conda env update --solver=libmamba -n morpheus "
+ "--file conda/environments/dev_cuda-121_arch-x86_64.yaml --prune`")
+
+try:
+ import openai
+ import openai.types.chat
+ import openai.types.chat.chat_completion
+except ImportError as import_exc:
+ IMPORT_EXCEPTION = import_exc
+
+
+class NIMChatClient(OpenAIChatClient):
+ """
+ Client for interacting with a specific NVIDIA Inference Microservice chat model. This class should be constructed with the
+ `NIMLLMService.get_client` method.
+
+ Parameters
+ ----------
+ model_name : str
+ The name of the model to interact with.
+
+ base_url: str
+ The URI at which the NIM can be reached.
+
+ set_assistant: bool, optional default=False
+ When `True`, a second input field named `assistant` will be used to proide additional context to the model.
+
+ max_retries: int, optional default=10
+ The maximum number of retries to attempt when making a request to the OpenAI API.
+
+ model_kwargs : dict[str, typing.Any]
+ Additional keyword arguments to pass to the model when generating text.
+ """
+
+ _prompt_key: str = "prompt"
+ _assistant_key: str = "assistant"
+
+ def __init__(self,
+ parent: "NIMChatService",
+ *,
+ model_name: str,
+ base_url: str,
+ set_assistant: bool = False,
+ max_retries: int = 10,
+ **model_kwargs) -> None:
+ if IMPORT_EXCEPTION is not None:
+ raise ImportError(IMPORT_ERROR_MESSAGE) from IMPORT_EXCEPTION
+
+ super().__init__(
+ parent=parent,
+ model_name=model_name,
+ set_assistant=set_assistant,
+ max_retries=max_retries,
+ **model_kwargs
+ )
+
+ self._base_url = base_url
+
+ # Create the client objects for both sync and async
+ self._client = openai.OpenAI(base_url = self._base_url, max_retries=max_retries)
+ self._client_async = openai.AsyncOpenAI(base_url = self._base_url, max_retries=max_retries)
+
+
+
+class NIMLLMService(OpenAIChatService):
+ """
+ A service for interacting with NIM Chat models, this class should be used to create clients.
+ """
+
+ def __init__(self, *, default_model_kwargs: dict = None) -> None:
+ """
+ Creates a service for interacting with OpenAI Chat models, this class should be used to create clients.
+
+ Parameters
+ ----------
+ default_model_kwargs : dict, optional
+ Default arguments to use when creating a client via the `get_client` function. Any argument specified here
+ will automatically be used when calling `get_client`. Arguments specified in the `get_client` function will
+ overwrite default values specified here. This is useful to set model arguments before creating multiple
+ clients. By default None
+
+ Raises
+ ------
+ ImportError
+ If the `openai` library is not found in the python environment.
+ """
+ if IMPORT_EXCEPTION is not None:
+ raise ImportError(IMPORT_ERROR_MESSAGE) from IMPORT_EXCEPTION
+
+ super().__init__()
+
+ self._default_model_kwargs = default_model_kwargs or {}
+
+
+ def get_client(self,
+ *,
+ model_name: str,
+ base_url: str,
+ set_assistant: bool = False,
+ max_retries: int = 10,
+ **model_kwargs) -> NIMChatClient:
+ """
+ Returns a client for interacting with a specific model. This method is the preferred way to create a client.
+
+ Parameters
+ ----------
+ model_name : str
+ The name of the model to create a client for.
+
+ base_url: str
+ The URI at which the NIM can be reached.
+
+ set_assistant: bool, optional default=False
+ When `True`, a second input field named `assistant` will be used to proide additional context to the model.
+
+ max_retries: int, optional default=10
+ The maximum number of retries to attempt when making a request to the OpenAI API.
+
+ model_kwargs : dict[str, typing.Any]
+ Additional keyword arguments to pass to the model when generating text. Arguments specified here will
+ overwrite the `default_model_kwargs` set in the service constructor
+ """
+
+ final_model_kwargs = {**self._default_model_kwargs, **model_kwargs}
+
+ return NIMChatClient(self,
+ model_name=model_name,
+ base_url=base_url,
+ set_assistant=set_assistant,
+ max_retries=max_retries,
+ **final_model_kwargs)
\ No newline at end of file
diff --git a/experimental/event-driven-rag-cve-analysis/cyber_dev_day/openai_chat_service.py b/experimental/event-driven-rag-cve-analysis/cyber_dev_day/openai_chat_service.py
new file mode 100644
index 000000000..376a67462
--- /dev/null
+++ b/experimental/event-driven-rag-cve-analysis/cyber_dev_day/openai_chat_service.py
@@ -0,0 +1,397 @@
+# Copyright (c) 2023-2024, NVIDIA CORPORATION.
+#
+# 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.
+import asyncio
+import copy
+import logging
+import os
+import time
+import typing
+from contextlib import contextmanager
+from textwrap import dedent
+
+import appdirs
+
+from cyber_dev_day.llm_service import LLMClient
+from cyber_dev_day.llm_service import LLMService
+
+logger = logging.getLogger(__name__)
+
+IMPORT_EXCEPTION = None
+IMPORT_ERROR_MESSAGE = ("OpenAIChatService & OpenAIChatClient require the openai package to be installed. "
+ "Install it by running the following command:\n"
+ "`conda env update --solver=libmamba -n morpheus "
+ "--file conda/environments/dev_cuda-121_arch-x86_64.yaml --prune`")
+
+try:
+ import openai
+ import openai.types.chat
+ import openai.types.chat.chat_completion
+except ImportError as import_exc:
+ IMPORT_EXCEPTION = import_exc
+
+
+class _ApiLogger:
+ """
+ Simple class that allows passing back and forth the inputs and outputs of an API call via a context manager.
+ """
+
+ log_template: typing.ClassVar[str] = dedent("""
+ ============= MESSAGE %d START ==============
+ --- Input ---
+ %s
+ --- Output --- (%f ms)
+ %s
+ ============= MESSAGE %d END ==============
+ """).strip("\n")
+
+ def __init__(self, *, message_id: int, inputs: typing.Any) -> None:
+
+ self.message_id = message_id
+ self.inputs = inputs
+ self.outputs = None
+
+ def set_output(self, output: typing.Any) -> None:
+ self.outputs = output
+
+
+class OpenAIChatClient(LLMClient):
+ """
+ Client for interacting with a specific OpenAI chat model. This class should be constructed with the
+ `OpenAIChatService.get_client` method.
+
+ Parameters
+ ----------
+ model_name : str
+ The name of the model to interact with.
+
+ set_assistant: bool, optional default=False
+ When `True`, a second input field named `assistant` will be used to proide additional context to the model.
+
+ max_retries: int, optional default=10
+ The maximum number of retries to attempt when making a request to the OpenAI API.
+
+ model_kwargs : dict[str, typing.Any]
+ Additional keyword arguments to pass to the model when generating text.
+ """
+
+ _prompt_key: str = "prompt"
+ _assistant_key: str = "assistant"
+
+ def __init__(self,
+ parent: "OpenAIChatService",
+ *,
+ model_name: str,
+ set_assistant: bool = False,
+ max_retries: int = 10,
+ **model_kwargs) -> None:
+ if IMPORT_EXCEPTION is not None:
+ raise ImportError(IMPORT_ERROR_MESSAGE) from IMPORT_EXCEPTION
+
+ super().__init__()
+
+ assert parent is not None, "Parent service cannot be None."
+
+ self._parent = parent
+
+ self._model_name = model_name
+ self._set_assistant = set_assistant
+ self._prompt_key = "prompt"
+ self._assistant_key = "assistant"
+
+ # Preserve original configuration.
+ self._model_kwargs = copy.deepcopy(model_kwargs)
+
+ # Create the client objects for both sync and async
+ self._client = openai.OpenAI(max_retries=max_retries)
+ self._client_async = openai.AsyncOpenAI(max_retries=max_retries)
+
+ def get_input_names(self) -> list[str]:
+ input_names = [self._prompt_key]
+ if self._set_assistant:
+ input_names.append(self._assistant_key)
+
+ return input_names
+
+ @contextmanager
+ def _api_logger(self, inputs: typing.Any):
+
+ message_id = self._parent._get_message_id()
+ start_time = time.time()
+
+ api_logger = _ApiLogger(message_id=message_id, inputs=inputs)
+
+ yield api_logger
+
+ end_time = time.time()
+ duration_ms = (end_time - start_time) * 1000.0
+
+ self._parent._logger.info(_ApiLogger.log_template,
+ message_id,
+ api_logger.inputs,
+ duration_ms,
+ api_logger.outputs,
+ message_id)
+
+ def _create_messages(self,
+ prompt: str,
+ assistant: str = None) -> list["openai.types.chat.ChatCompletionMessageParam"]:
+ messages: list[openai.types.chat.ChatCompletionMessageParam] = [{"role": "user", "content": prompt}]
+
+ if (self._set_assistant and assistant is not None):
+ messages.append({"role": "assistant", "content": assistant})
+
+ return messages
+
+ def _extract_completion(self, completion: "openai.types.chat.chat_completion.ChatCompletion") -> str:
+ choices = completion.choices
+ if len(choices) == 0:
+ raise ValueError("No choices were returned from the model.")
+
+ content = choices[0].message.content
+ if content is None:
+ raise ValueError("No content was returned from the model.")
+
+ return content
+
+ @typing.overload
+ def _generate(self,
+ prompt: str,
+ assistant: str = None,
+ return_exceptions: typing.Literal[True] = True) -> str | BaseException:
+ ...
+
+ @typing.overload
+ def _generate(self, prompt: str, assistant: str = None, return_exceptions: typing.Literal[False] = False) -> str:
+ ...
+
+ def _generate(self, prompt: str, assistant: str = None, return_exceptions: bool = False):
+
+ try:
+ messages = self._create_messages(prompt, assistant)
+
+ output: openai.types.chat.chat_completion.ChatCompletion = self._client.chat.completions.create(
+ model=self._model_name, messages=messages, **self._model_kwargs)
+
+ return self._extract_completion(output)
+ except BaseException as e:
+
+ if return_exceptions:
+ return e
+
+ raise
+
+ def generate(self, **input_dict) -> str:
+ """
+ Issue a request to generate a response based on a given prompt.
+
+ Parameters
+ ----------
+ input_dict : dict
+ Input containing prompt data.
+ """
+ return self._generate(input_dict[self._prompt_key],
+ input_dict.get(self._assistant_key),
+ return_exceptions=False)
+
+ async def _generate_async(self, prompt: str, assistant: str = None) -> str:
+
+ messages = self._create_messages(prompt, assistant)
+
+ with self._api_logger(inputs=messages) as msg_logger:
+
+ try:
+ output = await self._client_async.chat.completions.create(model=self._model_name,
+ messages=messages,
+ **self._model_kwargs)
+ except Exception as exc:
+ self._parent._logger.error("Error generating completion: %s", exc)
+ raise
+
+ msg_logger.set_output(output)
+
+ return self._extract_completion(output)
+
+ async def generate_async(self, **input_dict) -> str:
+ """
+ Issue an asynchronous request to generate a response based on a given prompt.
+
+ Parameters
+ ----------
+ input_dict : dict
+ Input containing prompt data.
+ """
+ return await self._generate_async(input_dict[self._prompt_key], input_dict.get(self._assistant_key))
+
+ @typing.overload
+ def generate_batch(self,
+ inputs: dict[str, list],
+ return_exceptions: typing.Literal[True] = True, **kwargs) -> list[str | BaseException]:
+ ...
+
+ @typing.overload
+ def generate_batch(self, inputs: dict[str, list], return_exceptions: typing.Literal[False] = False, **kwargs) -> list[str]:
+ ...
+
+ def generate_batch(self, inputs: dict[str, list], return_exceptions=False, **kwargs) -> list[str] | list[str | BaseException]:
+ """
+ Issue a request to generate a list of responses based on a list of prompts.
+
+ Parameters
+ ----------
+ inputs : dict
+ Inputs containing prompt data.
+ return_exceptions : bool
+ Whether to return exceptions in the output list or raise them immediately.
+ """
+ prompts = inputs[self._prompt_key]
+ assistants = None
+ if (self._set_assistant):
+ assistants = inputs[self._assistant_key]
+ if len(prompts) != len(assistants):
+ raise ValueError("The number of prompts and assistants must be equal.")
+
+ results = []
+ for (i, prompt) in enumerate(prompts):
+ assistant = assistants[i] if assistants is not None else None
+ if (return_exceptions):
+ results.append(self._generate(prompt, assistant, return_exceptions=True, **kwargs))
+ else:
+ results.append(self._generate(prompt, assistant, return_exceptions=False, **kwargs))
+
+ return results
+
+ @typing.overload
+ async def generate_batch_async(self,
+ inputs: dict[str, list],
+ return_exceptions: typing.Literal[True] = True, **kwargs) -> list[str | BaseException]:
+ ...
+
+ @typing.overload
+ async def generate_batch_async(self,
+ inputs: dict[str, list],
+ return_exceptions: typing.Literal[False] = False, **kwargs) -> list[str]:
+ ...
+
+ async def generate_batch_async(self,
+ inputs: dict[str, list],
+ return_exceptions=False, **kwargs) -> list[str] | list[str | BaseException]:
+ """
+ Issue an asynchronous request to generate a list of responses based on a list of prompts.
+
+ Parameters
+ ----------
+ inputs : dict
+ Inputs containing prompt data.
+ return_exceptions : bool
+ Whether to return exceptions in the output list or raise them immediately.
+ """
+ prompts = inputs[self._prompt_key]
+ assistants = None
+ if (self._set_assistant):
+ assistants = inputs[self._assistant_key]
+ if len(prompts) != len(assistants):
+ raise ValueError("The number of prompts and assistants must be equal.")
+
+ coros = []
+ for (i, prompt) in enumerate(prompts):
+ assistant = assistants[i] if assistants is not None else None
+ coros.append(self._generate_async(prompt, assistant, **kwargs))
+
+ return await asyncio.gather(*coros, return_exceptions=return_exceptions, **kwargs)
+
+
+class OpenAIChatService(LLMService):
+ """
+ A service for interacting with OpenAI Chat models, this class should be used to create clients.
+ """
+
+ def __init__(self, *, default_model_kwargs: dict = None) -> None:
+ """
+ Creates a service for interacting with OpenAI Chat models, this class should be used to create clients.
+
+ Parameters
+ ----------
+ default_model_kwargs : dict, optional
+ Default arguments to use when creating a client via the `get_client` function. Any argument specified here
+ will automatically be used when calling `get_client`. Arguments specified in the `get_client` function will
+ overwrite default values specified here. This is useful to set model arguments before creating multiple
+ clients. By default None
+
+ Raises
+ ------
+ ImportError
+ If the `openai` library is not found in the python environment.
+ """
+ if IMPORT_EXCEPTION is not None:
+ raise ImportError(IMPORT_ERROR_MESSAGE) from IMPORT_EXCEPTION
+
+ super().__init__()
+
+ self._default_model_kwargs = default_model_kwargs or {}
+
+ self._logger = logging.getLogger(f"{__package__}.{OpenAIChatService.__name__}")
+
+ # Dont propagate up to the default logger. Just log to file
+ self._logger.propagate = False
+
+ log_file = os.path.join(appdirs.user_log_dir(appauthor="NVIDIA", appname="morpheus"), "openai.log")
+
+ # Add a file handler
+ file_handler = logging.FileHandler(log_file)
+
+ self._logger.addHandler(file_handler)
+ self._logger.setLevel(logging.INFO)
+
+ self._logger.info("OpenAI Chat Service started.")
+
+ self._message_count = 0
+
+ def _get_message_id(self):
+
+ self._message_count += 1
+
+ return self._message_count
+
+ def get_client(self,
+ *,
+ model_name: str,
+ set_assistant: bool = False,
+ max_retries: int = 10,
+ **model_kwargs) -> OpenAIChatClient:
+ """
+ Returns a client for interacting with a specific model. This method is the preferred way to create a client.
+
+ Parameters
+ ----------
+ model_name : str
+ The name of the model to create a client for.
+
+ set_assistant: bool, optional default=False
+ When `True`, a second input field named `assistant` will be used to proide additional context to the model.
+
+ max_retries: int, optional default=10
+ The maximum number of retries to attempt when making a request to the OpenAI API.
+
+ model_kwargs : dict[str, typing.Any]
+ Additional keyword arguments to pass to the model when generating text. Arguments specified here will
+ overwrite the `default_model_kwargs` set in the service constructor
+ """
+
+ final_model_kwargs = {**self._default_model_kwargs, **model_kwargs}
+
+ return OpenAIChatClient(self,
+ model_name=model_name,
+ set_assistant=set_assistant,
+ max_retries=max_retries,
+ **final_model_kwargs)
diff --git a/experimental/event-driven-rag-cve-analysis/cyber_dev_day/pipeline.py b/experimental/event-driven-rag-cve-analysis/cyber_dev_day/pipeline.py
new file mode 100644
index 000000000..38d71ac82
--- /dev/null
+++ b/experimental/event-driven-rag-cve-analysis/cyber_dev_day/pipeline.py
@@ -0,0 +1,137 @@
+# Copyright (c) 2023-2024, NVIDIA CORPORATION.
+#
+# 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.
+
+import logging
+import time
+
+import cudf
+
+from morpheus.config import Config
+from morpheus.config import PipelineModes
+from morpheus.messages import ControlMessage
+from morpheus.pipeline.linear_pipeline import LinearPipeline
+from morpheus.stages.input.in_memory_source_stage import InMemorySourceStage
+from morpheus.stages.llm.llm_engine_stage import LLMEngineStage
+from morpheus.stages.output.in_memory_sink_stage import InMemorySinkStage
+from morpheus.stages.preprocess.deserialize_stage import DeserializeStage
+from morpheus.utils.concat_df import concat_dataframes
+
+from .config import EngineAgentConfig
+from .config import EngineChecklistConfig
+from .config import EngineCodeRepoConfig
+from .config import EngineConfig
+from .config import EngineSBOMConfig
+from .config import NeMoLLMModelConfig
+from .config import NeMoLLMServiceConfig
+from .config import NVFoundationLLMModelConfig
+from .config import NVFoundationLLMServiceConfig
+from .pipeline_utils import build_cve_llm_engine
+
+logger = logging.getLogger(__name__)
+
+
+def pipeline(
+ num_threads: int,
+ pipeline_batch_size,
+ model_max_batch_size,
+ model_name,
+ repeat_count,
+) -> float:
+
+ nemo_service_config = NeMoLLMServiceConfig()
+ nvfoundation_service_config = NVFoundationLLMServiceConfig()
+
+ engine_config = EngineConfig(
+ checklist=EngineChecklistConfig(model=NeMoLLMModelConfig(service=nemo_service_config,
+ model_name="gpt-43b-002"), ),
+ agent=EngineAgentConfig(
+ model=NVFoundationLLMModelConfig(service=nvfoundation_service_config, model_name="mixtral_8x7b"),
+ sbom=EngineSBOMConfig(data_file=""),
+ code_repo=EngineCodeRepoConfig(
+ faiss_dir="/home/mdemoret/Repos/morpheus/morpheus-dev2/.tmp/Sherlock/NSPECT-V1TL-NPZI_code_faiss",
+ embedding_model_name="Xenova/text-embedding-ada-002"),
+ ),
+ )
+
+ engine_config = EngineConfig.model_validate({
+ 'checklist': {
+ 'model': {
+ 'service': {
+ 'type': 'nemo', 'api_key': None, 'org_id': None
+ },
+ 'model_name': 'gpt-43b-002',
+ 'customization_id': None,
+ 'temperature': 0.0,
+ 'tokens_to_generate': 300
+ }
+ },
+ 'agent': {
+ 'model': {
+ 'service': {
+ 'type': 'nvfoundation', 'api_key': None
+ }, 'model_name': 'mixtral_8x7b', 'temperature': 0.0
+ },
+ 'sbom': {
+ 'data_file': ''
+ },
+ 'code_repo': {
+ 'faiss_dir': '/home/mdemoret/Repos/morpheus/morpheus-dev2/.tmp/Sherlock/NSPECT-V1TL-NPZI_code_faiss',
+ 'embedding_model_name': 'Xenova/text-embedding-ada-002'
+ }
+ }
+ })
+
+ logger.info("Using Engine Config: %s", engine_config.model_dump_json(indent=2))
+
+ config = Config()
+ config.mode = PipelineModes.OTHER
+
+ # Below properties are specified by the command line
+ config.num_threads = num_threads
+ config.pipeline_batch_size = pipeline_batch_size
+ config.model_max_batch_size = model_max_batch_size
+ config.mode = PipelineModes.NLP
+ config.edge_buffer_size = 128
+
+ source_dfs = [
+ cudf.DataFrame({
+ "cve_info": [
+ "An issue was discovered in the Linux kernel through 6.0.9. drivers/media/dvb-core/dvbdev.c has a use-after-free, related to dvb_register_device dynamically allocating fops."
+ ]
+ })
+ ]
+
+ completion_task = {"task_type": "completion", "task_dict": {"input_keys": ["cve_info"], }}
+
+ pipe = LinearPipeline(config)
+
+ pipe.set_source(InMemorySourceStage(config, dataframes=source_dfs, repeat=repeat_count))
+
+ pipe.add_stage(
+ DeserializeStage(config, message_type=ControlMessage, task_type="llm_engine", task_payload=completion_task))
+
+ pipe.add_stage(LLMEngineStage(config, engine=build_cve_llm_engine(engine_config)))
+
+ sink = pipe.add_stage(InMemorySinkStage(config))
+
+ start_time = time.time()
+
+ pipe.run()
+
+ messages = sink.get_messages()
+ responses = concat_dataframes(messages)
+
+ logger.info("Pipeline complete. Received %s responses:\n%s", len(messages), responses['response'])
+
+ return start_time
diff --git a/experimental/event-driven-rag-cve-analysis/cyber_dev_day/pipeline_utils.py b/experimental/event-driven-rag-cve-analysis/cyber_dev_day/pipeline_utils.py
new file mode 100644
index 000000000..660d4e618
--- /dev/null
+++ b/experimental/event-driven-rag-cve-analysis/cyber_dev_day/pipeline_utils.py
@@ -0,0 +1,262 @@
+# Copyright (c) 2024, NVIDIA CORPORATION.
+#
+# 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.
+
+import logging
+
+from langchain.agents import AgentType
+from langchain.agents import Tool
+from langchain.agents import initialize_agent
+from langchain.agents.agent import AgentExecutor
+from langchain.chains import RetrievalQA
+from langchain.embeddings.huggingface import HuggingFaceEmbeddings
+from langchain.vectorstores.faiss import FAISS
+
+from morpheus.llm import LLMEngine
+from morpheus.llm.nodes.extracter_node import ExtracterNode
+from morpheus.llm.nodes.langchain_agent_node import LangChainAgentNode
+from cyber_dev_day.llm_service import LLMService
+from cyber_dev_day.langchain_llm_client_wrapper import LangchainLLMClientWrapper
+from morpheus.llm.task_handlers.simple_task_handler import SimpleTaskHandler
+
+from .checklist_node import CVEChecklistNode
+from .config import EngineAgentConfig
+from .config import EngineConfig
+from .tools import SBOMChecker
+
+logger = logging.getLogger(__name__)
+
+
+def build_agent_executor(config: EngineAgentConfig, handle_parsing_errors=False) -> AgentExecutor:
+ llm_service = LLMService.create(config.model.service.type, **config.model.service.model_dump(exclude={"type"}))
+
+ llm_client = llm_service.get_client(**config.model.model_dump(exclude={"service"}))
+
+ # Wrap the Morpheus client in a LangChain compatible wrapper
+ langchain_llm = LangchainLLMClientWrapper(client=llm_client)
+
+ # tools = load_tools(["serpapi", "llm-math"], llm=llm)
+ tools: list[Tool] = []
+
+ if (config.sbom.data_file is not None):
+ # Load the SBOM
+ sbom_checker = SBOMChecker.from_csv(config.sbom.data_file)
+
+ tools.append(
+ Tool(name="SBOM Package Checker",
+ func=sbom_checker.sbom_checker,
+ description=("useful for when you need to check the Docker container's software bill of "
+ "materials (SBOM) to get whether or not a given library is in the container. "
+ "Input should be the name of the library or software, and no text following it until a response is returned. "
+ "If the package is "
+ "present a version number is returned, otherwise False is returned if the "
+ "package is not present.")))
+
+ if (config.code_repo.faiss_dir is not None):
+ embeddings = HuggingFaceEmbeddings(model_name=config.code_repo.embedding_model_name,
+ model_kwargs={'device': 'cuda'},
+ encode_kwargs={'normalize_embeddings': False})
+
+ # load code vector DB
+ code_vector_db = FAISS.load_local(folder_path=config.code_repo.faiss_dir,
+ embeddings=embeddings,
+ allow_dangerous_deserialization=True)
+ code_qa_tool = RetrievalQA.from_chain_type(llm=langchain_llm,
+ chain_type="stuff",
+ retriever=code_vector_db.as_retriever())
+ tools.append(
+ Tool(name="Docker Container Code QA System",
+ func=code_qa_tool.run,
+ description=("useful for when you need to review code to check for an import or function usage in "
+ "the Docker container. Input should be a question or the actual code. ")))
+
+ sys_prompt = ("You are a very powerful assistant who helps investigate Docker containers "
+ " given a checklist of investigation items. Your role is to walk through a provided checklist and answer each item in the checklist. "
+ " Do not investigate additional information per checklist item, just answer the checklist. "
+ " Information about the Docker container under investigation is stored in vector databases available to you via tools. ")
+
+ if handle_parsing_errors:
+ agent_executor = initialize_agent(tools,
+ langchain_llm,
+ agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
+ verbose=config.verbose,
+ handle_parsing_errors="Check your output. Make sure you're using the right Action/Action input syntax.")
+ else:
+ agent_executor = initialize_agent(tools,
+ langchain_llm,
+ agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
+ verbose=config.verbose)
+
+ agent_executor.agent.llm_chain.prompt.template = (
+ sys_prompt + ' ' + agent_executor.agent.llm_chain.prompt.template.replace(
+ "Answer the following questions as best you can.",
+ ("If the input is not a question, formulate it into a question first. "
+ "Include intermediate thought in the final answer.")).replace(
+ "Use the following format:",
+ ("Use the following format (start each response with one of the following prefixes): "
+ "[Question, Thought, Action, Action Input, Final Answer]). "
+ "If you are making an action, wait for a response to the action input before making an observation. Every response must contain at least one action (and thoughts and observations if you have them), but you cannot have both a final answer and an action in a response. Action input must only contain the exact input, do not provide any text following that in your response. Always end your response with either an action, or a final answer.")))
+
+ return agent_executor
+
+
+def build_cve_llm_engine(config: EngineConfig, handle_parsing_errors=True) -> LLMEngine:
+ engine = LLMEngine()
+
+ engine.add_node("extracter", node=ExtracterNode())
+
+ engine.add_node("checklist", inputs=["/extracter"], node=CVEChecklistNode(config=config.checklist))
+
+ engine.add_node("agent",
+ inputs=[("/checklist")],
+ node=LangChainAgentNode(agent_executor=build_agent_executor(config=config.agent,
+ handle_parsing_errors=handle_parsing_errors)))
+
+ engine.add_task_handler(
+ inputs=[("/checklist", "checklist"), ("/agent", "response")],
+ handler=SimpleTaskHandler(output_columns=["checklist", "response"]),
+ )
+
+ return engine
+
+
+# Copyright (c) 2024, NVIDIA CORPORATION.
+#
+# 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.
+
+import logging
+
+from langchain.agents import AgentType
+from langchain.agents import Tool
+from langchain.agents import initialize_agent
+from langchain.agents.agent import AgentExecutor
+from langchain.chains import RetrievalQA
+from langchain.embeddings.huggingface import HuggingFaceEmbeddings
+from langchain.vectorstores.faiss import FAISS
+
+from morpheus.llm import LLMEngine
+from morpheus.llm.nodes.extracter_node import ExtracterNode
+from morpheus.llm.nodes.langchain_agent_node import LangChainAgentNode
+from cyber_dev_day.llm_service import LLMService
+from cyber_dev_day.langchain_llm_client_wrapper import LangchainLLMClientWrapper
+from morpheus.llm.task_handlers.simple_task_handler import SimpleTaskHandler
+
+from .checklist_node import CVEChecklistNode
+from .config import EngineAgentConfig
+from .config import EngineConfig
+from .tools import SBOMChecker
+
+logger = logging.getLogger(__name__)
+
+
+def build_agent_executor(config: EngineAgentConfig, handle_parsing_errors=False) -> AgentExecutor:
+ llm_service = LLMService.create(config.model.service.type, **config.model.service.model_dump(exclude={"type"}))
+
+ llm_client = llm_service.get_client(**config.model.model_dump(exclude={"service"}))
+
+ # Wrap the Morpheus client in a LangChain compatible wrapper
+ langchain_llm = LangchainLLMClientWrapper(client=llm_client)
+
+ # tools = load_tools(["serpapi", "llm-math"], llm=llm)
+ tools: list[Tool] = []
+
+ if (config.sbom.data_file is not None):
+ # Load the SBOM
+ sbom_checker = SBOMChecker.from_csv(config.sbom.data_file)
+
+ tools.append(
+ Tool(name="SBOM Package Checker",
+ func=sbom_checker.sbom_checker,
+ description=("useful for when you need to check the Docker container's software bill of "
+ "materials (SBOM) to get whether or not a given library is in the container. "
+ "Input should be the name of the library or software, and no text following it until a response is returned. "
+ "If the package is "
+ "present a version number is returned, otherwise False is returned if the "
+ "package is not present.")))
+
+ if (config.code_repo.faiss_dir is not None):
+ embeddings = HuggingFaceEmbeddings(model_name=config.code_repo.embedding_model_name,
+ model_kwargs={'device': 'cuda'},
+ encode_kwargs={'normalize_embeddings': False})
+
+ # load code vector DB
+ code_vector_db = FAISS.load_local(folder_path=config.code_repo.faiss_dir,
+ embeddings=embeddings,
+ allow_dangerous_deserialization=True)
+ code_qa_tool = RetrievalQA.from_chain_type(llm=langchain_llm,
+ chain_type="stuff",
+ retriever=code_vector_db.as_retriever())
+ tools.append(
+ Tool(name="Docker Container Code QA System",
+ func=code_qa_tool.run,
+ description=("useful for when you need to review code to check for an import or function usage in "
+ "the Docker container. Input should be a question or the actual code. ")))
+
+ sys_prompt = ("You are a very powerful assistant who helps investigate Docker containers "
+ " given a checklist of investigation items. Your role is to walk through a provided checklist and answer each item in the checklist. "
+ " Do not investigate additional information per checklist item, just answer the checklist. "
+ " Information about the Docker container under investigation is stored in vector databases available to you via tools. ")
+
+ if handle_parsing_errors:
+ agent_executor = initialize_agent(tools,
+ langchain_llm,
+ agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
+ verbose=config.verbose,
+ handle_parsing_errors="Check your output. Make sure you're using the right Action/Action input syntax.")
+ else:
+ agent_executor = initialize_agent(tools,
+ langchain_llm,
+ agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
+ verbose=config.verbose)
+
+ agent_executor.agent.llm_chain.prompt.template = (
+ sys_prompt + ' ' + agent_executor.agent.llm_chain.prompt.template.replace(
+ "Answer the following questions as best you can.",
+ ("If the input is not a question, formulate it into a question first. "
+ "Include intermediate thought in the final answer.")).replace(
+ "Use the following format:",
+ ("Use the following format (start each response with one of the following prefixes): "
+ "[Question, Thought, Action, Action Input, Final Answer]). "
+ "If you are making an action, wait for a response to the action input before making an observation. Every response must contain at least one action (and thoughts and observations if you have them), but you cannot have both a final answer and an action in a response. Action input must only contain the exact input, do not provide any text following that in your response. Always end your response with either an action, or a final answer.")))
+
+ return agent_executor
+
+
+def build_cve_llm_engine(config: EngineConfig, handle_parsing_errors=True) -> LLMEngine:
+ engine = LLMEngine()
+
+ engine.add_node("extracter", node=ExtracterNode())
+
+ engine.add_node("checklist", inputs=["/extracter"], node=CVEChecklistNode(config=config.checklist))
+
+ engine.add_node("agent",
+ inputs=[("/checklist")],
+ node=LangChainAgentNode(agent_executor=build_agent_executor(config=config.agent,
+ handle_parsing_errors=handle_parsing_errors)))
+
+ engine.add_task_handler(
+ inputs=[("/checklist", "checklist"), ("/agent", "response")],
+ handler=SimpleTaskHandler(output_columns=["checklist", "response"]),
+ )
+
+ return engine
diff --git a/experimental/event-driven-rag-cve-analysis/cyber_dev_day/tools.py b/experimental/event-driven-rag-cve-analysis/cyber_dev_day/tools.py
new file mode 100644
index 000000000..f12442272
--- /dev/null
+++ b/experimental/event-driven-rag-cve-analysis/cyber_dev_day/tools.py
@@ -0,0 +1,191 @@
+# Copyright (c) 2023, NVIDIA CORPORATION.
+#
+# 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.
+
+import logging
+import warnings
+from textwrap import dedent
+
+from packaging.version import InvalidVersion
+from packaging.version import parse as parse_version
+
+logger = logging.getLogger(__name__)
+
+
+def range_version_comparator(software_version: str, vulnerability_lower_range: str, vulnerability_upper_range: str):
+ """
+ Compare a software's version to a range of vulnerable versions to determine vulnerability.
+
+ Parameters
+ ----------
+ software_version : str
+ The version of the software currently in use.
+ vulnerability_lower_range : str
+ The lower bound of the vulnerable version range.
+ vulnerability_upper_range : str
+ The upper bound of the vulnerable version range.
+
+ Returns
+ -------
+ bool
+ Returns True if the software version is within the range of vulnerable versions,
+ indicating potential vulnerability.
+
+ Raises
+ ------
+ InvalidVersion
+ If the version strings are not in a valid format, a warning is issued and alphabetic
+ comparison is used instead.
+
+ Notes
+ -----
+ This function assumes that the software is vulnerable if its version falls inclusively
+ between the lower and upper bounds of the vulnerability range. It uses the `parse_version`
+ function to interpret the versions and compares them accordingly. If `parse_version` fails,
+ Debian version parsing is attempted. Finally, if both of these fail, it falls
+ back to a simple string comparison.
+ """
+ try:
+ sv = parse_version(str(software_version))
+ lvv = parse_version(str(vulnerability_lower_range))
+ uvv = parse_version(str(vulnerability_upper_range))
+ return sv <= uvv and sv >= lvv
+ except InvalidVersion:
+ #Failed PEP440 versioning; moving on to Debian
+ pass
+
+ try:
+ return Dpkg.compare_versions(str(software_version),
+ str(vulnerability_lower_range)) != -1 and Dpkg.compare_versions(
+ str(software_version), str(vulnerability_upper_range)) != 1
+ except DpkgVersionError:
+ warnings.warn('Unable to parse provided versions. Using alpha sorting.', stacklevel=2)
+ # Fallback to alphabetic comparison if version parsing fails
+ return str(software_version) <= str(vulnerability_upper_range) and str(software_version) >= str(
+ vulnerability_lower_range)
+
+
+def single_version_comparator(software_version: str, vulnerability_version: str):
+ """
+ Compare a software's version to a known vulnerable version.
+
+ Parameters
+ ----------
+ software_version : str
+ The version of the software currently in use.
+ vulnerability_version : str
+ The version of the software that is known to be vulnerable.
+
+ Returns
+ -------
+ bool
+ Returns True if the software version is less than or equal to the vulnerability version,
+ indicating potential vulnerability.
+
+ Raises
+ ------
+ InvalidVersion
+ If the version strings are not in a valid format, a warning is issued and alphabetic
+ comparison is used instead.
+ """
+ try:
+ sv = parse_version(str(software_version))
+ vv = parse_version(str(vulnerability_version))
+ return sv <= vv
+ except InvalidVersion:
+ #Failed PEP440 versioning; moving on to Debian
+ pass
+ try:
+ return Dpkg.compare_versions(str(software_version), str(vulnerability_version)) != 1
+ except DpkgVersionError:
+ warnings.warn('Unable to parse provided versions. Using alpha sorting.', stacklevel=2)
+ return str(software_version) <= str(vulnerability_version)
+
+
+def version_comparison(software_version: str):
+ """
+ Compare a software's version to multiple known vulnerable versions.
+
+ Parameters
+ ----------
+ software_version : str
+ A string containing the software version to compare, and the vulnerable versions,
+ separated by commas. A single vulnerable version, a vulnerable range (two versions),
+ or multiple specific vulnerable versions can be provided.
+
+ Returns
+ -------
+ bool or str
+ Returns True if the software version matches any of the vulnerable versions,
+ or is within the vulnerable range. Returns a string message if the input doesn't
+ contain enough information for a comparison.
+
+ Notes
+ -----
+ This function can compare against a single vulnerable version, a range of versions,
+ or a list of specific versions. It uses the `single_version_comparator` for single comparisons,
+ and `range_version_comparator` for range comparisons.
+ """
+ v = software_version.split(',')
+ if len(v) == 2:
+ return single_version_comparator(v[0], v[1])
+ elif len(v) == 3:
+ return range_version_comparator(v[0], v[1], v[2])
+ elif len(v) > 3:
+ return any([v[0] == v_ for v_ in v[1:]])
+ else:
+ return "Couldn't able compare the software version, not enough input"
+
+
+class SBOMChecker:
+
+ tool_description = dedent("""
+ Useful for when you need to check the Docker container's software bill of
+ materials (SBOM) to get whether or not a given library is in the container.
+ Input should be the name of the library or software. If the package is
+ present a version number is returned, otherwise False is returned if the
+ package is not present.
+ """).replace("\n", "")
+
+ def __init__(self, sbom_map: dict[str, str]):
+
+ # Convert all keys to lowercase
+ self.sbom_map = {k.lower().strip(): v for k, v in sbom_map.items()}
+
+ def sbom_checker(self, package_name: str):
+ "use this tool to check the version of the software package from the SBOM"
+ "returns the software version if the package is present in the SBOM"
+ "if the package is not in the SBOM returns False"
+
+ num_substrings = len(package_name.split())
+
+ if num_substrings > 1:
+ return f"Could not comple action, try again. Action input must be only the package name. Input should not contain {package_name.split(maxsplit=1)[1:]} or any text after {package_name.split(maxsplit=1)[0]}"
+
+ cleaned_package = package_name.lower().strip()
+
+ return self.sbom_map.get(cleaned_package, f"The package '{cleaned_package}' was not found in the SBOM")
+
+ @staticmethod
+ def from_csv(file_path: str) -> "SBOMChecker":
+ """
+ Use this tool to load the SBOM from a CSV file returns an instance of the SBOMChecker class
+ """
+ try:
+ import pandas as pd
+ sbom = pd.read_csv(file_path)
+ sbom_map = dict(zip(sbom['package'].str.lower(), sbom['version']))
+ return SBOMChecker(sbom_map)
+ except Exception as e:
+ logger.error("Error loading SBOM from CSV file: %s. Error: %s", file_path, str(e), exc_info=True)
+ raise e
diff --git a/experimental/event-driven-rag-cve-analysis/data/morpheus_24.03-runtime_sbom.csv b/experimental/event-driven-rag-cve-analysis/data/morpheus_24.03-runtime_sbom.csv
new file mode 100644
index 000000000..b9c17f7c0
--- /dev/null
+++ b/experimental/event-driven-rag-cve-analysis/data/morpheus_24.03-runtime_sbom.csv
@@ -0,0 +1,914 @@
+package,version,license,type,cpes,origin,image_url,platform,created
+ca-certificates,20230311ubuntu0.22.04.1,GPL-2 GPL-2+ MPL-2.0,dpkg,"['cpe:2.3:a:ca-certificates:ca-certificates:20230311ubuntu0.22.04.1:*:*:*:*:*:*:*', 'cpe:2.3:a:ca-certificates:ca_certificates:20230311ubuntu0.22.04.1:*:*:*:*:*:*:*', 'cpe:2.3:a:ca_certificates:ca-certificates:20230311ubuntu0.22.04.1:*:*:*:*:*:*:*', 'cpe:2.3:a:ca_certificates:ca_certificates:20230311ubuntu0.22.04.1:*:*:*:*:*:*:*', 'cpe:2.3:a:ca:ca-certificates:20230311ubuntu0.22.04.1:*:*:*:*:*:*:*', 'cpe:2.3:a:ca:ca_certificates:20230311ubuntu0.22.04.1:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+cpp-11,11.4.0-1ubuntu1~22.04,Artistic GFDL-1.2 GPL GPL-2 GPL-3 LGPL,dpkg,"['cpe:2.3:a:cpp-11:cpp-11:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:cpp-11:cpp_11:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:cpp_11:cpp-11:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:cpp_11:cpp_11:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:cpp:cpp-11:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:cpp:cpp_11:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*']",Ubuntu Core developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+curl,7.81.0-1ubuntu1.15,BSD-3-Clause BSD-4-Clause ISC curl other public-domain,dpkg,['cpe:2.3:a:curl:curl:7.81.0-1ubuntu1.15:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+debianutils,5.5-1ubuntu2,GPL-2,dpkg,['cpe:2.3:a:debianutils:debianutils:5.5-1ubuntu2:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+exceptiongroup,1.2.0,Unknown,PYTHON,"['cpe:2.3:a:python-exceptiongroup:python-exceptiongroup:1.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-exceptiongroup:python_exceptiongroup:1.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_exceptiongroup:python-exceptiongroup:1.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_exceptiongroup:python_exceptiongroup:1.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:exceptiongroup:python-exceptiongroup:1.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:exceptiongroup:python_exceptiongroup:1.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-exceptiongroup:exceptiongroup:1.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_exceptiongroup:exceptiongroup:1.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:exceptiongroup:exceptiongroup:1.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-exceptiongroup:1.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_exceptiongroup:1.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:exceptiongroup:1.2.0:*:*:*:*:*:*:*']", >,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+filelock,3.13.1,Unknown,PYTHON,"['cpe:2.3:a:python-filelock:python-filelock:3.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-filelock:python_filelock:3.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_filelock:python-filelock:3.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_filelock:python_filelock:3.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:filelock:python-filelock:3.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:filelock:python_filelock:3.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-filelock:filelock:3.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_filelock:filelock:3.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-filelock:3.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_filelock:3.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:filelock:filelock:3.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:filelock:3.13.1:*:*:*:*:*:*:*']",Unknown,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+sphinxcontrib-jsmath,1.0.1,BSD,PYTHON,"['cpe:2.3:a:python-sphinxcontrib-jsmath:python-sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-sphinxcontrib-jsmath:python_sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_sphinxcontrib_jsmath:python-sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_sphinxcontrib_jsmath:python_sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:georg_brandl_project:python-sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:georg_brandl_project:python_sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-sphinxcontrib-jsmath:sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-sphinxcontrib-jsmath:sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-sphinxcontrib:python-sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-sphinxcontrib:python_sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_sphinxcontrib:python-sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_sphinxcontrib:python_sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_sphinxcontrib_jsmath:sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_sphinxcontrib_jsmath:sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:sphinxcontrib-jsmath:python-sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:sphinxcontrib-jsmath:python_sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:sphinxcontrib_jsmath:python-sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:sphinxcontrib_jsmath:python_sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:georg_brandlproject:python-sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:georg_brandlproject:python_sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:georg_brandl_project:sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:georg_brandl_project:sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:georg_project:python-sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:georg_project:python_sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-sphinxcontrib:sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-sphinxcontrib:sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_sphinxcontrib:sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_sphinxcontrib:sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:sphinxcontrib-jsmath:sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:sphinxcontrib-jsmath:sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:sphinxcontrib:python-sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:sphinxcontrib:python_sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:sphinxcontrib_jsmath:sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:sphinxcontrib_jsmath:sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:georg_brandl:python-sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:georg_brandl:python_sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:georg_brandlproject:sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:georg_brandlproject:sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:georgproject:python-sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:georgproject:python_sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:georg_project:sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:georg_project:sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:sphinxcontrib:sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:sphinxcontrib:sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:georg:python-sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:georg:python_sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:georg_brandl:sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:georg_brandl:sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:georgproject:sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:georgproject:sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:georg:sphinxcontrib-jsmath:1.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:georg:sphinxcontrib_jsmath:1.0.1:*:*:*:*:*:*:*']",Georg Brandl ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+gpg-wks-server,2.2.27-3ubuntu2.1,BSD-3-clause CC0-1.0 Expat GPL-3 GPL-3+ LGPL-2.1 LGPL-2.1+ LGPL-3 LGPL-3+ RFC-Reference TinySCHEME permissive,dpkg,"['cpe:2.3:a:gpg-wks-server:gpg-wks-server:2.2.27-3ubuntu2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:gpg-wks-server:gpg_wks_server:2.2.27-3ubuntu2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:gpg_wks_server:gpg-wks-server:2.2.27-3ubuntu2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:gpg_wks_server:gpg_wks_server:2.2.27-3ubuntu2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:gpg-wks:gpg-wks-server:2.2.27-3ubuntu2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:gpg-wks:gpg_wks_server:2.2.27-3ubuntu2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:gpg_wks:gpg-wks-server:2.2.27-3ubuntu2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:gpg_wks:gpg_wks_server:2.2.27-3ubuntu2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:gpg:gpg-wks-server:2.2.27-3ubuntu2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:gpg:gpg_wks_server:2.2.27-3ubuntu2.1:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+gpgv,2.2.27-3ubuntu2.1,BSD-3-clause CC0-1.0 Expat GPL-3 GPL-3+ LGPL-2.1 LGPL-2.1+ LGPL-3 LGPL-3+ RFC-Reference TinySCHEME permissive,dpkg,['cpe:2.3:a:gpgv:gpgv:2.2.27-3ubuntu2.1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+gzip,1.10-4ubuntu4.1,FSF-manpages GFDL-1.3+-no-invariant GFDL-3 GPL-3 GPL-3+,dpkg,['cpe:2.3:a:gzip:gzip:1.10-4ubuntu4.1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+init-system-helpers,1.62,BSD-3-clause GPL-2 GPL-2+,dpkg,"['cpe:2.3:a:init-system-helpers:init-system-helpers:1.62:*:*:*:*:*:*:*', 'cpe:2.3:a:init-system-helpers:init_system_helpers:1.62:*:*:*:*:*:*:*', 'cpe:2.3:a:init_system_helpers:init-system-helpers:1.62:*:*:*:*:*:*:*', 'cpe:2.3:a:init_system_helpers:init_system_helpers:1.62:*:*:*:*:*:*:*', 'cpe:2.3:a:init-system:init-system-helpers:1.62:*:*:*:*:*:*:*', 'cpe:2.3:a:init-system:init_system_helpers:1.62:*:*:*:*:*:*:*', 'cpe:2.3:a:init_system:init-system-helpers:1.62:*:*:*:*:*:*:*', 'cpe:2.3:a:init_system:init_system_helpers:1.62:*:*:*:*:*:*:*', 'cpe:2.3:a:init:init-system-helpers:1.62:*:*:*:*:*:*:*', 'cpe:2.3:a:init:init_system_helpers:1.62:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libmount1,2.37.2-4ubuntu3,BSD-2-clause BSD-3-clause BSD-4-clause GPL-2 GPL-2+ GPL-3 GPL-3+ LGPL LGPL-2 LGPL-2+ LGPL-2.1 LGPL-2.1+ LGPL-3 LGPL-3+ MIT public-domain,dpkg,['cpe:2.3:a:libmount1:libmount1:2.37.2-4ubuntu3:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+GitPython,3.1.40,BSD,PYTHON,"['cpe:2.3:a:sebastian_thiel\\,_michael_trier_project:python-GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:sebastian_thiel\\,_michael_trier_project:python_GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:sebastian_thiel\\,_michael_trierproject:python-GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:sebastian_thiel\\,_michael_trierproject:python_GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:sebastian_thiel\\,_michael_trier_project:GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:sebastian_thiel\\,_michael_trier:python-GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:sebastian_thiel\\,_michael_trier:python_GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:sebastian_thiel\\,_michael_trierproject:GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:sebastian_thiel\\,_michael_trier:GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:byronimo_project:python-GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:byronimo_project:python_GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:python-GitPython:python-GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:python-GitPython:python_GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:python_GitPython:python-GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:python_GitPython:python_GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:byronimoproject:python-GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:byronimoproject:python_GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:GitPython:python-GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:GitPython:python_GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:byronimo_project:GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:python-GitPython:GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:python_GitPython:GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:byronimo:python-GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:byronimo:python_GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:byronimoproject:GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:GitPython:GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:byronimo:GitPython:3.1.40:*:*:*:*:*:*:*', 'cpe:2.3:a:python:GitPython:3.1.40:*:*:*:*:*:*:*']","Sebastian Thiel, Michael Trier ",nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libncurses6,6.3-2ubuntu0.1,BSD-3-clause MIT/X11 X11,dpkg,['cpe:2.3:a:libncurses6:libncurses6:6.3-2ubuntu0.1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libnpth0,1.6-3build2,LGPL-2.1 LGPL-2.1+,dpkg,['cpe:2.3:a:libnpth0:libnpth0:1.6-3build2:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+gnupg2,2.2.27-3ubuntu2.1,BSD-3-clause CC0-1.0 Expat GPL-3 GPL-3+ LGPL-2.1 LGPL-2.1+ LGPL-3 LGPL-3+ RFC-Reference TinySCHEME permissive,dpkg,['cpe:2.3:a:gnupg2:gnupg2:2.2.27-3ubuntu2.1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+gpg-wks-client,2.2.27-3ubuntu2.1,BSD-3-clause CC0-1.0 Expat GPL-3 GPL-3+ LGPL-2.1 LGPL-2.1+ LGPL-3 LGPL-3+ RFC-Reference TinySCHEME permissive,dpkg,"['cpe:2.3:a:gpg-wks-client:gpg-wks-client:2.2.27-3ubuntu2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:gpg-wks-client:gpg_wks_client:2.2.27-3ubuntu2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:gpg_wks_client:gpg-wks-client:2.2.27-3ubuntu2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:gpg_wks_client:gpg_wks_client:2.2.27-3ubuntu2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:gpg-wks:gpg-wks-client:2.2.27-3ubuntu2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:gpg-wks:gpg_wks_client:2.2.27-3ubuntu2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:gpg_wks:gpg-wks-client:2.2.27-3ubuntu2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:gpg_wks:gpg_wks_client:2.2.27-3ubuntu2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:gpg:gpg-wks-client:2.2.27-3ubuntu2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:gpg:gpg_wks_client:2.2.27-3ubuntu2.1:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+filelock,3.13.1,Unknown,PYTHON,"['cpe:2.3:a:python-filelock:python-filelock:3.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-filelock:python_filelock:3.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_filelock:python-filelock:3.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_filelock:python_filelock:3.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:filelock:python-filelock:3.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:filelock:python_filelock:3.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-filelock:filelock:3.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_filelock:filelock:3.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-filelock:3.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_filelock:3.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:filelock:filelock:3.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:filelock:3.13.1:*:*:*:*:*:*:*']",Unknown,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+prometheus-client,0.19.0,Apache Software License 2.0,PYTHON,"['cpe:2.3:a:python-prometheus-client:python-prometheus-client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-prometheus-client:python_prometheus_client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_prometheus_client:python-prometheus-client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_prometheus_client:python_prometheus_client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:brian_brazil_project:python-prometheus-client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:brian_brazil_project:python_prometheus_client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:brian_brazilproject:python-prometheus-client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:brian_brazilproject:python_prometheus_client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:prometheus-client:python-prometheus-client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:prometheus-client:python_prometheus_client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:prometheus_client:python-prometheus-client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:prometheus_client:python_prometheus_client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-prometheus-client:prometheus-client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-prometheus-client:prometheus_client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-prometheus:python-prometheus-client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-prometheus:python_prometheus_client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_prometheus:python-prometheus-client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_prometheus:python_prometheus_client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_prometheus_client:prometheus-client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_prometheus_client:prometheus_client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:brian_brazil_project:prometheus-client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:brian_brazil_project:prometheus_client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:brian-brazil:python-prometheus-client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:brian-brazil:python_prometheus_client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:brian_brazil:python-prometheus-client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:brian_brazil:python_prometheus_client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:brian_brazilproject:prometheus-client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:brian_brazilproject:prometheus_client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:prometheus-client:prometheus-client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:prometheus-client:prometheus_client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:prometheus:python-prometheus-client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:prometheus:python_prometheus_client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:prometheus_client:prometheus-client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:prometheus_client:prometheus_client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-prometheus:prometheus-client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-prometheus:prometheus_client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_prometheus:prometheus-client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_prometheus:prometheus_client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-prometheus-client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_prometheus_client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:brian-brazil:prometheus-client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:brian-brazil:prometheus_client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:brian_brazil:prometheus-client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:brian_brazil:prometheus_client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:prometheus:prometheus-client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:prometheus:prometheus_client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:prometheus-client:0.19.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:prometheus_client:0.19.0:*:*:*:*:*:*:*']",Brian Brazil ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libcc1-0,12.3.0-1ubuntu1~22.04,Artistic GFDL-1.2 GPL GPL-2 GPL-3 LGPL,dpkg,"['cpe:2.3:a:libcc1-0:libcc1-0:12.3.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:libcc1-0:libcc1_0:12.3.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:libcc1_0:libcc1-0:12.3.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:libcc1_0:libcc1_0:12.3.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:libcc1:libcc1-0:12.3.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:libcc1:libcc1_0:12.3.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*']",Ubuntu Core developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+gcc,4:11.2.0-1ubuntu1,GPL-2,dpkg,['cpe:2.3:a:gcc:gcc:4\\:11.2.0-1ubuntu1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+gcc-11-base,11.4.0-1ubuntu1~22.04,Artistic GFDL-1.2 GPL GPL-2 GPL-3 LGPL,dpkg,"['cpe:2.3:a:gcc-11-base:gcc-11-base:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:gcc-11-base:gcc_11_base:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:gcc_11_base:gcc-11-base:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:gcc_11_base:gcc_11_base:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:gcc-11:gcc-11-base:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:gcc-11:gcc_11_base:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:gcc_11:gcc-11-base:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:gcc_11:gcc_11_base:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:gcc:gcc-11-base:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:gcc:gcc_11_base:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*']",Ubuntu Core developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+cffi,1.15.1,MIT,PYTHON,"['cpe:2.3:a:armin_rigo\\,_maciej_fijalkowski_project:python-cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_rigo\\,_maciej_fijalkowski_project:python_cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_rigo\\,_maciej_fijalkowskiproject:python-cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_rigo\\,_maciej_fijalkowskiproject:python_cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_rigo\\,_maciej_fijalkowski_project:cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_rigo\\,_maciej_fijalkowski:python-cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_rigo\\,_maciej_fijalkowski:python_cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_rigo\\,_maciej_fijalkowskiproject:cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_rigo\\,_maciej_fijalkowski:cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cffi_project:python-cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cffi_project:python_cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cffiproject:python-cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cffiproject:python_cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cffi_project:cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-cffi:python-cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-cffi:python_cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cffi:python-cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cffi:python_cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cffiproject:cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cffi:python-cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cffi:python_cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-cffi:cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cffi:cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:cffi:1.15.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cffi:cffi:1.15.1:*:*:*:*:*:*:*']","Armin Rigo, Maciej Fijalkowski ",nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libcufft-11-8,10.9.0.58-1,Unknown,dpkg,"['cpe:2.3:a:libcufft-11-8:libcufft-11-8:10.9.0.58-1:*:*:*:*:*:*:*', 'cpe:2.3:a:libcufft-11-8:libcufft_11_8:10.9.0.58-1:*:*:*:*:*:*:*', 'cpe:2.3:a:libcufft_11_8:libcufft-11-8:10.9.0.58-1:*:*:*:*:*:*:*', 'cpe:2.3:a:libcufft_11_8:libcufft_11_8:10.9.0.58-1:*:*:*:*:*:*:*', 'cpe:2.3:a:libcufft-11:libcufft-11-8:10.9.0.58-1:*:*:*:*:*:*:*', 'cpe:2.3:a:libcufft-11:libcufft_11_8:10.9.0.58-1:*:*:*:*:*:*:*', 'cpe:2.3:a:libcufft_11:libcufft-11-8:10.9.0.58-1:*:*:*:*:*:*:*', 'cpe:2.3:a:libcufft_11:libcufft_11_8:10.9.0.58-1:*:*:*:*:*:*:*', 'cpe:2.3:a:libcufft:libcufft-11-8:10.9.0.58-1:*:*:*:*:*:*:*', 'cpe:2.3:a:libcufft:libcufft_11_8:10.9.0.58-1:*:*:*:*:*:*:*']",cudatools (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libcrypt1,1:4.4.27-1,Unknown,dpkg,['cpe:2.3:a:libcrypt1:libcrypt1:1\\:4.4.27-1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+openssh-client,1:8.9p1-3ubuntu0.4,BSD-2-clause BSD-3-clause Expat-with-advertising-restriction Mazieres-BSD-style OpenSSH Powell-BSD-style public-domain,dpkg,"['cpe:2.3:a:openssh-client:openssh-client:1\\:8.9p1-3ubuntu0.4:*:*:*:*:*:*:*', 'cpe:2.3:a:openssh-client:openssh_client:1\\:8.9p1-3ubuntu0.4:*:*:*:*:*:*:*', 'cpe:2.3:a:openssh_client:openssh-client:1\\:8.9p1-3ubuntu0.4:*:*:*:*:*:*:*', 'cpe:2.3:a:openssh_client:openssh_client:1\\:8.9p1-3ubuntu0.4:*:*:*:*:*:*:*', 'cpe:2.3:a:openssh:openssh-client:1\\:8.9p1-3ubuntu0.4:*:*:*:*:*:*:*', 'cpe:2.3:a:openssh:openssh_client:1\\:8.9p1-3ubuntu0.4:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libdb5.3,5.3.28+dfsg1-0.8ubuntu3,Unknown,dpkg,['cpe:2.3:a:libdb5.3:libdb5.3:5.3.28\\+dfsg1-0.8ubuntu3:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+binutils,2.38-4ubuntu2.3,GFDL GPL LGPL,dpkg,['cpe:2.3:a:binutils:binutils:2.38-4ubuntu2.3:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libedit2,3.1-20210910-1build1,BSD-3-clause,dpkg,['cpe:2.3:a:libedit2:libedit2:3.1-20210910-1build1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+perl,5.34.0-3ubuntu1.3,"Artistic Artistic-2 Artistic-dist BSD-3-clause BSD-3-clause-GENERIC BSD-3-clause-with-weird-numbering BSD-4-clause-POWERDOG BZIP DONT-CHANGE-THE-GPL Expat GPL-1 GPL-1+ GPL-2 GPL-2+ GPL-3+-WITH-BISON-EXCEPTION HSIEH-BSD HSIEH-DERIVATIVE LGPL-2.1 REGCOMP REGCOMP, RRA-KEEP-THIS-NOTICE SDBM-PUBLIC-DOMAIN TEXT-TABS Unicode ZLIB",dpkg,['cpe:2.3:a:perl:perl:5.34.0-3ubuntu1.3:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+unzip,6.0-26ubuntu3.1,Unknown,dpkg,['cpe:2.3:a:unzip:unzip:6.0-26ubuntu3.1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+build-essential,12.9ubuntu3,GPL,dpkg,"['cpe:2.3:a:build-essential:build-essential:12.9ubuntu3:*:*:*:*:*:*:*', 'cpe:2.3:a:build-essential:build_essential:12.9ubuntu3:*:*:*:*:*:*:*', 'cpe:2.3:a:build_essential:build-essential:12.9ubuntu3:*:*:*:*:*:*:*', 'cpe:2.3:a:build_essential:build_essential:12.9ubuntu3:*:*:*:*:*:*:*', 'cpe:2.3:a:build:build-essential:12.9ubuntu3:*:*:*:*:*:*:*', 'cpe:2.3:a:build:build_essential:12.9ubuntu3:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+wget,1.21.2-2ubuntu1,GFDL-1.2 GPL-3,dpkg,['cpe:2.3:a:wget:wget:1.21.2-2ubuntu1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libffi8,3.4.2-4,GPL,dpkg,['cpe:2.3:a:libffi8:libffi8:3.4.2-4:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+xz-utils,5.2.5-2ubuntu1,Autoconf GPL-2 GPL-2+ GPL-3 LGPL-2 LGPL-2.1 LGPL-2.1+ PD PD-debian config-h noderivs permissive-fsf permissive-nowarranty probably-PD,dpkg,"['cpe:2.3:a:xz-utils:xz-utils:5.2.5-2ubuntu1:*:*:*:*:*:*:*', 'cpe:2.3:a:xz-utils:xz_utils:5.2.5-2ubuntu1:*:*:*:*:*:*:*', 'cpe:2.3:a:xz_utils:xz-utils:5.2.5-2ubuntu1:*:*:*:*:*:*:*', 'cpe:2.3:a:xz_utils:xz_utils:5.2.5-2ubuntu1:*:*:*:*:*:*:*', 'cpe:2.3:a:xz:xz-utils:5.2.5-2ubuntu1:*:*:*:*:*:*:*', 'cpe:2.3:a:xz:xz_utils:5.2.5-2ubuntu1:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libfido2-1,1.10.0-1,BSD-2-clause ISC public-domain,dpkg,"['cpe:2.3:a:libfido2-1:libfido2-1:1.10.0-1:*:*:*:*:*:*:*', 'cpe:2.3:a:libfido2-1:libfido2_1:1.10.0-1:*:*:*:*:*:*:*', 'cpe:2.3:a:libfido2_1:libfido2-1:1.10.0-1:*:*:*:*:*:*:*', 'cpe:2.3:a:libfido2_1:libfido2_1:1.10.0-1:*:*:*:*:*:*:*', 'cpe:2.3:a:libfido2:libfido2-1:1.10.0-1:*:*:*:*:*:*:*', 'cpe:2.3:a:libfido2:libfido2_1:1.10.0-1:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+networkx,3.2,Unknown,PYTHON,"['cpe:2.3:a:aric_hagberg_\\>,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libgmp10,2:6.2.1+dfsg-3ubuntu1,GPL GPL-2 GPL-3 LGPL-3,dpkg,['cpe:2.3:a:libgmp10:libgmp10:2\\:6.2.1\\+dfsg-3ubuntu1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+pytz,2023.3.post1,MIT,PYTHON,"['cpe:2.3:a:stuart_bishop_project:python-pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart_bishop_project:python_pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart_bishopproject:python-pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart_bishopproject:python_pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart_bishop_project:pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart_project:python-pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart_project:python_pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart_bishop:python-pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart_bishop:python_pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart_bishopproject:pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuartproject:python-pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuartproject:python_pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pytz:python-pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pytz:python_pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pytz:python-pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pytz:python_pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart_project:pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart:python-pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart:python_pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart_bishop:pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuartproject:pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pytz:pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pytz:pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:pytz:python-pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:pytz:python_pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart:pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:pytz:pytz:2023.3.post1:*:*:*:*:*:*:*']",Stuart Bishop ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+requests,2.31.0,Apache 2.0,PYTHON,"['cpe:2.3:a:kenneth_reitz_project:python-requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:kenneth_reitz_project:python_requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:kenneth_reitzproject:python-requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:kenneth_reitzproject:python_requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-requests:python-requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-requests:python_requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_requests:python-requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_requests:python_requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:kenneth_reitz_project:requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:kenneth_reitz:python-requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:kenneth_reitz:python_requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:kenneth_reitzproject:requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:me_project:python-requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:me_project:python_requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:meproject:python-requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:meproject:python_requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-requests:requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_requests:requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:requests:python-requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:requests:python_requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:kenneth_reitz:requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:me_project:requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:me:python-requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:me:python_requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:meproject:requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:requests:requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:requests:2.31.0:*:*:*:*:*:*:*', 'cpe:2.3:a:me:requests:2.31.0:*:*:*:*:*:*:*']",Kenneth Reitz ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+cudf-kafka,23.6.1,Apache 2.0,PYTHON,"['cpe:2.3:a:nvidia_corporation_project:python-cudf-kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporation_project:python_cudf_kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporationproject:python-cudf-kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporationproject:python_cudf_kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporation_project:cudf-kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporation_project:cudf_kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporation:python-cudf-kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporation:python_cudf_kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporationproject:cudf-kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporationproject:cudf_kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-cudf-kafka:python-cudf-kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-cudf-kafka:python_cudf_kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cudf_kafka:python-cudf-kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cudf_kafka:python_cudf_kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporation:cudf-kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporation:cudf_kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-cudf:python-cudf-kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-cudf:python_cudf_kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cudf:python-cudf-kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cudf:python_cudf_kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cudf-kafka:python-cudf-kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cudf-kafka:python_cudf_kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cudf_kafka:python-cudf-kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cudf_kafka:python_cudf_kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-cudf-kafka:cudf-kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-cudf-kafka:cudf_kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cudf_kafka:cudf-kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cudf_kafka:cudf_kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-cudf-kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_cudf_kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cudf:python-cudf-kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cudf:python_cudf_kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-cudf:cudf-kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-cudf:cudf_kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cudf:cudf-kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cudf:cudf_kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cudf-kafka:cudf-kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cudf-kafka:cudf_kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cudf_kafka:cudf-kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cudf_kafka:cudf_kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:cudf-kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:cudf_kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cudf:cudf-kafka:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cudf:cudf_kafka:23.6.1:*:*:*:*:*:*:*']",NVIDIA Corporation,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+confluent-kafka,1.9.2,Unknown,PYTHON,"['cpe:2.3:a:python-confluent-kafka:python-confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-confluent-kafka:python_confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_confluent_kafka:python-confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_confluent_kafka:python_confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:confluent_inc_project:python-confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:confluent_inc_project:python_confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:confluent_incproject:python-confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:confluent_incproject:python_confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-confluent:python-confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-confluent:python_confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_confluent:python-confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_confluent:python_confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:confluent-kafka:python-confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:confluent-kafka:python_confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:confluent_kafka:python-confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:confluent_kafka:python_confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-confluent-kafka:confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-confluent-kafka:confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_confluent_kafka:confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_confluent_kafka:confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:support_project:python-confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:support_project:python_confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:confluent_inc_project:confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:confluent_inc_project:confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:supportproject:python-confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:supportproject:python_confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:confluent_inc:python-confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:confluent_inc:python_confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:confluent_incproject:confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:confluent_incproject:confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:confluent:python-confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:confluent:python_confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-confluent:confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-confluent:confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_confluent:confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_confluent:confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:confluent-kafka:confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:confluent-kafka:confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:confluent_kafka:confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:confluent_kafka:confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:support_project:confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:support_project:confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:support:python-confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:support:python_confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:supportproject:confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:supportproject:confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:confluent_inc:confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:confluent_inc:confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:confluent:confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:confluent:confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:support:confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:support:confluent_kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:confluent-kafka:1.9.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:confluent_kafka:1.9.2:*:*:*:*:*:*:*']",Confluent Inc ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libasound2,1.2.6.1-1ubuntu1,LGPL-2.1 LPGL-2.1+,dpkg,['cpe:2.3:a:libasound2:libasound2:1.2.6.1-1ubuntu1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libassuan0,2.5.5-1build1,GAP GAP~FSF GPL-2 GPL-2+ GPL-3 GPL-3+ LGPL-2.1 LGPL-2.1+ LGPL-3 LGPL-3+,dpkg,['cpe:2.3:a:libassuan0:libassuan0:2.5.5-1build1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+librtmp1,2.4+20151223.gitfa8646d.1-2build4,GPL-2 LGPL-2.1,dpkg,['cpe:2.3:a:librtmp1:librtmp1:2.4\\+20151223.gitfa8646d.1-2build4:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libsasl2-2,2.1.27+dfsg2-3ubuntu1.2,BSD-2-clause BSD-2.2-clause BSD-3-clause BSD-3-clause-JANET BSD-3-clause-PADL BSD-4-clause BSD-4-clause-UC FSFULLR GPL-3 GPL-3+ IBM-as-is MIT-CMU MIT-Export MIT-OpenVision OpenLDAP OpenSSL RSA-MD SSLeay,dpkg,"['cpe:2.3:a:libsasl2-2:libsasl2-2:2.1.27\\+dfsg2-3ubuntu1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:libsasl2-2:libsasl2_2:2.1.27\\+dfsg2-3ubuntu1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:libsasl2_2:libsasl2-2:2.1.27\\+dfsg2-3ubuntu1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:libsasl2_2:libsasl2_2:2.1.27\\+dfsg2-3ubuntu1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:libsasl2:libsasl2-2:2.1.27\\+dfsg2-3ubuntu1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:libsasl2:libsasl2_2:2.1.27\\+dfsg2-3ubuntu1.2:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libaudit-common,1:3.0.7-1build1,GPL-1 GPL-2 LGPL-2.1,dpkg,"['cpe:2.3:a:libaudit-common:libaudit-common:1\\:3.0.7-1build1:*:*:*:*:*:*:*', 'cpe:2.3:a:libaudit-common:libaudit_common:1\\:3.0.7-1build1:*:*:*:*:*:*:*', 'cpe:2.3:a:libaudit_common:libaudit-common:1\\:3.0.7-1build1:*:*:*:*:*:*:*', 'cpe:2.3:a:libaudit_common:libaudit_common:1\\:3.0.7-1build1:*:*:*:*:*:*:*', 'cpe:2.3:a:libaudit:libaudit-common:1\\:3.0.7-1build1:*:*:*:*:*:*:*', 'cpe:2.3:a:libaudit:libaudit_common:1\\:3.0.7-1build1:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+click,8.1.7,BSD-3-Clause,PYTHON,"['cpe:2.3:a:python-click:python-click:8.1.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python-click:python_click:8.1.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python_click:python-click:8.1.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python_click:python_click:8.1.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-click:8.1.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_click:8.1.7:*:*:*:*:*:*:*', 'cpe:2.3:a:click:python-click:8.1.7:*:*:*:*:*:*:*', 'cpe:2.3:a:click:python_click:8.1.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python-click:click:8.1.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python_click:click:8.1.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python:click:8.1.7:*:*:*:*:*:*:*', 'cpe:2.3:a:click:click:8.1.7:*:*:*:*:*:*:*']",Unknown,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libaudit1,1:3.0.7-1build1,GPL-1 GPL-2 LGPL-2.1,dpkg,['cpe:2.3:a:libaudit1:libaudit1:1\\:3.0.7-1build1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+click,8.1.7,BSD-3-Clause,PYTHON,"['cpe:2.3:a:python-click:python-click:8.1.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python-click:python_click:8.1.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python_click:python-click:8.1.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python_click:python_click:8.1.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-click:8.1.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_click:8.1.7:*:*:*:*:*:*:*', 'cpe:2.3:a:click:python-click:8.1.7:*:*:*:*:*:*:*', 'cpe:2.3:a:click:python_click:8.1.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python-click:click:8.1.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python_click:click:8.1.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python:click:8.1.7:*:*:*:*:*:*:*', 'cpe:2.3:a:click:click:8.1.7:*:*:*:*:*:*:*']",Unknown,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libavahi-client3,0.8-5ubuntu5.2,GPL GPL-2 LGPL-2.1,dpkg,"['cpe:2.3:a:libavahi-client3:libavahi-client3:0.8-5ubuntu5.2:*:*:*:*:*:*:*', 'cpe:2.3:a:libavahi-client3:libavahi_client3:0.8-5ubuntu5.2:*:*:*:*:*:*:*', 'cpe:2.3:a:libavahi_client3:libavahi-client3:0.8-5ubuntu5.2:*:*:*:*:*:*:*', 'cpe:2.3:a:libavahi_client3:libavahi_client3:0.8-5ubuntu5.2:*:*:*:*:*:*:*', 'cpe:2.3:a:libavahi:libavahi-client3:0.8-5ubuntu5.2:*:*:*:*:*:*:*', 'cpe:2.3:a:libavahi:libavahi_client3:0.8-5ubuntu5.2:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libsemanage-common,3.3-1build2,GPL LGPL,dpkg,"['cpe:2.3:a:libsemanage-common:libsemanage-common:3.3-1build2:*:*:*:*:*:*:*', 'cpe:2.3:a:libsemanage-common:libsemanage_common:3.3-1build2:*:*:*:*:*:*:*', 'cpe:2.3:a:libsemanage_common:libsemanage-common:3.3-1build2:*:*:*:*:*:*:*', 'cpe:2.3:a:libsemanage_common:libsemanage_common:3.3-1build2:*:*:*:*:*:*:*', 'cpe:2.3:a:libsemanage:libsemanage-common:3.3-1build2:*:*:*:*:*:*:*', 'cpe:2.3:a:libsemanage:libsemanage_common:3.3-1build2:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libsemanage2,3.3-1build2,GPL LGPL,dpkg,['cpe:2.3:a:libsemanage2:libsemanage2:3.3-1build2:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libbrotli1,1.0.9-2build6,MIT,dpkg,['cpe:2.3:a:libbrotli1:libbrotli1:1.0.9-2build6:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libsqlite3-0,3.37.2-2ubuntu0.1,GPL-2 GPL-2+ public-domain,dpkg,"['cpe:2.3:a:libsqlite3-0:libsqlite3-0:3.37.2-2ubuntu0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:libsqlite3-0:libsqlite3_0:3.37.2-2ubuntu0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:libsqlite3_0:libsqlite3-0:3.37.2-2ubuntu0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:libsqlite3_0:libsqlite3_0:3.37.2-2ubuntu0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:libsqlite3:libsqlite3-0:3.37.2-2ubuntu0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:libsqlite3:libsqlite3_0:3.37.2-2ubuntu0.1:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libssh-4,0.9.6-2ubuntu0.22.04.1,BSD-2-clause BSD-3-clause LGPL-2.1 LGPL-2.1+~OpenSSL public-domain,dpkg,"['cpe:2.3:a:libssh-4:libssh-4:0.9.6-2ubuntu0.22.04.1:*:*:*:*:*:*:*', 'cpe:2.3:a:libssh-4:libssh_4:0.9.6-2ubuntu0.22.04.1:*:*:*:*:*:*:*', 'cpe:2.3:a:libssh_4:libssh-4:0.9.6-2ubuntu0.22.04.1:*:*:*:*:*:*:*', 'cpe:2.3:a:libssh_4:libssh_4:0.9.6-2ubuntu0.22.04.1:*:*:*:*:*:*:*', 'cpe:2.3:a:libssh:libssh-4:0.9.6-2ubuntu0.22.04.1:*:*:*:*:*:*:*', 'cpe:2.3:a:libssh:libssh_4:0.9.6-2ubuntu0.22.04.1:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+attrs,23.1.0,Unknown,PYTHON,"['cpe:2.3:a:hynek_schlawack_\\>,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+beautifulsoup4,4.12.2,Unknown,PYTHON,"['cpe:2.3:a:leonard_richardson_\\>,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+conda_package_streaming,0.9.0,Unknown,PYTHON,"['cpe:2.3:a:\\""anaconda\\,_inc__\\&_contributors\\""_\\>",nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+menuinst,2.0.0,"(c) 2016 Continuum Analytics, Inc. / http://continuum.io
+ 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 Continuum Analytics, Inc. 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 AND CONTRIBUTORS ""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 CONTINUUM ANALYTICS 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.
+ ",PYTHON,"['cpe:2.3:a:python-menuinst:python-menuinst:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-menuinst:python_menuinst:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_menuinst:python-menuinst:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_menuinst:python_menuinst:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:menuinst:python-menuinst:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:menuinst:python_menuinst:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-menuinst:menuinst:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_menuinst:menuinst:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-menuinst:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_menuinst:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:menuinst:menuinst:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:menuinst:2.0.0:*:*:*:*:*:*:*']",Unknown,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+pkgutil_resolve_name,1.3.10,Unknown,PYTHON,"['cpe:2.3:a:python-pkgutil-resolve-name:python-pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pkgutil-resolve-name:python-pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pkgutil-resolve-name:python_pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pkgutil_resolve_name:python-pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pkgutil_resolve_name:python-pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pkgutil_resolve_name:python_pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pkgutil_resolve_name:python-pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pkgutil_resolve_name:python-pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pkgutil_resolve_name:python_pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pkgutil-resolve:python-pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pkgutil-resolve:python-pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pkgutil-resolve:python_pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pkgutil_resolve:python-pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pkgutil_resolve:python-pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pkgutil_resolve:python_pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pkgutil_resolve:python-pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pkgutil_resolve:python-pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pkgutil_resolve:python_pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:pkgutil-resolve-name:python-pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:pkgutil-resolve-name:python-pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:pkgutil-resolve-name:python_pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:pkgutil_resolve_name:python-pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:pkgutil_resolve_name:python-pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:pkgutil_resolve_name:python_pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pkgutil-resolve-name:pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pkgutil-resolve-name:pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pkgutil_resolve_name:pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pkgutil_resolve_name:pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pkgutil_resolve_name:pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pkgutil_resolve_name:pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:vinay_sajip_project:python-pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:vinay_sajip_project:python-pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:vinay_sajip_project:python_pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:vinay_sajipproject:python-pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:vinay_sajipproject:python-pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:vinay_sajipproject:python_pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:pkgutil-resolve:python-pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:pkgutil-resolve:python-pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:pkgutil-resolve:python_pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:pkgutil_resolve:python-pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:pkgutil_resolve:python-pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:pkgutil_resolve:python_pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pkgutil-resolve:pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pkgutil-resolve:pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pkgutil_resolve:pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pkgutil_resolve:pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pkgutil_resolve:pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pkgutil_resolve:pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pkgutil:python-pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pkgutil:python-pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pkgutil:python_pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pkgutil:python-pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pkgutil:python-pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pkgutil:python_pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:pkgutil-resolve-name:pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:pkgutil-resolve-name:pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:pkgutil_resolve_name:pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:pkgutil_resolve_name:pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:vinay_sajip_project:pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:vinay_sajip_project:pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:vinay-sajip:python-pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:vinay-sajip:python-pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:vinay-sajip:python_pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:vinay_sajip:python-pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:vinay_sajip:python-pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:vinay_sajip:python_pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:vinay_sajipproject:pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:vinay_sajipproject:pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:pkgutil-resolve:pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:pkgutil-resolve:pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:pkgutil_resolve:pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:pkgutil_resolve:pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:pkgutil:python-pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:pkgutil:python-pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:pkgutil:python_pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pkgutil:pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pkgutil:pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pkgutil:pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pkgutil:pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:vinay-sajip:pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:vinay-sajip:pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:vinay_sajip:pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:vinay_sajip:pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:pkgutil:pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:pkgutil:pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python:pkgutil-resolve-name:1.3.10:*:*:*:*:*:*:*', 'cpe:2.3:a:python:pkgutil_resolve_name:1.3.10:*:*:*:*:*:*:*']",Vinay Sajip ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+pluggy,1.0.0,MIT,PYTHON,"['cpe:2.3:a:holger_krekel_project:python-pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:holger_krekel_project:python_pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:holger_krekelproject:python-pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:holger_krekelproject:python_pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:holger_krekel_project:pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:holger_project:python-pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:holger_project:python_pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:holger_krekel:python-pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:holger_krekel:python_pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:holger_krekelproject:pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:holgerproject:python-pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:holgerproject:python_pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pluggy:python-pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pluggy:python_pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pluggy:python-pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pluggy:python_pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:holger_project:pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:holger:python-pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:holger:python_pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:holger_krekel:pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:holgerproject:pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:pluggy:python-pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:pluggy:python_pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pluggy:pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pluggy:pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:holger:pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:pluggy:pluggy:1.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:pluggy:1.0.0:*:*:*:*:*:*:*']",Holger Krekel ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+matplotlib,3.8.2,PSF,PYTHON,"['cpe:2.3:a:john_d__hunter\\,_michael_droettboom_project:python-matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:john_d__hunter\\,_michael_droettboom_project:python_matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:john_d__hunter\\,_michael_droettboomproject:python-matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:john_d__hunter\\,_michael_droettboomproject:python_matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:john_d__hunter\\,_michael_droettboom_project:matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:john_d__hunter\\,_michael_droettboom:python-matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:john_d__hunter\\,_michael_droettboom:python_matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:john_d__hunter\\,_michael_droettboomproject:matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:john_d__hunter\\,_michael_droettboom:matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:matplotlib_users_project:python-matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:matplotlib_users_project:python_matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:matplotlib_usersproject:python-matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:matplotlib_usersproject:python_matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:matplotlib_users_project:matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-matplotlib:python-matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-matplotlib:python_matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_matplotlib:python-matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_matplotlib:python_matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:matplotlib-users:python-matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:matplotlib-users:python_matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:matplotlib_users:python-matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:matplotlib_users:python_matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:matplotlib_usersproject:matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:matplotlib:python-matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:matplotlib:python_matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-matplotlib:matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_matplotlib:matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:matplotlib-users:matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:matplotlib_users:matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:matplotlib:matplotlib:3.8.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:matplotlib:3.8.2:*:*:*:*:*:*:*']","John D. Hunter, Michael Droettboom ",nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+rpds-py,0.13.2,MIT,PYTHON,"['cpe:2.3:a:julian_berman_project:python-rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:julian_berman_project:python_rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:julian_bermanproject:python-rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:julian_bermanproject:python_rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:julian\\+rpds_project:python-rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:julian\\+rpds_project:python_rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:julian\\+rpdsproject:python-rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:julian\\+rpdsproject:python_rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:julian_berman_project:rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:julian_berman_project:rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-rpds-py:python-rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-rpds-py:python_rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_rpds_py:python-rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_rpds_py:python_rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:julian_berman:python-rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:julian_berman:python_rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:julian_bermanproject:rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:julian_bermanproject:rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:julian\\+rpds_project:rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:julian\\+rpds_project:rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:julian\\+rpds:python-rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:julian\\+rpds:python_rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:julian\\+rpdsproject:rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:julian\\+rpdsproject:rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-rpds:python-rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-rpds:python_rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_rpds:python-rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_rpds:python_rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-rpds-py:rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-rpds-py:rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_rpds_py:rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_rpds_py:rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:rpds-py:python-rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:rpds-py:python_rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:rpds_py:python-rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:rpds_py:python_rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:julian_berman:rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:julian_berman:rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:julian\\+rpds:rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:julian\\+rpds:rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-rpds:rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-rpds:rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_rpds:rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_rpds:rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:rpds:python-rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:rpds:python_rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:rpds-py:rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:rpds-py:rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:rpds_py:rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:rpds_py:rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:rpds_py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:rpds:rpds-py:0.13.2:*:*:*:*:*:*:*', 'cpe:2.3:a:rpds:rpds_py:0.13.2:*:*:*:*:*:*:*']",Julian Berman ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+setuptools,59.8.0,UNKNOWN,PYTHON,"['cpe:2.3:a:python_packaging_authority_project:python-setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_packaging_authority_project:python_setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_packaging_authorityproject:python-setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_packaging_authorityproject:python_setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_packaging_authority_project:setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_packaging_authority:python-setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_packaging_authority:python_setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_packaging_authorityproject:setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:distutils_sig_project:python-setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:distutils_sig_project:python_setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:distutils_sigproject:python-setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:distutils_sigproject:python_setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_packaging_authority:setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-setuptools:python-setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-setuptools:python_setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_setuptools:python-setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_setuptools:python_setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:distutils_sig_project:setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:distutils-sig:python-setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:distutils-sig:python_setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:distutils_sig:python-setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:distutils_sig:python_setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:distutils_sigproject:setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-setuptools:setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_setuptools:setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:setuptools:python-setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:setuptools:python_setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:distutils-sig:setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:distutils_sig:setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:setuptools:setuptools:59.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:setuptools:59.8.0:*:*:*:*:*:*:*']",Python Packaging Authority ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libncursesw6,6.3-2ubuntu0.1,BSD-3-clause MIT/X11 X11,dpkg,['cpe:2.3:a:libncursesw6:libncursesw6:6.3-2ubuntu0.1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libnsl-dev,1.3.0-2build2,BSD-3-clause GPL-2 GPL-2+-autoconf-exception GPL-2+-libtool-exception GPL-3 GPL-3+-autoconf-exception LGPL-2.1 LGPL-2.1+ MIT permissive-autoconf-m4 permissive-autoconf-m4-no-warranty permissive-configure permissive-fsf permissive-makefile-in,dpkg,"['cpe:2.3:a:libnsl-dev:libnsl-dev:1.3.0-2build2:*:*:*:*:*:*:*', 'cpe:2.3:a:libnsl-dev:libnsl_dev:1.3.0-2build2:*:*:*:*:*:*:*', 'cpe:2.3:a:libnsl_dev:libnsl-dev:1.3.0-2build2:*:*:*:*:*:*:*', 'cpe:2.3:a:libnsl_dev:libnsl_dev:1.3.0-2build2:*:*:*:*:*:*:*', 'cpe:2.3:a:libnsl:libnsl-dev:1.3.0-2build2:*:*:*:*:*:*:*', 'cpe:2.3:a:libnsl:libnsl_dev:1.3.0-2build2:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libnspr4,2:4.32-3build1,MPL-2.0,dpkg,['cpe:2.3:a:libnspr4:libnspr4:2\\:4.32-3build1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libonig5,6.9.7.1-2build1,BSD-2-clause GPL-2 GPL-2+,dpkg,['cpe:2.3:a:libonig5:libonig5:6.9.7.1-2build1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+cpp,4:11.2.0-1ubuntu1,GPL-2,dpkg,['cpe:2.3:a:cpp:cpp:4\\:11.2.0-1ubuntu1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libnghttp2-14,1.43.0-1ubuntu0.1,BSD-2-clause Expat GPL-3 GPL-3+ MIT SIL-OFL-1.1 all-permissive,dpkg,"['cpe:2.3:a:libnghttp2-14:libnghttp2-14:1.43.0-1ubuntu0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:libnghttp2-14:libnghttp2_14:1.43.0-1ubuntu0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:libnghttp2_14:libnghttp2-14:1.43.0-1ubuntu0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:libnghttp2_14:libnghttp2_14:1.43.0-1ubuntu0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:libnghttp2:libnghttp2-14:1.43.0-1ubuntu0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:libnghttp2:libnghttp2_14:1.43.0-1ubuntu0.1:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+cuda-toolkit-config-common,12.3.101-1,Unknown,dpkg,"['cpe:2.3:a:cuda-toolkit-config-common:cuda-toolkit-config-common:12.3.101-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda-toolkit-config-common:cuda_toolkit_config_common:12.3.101-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda_toolkit_config_common:cuda-toolkit-config-common:12.3.101-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda_toolkit_config_common:cuda_toolkit_config_common:12.3.101-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda-toolkit-config:cuda-toolkit-config-common:12.3.101-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda-toolkit-config:cuda_toolkit_config_common:12.3.101-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda_toolkit_config:cuda-toolkit-config-common:12.3.101-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda_toolkit_config:cuda_toolkit_config_common:12.3.101-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda-toolkit:cuda-toolkit-config-common:12.3.101-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda-toolkit:cuda_toolkit_config_common:12.3.101-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda_toolkit:cuda-toolkit-config-common:12.3.101-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda_toolkit:cuda_toolkit_config_common:12.3.101-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda:cuda-toolkit-config-common:12.3.101-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda:cuda_toolkit_config_common:12.3.101-1:*:*:*:*:*:*:*']",cudatools (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+debconf,1.5.79ubuntu1,BSD-2-clause,dpkg,['cpe:2.3:a:debconf:debconf:1.5.79ubuntu1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+cuda-cudart-11-8,11.8.89-1,Unknown,dpkg,"['cpe:2.3:a:cuda-cudart-11-8:cuda-cudart-11-8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda-cudart-11-8:cuda_cudart_11_8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda_cudart_11_8:cuda-cudart-11-8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda_cudart_11_8:cuda_cudart_11_8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda-cudart-11:cuda-cudart-11-8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda-cudart-11:cuda_cudart_11_8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda_cudart_11:cuda-cudart-11-8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda_cudart_11:cuda_cudart_11_8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda-cudart:cuda-cudart-11-8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda-cudart:cuda_cudart_11_8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda_cudart:cuda-cudart-11-8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda_cudart:cuda_cudart_11_8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda:cuda-cudart-11-8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda:cuda_cudart_11_8:11.8.89-1:*:*:*:*:*:*:*']",cudatools (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+sqlparse,0.4.4,Unknown,PYTHON,"['cpe:2.3:a:andi_albrecht_\\>,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+dpkg,1.21.1ubuntu2.2,BSD-2-clause GPL-2 GPL-2+ public-domain-md5 public-domain-s-s-d,dpkg,['cpe:2.3:a:dpkg:dpkg:1.21.1ubuntu2.2:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+pyarrow-hotfix,0.6,"Apache License, Version 2.0",PYTHON,"['cpe:2.3:a:antoine_pitrou_\\>,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+gnupg,2.2.27-3ubuntu2.1,BSD-3-clause CC0-1.0 Expat GPL-3 GPL-3+ LGPL-2.1 LGPL-2.1+ LGPL-3 LGPL-3+ RFC-Reference TinySCHEME permissive,dpkg,['cpe:2.3:a:gnupg:gnupg:2.2.27-3ubuntu2.1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+sphinxcontrib-qthelp,1.0.6,Unknown,PYTHON,"['cpe:2.3:a:georg_brandl_\\>,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libcurl4,7.81.0-1ubuntu1.15,BSD-3-Clause BSD-4-Clause ISC curl other public-domain,dpkg,['cpe:2.3:a:libcurl4:libcurl4:7.81.0-1ubuntu1.15:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+sphinxcontrib-serializinghtml,1.1.9,Unknown,PYTHON,"['cpe:2.3:a:python-sphinxcontrib-serializinghtml:python-sphinxcontrib-serializinghtml:1.1.9:*:*:*:*:*:*:*', 'cpe:2.3:a:python-sphinxcontrib-serializinghtml:python_sphinxcontrib_serializinghtml:1.1.9:*:*:*:*:*:*:*', 'cpe:2.3:a:python_sphinxcontrib_serializinghtml:python-sphinxcontrib-serializinghtml:1.1.9:*:*:*:*:*:*:*', 'cpe:2.3:a:python_sphinxcontrib_serializinghtml:python_sphinxcontrib_serializinghtml:1.1.9:*:*:*:*:*:*:*', 'cpe:2.3:a:python-sphinxcontrib-serializinghtml:sphinxcontrib-serializinghtml:1.1.9:*:*:*:*:*:*:*', 'cpe:2.3:a:python-sphinxcontrib-serializinghtml:sphinxcontrib_serializinghtml:1.1.9:*:*:*:*:*:*:*', 'cpe:2.3:a:python_sphinxcontrib_serializinghtml:sphinxcontrib-serializinghtml:1.1.9:*:*:*:*:*:*:*', 'cpe:2.3:a:python_sphinxcontrib_serializinghtml:sphinxcontrib_serializinghtml:1.1.9:*:*:*:*:*:*:*', 'cpe:2.3:a:sphinxcontrib-serializinghtml:python-sphinxcontrib-serializinghtml:1.1.9:*:*:*:*:*:*:*', 'cpe:2.3:a:sphinxcontrib-serializinghtml:python_sphinxcontrib_serializinghtml:1.1.9:*:*:*:*:*:*:*', 'cpe:2.3:a:sphinxcontrib_serializinghtml:python-sphinxcontrib-serializinghtml:1.1.9:*:*:*:*:*:*:*', 'cpe:2.3:a:sphinxcontrib_serializinghtml:python_sphinxcontrib_serializinghtml:1.1.9:*:*:*:*:*:*:*', 'cpe:2.3:a:georg_brandl_\\>,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+cattrs,23.2.3,MIT,PYTHON,"['cpe:2.3:a:tin_tvrtkovic_\\>,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+certifi,2023.11.17,MPL-2.0,PYTHON,"['cpe:2.3:a:kenneth_reitz_project:python-certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:kenneth_reitz_project:python_certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:kenneth_reitzproject:python-certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:kenneth_reitzproject:python_certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:kenneth_reitz_project:certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:python-certifi:python-certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:python-certifi:python_certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:python_certifi:python-certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:python_certifi:python_certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:kenneth_reitz:python-certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:kenneth_reitz:python_certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:kenneth_reitzproject:certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:me_project:python-certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:me_project:python_certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:meproject:python-certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:meproject:python_certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:certifi:python-certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:certifi:python_certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:python-certifi:certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:python_certifi:certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:kenneth_reitz:certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:me_project:certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:me:python-certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:me:python_certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:meproject:certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:certifi:certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:python:certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:me:certifi:2023.11.17:*:*:*:*:*:*:*']",Kenneth Reitz ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+gcc-12-base,12.3.0-1ubuntu1~22.04,Artistic GFDL-1.2 GPL GPL-2 GPL-3 LGPL,dpkg,"['cpe:2.3:a:gcc-12-base:gcc-12-base:12.3.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:gcc-12-base:gcc_12_base:12.3.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:gcc_12_base:gcc-12-base:12.3.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:gcc_12_base:gcc_12_base:12.3.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:gcc-12:gcc-12-base:12.3.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:gcc-12:gcc_12_base:12.3.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:gcc_12:gcc-12-base:12.3.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:gcc_12:gcc_12_base:12.3.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:gcc:gcc-12-base:12.3.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:gcc:gcc_12_base:12.3.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*']",Ubuntu Core developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+chardet,5.2.0,LGPL,PYTHON,"['cpe:2.3:a:mark_pilgrim_project:python-chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mark_pilgrim_project:python_chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mark_pilgrimproject:python-chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mark_pilgrimproject:python_chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-chardet:python-chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-chardet:python_chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_chardet:python-chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_chardet:python_chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mark_pilgrim_project:chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mark_pilgrim:python-chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mark_pilgrim:python_chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mark_pilgrimproject:chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mark_project:python-chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mark_project:python_chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:markproject:python-chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:markproject:python_chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:chardet:python-chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:chardet:python_chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-chardet:chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_chardet:chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mark_pilgrim:chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mark_project:chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mark:python-chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mark:python_chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:markproject:chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:chardet:chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:chardet:5.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mark:chardet:5.2.0:*:*:*:*:*:*:*']",Mark Pilgrim ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+bash,5.1-6ubuntu1,GPL-3,dpkg,['cpe:2.3:a:bash:bash:5.1-6ubuntu1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+passwd,1:4.8.1-2ubuntu2.1,GPL-2,dpkg,['cpe:2.3:a:passwd:passwd:1\\:4.8.1-2ubuntu2.1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+usrmerge,25ubuntu2,GPL GPL-2,dpkg,['cpe:2.3:a:usrmerge:usrmerge:25ubuntu2:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libexpat1,2.4.7-1ubuntu0.2,MIT,dpkg,['cpe:2.3:a:libexpat1:libexpat1:2.4.7-1ubuntu0.2:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+zip,3.0-12build2,Unknown,dpkg,['cpe:2.3:a:zip:zip:3.0-12build2:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+cuda-driver-dev-11-8,11.8.89-1,Unknown,dpkg,"['cpe:2.3:a:cuda-driver-dev-11-8:cuda-driver-dev-11-8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda-driver-dev-11-8:cuda_driver_dev_11_8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda_driver_dev_11_8:cuda-driver-dev-11-8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda_driver_dev_11_8:cuda_driver_dev_11_8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda-driver-dev-11:cuda-driver-dev-11-8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda-driver-dev-11:cuda_driver_dev_11_8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda_driver_dev_11:cuda-driver-dev-11-8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda_driver_dev_11:cuda_driver_dev_11_8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda-driver-dev:cuda-driver-dev-11-8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda-driver-dev:cuda_driver_dev_11_8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda_driver_dev:cuda-driver-dev-11-8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda_driver_dev:cuda_driver_dev_11_8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda-driver:cuda-driver-dev-11-8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda-driver:cuda_driver_dev_11_8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda_driver:cuda-driver-dev-11-8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda_driver:cuda_driver_dev_11_8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda:cuda-driver-dev-11-8:11.8.89-1:*:*:*:*:*:*:*', 'cpe:2.3:a:cuda:cuda_driver_dev_11_8:11.8.89-1:*:*:*:*:*:*:*']",cudatools (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+liblz4-1,1.9.3-2build2,BSD-2-clause GPL-2 GPL-2+,dpkg,"['cpe:2.3:a:liblz4-1:liblz4-1:1.9.3-2build2:*:*:*:*:*:*:*', 'cpe:2.3:a:liblz4-1:liblz4_1:1.9.3-2build2:*:*:*:*:*:*:*', 'cpe:2.3:a:liblz4_1:liblz4-1:1.9.3-2build2:*:*:*:*:*:*:*', 'cpe:2.3:a:liblz4_1:liblz4_1:1.9.3-2build2:*:*:*:*:*:*:*', 'cpe:2.3:a:liblz4:liblz4-1:1.9.3-2build2:*:*:*:*:*:*:*', 'cpe:2.3:a:liblz4:liblz4_1:1.9.3-2build2:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libapt-pkg6.0,2.4.11,GPL-2 GPLv2+,dpkg,"['cpe:2.3:a:libapt-pkg6.0:libapt-pkg6.0:2.4.11:*:*:*:*:*:*:*', 'cpe:2.3:a:libapt-pkg6.0:libapt_pkg6.0:2.4.11:*:*:*:*:*:*:*', 'cpe:2.3:a:libapt_pkg6.0:libapt-pkg6.0:2.4.11:*:*:*:*:*:*:*', 'cpe:2.3:a:libapt_pkg6.0:libapt_pkg6.0:2.4.11:*:*:*:*:*:*:*', 'cpe:2.3:a:libapt:libapt-pkg6.0:2.4.11:*:*:*:*:*:*:*', 'cpe:2.3:a:libapt:libapt_pkg6.0:2.4.11:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+grep,3.7-1build1,GPL-3 GPL-3+,dpkg,['cpe:2.3:a:grep:grep:3.7-1build1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libmd0,1.0.4-1build1,BSD-2-clause BSD-2-clause-NetBSD BSD-3-clause BSD-3-clause-Aaron-D-Gifford Beerware ISC public-domain-md4 public-domain-md5 public-domain-sha1,dpkg,['cpe:2.3:a:libmd0:libmd0:1.0.4-1build1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+ConfigArgParse,1.5.5,MIT,PYTHON,"['cpe:2.3:a:python-ConfigArgParse:python-ConfigArgParse:1.5.5:*:*:*:*:*:*:*', 'cpe:2.3:a:python-ConfigArgParse:python_ConfigArgParse:1.5.5:*:*:*:*:*:*:*', 'cpe:2.3:a:python_ConfigArgParse:python-ConfigArgParse:1.5.5:*:*:*:*:*:*:*', 'cpe:2.3:a:python_ConfigArgParse:python_ConfigArgParse:1.5.5:*:*:*:*:*:*:*', 'cpe:2.3:a:ConfigArgParse:python-ConfigArgParse:1.5.5:*:*:*:*:*:*:*', 'cpe:2.3:a:ConfigArgParse:python_ConfigArgParse:1.5.5:*:*:*:*:*:*:*', 'cpe:2.3:a:python-ConfigArgParse:ConfigArgParse:1.5.5:*:*:*:*:*:*:*', 'cpe:2.3:a:python_ConfigArgParse:ConfigArgParse:1.5.5:*:*:*:*:*:*:*', 'cpe:2.3:a:ConfigArgParse:ConfigArgParse:1.5.5:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-ConfigArgParse:1.5.5:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_ConfigArgParse:1.5.5:*:*:*:*:*:*:*', 'cpe:2.3:a:python:ConfigArgParse:1.5.5:*:*:*:*:*:*:*']",Unknown,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+sphinxcontrib-devhelp,1.0.5,Unknown,PYTHON,"['cpe:2.3:a:python-sphinxcontrib-devhelp:python-sphinxcontrib-devhelp:1.0.5:*:*:*:*:*:*:*', 'cpe:2.3:a:python-sphinxcontrib-devhelp:python_sphinxcontrib_devhelp:1.0.5:*:*:*:*:*:*:*', 'cpe:2.3:a:python_sphinxcontrib_devhelp:python-sphinxcontrib-devhelp:1.0.5:*:*:*:*:*:*:*', 'cpe:2.3:a:python_sphinxcontrib_devhelp:python_sphinxcontrib_devhelp:1.0.5:*:*:*:*:*:*:*', 'cpe:2.3:a:georg_brandl_\\>,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+sphinxcontrib-applehelp,1.0.7,Unknown,PYTHON,"['cpe:2.3:a:python-sphinxcontrib-applehelp:python-sphinxcontrib-applehelp:1.0.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python-sphinxcontrib-applehelp:python_sphinxcontrib_applehelp:1.0.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python_sphinxcontrib_applehelp:python-sphinxcontrib-applehelp:1.0.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python_sphinxcontrib_applehelp:python_sphinxcontrib_applehelp:1.0.7:*:*:*:*:*:*:*', 'cpe:2.3:a:georg_brandl_\\>,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+betterproto,1.2.5,MIT,PYTHON,"['cpe:2.3:a:daniel_g__taylor_project:python-betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:daniel_g__taylor_project:python_betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:daniel_g__taylorproject:python-betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:daniel_g__taylorproject:python_betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:danielgtaylor_project:python-betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:danielgtaylor_project:python_betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:danielgtaylorproject:python-betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:danielgtaylorproject:python_betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:python-betterproto:python-betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:python-betterproto:python_betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:python_betterproto:python-betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:python_betterproto:python_betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:daniel_g__taylor_project:betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:daniel_g__taylor:python-betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:daniel_g__taylor:python_betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:daniel_g__taylorproject:betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:danielgtaylor_project:betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:danielgtaylor:python-betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:danielgtaylor:python_betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:danielgtaylorproject:betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:betterproto:python-betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:betterproto:python_betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:python-betterproto:betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:python_betterproto:betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:daniel_g__taylor:betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:danielgtaylor:betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:betterproto:betterproto:1.2.5:*:*:*:*:*:*:*', 'cpe:2.3:a:python:betterproto:1.2.5:*:*:*:*:*:*:*']",Daniel G. Taylor ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+Jinja2,3.1.2,BSD-3-Clause,PYTHON,"['cpe:2.3:a:armin_ronacher_project:python-Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_ronacher_project:python_Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_ronacherproject:python-Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_ronacherproject:python_Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_ronacher_project:Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:armin-ronacher:python-Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:armin-ronacher:python_Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_ronacher:python-Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_ronacher:python_Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_ronacherproject:Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-Jinja2:python-Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-Jinja2:python_Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_Jinja2:python-Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_Jinja2:python_Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:armin-ronacher:Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_ronacher:Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:Jinja2:python-Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:Jinja2:python_Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-Jinja2:Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_Jinja2:Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:Jinja2:Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:Jinja2:3.1.2:*:*:*:*:*:*:*']",Armin Ronacher ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+gunicorn,21.2.0,MIT,PYTHON,"['cpe:2.3:a:benoit_chesneau_project:python-gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:benoit_chesneau_project:python_gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:benoit_chesneauproject:python-gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:benoit_chesneauproject:python_gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:benoit_chesneau_project:gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:benoit_chesneau:python-gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:benoit_chesneau:python_gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:benoit_chesneauproject:gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:benoitc_project:python-gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:benoitc_project:python_gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-gunicorn:python-gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-gunicorn:python_gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_gunicorn:python-gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_gunicorn:python_gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:benoitcproject:python-gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:benoitcproject:python_gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:benoit_chesneau:gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:benoitc_project:gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:gunicorn:python-gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:gunicorn:python_gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-gunicorn:gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_gunicorn:gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:benoitc:python-gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:benoitc:python_gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:benoitcproject:gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:gunicorn:gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:benoitc:gunicorn:21.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:gunicorn:21.2.0:*:*:*:*:*:*:*']",Benoit Chesneau ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+bokeh,2.4.3,BSD-3-Clause,PYTHON,"['cpe:2.3:a:bokeh_team_project:python-bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:bokeh_team_project:python_bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:bokeh_teamproject:python-bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:bokeh_teamproject:python_bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:info_project:python-bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:info_project:python_bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:python-bokeh:python-bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:python-bokeh:python_bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:python_bokeh:python-bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:python_bokeh:python_bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:bokeh_team_project:bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:infoproject:python-bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:infoproject:python_bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:bokeh_team:python-bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:bokeh_team:python_bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:bokeh_teamproject:bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:bokeh:python-bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:bokeh:python_bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:info_project:bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:python-bokeh:bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:python_bokeh:bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:info:python-bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:info:python_bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:infoproject:bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:bokeh_team:bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:python:bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:bokeh:bokeh:2.4.3:*:*:*:*:*:*:*', 'cpe:2.3:a:info:bokeh:2.4.3:*:*:*:*:*:*:*']",Bokeh Team ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+hpack,4.0.0,MIT License,PYTHON,"['cpe:2.3:a:cory_benfield_project:python-hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:cory_benfield_project:python_hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:cory_benfieldproject:python-hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:cory_benfieldproject:python_hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:cory_benfield_project:hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:cory_benfield:python-hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:cory_benfield:python_hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:cory_benfieldproject:hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:cory_project:python-hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:cory_project:python_hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-hpack:python-hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-hpack:python_hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_hpack:python-hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_hpack:python_hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:coryproject:python-hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:coryproject:python_hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:cory_benfield:hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:cory_project:hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:hpack:python-hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:hpack:python_hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-hpack:hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_hpack:hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:cory:python-hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:cory:python_hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:coryproject:hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:hpack:hpack:4.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:cory:hpack:4.0.0:*:*:*:*:*:*:*']",Cory Benfield ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+PyYAML,6.0.1,MIT,PYTHON,"['cpe:2.3:a:kirill_simonov_project:python-PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:kirill_simonov_project:python_PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:kirill_simonovproject:python-PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:kirill_simonovproject:python_PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:kirill_simonov_project:PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:kirill_simonov:python-PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:kirill_simonov:python_PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:kirill_simonovproject:PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-PyYAML:python-PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-PyYAML:python_PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_PyYAML:python-PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_PyYAML:python_PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:xi_project:python-PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:xi_project:python_PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:xiproject:python-PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:xiproject:python_PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:kirill_simonov:PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:PyYAML:python-PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:PyYAML:python_PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-PyYAML:PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_PyYAML:PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:xi_project:PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:xi:python-PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:xi:python_PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:xiproject:PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:PyYAML:PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:PyYAML:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:xi:PyYAML:6.0.1:*:*:*:*:*:*:*']",Kirill Simonov ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+hyperframe,6.0.1,MIT License,PYTHON,"['cpe:2.3:a:cory_benfield_project:python-hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cory_benfield_project:python_hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cory_benfieldproject:python-hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cory_benfieldproject:python_hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-hyperframe:python-hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-hyperframe:python_hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_hyperframe:python-hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_hyperframe:python_hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cory_benfield_project:hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cory_benfield:python-hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cory_benfield:python_hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cory_benfieldproject:hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cory_project:python-hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cory_project:python_hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:coryproject:python-hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:coryproject:python_hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:hyperframe:python-hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:hyperframe:python_hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-hyperframe:hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_hyperframe:hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cory_benfield:hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cory_project:hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cory:python-hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cory:python_hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:coryproject:hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:hyperframe:hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:hyperframe:6.0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cory:hyperframe:6.0.1:*:*:*:*:*:*:*']",Cory Benfield ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+unicodedata2,15.1.0,Apache License 2.0,PYTHON,"['cpe:2.3:a:mike_kaplinskiy_project:python-unicodedata2:15.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_kaplinskiy_project:python_unicodedata2:15.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_kaplinskiyproject:python-unicodedata2:15.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_kaplinskiyproject:python_unicodedata2:15.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-unicodedata2:python-unicodedata2:15.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-unicodedata2:python_unicodedata2:15.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_unicodedata2:python-unicodedata2:15.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_unicodedata2:python_unicodedata2:15.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_kaplinskiy_project:unicodedata2:15.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mike-kaplinskiy:python-unicodedata2:15.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mike-kaplinskiy:python_unicodedata2:15.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_kaplinskiy:python-unicodedata2:15.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_kaplinskiy:python_unicodedata2:15.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_kaplinskiyproject:unicodedata2:15.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-unicodedata2:unicodedata2:15.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_unicodedata2:unicodedata2:15.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:unicodedata2:python-unicodedata2:15.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:unicodedata2:python_unicodedata2:15.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mike-kaplinskiy:unicodedata2:15.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_kaplinskiy:unicodedata2:15.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-unicodedata2:15.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_unicodedata2:15.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:unicodedata2:unicodedata2:15.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:unicodedata2:15.1.0:*:*:*:*:*:*:*']",Mike Kaplinskiy ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+cytoolz,0.12.2,BSD,PYTHON,"['cpe:2.3:a:https\\:\\/\\/raw_github_com\\/pytoolz\\/cytoolz\\/master\\/authors_md_project:python-cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:https\\:\\/\\/raw_github_com\\/pytoolz\\/cytoolz\\/master\\/authors_md_project:python_cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:https\\:\\/\\/raw_github_com\\/pytoolz\\/cytoolz\\/master\\/authors_mdproject:python-cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:https\\:\\/\\/raw_github_com\\/pytoolz\\/cytoolz\\/master\\/authors_mdproject:python_cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:https\\:\\/\\/raw_github_com\\/pytoolz\\/cytoolz\\/master\\/authors_md_project:cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:https\\:\\/\\/raw_github_com\\/pytoolz\\/cytoolz\\/master\\/authors_md:python-cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:https\\:\\/\\/raw_github_com\\/pytoolz\\/cytoolz\\/master\\/authors_md:python_cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:https\\:\\/\\/raw_github_com\\/pytoolz\\/cytoolz\\/master\\/authors_mdproject:cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:https\\:\\/\\/raw_github_com\\/pytoolz\\/cytoolz\\/master\\/authors_md:cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:erik_n_welch_project:python-cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:erik_n_welch_project:python_cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:erik_n_welchproject:python-cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:erik_n_welchproject:python_cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-cytoolz:python-cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-cytoolz:python_cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cytoolz:python-cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cytoolz:python_cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:erik_n_welch_project:cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:erik-n-welch:python-cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:erik-n-welch:python_cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:erik_n_welch:python-cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:erik_n_welch:python_cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:erik_n_welchproject:cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:cytoolz:python-cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:cytoolz:python_cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-cytoolz:cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cytoolz:cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:erik-n-welch:cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:erik_n_welch:cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:cytoolz:cytoolz:0.12.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:cytoolz:0.12.2:*:*:*:*:*:*:*']",https://raw.github.com/pytoolz/cytoolz/master/AUTHORS.md ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+diffutils,1:3.8-0ubuntu2,GFDL GPL,dpkg,['cpe:2.3:a:diffutils:diffutils:1\\:3.8-0ubuntu2:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+exceptiongroup,1.2.0,Unknown,PYTHON,"['cpe:2.3:a:python-exceptiongroup:python-exceptiongroup:1.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-exceptiongroup:python_exceptiongroup:1.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_exceptiongroup:python-exceptiongroup:1.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_exceptiongroup:python_exceptiongroup:1.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:exceptiongroup:python-exceptiongroup:1.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:exceptiongroup:python_exceptiongroup:1.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-exceptiongroup:exceptiongroup:1.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_exceptiongroup:exceptiongroup:1.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:exceptiongroup:exceptiongroup:1.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-exceptiongroup:1.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_exceptiongroup:1.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:exceptiongroup:1.2.0:*:*:*:*:*:*:*']", >,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+fonttools,4.46.0,MIT,PYTHON,"['cpe:2.3:a:just_van_rossum_project:python-fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:just_van_rossum_project:python_fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:just_van_rossumproject:python-fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:just_van_rossumproject:python_fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:just_van_rossum_project:fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-fonttools:python-fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-fonttools:python_fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_fonttools:python-fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_fonttools:python_fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:just_van_rossum:python-fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:just_van_rossum:python_fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:just_van_rossumproject:fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:just_project:python-fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:just_project:python_fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:justproject:python-fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:justproject:python_fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:fonttools:python-fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:fonttools:python_fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-fonttools:fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_fonttools:fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:just_van_rossum:fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:just_project:fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:just:python-fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:just:python_fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:justproject:fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:fonttools:fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:fonttools:4.46.0:*:*:*:*:*:*:*', 'cpe:2.3:a:just:fonttools:4.46.0:*:*:*:*:*:*:*']",Just van Rossum ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+dpkg-dev,1.21.1ubuntu2.2,BSD-2-clause GPL-2 GPL-2+ public-domain-md5 public-domain-s-s-d,dpkg,"['cpe:2.3:a:dpkg-dev:dpkg-dev:1.21.1ubuntu2.2:*:*:*:*:*:*:*', 'cpe:2.3:a:dpkg-dev:dpkg_dev:1.21.1ubuntu2.2:*:*:*:*:*:*:*', 'cpe:2.3:a:dpkg_dev:dpkg-dev:1.21.1ubuntu2.2:*:*:*:*:*:*:*', 'cpe:2.3:a:dpkg_dev:dpkg_dev:1.21.1ubuntu2.2:*:*:*:*:*:*:*', 'cpe:2.3:a:dpkg:dpkg-dev:1.21.1ubuntu2.2:*:*:*:*:*:*:*', 'cpe:2.3:a:dpkg:dpkg_dev:1.21.1ubuntu2.2:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+fontconfig-config,2.13.1-4.2ubuntu5,Unknown,dpkg,"['cpe:2.3:a:fontconfig-config:fontconfig-config:2.13.1-4.2ubuntu5:*:*:*:*:*:*:*', 'cpe:2.3:a:fontconfig-config:fontconfig_config:2.13.1-4.2ubuntu5:*:*:*:*:*:*:*', 'cpe:2.3:a:fontconfig_config:fontconfig-config:2.13.1-4.2ubuntu5:*:*:*:*:*:*:*', 'cpe:2.3:a:fontconfig_config:fontconfig_config:2.13.1-4.2ubuntu5:*:*:*:*:*:*:*', 'cpe:2.3:a:fontconfig:fontconfig-config:2.13.1-4.2ubuntu5:*:*:*:*:*:*:*', 'cpe:2.3:a:fontconfig:fontconfig_config:2.13.1-4.2ubuntu5:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+g++-11,11.4.0-1ubuntu1~22.04,Artistic GFDL-1.2 GPL GPL-2 GPL-3 LGPL,dpkg,"['cpe:2.3:a:g\\+\\+-11:g\\+\\+-11:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:g\\+\\+-11:g\\+\\+_11:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:g\\+\\+_11:g\\+\\+-11:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:g\\+\\+_11:g\\+\\+_11:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:g\\+\\+:g\\+\\+-11:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:g\\+\\+:g\\+\\+_11:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*']",Ubuntu Core developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+gcc-11,11.4.0-1ubuntu1~22.04,Artistic GFDL-1.2 GPL GPL-2 GPL-3 LGPL,dpkg,"['cpe:2.3:a:gcc-11:gcc-11:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:gcc-11:gcc_11:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:gcc_11:gcc-11:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:gcc_11:gcc_11:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:gcc:gcc-11:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:gcc:gcc_11:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*']",Ubuntu Core developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+certifi,2023.11.17,MPL-2.0,PYTHON,"['cpe:2.3:a:kenneth_reitz_project:python-certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:kenneth_reitz_project:python_certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:kenneth_reitzproject:python-certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:kenneth_reitzproject:python_certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:kenneth_reitz_project:certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:python-certifi:python-certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:python-certifi:python_certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:python_certifi:python-certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:python_certifi:python_certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:kenneth_reitz:python-certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:kenneth_reitz:python_certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:kenneth_reitzproject:certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:me_project:python-certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:me_project:python_certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:meproject:python-certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:meproject:python_certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:certifi:python-certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:certifi:python_certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:python-certifi:certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:python_certifi:certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:kenneth_reitz:certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:me_project:certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:me:python-certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:me:python_certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:meproject:certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:certifi:certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:python:certifi:2023.11.17:*:*:*:*:*:*:*', 'cpe:2.3:a:me:certifi:2023.11.17:*:*:*:*:*:*:*']",Kenneth Reitz ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+cffi,1.16.0,MIT,PYTHON,"['cpe:2.3:a:armin_rigo\\,_maciej_fijalkowski_project:python-cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_rigo\\,_maciej_fijalkowski_project:python_cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_rigo\\,_maciej_fijalkowskiproject:python-cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_rigo\\,_maciej_fijalkowskiproject:python_cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_rigo\\,_maciej_fijalkowski_project:cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_rigo\\,_maciej_fijalkowski:python-cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_rigo\\,_maciej_fijalkowski:python_cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_rigo\\,_maciej_fijalkowskiproject:cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_rigo\\,_maciej_fijalkowski:cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cffi_project:python-cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cffi_project:python_cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cffiproject:python-cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cffiproject:python_cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cffi_project:cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-cffi:python-cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-cffi:python_cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cffi:python-cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cffi:python_cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cffiproject:cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:cffi:python-cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:cffi:python_cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-cffi:cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cffi:cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:cffi:1.16.0:*:*:*:*:*:*:*', 'cpe:2.3:a:cffi:cffi:1.16.0:*:*:*:*:*:*:*']","Armin Rigo, Maciej Fijalkowski ",nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+ncurses-bin,6.3-2ubuntu0.1,BSD-3-clause MIT/X11 X11,dpkg,"['cpe:2.3:a:ncurses-bin:ncurses-bin:6.3-2ubuntu0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:ncurses-bin:ncurses_bin:6.3-2ubuntu0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:ncurses_bin:ncurses-bin:6.3-2ubuntu0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:ncurses_bin:ncurses_bin:6.3-2ubuntu0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:ncurses:ncurses-bin:6.3-2ubuntu0.1:*:*:*:*:*:*:*', 'cpe:2.3:a:ncurses:ncurses_bin:6.3-2ubuntu0.1:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+base-files,12ubuntu4.4,GPL,dpkg,"['cpe:2.3:a:base-files:base-files:12ubuntu4.4:*:*:*:*:*:*:*', 'cpe:2.3:a:base-files:base_files:12ubuntu4.4:*:*:*:*:*:*:*', 'cpe:2.3:a:base_files:base-files:12ubuntu4.4:*:*:*:*:*:*:*', 'cpe:2.3:a:base_files:base_files:12ubuntu4.4:*:*:*:*:*:*:*', 'cpe:2.3:a:base:base-files:12ubuntu4.4:*:*:*:*:*:*:*', 'cpe:2.3:a:base:base_files:12ubuntu4.4:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libgomp1,12.3.0-1ubuntu1~22.04,Artistic GFDL-1.2 GPL GPL-2 GPL-3 LGPL,dpkg,['cpe:2.3:a:libgomp1:libgomp1:12.3.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*'],Ubuntu Core developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+perl-base,5.34.0-3ubuntu1.3,"Artistic Artistic-2 Artistic-dist BSD-3-clause BSD-3-clause-GENERIC BSD-3-clause-with-weird-numbering BSD-4-clause-POWERDOG BZIP DONT-CHANGE-THE-GPL Expat GPL-1 GPL-1+ GPL-2 GPL-2+ GPL-3+-WITH-BISON-EXCEPTION HSIEH-BSD HSIEH-DERIVATIVE LGPL-2.1 REGCOMP REGCOMP, RRA-KEEP-THIS-NOTICE SDBM-PUBLIC-DOMAIN TEXT-TABS Unicode ZLIB",dpkg,"['cpe:2.3:a:perl-base:perl-base:5.34.0-3ubuntu1.3:*:*:*:*:*:*:*', 'cpe:2.3:a:perl-base:perl_base:5.34.0-3ubuntu1.3:*:*:*:*:*:*:*', 'cpe:2.3:a:perl_base:perl-base:5.34.0-3ubuntu1.3:*:*:*:*:*:*:*', 'cpe:2.3:a:perl_base:perl_base:5.34.0-3ubuntu1.3:*:*:*:*:*:*:*', 'cpe:2.3:a:perl:perl-base:5.34.0-3ubuntu1.3:*:*:*:*:*:*:*', 'cpe:2.3:a:perl:perl_base:5.34.0-3ubuntu1.3:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+bsdutils,1:2.37.2-4ubuntu3,BSD-2-clause BSD-3-clause BSD-4-clause GPL-2 GPL-2+ GPL-3 GPL-3+ LGPL LGPL-2 LGPL-2+ LGPL-2.1 LGPL-2.1+ LGPL-3 LGPL-3+ MIT public-domain,dpkg,['cpe:2.3:a:bsdutils:bsdutils:1\\:2.37.2-4ubuntu3:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+util-linux,2.37.2-4ubuntu3,BSD-2-clause BSD-3-clause BSD-4-clause GPL-2 GPL-2+ GPL-3 GPL-3+ LGPL LGPL-2 LGPL-2+ LGPL-2.1 LGPL-2.1+ LGPL-3 LGPL-3+ MIT public-domain,dpkg,"['cpe:2.3:a:util-linux:util-linux:2.37.2-4ubuntu3:*:*:*:*:*:*:*', 'cpe:2.3:a:util-linux:util_linux:2.37.2-4ubuntu3:*:*:*:*:*:*:*', 'cpe:2.3:a:util_linux:util-linux:2.37.2-4ubuntu3:*:*:*:*:*:*:*', 'cpe:2.3:a:util_linux:util_linux:2.37.2-4ubuntu3:*:*:*:*:*:*:*', 'cpe:2.3:a:util:util-linux:2.37.2-4ubuntu3:*:*:*:*:*:*:*', 'cpe:2.3:a:util:util_linux:2.37.2-4ubuntu3:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libext2fs2,1.46.5-2ubuntu1.1,GPL-2 LGPL-2,dpkg,['cpe:2.3:a:libext2fs2:libext2fs2:1.46.5-2ubuntu1.1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+nb-conda-kernels,2.3.1,Unknown,PYTHON,"['cpe:2.3:a:continuum_analytics_project:python-nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:continuum_analytics_project:python_nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:continuum_analyticsproject:python-nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:continuum_analyticsproject:python_nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-nb-conda-kernels:python-nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-nb-conda-kernels:python_nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_nb_conda_kernels:python-nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_nb_conda_kernels:python_nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:continuum_analytics_project:nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:continuum_analytics_project:nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:continuum_analytics:python-nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:continuum_analytics:python_nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:continuum_analyticsproject:nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:continuum_analyticsproject:nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nb-conda-kernels:python-nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nb-conda-kernels:python_nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nb_conda_kernels:python-nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nb_conda_kernels:python_nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-nb-conda-kernels:nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-nb-conda-kernels:nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_nb_conda_kernels:nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_nb_conda_kernels:nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-nb-conda:python-nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-nb-conda:python_nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_nb_conda:python-nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_nb_conda:python_nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:continuum_analytics:nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:continuum_analytics:nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nb-conda-kernels:nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nb-conda-kernels:nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nb_conda_kernels:nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nb_conda_kernels:nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-nb:python-nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-nb:python_nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_nb:python-nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_nb:python_nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nb-conda:python-nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nb-conda:python_nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nb_conda:python-nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nb_conda:python_nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-nb-conda:nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-nb-conda:nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_nb_conda:nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_nb_conda:nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nb:python-nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nb:python_nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-nb:nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-nb:nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_nb:nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_nb:nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nb-conda:nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nb-conda:nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nb_conda:nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nb_conda:nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:nb_conda_kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nb:nb-conda-kernels:2.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nb:nb_conda_kernels:2.3.1:*:*:*:*:*:*:*']",Continuum Analytics,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libfontconfig1,2.13.1-4.2ubuntu5,Unknown,dpkg,['cpe:2.3:a:libfontconfig1:libfontconfig1:2.13.1-4.2ubuntu5:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+js,1.0.0,ISC,NPM,['cpe:2.3:a:js:js:1.0.0:*:*:*:*:*:*:*'],Unknown,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libfreetype6,2.11.1+dfsg-1ubuntu0.2,BSD-3-Clause BSL-1.0 FSFAP FTL GPL-2 GPL-2+ GPL-3 GPL-3+ MIT OpenGroup-BSD-like Public-Domain Zlib,dpkg,['cpe:2.3:a:libfreetype6:libfreetype6:2.11.1\\+dfsg-1ubuntu0.2:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+Babel,2.13.1,BSD-3-Clause,PYTHON,"['cpe:2.3:a:armin_ronacher_project:python-Babel:2.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_ronacher_project:python_Babel:2.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_ronacherproject:python-Babel:2.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_ronacherproject:python_Babel:2.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_ronacher_project:Babel:2.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:armin-ronacher:python-Babel:2.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:armin-ronacher:python_Babel:2.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_ronacher:python-Babel:2.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_ronacher:python_Babel:2.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_ronacherproject:Babel:2.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-Babel:python-Babel:2.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-Babel:python_Babel:2.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_Babel:python-Babel:2.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_Babel:python_Babel:2.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:armin-ronacher:Babel:2.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_ronacher:Babel:2.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-Babel:2.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_Babel:2.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:Babel:python-Babel:2.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:Babel:python_Babel:2.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-Babel:Babel:2.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_Babel:Babel:2.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:Babel:2.13.1:*:*:*:*:*:*:*', 'cpe:2.3:a:Babel:Babel:2.13.1:*:*:*:*:*:*:*']",Armin Ronacher ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libgcc-11-dev,11.4.0-1ubuntu1~22.04,Artistic GFDL-1.2 GPL GPL-2 GPL-3 LGPL,dpkg,"['cpe:2.3:a:libgcc-11-dev:libgcc-11-dev:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:libgcc-11-dev:libgcc_11_dev:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:libgcc_11_dev:libgcc-11-dev:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:libgcc_11_dev:libgcc_11_dev:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:libgcc-11:libgcc-11-dev:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:libgcc-11:libgcc_11_dev:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:libgcc_11:libgcc-11-dev:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:libgcc_11:libgcc_11_dev:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:libgcc:libgcc-11-dev:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:libgcc:libgcc_11_dev:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*']",Ubuntu Core developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+npy-append-array,0.9.16,MIT,PYTHON,"['cpe:2.3:a:michael_siebert2k_project:python-npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael_siebert2k_project:python_npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael_siebert2kproject:python-npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael_siebert2kproject:python_npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael_siebert_project:python-npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael_siebert_project:python_npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python-npy-append-array:python-npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python-npy-append-array:python_npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python_npy_append_array:python-npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python_npy_append_array:python_npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael_siebertproject:python-npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael_siebertproject:python_npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael_siebert2k_project:npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael_siebert2k_project:npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael-siebert2k:python-npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael-siebert2k:python_npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael_siebert2k:python-npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael_siebert2k:python_npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael_siebert2kproject:npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael_siebert2kproject:npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python-npy-append:python-npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python-npy-append:python_npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python_npy_append:python-npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python_npy_append:python_npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael_siebert_project:npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael_siebert_project:npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:npy-append-array:python-npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:npy-append-array:python_npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:npy_append_array:python-npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:npy_append_array:python_npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python-npy-append-array:npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python-npy-append-array:npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python_npy_append_array:npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python_npy_append_array:npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael_siebert:python-npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael_siebert:python_npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael_siebertproject:npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael_siebertproject:npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael-siebert2k:npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael-siebert2k:npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael_siebert2k:npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael_siebert2k:npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:npy-append:python-npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:npy-append:python_npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:npy_append:python-npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:npy_append:python_npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python-npy-append:npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python-npy-append:npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python-npy:python-npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python-npy:python_npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python_npy:python-npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python_npy:python_npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python_npy_append:npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python_npy_append:npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:npy-append-array:npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:npy-append-array:npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:npy_append_array:npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:npy_append_array:npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael_siebert:npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:michael_siebert:npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:npy-append:npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:npy-append:npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:npy:python-npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:npy:python_npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:npy_append:npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:npy_append:npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python-npy:npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python-npy:npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python_npy:npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python_npy:npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python:npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:python:npy_append_array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:npy:npy-append-array:0.9.16:*:*:*:*:*:*:*', 'cpe:2.3:a:npy:npy_append_array:0.9.16:*:*:*:*:*:*:*']",Michael Siebert ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libgcc-s1,12.3.0-1ubuntu1~22.04,Artistic GFDL-1.2 GPL GPL-2 GPL-3 LGPL,dpkg,"['cpe:2.3:a:libgcc-s1:libgcc-s1:12.3.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:libgcc-s1:libgcc_s1:12.3.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:libgcc_s1:libgcc-s1:12.3.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:libgcc_s1:libgcc_s1:12.3.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:libgcc:libgcc-s1:12.3.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*', 'cpe:2.3:a:libgcc:libgcc_s1:12.3.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*']",Ubuntu Core developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+Brotli,1.0.9,MIT,PYTHON,"['cpe:2.3:a:brotli_authors_project:python-Brotli:1.0.9:*:*:*:*:*:*:*', 'cpe:2.3:a:brotli_authors_project:python_Brotli:1.0.9:*:*:*:*:*:*:*', 'cpe:2.3:a:brotli_authorsproject:python-Brotli:1.0.9:*:*:*:*:*:*:*', 'cpe:2.3:a:brotli_authorsproject:python_Brotli:1.0.9:*:*:*:*:*:*:*', 'cpe:2.3:a:brotli_authors_project:Brotli:1.0.9:*:*:*:*:*:*:*', 'cpe:2.3:a:brotli_authors:python-Brotli:1.0.9:*:*:*:*:*:*:*', 'cpe:2.3:a:brotli_authors:python_Brotli:1.0.9:*:*:*:*:*:*:*', 'cpe:2.3:a:brotli_authorsproject:Brotli:1.0.9:*:*:*:*:*:*:*', 'cpe:2.3:a:python-Brotli:python-Brotli:1.0.9:*:*:*:*:*:*:*', 'cpe:2.3:a:python-Brotli:python_Brotli:1.0.9:*:*:*:*:*:*:*', 'cpe:2.3:a:python_Brotli:python-Brotli:1.0.9:*:*:*:*:*:*:*', 'cpe:2.3:a:python_Brotli:python_Brotli:1.0.9:*:*:*:*:*:*:*', 'cpe:2.3:a:brotli_authors:Brotli:1.0.9:*:*:*:*:*:*:*', 'cpe:2.3:a:Brotli:python-Brotli:1.0.9:*:*:*:*:*:*:*', 'cpe:2.3:a:Brotli:python_Brotli:1.0.9:*:*:*:*:*:*:*', 'cpe:2.3:a:python-Brotli:Brotli:1.0.9:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-Brotli:1.0.9:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_Brotli:1.0.9:*:*:*:*:*:*:*', 'cpe:2.3:a:python_Brotli:Brotli:1.0.9:*:*:*:*:*:*:*', 'cpe:2.3:a:Brotli:Brotli:1.0.9:*:*:*:*:*:*:*', 'cpe:2.3:a:python:Brotli:1.0.9:*:*:*:*:*:*:*']",The Brotli Authors,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libgcrypt20,1.9.4-3ubuntu3,GPL-2 LGPL,dpkg,['cpe:2.3:a:libgcrypt20:libgcrypt20:1.9.4-3ubuntu3:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+numba,0.58.1,BSD,PYTHON,"['cpe:2.3:a:python-numba:python-numba:0.58.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-numba:python_numba:0.58.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_numba:python-numba:0.58.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_numba:python_numba:0.58.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-numba:0.58.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_numba:0.58.1:*:*:*:*:*:*:*', 'cpe:2.3:a:numba:python-numba:0.58.1:*:*:*:*:*:*:*', 'cpe:2.3:a:numba:python_numba:0.58.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-numba:numba:0.58.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_numba:numba:0.58.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:numba:0.58.1:*:*:*:*:*:*:*', 'cpe:2.3:a:numba:numba:0.58.1:*:*:*:*:*:*:*']",Unknown,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+Brotli,1.1.0,MIT,PYTHON,"['cpe:2.3:a:brotli_authors_project:python-Brotli:1.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:brotli_authors_project:python_Brotli:1.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:brotli_authorsproject:python-Brotli:1.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:brotli_authorsproject:python_Brotli:1.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:brotli_authors_project:Brotli:1.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:brotli_authors:python-Brotli:1.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:brotli_authors:python_Brotli:1.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:brotli_authorsproject:Brotli:1.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-Brotli:python-Brotli:1.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-Brotli:python_Brotli:1.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_Brotli:python-Brotli:1.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_Brotli:python_Brotli:1.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:brotli_authors:Brotli:1.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:Brotli:python-Brotli:1.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:Brotli:python_Brotli:1.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-Brotli:Brotli:1.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-Brotli:1.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_Brotli:1.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_Brotli:Brotli:1.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:Brotli:Brotli:1.1.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:Brotli:1.1.0:*:*:*:*:*:*:*']",The Brotli Authors,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libgdbm-compat4,1.23-1,GFDL-NIV-1.3+ GPL-2 GPL-2+ GPL-3 GPL-3+,dpkg,"['cpe:2.3:a:libgdbm-compat4:libgdbm-compat4:1.23-1:*:*:*:*:*:*:*', 'cpe:2.3:a:libgdbm-compat4:libgdbm_compat4:1.23-1:*:*:*:*:*:*:*', 'cpe:2.3:a:libgdbm_compat4:libgdbm-compat4:1.23-1:*:*:*:*:*:*:*', 'cpe:2.3:a:libgdbm_compat4:libgdbm_compat4:1.23-1:*:*:*:*:*:*:*', 'cpe:2.3:a:libgdbm:libgdbm-compat4:1.23-1:*:*:*:*:*:*:*', 'cpe:2.3:a:libgdbm:libgdbm_compat4:1.23-1:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libgdbm6,1.23-1,GFDL-NIV-1.3+ GPL-2 GPL-2+ GPL-3 GPL-3+,dpkg,['cpe:2.3:a:libgdbm6:libgdbm6:1.23-1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libbsd0,0.11.5-1,BSD-2-clause BSD-2-clause-NetBSD BSD-2-clause-author BSD-2-clause-verbatim BSD-3-clause BSD-3-clause-John-Birrell BSD-3-clause-Regents BSD-3-clause-author BSD-4-clause-Christopher-G-Demetriou BSD-4-clause-Niels-Provos BSD-5-clause-Peter-Wemm Beerware Expat ISC ISC-Original public-domain,dpkg,['cpe:2.3:a:libbsd0:libbsd0:0.11.5-1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libglib2.0-0,2.72.4-0ubuntu2.2,Expat GPL-2+ LGPL,dpkg,"['cpe:2.3:a:libglib2.0-0:libglib2.0-0:2.72.4-0ubuntu2.2:*:*:*:*:*:*:*', 'cpe:2.3:a:libglib2.0-0:libglib2.0_0:2.72.4-0ubuntu2.2:*:*:*:*:*:*:*', 'cpe:2.3:a:libglib2.0_0:libglib2.0-0:2.72.4-0ubuntu2.2:*:*:*:*:*:*:*', 'cpe:2.3:a:libglib2.0_0:libglib2.0_0:2.72.4-0ubuntu2.2:*:*:*:*:*:*:*', 'cpe:2.3:a:libglib2.0:libglib2.0-0:2.72.4-0ubuntu2.2:*:*:*:*:*:*:*', 'cpe:2.3:a:libglib2.0:libglib2.0_0:2.72.4-0ubuntu2.2:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libbz2-1.0,1.0.8-5build1,BSD-variant GPL-2,dpkg,"['cpe:2.3:a:libbz2-1.0:libbz2-1.0:1.0.8-5build1:*:*:*:*:*:*:*', 'cpe:2.3:a:libbz2-1.0:libbz2_1.0:1.0.8-5build1:*:*:*:*:*:*:*', 'cpe:2.3:a:libbz2_1.0:libbz2-1.0:1.0.8-5build1:*:*:*:*:*:*:*', 'cpe:2.3:a:libbz2_1.0:libbz2_1.0:1.0.8-5build1:*:*:*:*:*:*:*', 'cpe:2.3:a:libbz2:libbz2-1.0:1.0.8-5build1:*:*:*:*:*:*:*', 'cpe:2.3:a:libbz2:libbz2_1.0:1.0.8-5build1:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+dataclasses,0.8,UNKNOWN,PYTHON,"['cpe:2.3:a:python-dataclasses:python-dataclasses:0.8:*:*:*:*:*:*:*', 'cpe:2.3:a:python-dataclasses:python_dataclasses:0.8:*:*:*:*:*:*:*', 'cpe:2.3:a:python_dataclasses:python-dataclasses:0.8:*:*:*:*:*:*:*', 'cpe:2.3:a:python_dataclasses:python_dataclasses:0.8:*:*:*:*:*:*:*', 'cpe:2.3:a:dataclasses:python-dataclasses:0.8:*:*:*:*:*:*:*', 'cpe:2.3:a:dataclasses:python_dataclasses:0.8:*:*:*:*:*:*:*', 'cpe:2.3:a:python-dataclasses:dataclasses:0.8:*:*:*:*:*:*:*', 'cpe:2.3:a:python_dataclasses:dataclasses:0.8:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-dataclasses:0.8:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_dataclasses:0.8:*:*:*:*:*:*:*', 'cpe:2.3:a:dataclasses:dataclasses:0.8:*:*:*:*:*:*:*', 'cpe:2.3:a:python:dataclasses:0.8:*:*:*:*:*:*:*']",Unknown,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+referencing,0.31.1,MIT,PYTHON,"['cpe:2.3:a:julian\\+referencing_project:python-referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:julian\\+referencing_project:python_referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:julian\\+referencingproject:python-referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:julian\\+referencingproject:python_referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:julian_berman_project:python-referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:julian_berman_project:python_referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:julian_bermanproject:python-referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:julian_bermanproject:python_referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:julian\\+referencing_project:referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:julian\\+referencing:python-referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:julian\\+referencing:python_referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:julian\\+referencingproject:referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-referencing:python-referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-referencing:python_referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_referencing:python-referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_referencing:python_referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:julian_berman_project:referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:julian_berman:python-referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:julian_berman:python_referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:julian_bermanproject:referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:julian\\+referencing:referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-referencing:referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_referencing:referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:referencing:python-referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:referencing:python_referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:julian_berman:referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:referencing:referencing:0.31.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:referencing:0.31.1:*:*:*:*:*:*:*']",Julian Berman ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+datacompy,0.8.4,Apache Software License,PYTHON,"['cpe:2.3:a:ian_robertson\\,_dan_coates\\,_faisal_dosani_project:python-datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:ian_robertson\\,_dan_coates\\,_faisal_dosani_project:python_datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:ian_robertson\\,_dan_coates\\,_faisal_dosaniproject:python-datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:ian_robertson\\,_dan_coates\\,_faisal_dosaniproject:python_datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:ian_robertson\\,_dan_coates\\,_faisal_dosani_project:datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:ian_robertson\\,_dan_coates\\,_faisal_dosani:python-datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:ian_robertson\\,_dan_coates\\,_faisal_dosani:python_datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:ian_robertson\\,_dan_coates\\,_faisal_dosaniproject:datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:ian_robertson\\,_dan_coates\\,_faisal_dosani:datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:faisal_dosani_project:python-datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:faisal_dosani_project:python_datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:faisal_dosaniproject:python-datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:faisal_dosaniproject:python_datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:python-datacompy:python-datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:python-datacompy:python_datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:python_datacompy:python-datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:python_datacompy:python_datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:faisal_dosani_project:datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:faisal-dosani:python-datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:faisal-dosani:python_datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:faisal_dosani:python-datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:faisal_dosani:python_datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:faisal_dosaniproject:datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:datacompy:python-datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:datacompy:python_datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:python-datacompy:datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:python_datacompy:datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:faisal-dosani:datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:faisal_dosani:datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:datacompy:datacompy:0.8.4:*:*:*:*:*:*:*', 'cpe:2.3:a:python:datacompy:0.8.4:*:*:*:*:*:*:*']","Ian Robertson, Dan Coates, Faisal Dosani ",nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+imagesize,1.4.1,MIT,PYTHON,"['cpe:2.3:a:yoshiki_shibukawa_project:python-imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:yoshiki_shibukawa_project:python_imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:yoshiki_shibukawaproject:python-imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:yoshiki_shibukawaproject:python_imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:yoshiki_shibukawa_project:imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:yoshiki_shibukawa:python-imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:yoshiki_shibukawa:python_imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:yoshiki_shibukawaproject:imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-imagesize:python-imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-imagesize:python_imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_imagesize:python-imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_imagesize:python_imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:yoshiki_project:python-imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:yoshiki_project:python_imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:yoshikiproject:python-imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:yoshikiproject:python_imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:yoshiki_shibukawa:imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:imagesize:python-imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:imagesize:python_imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-imagesize:imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_imagesize:imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:yoshiki_project:imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:yoshiki:python-imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:yoshiki:python_imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:yoshikiproject:imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:imagesize:imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:yoshiki:imagesize:1.4.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:imagesize:1.4.1:*:*:*:*:*:*:*']",Yoshiki Shibukawa ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+dill,0.3.7,BSD-3-Clause,PYTHON,"['cpe:2.3:a:mike_mckerns_project:python-dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_mckerns_project:python_dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_mckernsproject:python-dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_mckernsproject:python_dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:mmckerns_project:python-dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:mmckerns_project:python_dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:mmckernsproject:python-dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:mmckernsproject:python_dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_mckerns_project:dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_mckerns:python-dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_mckerns:python_dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_mckernsproject:dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python-dill:python-dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python-dill:python_dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python_dill:python-dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python_dill:python_dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:mmckerns_project:dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:mmckerns:python-dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:mmckerns:python_dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:mmckernsproject:dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_mckerns:dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:dill:python-dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:dill:python_dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python-dill:dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python_dill:dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:mmckerns:dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:python:dill:0.3.7:*:*:*:*:*:*:*', 'cpe:2.3:a:dill:dill:0.3.7:*:*:*:*:*:*:*']",Mike McKerns ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+distributed,2023.3.2.1,BSD,PYTHON,"['cpe:2.3:a:python-distributed:python-distributed:2023.3.2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-distributed:python_distributed:2023.3.2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_distributed:python-distributed:2023.3.2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_distributed:python_distributed:2023.3.2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:distributed:python-distributed:2023.3.2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:distributed:python_distributed:2023.3.2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-distributed:distributed:2023.3.2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_distributed:distributed:2023.3.2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-distributed:2023.3.2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_distributed:2023.3.2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:distributed:distributed:2023.3.2.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:distributed:2023.3.2.1:*:*:*:*:*:*:*']",Unknown,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+importlib-metadata,7.0.0,Unknown,PYTHON,"['cpe:2.3:a:python-importlib-metadata:python-importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-importlib-metadata:python_importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_importlib_metadata:python-importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_importlib_metadata:python_importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jason_r__coombs_project:python-importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jason_r__coombs_project:python_importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jason_r__coombsproject:python-importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jason_r__coombsproject:python_importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:importlib-metadata:python-importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:importlib-metadata:python_importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:importlib_metadata:python-importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:importlib_metadata:python_importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-importlib-metadata:importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-importlib-metadata:importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_importlib_metadata:importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_importlib_metadata:importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jason_r__coombs_project:importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jason_r__coombs_project:importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-importlib:python-importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-importlib:python_importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_importlib:python-importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_importlib:python_importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jason_r__coombs:python-importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jason_r__coombs:python_importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jason_r__coombsproject:importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jason_r__coombsproject:importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jaraco_project:python-importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jaraco_project:python_importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jaracoproject:python-importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jaracoproject:python_importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:importlib-metadata:importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:importlib-metadata:importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:importlib_metadata:importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:importlib_metadata:importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:importlib:python-importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:importlib:python_importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-importlib:importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-importlib:importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_importlib:importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_importlib:importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jason_r__coombs:importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jason_r__coombs:importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jaraco_project:importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jaraco_project:importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jaraco:python-importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jaraco:python_importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jaracoproject:importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jaracoproject:importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:importlib:importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:importlib:importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jaraco:importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jaraco:importlib_metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:importlib-metadata:7.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:importlib_metadata:7.0.0:*:*:*:*:*:*:*']",Jason R. Coombs ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+docker,5.0.3,Apache License 2.0,PYTHON,"['cpe:2.3:a:python-docker:python-docker:5.0.3:*:*:*:*:*:*:*', 'cpe:2.3:a:python-docker:python_docker:5.0.3:*:*:*:*:*:*:*', 'cpe:2.3:a:python_docker:python-docker:5.0.3:*:*:*:*:*:*:*', 'cpe:2.3:a:python_docker:python_docker:5.0.3:*:*:*:*:*:*:*', 'cpe:2.3:a:docker:python-docker:5.0.3:*:*:*:*:*:*:*', 'cpe:2.3:a:docker:python_docker:5.0.3:*:*:*:*:*:*:*', 'cpe:2.3:a:python-docker:docker:5.0.3:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-docker:5.0.3:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_docker:5.0.3:*:*:*:*:*:*:*', 'cpe:2.3:a:python_docker:docker:5.0.3:*:*:*:*:*:*:*', 'cpe:2.3:a:docker:docker:5.0.3:*:*:*:*:*:*:*', 'cpe:2.3:a:python:docker:5.0.3:*:*:*:*:*:*:*']",Unknown,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+docker-pycreds,0.4.0,Apache License 2.0,PYTHON,"['cpe:2.3:a:python-docker-pycreds:python-docker-pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-docker-pycreds:python_docker_pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_docker_pycreds:python-docker-pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_docker_pycreds:python_docker_pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:unknown_project:python-docker-pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:unknown_project:python_docker_pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:docker-pycreds:python-docker-pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:docker-pycreds:python_docker_pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:docker_pycreds:python-docker-pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:docker_pycreds:python_docker_pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-docker-pycreds:docker-pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-docker-pycreds:docker_pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_docker_pycreds:docker-pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_docker_pycreds:docker_pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:unknownproject:python-docker-pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:unknownproject:python_docker_pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-docker:python-docker-pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-docker:python_docker_pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_docker:python-docker-pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_docker:python_docker_pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:unknown_project:docker-pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:unknown_project:docker_pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:docker-pycreds:docker-pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:docker-pycreds:docker_pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:docker_pycreds:docker-pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:docker_pycreds:docker_pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:unknown:python-docker-pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:unknown:python_docker_pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:unknownproject:docker-pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:unknownproject:docker_pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:docker:python-docker-pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:docker:python_docker_pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-docker:docker-pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-docker:docker_pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-docker-pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_docker_pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_docker:docker-pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_docker:docker_pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:unknown:docker-pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:unknown:docker_pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:docker:docker-pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:docker:docker_pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:docker-pycreds:0.4.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:docker_pycreds:0.4.0:*:*:*:*:*:*:*']",UNKNOWN ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+importlib-resources,6.1.1,Unknown,PYTHON,"['cpe:2.3:a:python-importlib-resources:python-importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-importlib-resources:python_importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_importlib_resources:python-importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_importlib_resources:python_importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:barry_warsaw_project:python-importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:barry_warsaw_project:python_importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:barry_warsawproject:python-importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:barry_warsawproject:python_importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:importlib-resources:python-importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:importlib-resources:python_importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:importlib_resources:python-importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:importlib_resources:python_importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-importlib-resources:importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-importlib-resources:importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_importlib_resources:importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_importlib_resources:importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-importlib:python-importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-importlib:python_importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_importlib:python-importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_importlib:python_importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:barry_project:python-importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:barry_project:python_importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:barry_warsaw_project:importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:barry_warsaw_project:importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:barry_warsaw:python-importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:barry_warsaw:python_importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:barry_warsawproject:importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:barry_warsawproject:importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:barryproject:python-importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:barryproject:python_importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:importlib-resources:importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:importlib-resources:importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:importlib_resources:importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:importlib_resources:importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:importlib:python-importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:importlib:python_importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-importlib:importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-importlib:importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_importlib:importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_importlib:importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:barry_project:importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:barry_project:importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:barry:python-importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:barry:python_importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:barry_warsaw:importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:barry_warsaw:importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:barryproject:importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:barryproject:importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:importlib:importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:importlib:importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:importlib_resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:barry:importlib-resources:6.1.1:*:*:*:*:*:*:*', 'cpe:2.3:a:barry:importlib_resources:6.1.1:*:*:*:*:*:*:*']",Barry Warsaw ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+docutils,0.20.1,"public domain, Python, 2-Clause BSD, GPL 3 (see COPYING.txt)",PYTHON,"['cpe:2.3:a:david_goodger_project:python-docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:david_goodger_project:python_docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:david_goodgerproject:python-docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:david_goodgerproject:python_docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:goodger_project:python-docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:goodger_project:python_docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-docutils:python-docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-docutils:python_docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_docutils:python-docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_docutils:python_docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:david_goodger_project:docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:goodgerproject:python-docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:goodgerproject:python_docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:david_goodger:python-docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:david_goodger:python_docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:david_goodgerproject:docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:docutils:python-docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:docutils:python_docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:goodger_project:docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-docutils:docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_docutils:docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:goodger:python-docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:goodger:python_docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:goodgerproject:docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:david_goodger:docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:docutils:docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:goodger:docutils:0.20.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:docutils:0.20.1:*:*:*:*:*:*:*']",David Goodger ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+traitlets,5.14.0,"BSD 3-Clause License
+
+ - Copyright (c) 2001-, IPython Development Team
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ 2. 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.
+
+ 3. Neither the name of the copyright holder 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 AND CONTRIBUTORS ""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 HOLDER 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.",PYTHON,"['cpe:2.3:a:ipython_development_team_\\>,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+triton,2.0.0,Unknown,PYTHON,"['cpe:2.3:a:philippe_tillet_project:python-triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:philippe_tillet_project:python_triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:philippe_tilletproject:python-triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:philippe_tilletproject:python_triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:philippe_tillet_project:triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:philippe_tillet:python-triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:philippe_tillet:python_triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:philippe_tilletproject:triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-triton:python-triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-triton:python_triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_triton:python-triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_triton:python_triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:phil_project:python-triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:phil_project:python_triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:philproject:python-triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:philproject:python_triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:philippe_tillet:triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-triton:triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_triton:triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:triton:python-triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:triton:python_triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:phil_project:triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:phil:python-triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:phil:python_triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:philproject:triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:triton:triton:2.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:phil:triton:2.0.0:*:*:*:*:*:*:*']",Philippe Tillet ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+tritonclient,2.26.0,BSD,PYTHON,"['cpe:2.3:a:sw_dl_triton_project:python-tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:sw_dl_triton_project:python_tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_inc__project:python-tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_inc__project:python_tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-tritonclient:python-tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-tritonclient:python_tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_tritonclient:python-tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_tritonclient:python_tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:sw_dl_tritonproject:python-tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:sw_dl_tritonproject:python_tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_inc_project:python-tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_inc_project:python_tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:sw_dl_triton_project:tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_inc__project:tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-tritonclient:tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_tritonclient:tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:sw-dl-triton:python-tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:sw-dl-triton:python_tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:sw_dl_triton:python-tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:sw_dl_triton:python_tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:sw_dl_tritonproject:tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:tritonclient:python-tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:tritonclient:python_tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_inc_:python-tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_inc_:python_tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_inc_project:tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:sw-dl-triton:tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:sw_dl_triton:tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:tritonclient:tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_inc_:tritonclient:2.26.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:tritonclient:2.26.0:*:*:*:*:*:*:*']",NVIDIA Inc. ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libkeyutils1,1.6.1-2ubuntu3,GPL-2 GPL-2+ LGPL-2 LGPL-2+,dpkg,['cpe:2.3:a:libkeyutils1:libkeyutils1:1.6.1-2ubuntu3:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+PyJWT,2.8.0,MIT,PYTHON,"['cpe:2.3:a:jose_padilla_project:python-PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jose_padilla_project:python_PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jose_padillaproject:python-PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jose_padillaproject:python_PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:hello_project:python-PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:hello_project:python_PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jose_padilla_project:PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:helloproject:python-PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:helloproject:python_PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jose_padilla:python-PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jose_padilla:python_PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jose_padillaproject:PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-PyJWT:python-PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-PyJWT:python_PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_PyJWT:python-PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_PyJWT:python_PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:hello_project:PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:PyJWT:python-PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:PyJWT:python_PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:hello:python-PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:hello:python_PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:helloproject:PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:jose_padilla:PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-PyJWT:PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_PyJWT:PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:PyJWT:PyJWT:2.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:hello:PyJWT:2.8.0:*:*:*:*:*:*:*']",Jose Padilla ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+liblcms2-2,2.12~rc1-2build2,GPL-2 GPL-2+ GPL-3 MIT,dpkg,"['cpe:2.3:a:liblcms2-2:liblcms2-2:2.12\\~rc1-2build2:*:*:*:*:*:*:*', 'cpe:2.3:a:liblcms2-2:liblcms2_2:2.12\\~rc1-2build2:*:*:*:*:*:*:*', 'cpe:2.3:a:liblcms2_2:liblcms2-2:2.12\\~rc1-2build2:*:*:*:*:*:*:*', 'cpe:2.3:a:liblcms2_2:liblcms2_2:2.12\\~rc1-2build2:*:*:*:*:*:*:*', 'cpe:2.3:a:liblcms2:liblcms2-2:2.12\\~rc1-2build2:*:*:*:*:*:*:*', 'cpe:2.3:a:liblcms2:liblcms2_2:2.12\\~rc1-2build2:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libacl1,2.3.1-1,GPL-2 GPL-2+ LGPL-2+ LGPL-2.1,dpkg,['cpe:2.3:a:libacl1:libacl1:2.3.1-1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+liblsan0,12.3.0-1ubuntu1~22.04,Artistic GFDL-1.2 GPL GPL-2 GPL-3 LGPL,dpkg,['cpe:2.3:a:liblsan0:liblsan0:12.3.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*'],Ubuntu Core developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libasan6,11.4.0-1ubuntu1~22.04,Artistic GFDL-1.2 GPL GPL-2 GPL-3 LGPL,dpkg,['cpe:2.3:a:libasan6:libasan6:11.4.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*'],Ubuntu Core developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+liblzma5,5.2.5-2ubuntu1,Autoconf GPL-2 GPL-2+ GPL-3 LGPL-2 LGPL-2.1 LGPL-2.1+ PD PD-debian config-h noderivs permissive-fsf permissive-nowarranty probably-PD,dpkg,['cpe:2.3:a:liblzma5:liblzma5:5.2.5-2ubuntu1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libmpc3,1.2.1-2build1,LGPL-3,dpkg,['cpe:2.3:a:libmpc3:libmpc3:1.2.1-2build1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+Jinja2,3.1.2,BSD-3-Clause,PYTHON,"['cpe:2.3:a:armin_ronacher_project:python-Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_ronacher_project:python_Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_ronacherproject:python-Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_ronacherproject:python_Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_ronacher_project:Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:armin-ronacher:python-Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:armin-ronacher:python_Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_ronacher:python-Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_ronacher:python_Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_ronacherproject:Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-Jinja2:python-Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-Jinja2:python_Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_Jinja2:python-Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_Jinja2:python_Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:armin-ronacher:Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:armin_ronacher:Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:Jinja2:python-Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:Jinja2:python_Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-Jinja2:Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_Jinja2:Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:Jinja2:Jinja2:3.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:Jinja2:3.1.2:*:*:*:*:*:*:*']",Armin Ronacher ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+Mako,1.3.0,MIT,PYTHON,"['cpe:2.3:a:mike_bayer_project:python-Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_bayer_project:python_Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_bayerproject:python-Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_bayerproject:python_Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_project:python-Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_project:python_Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_bayer_project:Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mikeproject:python-Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mikeproject:python_Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-Mako:python-Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-Mako:python_Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_Mako:python-Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_Mako:python_Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_bayer:python-Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_bayer:python_Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_bayerproject:Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_project:Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:Mako:python-Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:Mako:python_Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mike:python-Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mike:python_Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mikeproject:Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-Mako:Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_Mako:Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mike_bayer:Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:Mako:Mako:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mike:Mako:1.3.0:*:*:*:*:*:*:*']",Mike Bayer ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+sphinxcontrib-htmlhelp,2.0.4,Unknown,PYTHON,"['cpe:2.3:a:python-sphinxcontrib-htmlhelp:python-sphinxcontrib-htmlhelp:2.0.4:*:*:*:*:*:*:*', 'cpe:2.3:a:python-sphinxcontrib-htmlhelp:python_sphinxcontrib_htmlhelp:2.0.4:*:*:*:*:*:*:*', 'cpe:2.3:a:python_sphinxcontrib_htmlhelp:python-sphinxcontrib-htmlhelp:2.0.4:*:*:*:*:*:*:*', 'cpe:2.3:a:python_sphinxcontrib_htmlhelp:python_sphinxcontrib_htmlhelp:2.0.4:*:*:*:*:*:*:*', 'cpe:2.3:a:georg_brandl_\\>,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+blinker,1.7.0,Unknown,PYTHON,"['cpe:2.3:a:jason_kirtland_\\>,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+cubinlinker,0.3.0,Unknown,PYTHON,"['cpe:2.3:a:python-cubinlinker:python-cubinlinker:0.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-cubinlinker:python_cubinlinker:0.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cubinlinker:python-cubinlinker:0.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cubinlinker:python_cubinlinker:0.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:cubinlinker:python-cubinlinker:0.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:cubinlinker:python_cubinlinker:0.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-cubinlinker:cubinlinker:0.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cubinlinker:cubinlinker:0.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-cubinlinker:0.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_cubinlinker:0.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:cubinlinker:cubinlinker:0.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:cubinlinker:0.3.0:*:*:*:*:*:*:*']",Unknown,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+boltons,23.0.0,BSD,PYTHON,"['cpe:2.3:a:mahmoud_hashemi_project:python-boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mahmoud_hashemi_project:python_boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mahmoud_hashemiproject:python-boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mahmoud_hashemiproject:python_boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mahmoud_hashemi_project:boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mahmoud_hashemi:python-boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mahmoud_hashemi:python_boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mahmoud_hashemiproject:boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mahmoud_project:python-boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mahmoud_project:python_boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mahmoudproject:python-boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mahmoudproject:python_boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-boltons:python-boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-boltons:python_boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_boltons:python-boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_boltons:python_boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mahmoud_hashemi:boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mahmoud_project:boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:boltons:python-boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:boltons:python_boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mahmoud:python-boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mahmoud:python_boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mahmoudproject:boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-boltons:boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_boltons:boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:boltons:boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mahmoud:boltons:23.0.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:boltons:23.0.0:*:*:*:*:*:*:*']",Mahmoud Hashemi ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+typing_extensions,4.8.0,Unknown,PYTHON,"['cpe:2.3:a:python-typing-extensions:python-typing-extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-typing-extensions:python-typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-typing-extensions:python_typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-typing_extensions:python-typing-extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-typing_extensions:python-typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-typing_extensions:python_typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_typing_extensions:python-typing-extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_typing_extensions:python-typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_typing_extensions:python_typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-typing-extensions:typing-extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-typing-extensions:typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-typing_extensions:typing-extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-typing_extensions:typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_typing_extensions:typing-extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_typing_extensions:typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:typing-extensions:python-typing-extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:typing-extensions:python-typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:typing-extensions:python_typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:typing_extensions:python-typing-extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:typing_extensions:python-typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:typing_extensions:python_typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-typing:python-typing-extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-typing:python-typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-typing:python_typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_typing:python-typing-extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_typing:python-typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_typing:python_typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:typing-extensions:typing-extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:typing-extensions:typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:typing_extensions:typing-extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:typing_extensions:typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-typing:typing-extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-typing:typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-typing-extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_typing:typing-extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_typing:typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:typing:python-typing-extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:typing:python-typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:typing:python_typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:typing-extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:typing_extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:typing:typing-extensions:4.8.0:*:*:*:*:*:*:*', 'cpe:2.3:a:typing:typing_extensions:4.8.0:*:*:*:*:*:*:*']"," <""Guido van Rossum, Jukka Lehtosalo, Łukasz Langa, Michael Lee"" >",nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+idna,3.4,Unknown,PYTHON,"['cpe:2.3:a:kim_davies_\\>,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+idna,3.6,Unknown,PYTHON,"['cpe:2.3:a:kim_davies_\\>,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+kiwisolver,1.4.5,"=========================
+ The Kiwi licensing terms
+ =========================
+ Kiwi is licensed under the terms of the Modified BSD License (also known as
+ New or Revised BSD), as follows:
+
+ Copyright (c) 2013, Nucleic Development Team
+
+ 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 the Nucleic Development Team 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 AND CONTRIBUTORS ""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.
+
+ About Kiwi
+ ----------
+ Chris Colbert began the Kiwi project in December 2013 in an effort to
+ create a blisteringly fast UI constraint solver. Chris is still the
+ project lead.
+
+ The Nucleic Development Team is the set of all contributors to the Nucleic
+ project and its subprojects.
+
+ The core team that coordinates development on GitHub can be found here:
+ http://github.com/nucleic. The current team consists of:
+
+ * Chris Colbert
+
+ Our Copyright Policy
+ --------------------
+ Nucleic uses a shared copyright model. Each contributor maintains copyright
+ over their contributions to Nucleic. But, it is important to note that these
+ contributions are typically only changes to the repositories. Thus, the Nucleic
+ source code, in its entirety is not the copyright of any single person or
+ institution. Instead, it is the collective copyright of the entire Nucleic
+ Development Team. If individual contributors want to maintain a record of what
+ changes/contributions they have specific copyright on, they should indicate
+ their copyright in the commit message of the change, when they commit the
+ change to one of the Nucleic repositories.
+
+ With this in mind, the following banner should be used in any source code file
+ to indicate the copyright and license terms:
+
+ #------------------------------------------------------------------------------
+ # Copyright (c) 2013, Nucleic Development Team.
+ #
+ # Distributed under the terms of the Modified BSD License.
+ #
+ # The full license is in the file LICENSE, distributed with this software.
+ #------------------------------------------------------------------------------
+ ",PYTHON,"['cpe:2.3:a:nucleic_development_team_\\>,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libarchive-c,5.0,CC0,PYTHON,"['cpe:2.3:a:python-libarchive-c:python-libarchive-c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-libarchive-c:python_libarchive_c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_libarchive_c:python-libarchive-c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_libarchive_c:python_libarchive_c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-libarchive:python-libarchive-c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-libarchive:python_libarchive_c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_libarchive:python-libarchive-c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_libarchive:python_libarchive_c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:changaco_project:python-libarchive-c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:changaco_project:python_libarchive_c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:changacoproject:python-libarchive-c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:changacoproject:python_libarchive_c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:libarchive-c:python-libarchive-c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:libarchive-c:python_libarchive_c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:libarchive_c:python-libarchive-c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:libarchive_c:python_libarchive_c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-libarchive-c:libarchive-c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-libarchive-c:libarchive_c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_libarchive_c:libarchive-c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_libarchive_c:libarchive_c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:libarchive:python-libarchive-c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:libarchive:python_libarchive_c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-libarchive:libarchive-c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-libarchive:libarchive_c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_libarchive:libarchive-c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_libarchive:libarchive_c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:changaco_project:libarchive-c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:changaco_project:libarchive_c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:changaco:python-libarchive-c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:changaco:python_libarchive_c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:changacoproject:libarchive-c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:changacoproject:libarchive_c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-libarchive-c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_libarchive_c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:libarchive-c:libarchive-c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:libarchive-c:libarchive_c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:libarchive_c:libarchive-c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:libarchive_c:libarchive_c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:libarchive:libarchive-c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:libarchive:libarchive_c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:changaco:libarchive-c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:changaco:libarchive_c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:libarchive-c:5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:libarchive_c:5.0:*:*:*:*:*:*:*']",Changaco ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libmambapy,1.5.0,Unknown,PYTHON,"['cpe:2.3:a:quantstack_project:python-libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:quantstack_project:python_libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-libmambapy:python-libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-libmambapy:python_libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_libmambapy:python-libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_libmambapy:python_libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:quantstackproject:python-libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:quantstackproject:python_libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:info_project:python-libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:info_project:python_libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:infoproject:python-libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:infoproject:python_libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:quantstack_project:libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:libmambapy:python-libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:libmambapy:python_libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-libmambapy:libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_libmambapy:libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:quantstack:python-libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:quantstack:python_libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:quantstackproject:libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:info_project:libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:info:python-libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:info:python_libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:infoproject:libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:libmambapy:libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:quantstack:libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:libmambapy:1.5.0:*:*:*:*:*:*:*', 'cpe:2.3:a:info:libmambapy:1.5.0:*:*:*:*:*:*:*']",QuantStack ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+llvmlite,0.41.1,BSD,PYTHON,"['cpe:2.3:a:python-llvmlite:python-llvmlite:0.41.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-llvmlite:python_llvmlite:0.41.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_llvmlite:python-llvmlite:0.41.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_llvmlite:python_llvmlite:0.41.1:*:*:*:*:*:*:*', 'cpe:2.3:a:llvmlite:python-llvmlite:0.41.1:*:*:*:*:*:*:*', 'cpe:2.3:a:llvmlite:python_llvmlite:0.41.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-llvmlite:llvmlite:0.41.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_llvmlite:llvmlite:0.41.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-llvmlite:0.41.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_llvmlite:0.41.1:*:*:*:*:*:*:*', 'cpe:2.3:a:llvmlite:llvmlite:0.41.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:llvmlite:0.41.1:*:*:*:*:*:*:*']",Unknown,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+pip,23.3.1,MIT,PYTHON,"['cpe:2.3:a:pip_developers_project:python-pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:pip_developers_project:python_pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:distutils_sig_project:python-pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:distutils_sig_project:python_pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:pip_developersproject:python-pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:pip_developersproject:python_pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:distutils_sigproject:python-pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:distutils_sigproject:python_pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:pip_developers_project:pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:distutils_sig_project:pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:pip_developers:python-pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:pip_developers:python_pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:pip_developersproject:pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:distutils-sig:python-pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:distutils-sig:python_pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:distutils_sig:python-pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:distutils_sig:python_pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:distutils_sigproject:pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pip:python-pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pip:python_pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pip:python-pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pip:python_pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:pip_developers:pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:distutils-sig:pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:distutils_sig:pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:pypa:python-pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:pypa:python_pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:pip:python-pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:pip:python_pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pip:pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pip:pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:pypa:pip:23.3.1:*:*:*:*:*:*:*', 'cpe:2.3:a:pip:pip:23.3.1:*:*:*:*:*:*:*']",The pip developers ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libgraphite2-3,1.3.14-1build2,Artistic GPL-1 GPL-1+ GPL-2 GPL-2+ LGPL-2.1 LGPL-2.1+ MPL-1.1 custom-sil-open-font-license public-domain,dpkg,"['cpe:2.3:a:libgraphite2-3:libgraphite2-3:1.3.14-1build2:*:*:*:*:*:*:*', 'cpe:2.3:a:libgraphite2-3:libgraphite2_3:1.3.14-1build2:*:*:*:*:*:*:*', 'cpe:2.3:a:libgraphite2_3:libgraphite2-3:1.3.14-1build2:*:*:*:*:*:*:*', 'cpe:2.3:a:libgraphite2_3:libgraphite2_3:1.3.14-1build2:*:*:*:*:*:*:*', 'cpe:2.3:a:libgraphite2:libgraphite2-3:1.3.14-1build2:*:*:*:*:*:*:*', 'cpe:2.3:a:libgraphite2:libgraphite2_3:1.3.14-1build2:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libgssapi-krb5-2,1.19.2-2ubuntu0.3,GPL-2,dpkg,"['cpe:2.3:a:libgssapi-krb5-2:libgssapi-krb5-2:1.19.2-2ubuntu0.3:*:*:*:*:*:*:*', 'cpe:2.3:a:libgssapi-krb5-2:libgssapi_krb5_2:1.19.2-2ubuntu0.3:*:*:*:*:*:*:*', 'cpe:2.3:a:libgssapi_krb5_2:libgssapi-krb5-2:1.19.2-2ubuntu0.3:*:*:*:*:*:*:*', 'cpe:2.3:a:libgssapi_krb5_2:libgssapi_krb5_2:1.19.2-2ubuntu0.3:*:*:*:*:*:*:*', 'cpe:2.3:a:libgssapi-krb5:libgssapi-krb5-2:1.19.2-2ubuntu0.3:*:*:*:*:*:*:*', 'cpe:2.3:a:libgssapi-krb5:libgssapi_krb5_2:1.19.2-2ubuntu0.3:*:*:*:*:*:*:*', 'cpe:2.3:a:libgssapi_krb5:libgssapi-krb5-2:1.19.2-2ubuntu0.3:*:*:*:*:*:*:*', 'cpe:2.3:a:libgssapi_krb5:libgssapi_krb5_2:1.19.2-2ubuntu0.3:*:*:*:*:*:*:*', 'cpe:2.3:a:libgssapi:libgssapi-krb5-2:1.19.2-2ubuntu0.3:*:*:*:*:*:*:*', 'cpe:2.3:a:libgssapi:libgssapi_krb5_2:1.19.2-2ubuntu0.3:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+morpheus,23.11.1,Apache,PYTHON,"['cpe:2.3:a:nvidia_corporation_project:python-morpheus:23.11.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporation_project:python_morpheus:23.11.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporationproject:python-morpheus:23.11.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporationproject:python_morpheus:23.11.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporation_project:morpheus:23.11.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporation:python-morpheus:23.11.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporation:python_morpheus:23.11.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporationproject:morpheus:23.11.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-morpheus:python-morpheus:23.11.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-morpheus:python_morpheus:23.11.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_morpheus:python-morpheus:23.11.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_morpheus:python_morpheus:23.11.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporation:morpheus:23.11.1:*:*:*:*:*:*:*', 'cpe:2.3:a:morpheus:python-morpheus:23.11.1:*:*:*:*:*:*:*', 'cpe:2.3:a:morpheus:python_morpheus:23.11.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-morpheus:morpheus:23.11.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_morpheus:morpheus:23.11.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-morpheus:23.11.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_morpheus:23.11.1:*:*:*:*:*:*:*', 'cpe:2.3:a:morpheus:morpheus:23.11.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:morpheus:23.11.1:*:*:*:*:*:*:*']",NVIDIA Corporation,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+tomli,2.0.1,Unknown,PYTHON,"['cpe:2.3:a:taneli_hukkinen_\\>,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+mpmath,1.3.0,BSD,PYTHON,"['cpe:2.3:a:fredrik_johansson_project:python-mpmath:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:fredrik_johansson_project:python_mpmath:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:fredrik_johanssonproject:python-mpmath:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:fredrik_johanssonproject:python_mpmath:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:fredrik_johansson_project:mpmath:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:fredrik-johansson:python-mpmath:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:fredrik-johansson:python_mpmath:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:fredrik_johansson:python-mpmath:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:fredrik_johansson:python_mpmath:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:fredrik_johanssonproject:mpmath:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-mpmath:python-mpmath:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-mpmath:python_mpmath:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_mpmath:python-mpmath:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_mpmath:python_mpmath:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:fredrik-johansson:mpmath:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:fredrik_johansson:mpmath:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mpmath:python-mpmath:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mpmath:python_mpmath:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-mpmath:mpmath:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-mpmath:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_mpmath:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_mpmath:mpmath:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:mpmath:mpmath:1.3.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:mpmath:1.3.0:*:*:*:*:*:*:*']",Fredrik Johansson ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+pytz,2023.3.post1,MIT,PYTHON,"['cpe:2.3:a:stuart_bishop_project:python-pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart_bishop_project:python_pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart_bishopproject:python-pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart_bishopproject:python_pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart_bishop_project:pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart_project:python-pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart_project:python_pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart_bishop:python-pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart_bishop:python_pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart_bishopproject:pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuartproject:python-pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuartproject:python_pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pytz:python-pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pytz:python_pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pytz:python-pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pytz:python_pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart_project:pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart:python-pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart:python_pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart_bishop:pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuartproject:pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pytz:pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pytz:pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:pytz:python-pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:pytz:python_pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:stuart:pytz:2023.3.post1:*:*:*:*:*:*:*', 'cpe:2.3:a:pytz:pytz:2023.3.post1:*:*:*:*:*:*:*']",Stuart Bishop ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libidn2-0,2.3.2-2build1,GPL-2 GPL-2+ GPL-3 GPL-3+ LGPL-3 LGPL-3+ Unicode,dpkg,"['cpe:2.3:a:libidn2-0:libidn2-0:2.3.2-2build1:*:*:*:*:*:*:*', 'cpe:2.3:a:libidn2-0:libidn2_0:2.3.2-2build1:*:*:*:*:*:*:*', 'cpe:2.3:a:libidn2_0:libidn2-0:2.3.2-2build1:*:*:*:*:*:*:*', 'cpe:2.3:a:libidn2_0:libidn2_0:2.3.2-2build1:*:*:*:*:*:*:*', 'cpe:2.3:a:libidn2:libidn2-0:2.3.2-2build1:*:*:*:*:*:*:*', 'cpe:2.3:a:libidn2:libidn2_0:2.3.2-2build1:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+pyzmq,25.1.2,LGPL+BSD,PYTHON,"['cpe:2.3:a:brian_e__granger\\,_min_ragan_kelley_project:python-pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:brian_e__granger\\,_min_ragan_kelley_project:python_pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:brian_e__granger\\,_min_ragan_kelleyproject:python-pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:brian_e__granger\\,_min_ragan_kelleyproject:python_pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:brian_e__granger\\,_min_ragan_kelley_project:pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:brian_e__granger\\,_min_ragan_kelley:python-pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:brian_e__granger\\,_min_ragan_kelley:python_pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:brian_e__granger\\,_min_ragan_kelleyproject:pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:brian_e__granger\\,_min_ragan_kelley:pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:zeromq_dev_project:python-pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:zeromq_dev_project:python_pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:zeromq_devproject:python-pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:zeromq_devproject:python_pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pyzmq:python-pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pyzmq:python_pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pyzmq:python-pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pyzmq:python_pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:zeromq_dev_project:pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:zeromq-dev:python-pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:zeromq-dev:python_pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:zeromq_dev:python-pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:zeromq_dev:python_pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:zeromq_devproject:pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-pyzmq:pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_pyzmq:pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:pyzmq:python-pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:pyzmq:python_pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:zeromq-dev:pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:zeromq_dev:pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:pyzmq:25.1.2:*:*:*:*:*:*:*', 'cpe:2.3:a:pyzmq:pyzmq:25.1.2:*:*:*:*:*:*:*']","Brian E. Granger, Min Ragan-Kelley ",nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+cudf,23.6.1,Apache 2.0,PYTHON,"['cpe:2.3:a:nvidia_corporation_project:python-cudf:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporation_project:python_cudf:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporationproject:python-cudf:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporationproject:python_cudf:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporation_project:cudf:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporation:python-cudf:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporation:python_cudf:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporationproject:cudf:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:nvidia_corporation:cudf:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-cudf:python-cudf:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-cudf:python_cudf:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cudf:python-cudf:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cudf:python_cudf:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-cudf:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_cudf:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cudf:python-cudf:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cudf:python_cudf:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python-cudf:cudf:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python_cudf:cudf:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:python:cudf:23.6.1:*:*:*:*:*:*:*', 'cpe:2.3:a:cudf:cudf:23.6.1:*:*:*:*:*:*:*']",NVIDIA Corporation,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libitm1,12.3.0-1ubuntu1~22.04,Artistic GFDL-1.2 GPL GPL-2 GPL-3 LGPL,dpkg,['cpe:2.3:a:libitm1:libitm1:12.3.0-1ubuntu1\\~22.04:*:*:*:*:*:*:*'],Ubuntu Core developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+rich,13.7.0,MIT,PYTHON,"['cpe:2.3:a:will_mcgugan_project:python-rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:will_mcgugan_project:python_rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:will_mcguganproject:python-rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:will_mcguganproject:python_rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:willmcgugan_project:python-rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:willmcgugan_project:python_rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:willmcguganproject:python-rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:willmcguganproject:python_rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:will_mcgugan_project:rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:will_mcgugan:python-rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:will_mcgugan:python_rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:will_mcguganproject:rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:willmcgugan_project:rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-rich:python-rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-rich:python_rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_rich:python-rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_rich:python_rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:willmcgugan:python-rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:willmcgugan:python_rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:willmcguganproject:rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:will_mcgugan:rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-rich:rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_rich:rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:rich:python-rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:rich:python_rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:willmcgugan:rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:rich:13.7.0:*:*:*:*:*:*:*', 'cpe:2.3:a:rich:rich:13.7.0:*:*:*:*:*:*:*']",Will McGugan ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libjpeg-turbo8,2.1.2-0ubuntu1,LGPL-2.1,dpkg,"['cpe:2.3:a:libjpeg-turbo8:libjpeg-turbo8:2.1.2-0ubuntu1:*:*:*:*:*:*:*', 'cpe:2.3:a:libjpeg-turbo8:libjpeg_turbo8:2.1.2-0ubuntu1:*:*:*:*:*:*:*', 'cpe:2.3:a:libjpeg_turbo8:libjpeg-turbo8:2.1.2-0ubuntu1:*:*:*:*:*:*:*', 'cpe:2.3:a:libjpeg_turbo8:libjpeg_turbo8:2.1.2-0ubuntu1:*:*:*:*:*:*:*', 'cpe:2.3:a:libjpeg:libjpeg-turbo8:2.1.2-0ubuntu1:*:*:*:*:*:*:*', 'cpe:2.3:a:libjpeg:libjpeg_turbo8:2.1.2-0ubuntu1:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+cycler,0.12.1,"Copyright (c) 2015, matplotlib project
+ 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 the matplotlib project 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 AND CONTRIBUTORS ""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 HOLDER 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.",PYTHON,"['cpe:2.3:a:thomas_a_caswell_\\>,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+sysvinit-utils,3.01-1ubuntu1,GPL-2 GPL-2+,dpkg,"['cpe:2.3:a:sysvinit-utils:sysvinit-utils:3.01-1ubuntu1:*:*:*:*:*:*:*', 'cpe:2.3:a:sysvinit-utils:sysvinit_utils:3.01-1ubuntu1:*:*:*:*:*:*:*', 'cpe:2.3:a:sysvinit_utils:sysvinit-utils:3.01-1ubuntu1:*:*:*:*:*:*:*', 'cpe:2.3:a:sysvinit_utils:sysvinit_utils:3.01-1ubuntu1:*:*:*:*:*:*:*', 'cpe:2.3:a:sysvinit:sysvinit-utils:3.01-1ubuntu1:*:*:*:*:*:*:*', 'cpe:2.3:a:sysvinit:sysvinit_utils:3.01-1ubuntu1:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libasound2-data,1.2.6.1-1ubuntu1,LGPL-2.1 LPGL-2.1+,dpkg,"['cpe:2.3:a:libasound2-data:libasound2-data:1.2.6.1-1ubuntu1:*:*:*:*:*:*:*', 'cpe:2.3:a:libasound2-data:libasound2_data:1.2.6.1-1ubuntu1:*:*:*:*:*:*:*', 'cpe:2.3:a:libasound2_data:libasound2-data:1.2.6.1-1ubuntu1:*:*:*:*:*:*:*', 'cpe:2.3:a:libasound2_data:libasound2_data:1.2.6.1-1ubuntu1:*:*:*:*:*:*:*', 'cpe:2.3:a:libasound2:libasound2-data:1.2.6.1-1ubuntu1:*:*:*:*:*:*:*', 'cpe:2.3:a:libasound2:libasound2_data:1.2.6.1-1ubuntu1:*:*:*:*:*:*:*']",Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+tar,1.34+dfsg-1ubuntu0.1.22.04.1,GPL-2 GPL-3,dpkg,['cpe:2.3:a:tar:tar:1.34\\+dfsg-1ubuntu0.1.22.04.1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+charset-normalizer,3.2.0,MIT,PYTHON,"['cpe:2.3:a:python-charset-normalizer:python-charset-normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-charset-normalizer:python_charset_normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_charset_normalizer:python-charset-normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_charset_normalizer:python_charset_normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed_tahri_project:python-charset-normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed_tahri_project:python_charset_normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed_tahriproject:python-charset-normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed_tahriproject:python_charset_normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:charset-normalizer:python-charset-normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:charset-normalizer:python_charset_normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:charset_normalizer:python-charset-normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:charset_normalizer:python_charset_normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-charset-normalizer:charset-normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-charset-normalizer:charset_normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_charset_normalizer:charset-normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_charset_normalizer:charset_normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-charset:python-charset-normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-charset:python_charset_normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_charset:python-charset-normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_charset:python_charset_normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed_tahri_project:charset-normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed_tahri_project:charset_normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed-tahri:python-charset-normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed-tahri:python_charset_normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed_tahri:python-charset-normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed_tahri:python_charset_normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed_tahriproject:charset-normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed_tahriproject:charset_normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:charset-normalizer:charset-normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:charset-normalizer:charset_normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:charset_normalizer:charset-normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:charset_normalizer:charset_normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:charset:python-charset-normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:charset:python_charset_normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-charset:charset-normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python-charset:charset_normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_charset:charset-normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python_charset:charset_normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-charset-normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_charset_normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed-tahri:charset-normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed-tahri:charset_normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed_tahri:charset-normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed_tahri:charset_normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:charset:charset-normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:charset:charset_normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:charset-normalizer:3.2.0:*:*:*:*:*:*:*', 'cpe:2.3:a:python:charset_normalizer:3.2.0:*:*:*:*:*:*:*']",Ahmed TAHRI ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+cryptography,41.0.3,Apache-2.0 OR BSD-3-Clause,PYTHON,"['cpe:2.3:a:python_cryptographic_authority_and_individual_contributors_\\>,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+charset-normalizer,3.3.2,MIT,PYTHON,"['cpe:2.3:a:python-charset-normalizer:python-charset-normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-charset-normalizer:python_charset_normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_charset_normalizer:python-charset-normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_charset_normalizer:python_charset_normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed_tahri_project:python-charset-normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed_tahri_project:python_charset_normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed_tahriproject:python-charset-normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed_tahriproject:python_charset_normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:charset-normalizer:python-charset-normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:charset-normalizer:python_charset_normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:charset_normalizer:python-charset-normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:charset_normalizer:python_charset_normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-charset-normalizer:charset-normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-charset-normalizer:charset_normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_charset_normalizer:charset-normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_charset_normalizer:charset_normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-charset:python-charset-normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-charset:python_charset_normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_charset:python-charset-normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_charset:python_charset_normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed_tahri_project:charset-normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed_tahri_project:charset_normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed-tahri:python-charset-normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed-tahri:python_charset_normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed_tahri:python-charset-normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed_tahri:python_charset_normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed_tahriproject:charset-normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed_tahriproject:charset_normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:charset-normalizer:charset-normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:charset-normalizer:charset_normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:charset_normalizer:charset-normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:charset_normalizer:charset_normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:charset:python-charset-normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:charset:python_charset_normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-charset:charset-normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python-charset:charset_normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_charset:charset-normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python_charset:charset_normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python-charset-normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:python_charset_normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed-tahri:charset-normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed-tahri:charset_normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed_tahri:charset-normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:ahmed_tahri:charset_normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:charset:charset-normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:charset:charset_normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:charset-normalizer:3.3.2:*:*:*:*:*:*:*', 'cpe:2.3:a:python:charset_normalizer:3.3.2:*:*:*:*:*:*:*']",Ahmed TAHRI ,nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libattr1,1:2.5.1-1build1,GPL-2 GPL-2+ LGPL-2+ LGPL-2.1,dpkg,['cpe:2.3:a:libattr1:libattr1:1\\:2.5.1-1build1:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libseccomp2,2.5.3-2ubuntu2,LGPL-2.1,dpkg,['cpe:2.3:a:libseccomp2:libseccomp2:2.5.3-2ubuntu2:*:*:*:*:*:*:*'],Ubuntu Developers (maintainer),nvcr.io/nvidia/morpheus/morpheus:23.11-runtime,linux/amd64,02/01/2024
+libselinux1,3.3-1build2,GPL-2 LGPL-2.1,dpkg,['cpe:2.3:a:libselinux1:libselinux1:3.3-1build2:*:*:*:*:*:*:*'],Ubuntu Developers