Deploy with Helm Chart#
This guide shows how to deploy the Live Video Captioning RAG application on Kubernetes with the Helm chart included in this repository.
The live-video-captioning-rag/charts chart is a parent chart that deploys:
Live Video Captioning core services (
mqtt-broker,dlstreamer-pipeline-server,video-caption-service,mediamtx,coturn, andmetrics-manager)Live Video Captioning RAG service
Multimodal embedding service
VDMS vector database service
Prerequisites#
Before you begin, ensure that you have the following:
A Kubernetes cluster with
kubectlconfigured for access.Helm installed on your system. See the Installation Guide.
The cluster must support dynamic provisioning of Persistent Volumes (PV). See Kubernetes Documentation on Dynamic Volume Provisioning for details.
A worker node reachable by your browser client. Prefer a GPU-capable worker node when available, because the chart pins media and inference workloads to the selected node.
An Intel GPU/NPU-capable worker node is recommended so the
metrics-managercan report GPU and NPU utilization (via qmassa). GPU/NPU metrics are omitted on nodes without the hardware.An RTSP source reachable from the Kubernetes node that runs
dlstreamer-pipeline-server.Setup the Model Download chart, which is responsible for downloading and converting models used by this deployment. If you use gated Hugging Face models, a Hugging Face token is required.
Prepare/Deploy model-download chart#
Model Download Service from Open Edge Platform - Edge AI Libraries is used for model management.
Install the model-download chart.
Refer to this guide section to download and install the chart.
Configure the values.yaml file.
Edit the
values.yamllocated in the model-download chart.Configure the following:
Parameter
Description
Required Values
proxySet the proxy value based on your system environment
<your_system_proxy>HUGGINGFACEHUB_API_TOKENHuggingFace token to download gated model
<your_huggingface_token>ENABLE_PLUGINSComma-separated list of plugins to enable
"openvino,ultralytics"OVMS_RELEASE_TAGOVMS release tag used by the conversion script
default:
v2025.4.1gpu.enabledDeploy model-download service pod on GPU node
truegpu.keyGPU node resource key from your Kubernetes node
gpu.intel.com/i915orgpu.intel.com/xeaffinity.enabledSet to true to deploy on dedicated node
trueaffinity.valueDedicated node name/value from
kubectl get node<your_node_name>Note: The chart can run on CPU-only nodes; however, a GPU-enabled node is strongly recommended for better conversion and runtime performance.
Deploy the chart.
helm install model-download . -n <your-namespace>
Note:
model-downloadcreates and manages a shared PVC consumed by Live Video Captioning and Live Video Captioning RAG workloads.Verify deployment.
kubectl get pods -n <your-namespace> kubectl get services -n <your-namespace>
Prepare/Deploy live-video-captioning-rag chart#
To set up the integrated deployment, obtain the chart and install it with your environment-specific overrides.
Acquire the chart#
Option 1: Get charts from Docker Hub#
Run the following command to pull the prebuild chart from Docker Hub. Refer to the release notes for details on the latest version number to use for the sample application.
helm pull oci://registry-1.docker.io/intel/live-video-captioning-rag --version <version-no>
Note: When browsing available tags, look for tags ending with the
helmsuffix — these indicate a Helm chart package.Extract the
.tgzfile.tar -xvf live-video-captioning-rag-<version-no>.tgz cd live-video-captioning-rag
Configure the
values-override.yamlusing the Select target node and Configured required values sections below.Install/Deploy the chart.
helm install lvc-rag . \ -f values-override.yaml \ -n "$my_namespace"
See the Verify the deployment section to confirm the deployment.
If you modify the chart or subcharts, refresh dependencies first:
# Update/refresh the chart helm dependency update
Then upgrade the deployment:
helm upgrade lvc-rag . \ -f values-override.yaml \ -n "$my_namespace"
Uninstall the chart.
helm uninstall lvc-rag -n "$my_namespace"
Option 2: Install from source#
Clone the repository.
# Clone latest mainline git clone https://github.com/open-edge-platform/edge-ai-suites.git edge-ai-suites -b main # Or clone a specific release branch git clone https://github.com/open-edge-platform/edge-ai-suites.git edge-ai-suites -b <release-tag>
Navigate to the chart directory.
cd edge-ai-suites/metro-ai-suite/live-video-analysis/live-video-captioning-rag/charts
Select the target node#
The chart pins host-coupled workloads from both to one target node via global.nodeName, including:
model-downloaddlstreamer-pipeline-servervideo-caption-servicemediamtxcoturnmetrics-managerlive-video-captioning-rag
This keeps media, model PVC access, and host-exposed ports aligned on a single reachable worker.
In charts/values-override.yaml, set:
global:
nodeName: worker4
Use the same node that you used for model-download.
Configure host-reachable IP#
Set global.hostIP to the node IP your browser can reach.
Helpful commands:
kubectl get node <your_node_name> -owide
kubectl get node <node-name> -o jsonpath='{.status.addresses[?(@.type=="InternalIP")].address}'
kubectl get node <node-name> -o jsonpath='{.status.addresses[?(@.type=="ExternalIP")].address}'
Use
INTERNAL-IPwhen your browser is on the same reachable network (LAN/VPN).Use
EXTERNAL-IPwhen internal networking is not directly reachable.
Configure required values#
Prior to deployment, edit charts/values-override.yaml and set at least the following:
Key |
Description |
Example |
|---|---|---|
|
Browser-reachable IP of the selected node |
|
|
Node name used to pin host-coupled services |
|
|
VLM model entries for captioning ( |
|
|
Hugging Face token for gated models (if needed) |
|
|
LLM model for RAG chatbot |
|
|
Precision of model weights for conversion |
|
|
Enable GPU scheduling for LLM model runtime |
|
|
GPU resource key used to schedule the LLM workload |
|
|
Enable GPU scheduling for embedding model runtime |
|
|
GPU resource key used to schedule embedding workload |
|
|
Max generated tokens for RAG response |
|
|
Number of retrieved context candidates |
|
Note: You can find GPU resource keys by running
kubectl describe node <node-name>. Common values for intel GPUs includegpu.intel.com/i915andgpu.intel.com/xe.Note: If
NPUis selected inglobal.models[].devicefor VLM models,weightFormatis automatically forced toint4.Note: LLM models in the Live-Video-Captioning-RAG application currently do not support NPU inference.
Optional: Proxy configuration#
If your cluster is behind a proxy, configure:
global:
httpProxy: "http://<your-proxy-host>:<port>"
httpsProxy: "http://<your-proxy-host>:<port>"
noProxy: "<your-rtsp-camera-host-or-ip>"
Important: the host portion of every RTSP URL must be included in
noProxywhen the deployment runs behind a proxy.For example:
If your stream URL is
rtsp://camera.example.com:8554/live, addcamera.example.comtonoProxy.If your stream URL is
rtsp://192.168.1.50:554/stream1, add192.168.1.50tonoProxy.If the RTSP host is not listed in
noProxy, the application may try to reach the stream through the proxy and fail to connect.
Optional: Detection pipeline#
To enable detection filtering in captioning flow, set:
live-video-captioning.video-caption-service.env.enableDetectionPipeline: "true"global.detectionModelswith required detection models (for example,yolov8s)
Build chart dependencies#
Run from the charts/ directory, build the chart using the Makefile target:
make deps
This builds dependencies in the required order for both child and parent charts.
Install the chart#
From charts/, deploy using the Makefile target:
make deploy NAMESPACE=<your-namespace>
To see available targets and overridable variables for Makefile (for example, RELEASE, NAMESPACE, and VALUES_FILE), run:
make help
Verify the deployment#
Before accessing the application, confirm:
models-pvcis inBoundstate.All pods are in
Runningstate.All containers are
Ready.
kubectl get pvc -n <your-namespace>
kubectl get pods -n <your-namespace>
kubectl get services -n <your-namespace>
Note: First-time deployment can take several minutes because models may be downloaded and converted before services become ready.
Access the application#
By default, the chart exposes:
Live Video Captioning dashboard:
http://<global.hostIP>:4173Live Video Captioning RAG dashboard/API:
http://<global.hostIP>:4172
To start:
Open the Live Video Captioning dashboard.
Provide RTSP URL (or select available USB/webcam source).
Select runtime device and model.
Start stream to generate captions and embedding context.
Use the chat icon in the Live Video Captioning UI (RAG-enabled flow), or access the RAG dashboard directly on port
4172.
Upgrade the release#
If you modify chart or subcharts, rerun:
make deps
Then apply the update:
make deploy NAMESPACE=<your-namespace>
Uninstall the release#
make uninstall
Known Limitations#
Single-node deployment with host port binding#
This chart is designed to run on a single worker node.
global.nodeNamepins host-coupled workloads to one node.live-video-captioning-raguses host port binding on port4172;replicaCountmust remain1.Multi-node or high-availability deployment is not supported in the current chart design.
Ensure required host ports are not already in use on the selected node.
Troubleshooting#
If pods remain
Pending, verifyglobal.nodeNameand hardware/resource availability on the selected node.If dashboard opens but video does not start, verify
global.hostIPreachability and RTSP source reachability from the node.If RAG service remains in
Init, inspect init container logs for model download and embedding readiness:kubectl get pods -n <your-namespace> kubectl logs -f <live-video-captioning-rag-pod> -n <your-namespace> -c download-models kubectl logs -f <live-video-captioning-rag-pod> -n <your-namespace> -c wait-for-multimodal-embedding
If
metrics-managerdoes not report metrics, verify scheduling on the target node and required host access permissions.If model download fails for gated models, ensure
global.huggingface.apiTokenis configured with a valid token.If PVCs are left behind after failed deployments, list and clean them manually only after confirming no dependent workloads are running:
kubectl get pvc -n <your-namespace> kubectl delete pvc <pvc-name> -n <your-namespace>