diff --git a/examples/basics/kubernetes/Distributed_Inference/README.md b/examples/basics/kubernetes/Distributed_Inference/README.md new file mode 100644 index 0000000000..1a1515608b --- /dev/null +++ b/examples/basics/kubernetes/Distributed_Inference/README.md @@ -0,0 +1,57 @@ +# Distributed Inferences with Dynamo +## 1. Single-Node-Sized Models hosting on multiple Nodes +For SNS (Single-Node-Sized) Model, we can use Dynamo aggregated serving to deploy multiple replicas of the model and create a frontend with different routing strategies +1. Install Dynamo CRD +```sh +export RELEASE_VERSION=0.5.0 # any version of Dynamo 0.3.2+ +helm fetch https://helm.ngc.nvidia.com/nvidia/ai-dynamo/charts/dynamo-crds-${RELEASE_VERSION}.tgz +helm install dynamo-crds dynamo-crds-${RELEASE_VERSION}.tgz --namespace default +``` +2. Install Dynamo platform +Create a K8S namespace for your Dynamo application and install the Dynamo platform. It will install following pods: +- ETCD +- NATS +- Dynamo Operator Controller +```sh +export NAMESPACE=YOUR_DYNAMO_NAMESPACE +kubectl create namespace ${NAMESPACE} +helm fetch https://helm.ngc.nvidia.com/nvidia/ai-dynamo/charts/dynamo-platform-${RELEASE_VERSION}.tgz +helm install dynamo-platform dynamo-platform-${RELEASE_VERSION}.tgz --namespace ${NAMESPACE} +``` +3. Model hosting with vLLM backend +This `agg_router.yaml` is adpated from vLLM deployment [example](https://github.com/ai-dynamo/dynamo/blob/main/components/backends/vllm/deploy/agg_router.yaml). It has following customizations +- Deployed `Qwen/Qwen2.5-1.5B-Instruct` model +- Use KV cache based routing in frontend deployment `--router-mode kv` +- Mounted a local cache folder `/YOUR/LOCAL/CACHE/FOLDER` for model artifacts reuse +- Created 4 replicas for this model deployment by setting `replicas: 4` +- Added `debug` flag environment variable for observability +Create a K8S secret with your Huggingface token and then deploy the models +```sh +export HF_TOKEN=YOUR_HF_TOKEN +kubectl create secret generic hf-token-secret \ + --from-literal=HF_TOKEN=${HF_TOKEN} \ + --namespace ${NAMESPACE} +kubectl apply -f agg_router.yaml --namespace ${NAMESPACE} +``` +4. Testing the deployment and run benchmarks +After deployment, forward the frontend service to access the API: +```sh +kubectl port-forward deployment/vllm-agg-router-frontend 8000:8000 -n ${NAMESPACE} +``` +and use following request to test the deployed model +```sh +curl localhost:8000/v1/chat/completions \ + -H "Content-Type: application/json" \ + -d '{ + "model": "Qwen/Qwen3-0.6B", + "messages": [ + { + "role": "user", + "content": "In the heart of Eldoria, an ancient land of boundless magic and mysterious creatures, lies the long-forgotten city of Aeloria. Once a beacon of knowledge and power, Aeloria was buried beneath the shifting sands of time, lost to the world for centuries. You are an intrepid explorer, known for your unparalleled curiosity and courage, who has stumbled upon an ancient map hinting at ests that Aeloria holds a secret so profound that it has the potential to reshape the very fabric of reality. Your journey will take you through treacherous deserts, enchanted forests, and across perilous mountain ranges. Your Task: Character Background: Develop a detailed background for your character. Describe their motivations for seeking out Aeloria, their skills and weaknesses, and any personal connections to the ancient city or its legends. Are they driven by a quest for knowledge, a search for lost familt clue is hidden." + } + ], + "stream": false, + "max_tokens": 30 + }' + ``` +You can also benchmark the performance of the endpoint by [GenAI-Perf](https://docs.nvidia.com/deeplearning/triton-inference-server/user-guide/docs/perf_analyzer/genai-perf/README.html) diff --git a/examples/basics/kubernetes/Distributed_Inference/agg_router.yaml b/examples/basics/kubernetes/Distributed_Inference/agg_router.yaml new file mode 100644 index 0000000000..f4fb97eacf --- /dev/null +++ b/examples/basics/kubernetes/Distributed_Inference/agg_router.yaml @@ -0,0 +1,107 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: nvidia.com/v1alpha1 +kind: DynamoGraphDeployment +metadata: + name: vllm-agg-router +spec: + services: + Frontend: + livenessProbe: + httpGet: + path: /health + port: 8000 + initialDelaySeconds: 60 + periodSeconds: 60 + timeoutSeconds: 30 + failureThreshold: 10 + readinessProbe: + exec: + command: + - /bin/sh + - -c + - 'curl -s http://localhost:8000/health | jq -e ".status == \"healthy\""' + initialDelaySeconds: 60 + periodSeconds: 60 + timeoutSeconds: 30 + failureThreshold: 10 + dynamoNamespace: vllm-agg-router + componentType: main + replicas: 1 + resources: + requests: + cpu: "1" + memory: "2Gi" + limits: + cpu: "1" + memory: "2Gi" + extraPodSpec: + mainContainer: + image: nvcr.io/nvidia/ai-dynamo/vllm-runtime:0.5.0 + workingDir: /workspace/components/backends/vllm + command: + - /bin/sh + - -c + args: + - "python3 -m dynamo.frontend --http-port 8000 --router-mode kv" + VllmDecodeWorker: + envFromSecret: hf-token-secret + livenessProbe: + httpGet: + path: /live + port: 9090 + periodSeconds: 5 + timeoutSeconds: 30 + failureThreshold: 1 + readinessProbe: + httpGet: + path: /health + port: 9090 + periodSeconds: 10 + timeoutSeconds: 30 + failureThreshold: 60 + dynamoNamespace: vllm-agg-router + componentType: worker + replicas: 4 + resources: + requests: + cpu: "10" + memory: "20Gi" + gpu: "1" + limits: + cpu: "10" + memory: "20Gi" + gpu: "1" + envs: + - name: DYN_SYSTEM_ENABLED + value: "true" + - name: DYN_SYSTEM_USE_ENDPOINT_HEALTH_STATUS + value: "[\"generate\"]" + - name: DYN_SYSTEM_PORT + value: "9090" + - name: DYN_LOG + value: "debug" + extraPodSpec: + volumes: + - name: local-model-cache + hostPath: + path: /YOUR/LOCAL/CACHE/FOLDER + type: DirectoryOrCreate + mainContainer: + startupProbe: + httpGet: + path: /health + port: 9090 + periodSeconds: 10 + failureThreshold: 60 + image: nvcr.io/nvidia/ai-dynamo/vllm-runtime:0.5.0 + volumeMounts: + - name: local-model-cache + mountPath: /root/.cache + workingDir: /workspace/components/backends/vllm + command: + - /bin/sh + - -c + args: + - python3 -m dynamo.vllm --model Qwen/Qwen3-0.6B 2>&1 | tee /tmp/vllm.log