# How to Deploy with Helm\* Chart This section shows how to deploy the Video Search and Summarization Sample Application using Helm chart. ## Prerequisites Before you begin, ensure that you have the following: - Kubernetes\* cluster set up and running. - The cluster must support **dynamic provisioning of Persistent Volumes (PV)**. Refer to the [Kubernetes Dynamic Provisioning Guide](https://kubernetes.io/docs/concepts/storage/dynamic-provisioning/) for more details. - Install `kubectl` on your system. See the [Installation Guide](https://kubernetes.io/docs/tasks/tools/install-kubectl/). Ensure access to the Kubernetes cluster. - Helm chart installed on your system. See the [Installation Guide](https://helm.sh/docs/intro/install/). - **Storage Requirement :** Application requests for **50GiB** of storage in its default configuration. (This should change with choice of models and needs to be properly configured). Please make sure that required storage is available in you cluster. ## Helm Chart Installation In order to setup the end-to-end application, we need to acquire the charts and install it with optimal values and configurations. Subsequent sections will provide step by step details for the same. ### 1. Acquire the Helm chart There are 2 options to get the charts in your workspace: #### Option 1: Get the charts from Docker Hub ##### Step 1: Pull the Specific Chart Use the following command to pull the Helm chart from Docker Hub: ```bash helm pull oci://registry-1.docker.io/intel/video-search-and-summarization --version 2026.2.0-rc2-helm ``` Use chart version `2026.2.0-rc2-helm` for this release workflow. ##### Step 2: Extract the `.tgz` File After pulling the chart, extract the `.tgz` file: ```bash tar -xvf video-search-and-summarization-2026.2.0-rc2-helm.tgz ``` This will create a directory named `video-search-and-summarization` containing the chart files. Navigate to the extracted directory to access the charts. ```bash cd video-search-and-summarization ``` #### Option 2: Install from Source ##### Step 1: Clone the Repository Clone the repository containing the Helm chart: ```bash # Clone the latest on mainline # git clone https://github.com/open-edge-platform/edge-ai-libraries.git edge-ai-libraries # Clone the release branch git clone https://github.com/open-edge-platform/edge-ai-libraries.git edge-ai-libraries -b release-2026.2.0 ``` ##### Step 2: Change to the Chart Directory Navigate to the chart directory: ```bash cd edge-ai-libraries/sample-applications/video-search-and-summarization/chart ``` ### 2. Configure Required Values The application requires several values to be set by user in order to work. To make it easier, we have included a `user_values_override.yaml` file, which contains only the values that user needs to tweak. Open the file in your favorite editor or use nano: ```bash nano user_values_override.yaml ``` Update or edit the values in YAML file as follows: | Key | Description | Example Value | | --- | ----------- | ------------- | | `global.registry` | Single-source image registry override for all VSS service images (pipeline-manager, video-ingestion, video-search, vss-ui, multimodal-dataprep, multimodal-embedding-serving, vector-retriever). Leave empty to keep each subchart's own default. | `""` or `my-registry.example.com/vss/` | | `global.tag` | Single-source image tag override for the VSS service images above. Also used as fallback for `global.modelDownload.image.tag` when that value is empty. | `""` or `2026.2.0-rc2` | | `global.modelDownload.image.tag` | Optional explicit model-download image tag. Leave empty to inherit `global.tag` (and if both are empty, chart defaults to `latest`). | `""` or `2026.2.0-rc2` | | `global.pullPolicy` | Image pull policy override for the VSS service images above. Leave empty to keep each subchart's default (`IfNotPresent`). Set to `Always` to force a fresh pull on every pod start (e.g. when reusing a mutable tag). | `""`, `Always`, or `IfNotPresent` | | `global.metricsManager.enabled` | Deploy Metrics Manager and enable direct DataPrep metric publishing | `true` or `false` | | `global.keepPvc` | PVC gets deleted by default once helm is uninstalled. Set this to true to persist PVC (helps avoid delay due to model re-downloads when re-installing chart). | `true` or `false` | | `global.huggingfaceToken` | Your Hugging Face API token | `` | | `global.proxy.http_proxy` | HTTP proxy if required | `http://proxy-example.com:000` | | `global.proxy.https_proxy` | HTTPS proxy if required | `http://proxy-example.com:000` | | `global.vlmName` | VLM model to be used by OVMS or vLLM for captioning and summarization | `Qwen/Qwen3-VL-4B-Instruct` (CPU) or `OpenVINO/Phi-3.5-vision-instruct-int8-ov` (GPU) | | `global.llmName` | Optional separate LLM model for final summarization (OVMS split-model mode). Leave empty for shared-model mode. | `Qwen/Qwen3-4B-Instruct-2507` (CPU) or `Qwen/Qwen3-4B-Instruct-2507` (GPU) or `OpenVINO/Qwen3-8B-int4-cw-ov` (NPU) | | `global.env.POSTGRES_USER` | PostgreSQL user | `` | | `global.env.POSTGRES_PASSWORD` | PostgreSQL password | `` | | `global.env.MINIO_ROOT_USER` | MinIO server user name | `` (at least 3 characters) | | `global.env.MINIO_ROOT_PASSWORD` | MinIO server password | `` (at least 8 characters) | | `global.env.RABBITMQ_DEFAULT_USER` | RabbitMQ username | `` | | `global.env.RABBITMQ_DEFAULT_PASS` | RabbitMQ password | `` | | `global.env.OTLP_ENDPOINT` | OTLP endpoint | Leave empty if not using telemetry | | `global.env.OTLP_ENDPOINT_TRACE` | OTLP trace endpoint | Leave empty if not using telemetry | | `global.env.MM_DATAPREP_ALLOW_DUPLICATE_UPLOADS` | Duplicate-upload policy for `multimodal-dataprep`. `true` keeps historical behavior (accept content-identical re-uploads). `false` rejects duplicate-content uploads with HTTP `409`. | `true` (default) or `false` | | `global.embeddingModelName` | Embedding model used by Multimodal Embedding MS, DataPrep, and Video Search. Use a multimodal model for search-only and dual mode (e.g., `CLIP/clip-vit-b-32`) or a text embedding model for unified mode (e.g., `QwenText/qwen3-embedding-0.6b`). | `CLIP/clip-vit-b-32` or `QwenText/qwen3-embedding-0.6b` | | `global.vectordbBackend` | Active vector database backend used by `multimodal-dataprep` and `vector-retriever`. | `vdms` (default) or `milvus` | | `global.devices.multimodalEmbedding.device` | Device for multimodal-embedding service | `CPU`, `GPU`, or `NPU` | | `global.devices.multimodalEmbedding.key` | K8s resource key for accelerator (required when device=GPU/NPU) | `gpu.intel.com/i915`, `gpu.intel.com/xe`, or `npu.intel.com/accel` | | `global.devices.multimodalDataprep.embedding.device` | Device for DataPrep embedding execution | `CPU`, `GPU`, or `NPU` | | `global.devices.multimodalDataprep.embedding.key` | K8s resource key for DataPrep embedding accelerator (required when embedding.device=GPU/NPU) | `gpu.intel.com/i915`, `gpu.intel.com/xe`, or `npu.intel.com/accel` | | `global.devices.multimodalDataprep.detection.device` | Device for DataPrep object-detection execution | `CPU`, `GPU`, or `NPU` | | `global.devices.multimodalDataprep.detection.key` | K8s resource key for DataPrep detection accelerator (required when detection.device=GPU/NPU) | `gpu.intel.com/i915`, `gpu.intel.com/xe`, or `npu.intel.com/accel` | | `global.devices.ovms.vlm.device` | Device for OVMS VLM model | `CPU`, `GPU`, `NPU`, or `HETERO:GPU,CPU` | | `global.devices.ovms.vlm.key` | K8s resource key (required when device is GPU/NPU/HETERO) | `gpu.intel.com/i915`, `gpu.intel.com/xe`, or `npu.intel.com/accel` | | `global.devices.ovms.llm.device` | Device for OVMS LLM model (split-model mode) | `CPU`, `GPU`, `NPU`, or `HETERO:GPU,CPU` | | `global.devices.ovms.llm.key` | K8s resource key (required when device is GPU/NPU/HETERO) | `gpu.intel.com/i915`, `gpu.intel.com/xe`, or `npu.intel.com/accel` | | `global.accelGroupIds` | Host group ids owning the accelerator device nodes (`/dev/dri` for GPU, `/dev/accel` for NPU). Added to the pod `supplementalGroups` when a service uses GPU/NPU so the non-root container user can open the device. Host-specific — override to match the target node. | `[992]` | | `ovms.env.VLM_WEIGHT_FORMAT` | Override weight format for VLM model conversion | `int4` or `int8` (auto-detected if not set) | | `ovms.env.LLM_WEIGHT_FORMAT` | Override weight format for LLM model conversion | `int4` or `int8` (auto-detected if not set) | | `ovms.enabled` | Enable OVMS as the inference backend (default: true in summary mode) | `true` or `false` | | `vllm.enabled` | Enable vLLM as the inference backend (alternative to OVMS) | `true` or `false` | | `pipelinemanager.env.USE_VLLM` | Set to `CONFIG_ON` when using vLLM backend | `CONFIG_OFF` (default) or `CONFIG_ON` | | `pipelinemanager.env.AUDIO_DEVICE` | Device used for audio transcription (Whisper) | `cpu` (default) | | `pipelinemanager.env.AUDIO_USE_FULL_TRANSCRIPT_SUMMARY` | Default for audio transcript summarization. When enabled, the full audio transcript is summarized by the LLM and included in the final video summary. Users can override this per-video via the UI toggle. | `true` (default) or `false` | | `pipelinemanager.env.PRODUCE_FINAL_SUMMARY` | Default for producing a final video summary. When enabled, chunk summaries are consolidated into a single video summary via map-reduce. When disabled, only per-chunk summaries are generated. Users can override this per-video via the UI toggle. | `true` (default) or `false` | | `pipelinemanager.env.SEARCH_DATAPREP_TIMEOUT_MS` | Timeout in milliseconds for search dataprep operations (video embedding pipeline). Increase for large videos or slow hardware. | `600000` (default, 10 minutes) | | `videoingestion.odModelName` | Name of object detection model (generic YOLO id from the model-download ultralytics hub) used during video ingestion | `yolov8l` | | `metricsmanager.image.repository` | Metrics Manager image repository | `docker.io/intel/metrics-manager` | | `metricsmanager.image.tag` | Metrics Manager image tag | `2026.2.0-rc2` | > **`MM_DATAPREP_ALLOW_DUPLICATE_UPLOADS` override:** You do **not** need to put this in `user_values_override.yaml`. You can set it directly at install/upgrade time with `--set`, for example: > > ```bash > helm install vss . -f search_override.yaml -f user_values_override.yaml \ > --set global.env.MM_DATAPREP_ALLOW_DUPLICATE_UPLOADS=false -n $my_namespace > ``` > **Tip:** Set `global.embeddingModelName` to pick the embedding model for all services. For search-only and dual UI mode, use a multimodal model (e.g., `CLIP/clip-vit-b-32`). For unified mode, use a text embedding model (e.g., `QwenText/qwen3-embedding-0.6b`). Review the supported model list in [supported-models](https://docs.openedgeplatform.intel.com/2026.2/edge-ai-libraries/multimodal-embedding-serving/supported-models.html) before choosing model IDs. > **DataPrep device override precedence:** `global.devices.multimodalDataprep.embedding.device` and `global.devices.multimodalDataprep.detection.device` are set independently in `user_values_override.yaml`. Each defaults to `CPU`; set `GPU`/`NPU` (with the matching resource `key`) to offload that component. > **Note:** `multimodal-embedding-ms` and `multimodal-dataprep` now use independent PVCs for model/cache data by default, so their device settings can be configured independently. > **Single-source image override:** Set `global.registry`, `global.tag`, and `global.pullPolicy` once to apply across all VSS service images (pipeline-manager, video-ingestion, video-search, vss-ui, multimodal-dataprep, multimodal-embedding-serving, vector-retriever) instead of overriding each subchart. Leave any of them empty to keep that subchart's own default. Set `global.pullPolicy: Always` when you reuse a mutable tag and need a fresh pull on every pod start. > **Accelerator device permissions:** When a service runs on GPU or NPU, its host accelerator node (`/dev/dri` for GPU, `/dev/accel` for NPU) is mounted and the gids in `global.accelGroupIds` are added to the pod `supplementalGroups` so the non-root container user can open the device. These gids are host-specific (they mirror the Compose `group_add` render/video groups) — check the target node with `ls -ln /dev/accel` and `ls -ln /dev/dri` and override `global.accelGroupIds` to match (default `[992]`). If the gid is wrong, OpenVINO™ falls back to CPU-only and NPU/GPU device initialization fails. > **OpenVINO™ model cache:** On GPU/NPU, `multimodal-embedding-ms` and `multimodal-dataprep` write the first-time OpenVINO™ model compilation to `ovCacheDir` (default `/app/ov_models/ov_cache`, on the persistent models mount), so the compile is reused across pod restarts instead of recompiling on every start. The DataPrep `startupProbe` budget is sized to allow this first cold compile to finish before the pod is restarted. > **Metrics Manager:** Set `global.metricsManager.enabled=true` for search, > dual, or unified deployments. The chart mounts host `/dev`, `/sys`, and > `/run`, uses host PID visibility, and runs the service privileged so it can > collect CPU, RAM, Intel GPU, and Intel NPU metrics. DataPrep publishes > embeddings/sec directly to `http://metrics-manager:9090`; nginx exposes only > `/metrics-manager/health` and `/metrics-manager/metrics/stream`. The bundled > DataPrep image must contain the direct publisher introduced with this > integration. Missing GPU/NPU devices simply result in absent device metrics. > **Split-device OVMS example (GPU VLM + NPU LLM):** > > To run VLM on GPU and LLM on NPU, set the following in `user_values_override.yaml`: > > ```yaml > global: > vlmName: "OpenVINO/Phi-3.5-vision-instruct-int8-ov" > llmName: "OpenVINO/Qwen3-8B-int4-cw-ov" > devices: > ovms: > vlm: > device: GPU > key: "gpu.intel.com/i915" > llm: > device: NPU > key: "npu.intel.com/accel" > ``` ### 3. Build Helm Dependencies Navigate to the chart directory and build the Helm dependencies using the following command: ```bash helm dependency update ``` ### 4. Set and Create a Namespace We will install the Helm chart in a new namespace. Create a shell variable to refer a new namespace and create it. 1. Refer a new namespace using shell variable `my_namespace`. Set any desired unique value. ```bash my_namespace=foobar ``` 2. Create the Kubernetes namespace. If it is already created, creation will fail. You can update the namespace in previous step and try again. ```bash kubectl create namespace $my_namespace ``` > **Note:** All subsequent steps assume that you have `my_namespace` variable set and accessible on your shell with the desired namespace as its value. ### 5. Deploy the Helm Chart At present, there are multiple deployment modes for **Video Search and Summarization Application**. We will learn how to deploy each use-case using the Helm chart. > **Note:** Before switching to a different use-case always stop the current running use-case's application stack (if any) by uninstalling the chart : `helm uninstall vss -n $my_namespace`. This is not required if you are installing the Helm chart for the first time. #### **Use Case 1: Video Summarization with OVMS (Default - CPU)** Deploy the Video Summarization application using OVMS (OpenVINO™ Model Server) for both VLM captioning and LLM summarization: ```bash helm install vss . -f summary_override.yaml -f user_values_override.yaml -n $my_namespace ``` This is the default and recommended deployment mode. OVMS hosts the VLM model specified in `global.vlmName` and uses it for both chunk-wise captioning and final summarization (shared-model mode). > **Note:** When deploying OVMS, the service may take longer to start on first run due to model conversion. Subsequent starts are faster as models are cached. #### **Use Case 1a: OVMS with Separate LLM Model (Split-Model Mode)** To use a separate LLM model for final summarization while using VLM for captioning, set `global.vlmName` and `global.llmName` in `user_values_override.yaml`: ```yaml global: vlmName: "Qwen/Qwen3-VL-4B-Instruct" llmName: "Qwen/Qwen3-4B-Instruct-2507" ``` Then deploy: ```bash helm install vss . -f summary_override.yaml -f user_values_override.yaml -n $my_namespace ``` This deploys OVMS hosting both models: - VLM model (from `global.vlmName`) for chunk-wise captioning - LLM model (from `global.llmName`) for final summarization #### **Use Case 1b: OVMS with GPU Acceleration** To enable GPU acceleration for OVMS, configure the device settings and model in `user_values_override.yaml`: ```yaml global: vlmName: "OpenVINO/Phi-3.5-vision-instruct-int8-ov" devices: ovms: vlm: device: GPU key: "gpu.intel.com/i915" ``` Then deploy: ```bash helm install vss . -f summary_override.yaml -f user_values_override.yaml -n $my_namespace ``` > **Note:** GPU deployment requires the Intel device plugin to be installed on your cluster. Verify your GPU node label with `kubectl describe node ` and set the appropriate `key` value accordingly. ##### Discovering Available Device Resource Keys Before configuring GPU or NPU devices, verify what resources are available in your cluster: **List all allocatable resources across all nodes:** ```bash kubectl get nodes -o json | jq -r '.items[] | "\(.metadata.name):\n" + (.status.allocatable | to_entries | map(select(.key | test("gpu|npu|vpu|accel";"i"))) | map(" \(.key): \(.value)") | join("\n"))' ``` **Alternative - inspect a specific node:** ```bash kubectl describe node | grep -A20 "Allocatable:" | grep -E "gpu|npu|vpu|accel" ``` **Common Intel device resource keys:** | Device Type | Common Resource Keys | | ----------- | -------------------- | | Intel Integrated GPU | `gpu.intel.com/i915` | | Intel Discrete GPU (Arc/Flex) | `gpu.intel.com/xe` | | Intel NPU (AI Boost) | `npu.intel.com/accel` | > **Tip:** If no GPU/NPU resources appear, ensure the Intel device plugin is installed. See [Intel Device Plugins for Kubernetes](https://github.com/intel/intel-device-plugins-for-kubernetes). > > **Split-device note:** When using different devices for VLM and LLM (e.g., GPU + NPU), ensure at least one node in your cluster has **both** resources available. The pod will only schedule on nodes that satisfy all resource requests. > > **NPU Support:** Not all models support NPU execution. Verify model and hardware compatibility at the [OpenVINO™ Supported Models](https://docs.openvino.ai/2026/documentation/compatibility-and-support/supported-models.html) page before selecting `NPU` as target device. ##### Model Weight Format OVMS automatically selects the optimal weight compression format based on the target device: | Device | Default Weight Format | | ------ | --------------------- | | CPU | `int8` | | GPU | `int4` | | NPU | `int4` | | HETERO:GPU,CPU | `int4` | **Overriding Weight Format:** To explicitly set the weight format for VLM or LLM models, set `ovms.env.VLM_WEIGHT_FORMAT` and/or `ovms.env.LLM_WEIGHT_FORMAT` in `user_values_override.yaml`: ```yaml ovms: env: VLM_WEIGHT_FORMAT: "int8" LLM_WEIGHT_FORMAT: "int8" ``` > **Note:** Models from the `OpenVINO/` namespace (e.g., `OpenVINO/Phi-3.5-vision-instruct-int8-ov`) are pre-converted and do not undergo weight format conversion. The weight format in the model name indicates its native format. > > **Storage Model Names:** Converted models are stored with device and weight format in the path (e.g., `Qwen_Qwen2.5-VL-3B-Instruct_GPU_int4`). Changing the device or weight format creates a new conversion, preserving existing models. #### **Use Case 2: Video Summarization with vLLM (CPU-based)** If you want to use vLLM as the inference backend for CPU-based deployment, deploy with the vLLM override values: ```bash helm install vss . -f summary_override.yaml -f xeon_vllm_values.yaml -f user_values_override.yaml -n $my_namespace ``` **vLLM Configuration Details:** - vLLM provides an OpenAI-compatible API for efficient LLM inference on CPU - The `xeon_vllm_values.yaml` override file includes: - vLLM service with 16 CPU cores and 128Gi memory allocation - Resource configurations for all dependent services (PostgreSQL, RabbitMQ, audio-analyzer, etc.) - Automatic disabling of OVMS (`ovms.enabled=false`) **Prerequisites for vLLM:** - Ensure your Kubernetes node has sufficient CPU resources (minimum 32 logical cores recommended) - The vLLM container requires at least 128Gi of memory for typical LLM models - Cache storage must be configured (default 80Gi PVC for model cache) > **Model Selection:** vLLM uses the model specified in `global.vlmName`. Set `global.vlmName: "Qwen/Qwen2.5-VL-3B-Instruct"` for vLLM. Ensure the model is compatible with vLLM and available on Hugging Face. Update `global.huggingfaceToken` if using private models. > > **Performance Tip:** vLLM's performance scales with available CPU cores. If you have nodes with different CPU counts, consider using node affinity to deploy vLLM on high-CPU nodes. #### **Use Case 3: Video Search Only** To deploy only the Video Search functionality, first set `global.embeddingModelName` to a multimodal embedding model (e.g., "CLIP/clip-vit-b-32"). Then run the following command: ```bash helm install vss . -f search_override.yaml -f user_values_override.yaml -n $my_namespace ``` To deploy the same search stack on the Milvus backend (equivalent to `VECTORDB_BACKEND=milvus` in Compose), add the Milvus override file: ```bash helm install vss . -f search_override.yaml -f search_milvus_override.yaml -f user_values_override.yaml -n $my_namespace ``` > **Important — clear persisted data when switching backends:** embeddings live only in the vector database, but uploaded videos and their metadata live in MinIO and the Pipeline Manager's PostgreSQL database, which are backed by PVCs shared across backends. Switching `global.vectordbBackend` without clearing them leaves the previously ingested videos visible in the UI while the new backend holds no embeddings for them, so search returns nothing for those videos. Uninstall the chart, delete the PVCs, then reinstall: > > ```bash > helm uninstall vss -n $my_namespace > kubectl delete pvc --all -n $my_namespace > helm install vss . -f search_override.yaml -f search_milvus_override.yaml -f user_values_override.yaml -n $my_namespace > ``` > > `kubectl delete pvc --all` also removes the model-cache PVCs, so the first start after this re-downloads and re-converts the models. To keep those, delete only the data PVCs (MinIO, PostgreSQL, dataprep and the vector database) instead — list them with `kubectl get pvc -n $my_namespace`. Alternatively, re-ingest every video after the switch instead of clearing the PVCs. #### **Use Case 4: Unified Video Search and Summarization** To deploy the combined video search and summarization functionality with a single unified UI: ```bash helm install vss . -f unified_summary_search.yaml -f user_values_override.yaml -n $my_namespace ``` > **Requirement:** Before installing the unified stack, set `global.embeddingModelName` to a text embedding model (e.g., `QwenText/qwen3-embedding-0.6b`) in `user_values_override.yaml`. The chart will raise an error if the embedding model is not set. Review the supported model list in [supported-models](https://docs.openedgeplatform.intel.com/2026.2/edge-ai-libraries/multimodal-embedding-serving/supported-models.html) before choosing model IDs. > > **Device Tip:** In unified mode, `multimodal-embedding-ms` and `multimodal-dataprep` run with independent PVC-backed model/cache storage, so you can choose different devices per service. #### **Use Case 5: Dual UI (Separate Summary and Search UIs)** Deploy both Summary and Search functionality with separate UIs accessible via path-based routing by combining both override files: ```bash helm install vss . -f summary_override.yaml -f search_override.yaml -f user_values_override.yaml -n $my_namespace ``` This mode deploys two independent UI instances: - **Summary UI** accessible at `http://:/summary/` - **Search UI** accessible at `http://:/search/` The root URL (`/`) redirects to `/summary/` by default. > **How it works:** Combining `summary_override.yaml` and `search_override.yaml` enables both VSS UI subchart aliases (`summaryui` and `searchui`). Nginx is automatically configured with path-based routing when both aliases are enabled; using either override file alone routes `/` to the single enabled UI. > > **Requirements:** Same as Use Case 4 (unified mode) — both summary and search backends are enabled. Set `global.embeddingModelName` to a text embedding model in `user_values_override.yaml`. > > **When to use Dual UI vs Unified:** Use Dual UI when you want physically separate interfaces for summary and search workflows (e.g., different teams or use cases). Use Unified when you prefer a single combined interface. ### Step 6: Verify the Deployment Check the status of the deployed resources to ensure everything is running correctly: ```bash kubectl get pods -n $my_namespace ``` **Before proceeding to access the application we must ensure the following status of output of the above command:** 1. Ensure all pods are in the "Running" state. This is denoted by **Running** state mentioned in the **STATUS** column. 2. Ensure all containers in each pod are _Ready_. As all pods are running single container only, this is typically denoted by mentioning **1/1** in the **READY** column. > **Important:** > > - When deployed for first time, it may take up-to around 50 Mins to bring all the pods/containers in running and ready state, as several containers try to download models which can take a while. The time to bring up all the pods depends on several factors including but not limited to node availability, node load average, network speed, compute availability, etc. > - If you want to persist the downloaded models and avoid delays pertaining to model downloads when re-installing the charts, set the `global.keepPvc` value to `true` in `user_values_override.yaml` file before installing the chart. ### Step 7: Accessing the application Nginx service running as a reverse proxy in one of the pods, helps us to access the application. We need to get Host IP and Port on the node where the nginx service is running. Run the following command to get the host IP of the node and port exposed by Nginx service: ```bash vss_hostip=$(kubectl get pods -l app=vss-nginx -n $my_namespace -o jsonpath='{.items[0].status.hostIP}') vss_port=$(kubectl get service vss-nginx -n $my_namespace -o jsonpath='{.spec.ports[0].nodePort}') echo "http://${vss_hostip}:${vss_port}" ``` Copy the output of above bash snippet and paste it into your browser to access the **Video Search and Summarization Application**. ### Step 8: Update Helm Dependencies If any changes are made to the sub-charts, always remember to update the Helm dependencies using the following command before re-installing or upgrading your helm installation: ```bash helm dependency update ``` ### Step 9: Uninstall Helm chart To uninstall the Video Summary Helm chart, use the following command: ```bash helm uninstall vss -n $my_namespace ``` ## Updating PVC Storage Size If any of the microservice requires more or less storage than the default allotted storage in values file, this can be overridden for one or more services. ### Updating storage for Multimodal DataPrep and MultiModal Embedding Service Multimodal DataPrep and the MultiModal Embedding Service use independent model PVCs. Override either or both PVC sizes while installing the Helm chart. For example, when installing the chart in search-only mode: ```bash helm install vss . -f search_override.yaml -f user_values_override.yaml \ --set multimodaldataprep.modelPvc.size=20Gi \ --set multimodalembeddingms.modelPvc.size=15Gi \ -n $my_namespace ``` The same settings apply in combined Video Search and Summarization mode: ```bash helm install vss . -f unified_summary_search.yaml -f user_values_override.yaml \ --set multimodaldataprep.modelPvc.size=20Gi \ --set multimodalembeddingms.modelPvc.size=15Gi \ -n $my_namespace ``` ### Updating storage for other microservices To update storage for other microservices we can, override the corresponding `claimSize` value in the main chart values file, while installing the chart. For example, for updating storage for VLM-Inference Microservice in Video Summarization mode: ```bash helm install vss . -f summary_override.yaml -f user_values_override.yaml --set vlminference.claimSize=50Gi -n $my_namespace ``` Similarly, for updating storage for OVMS in Video Summarization mode, we can install the chart in the following ways: ```bash helm install vss . -f summary_override.yaml -f user_values_override.yaml -f ovms_override.yaml --set ovms.claimSize=10Gi -n $my_namespace ``` For updating storage for vLLM in Video Summarization mode with vLLM backend: ```bash helm install vss . -f summary_override.yaml -f xeon_vllm_values.yaml -f user_values_override.yaml --set vllm.pvc.size=100Gi -n $my_namespace ``` For updating storage for Minio Server in the combined Video Search and Summarization mode: ```bash helm install vss . -f unified_summary_search.yaml -f user_values_override.yaml --set minioserver.claimSize=10Gi -n $my_namespace ``` If not set while installing the chart, all services will claim a default amount of storage set in the values file. ## Verification - Ensure that all pods are running and the services are accessible. - Access the Video Summarization application dashboard and verify that it is functioning as expected. - Upload a test video to verify that the ingestion, processing, and summarization pipeline works correctly. - Check that all components (MinIO, PostgreSQL, RabbitMQ, video ingestion, VLM inference, Audio Analyzer) are functioning properly. ## Troubleshooting - **Pods not coming in Ready or Running state for a long time.** There could be several possible reasons for this. Most likely reasons are storage unavailability, node unavailability, network slow-down or faulty network, etc. Please check with your cluster admin or try fresh installation of charts, **after deleting the PVC _(see next issue)_ and un-installing the current chart**. - **All containers Ready, all Pods in Running state, application UI is accessible but search or summarization is failing.** If PVC has been configured to be retained, most common reason for application to fail to work is a stale PVC. This problem most likely occurs when Helm charts are re-installed after some updates to Helm chart or the application image. To fix this, delete the service PVCs before re-installing the Helm chart: ```bash kubectl delete pvc -multimodalembeddingms-models-pvc -n $my_namespace kubectl delete pvc -multimodaldataprep-models-pvc -n $my_namespace # If modelPvc.enabled=false, delete the fallback data PVCs instead: # kubectl delete pvc -multimodalembeddingms-data-pvc -n $my_namespace # kubectl delete pvc -multimodaldataprep-data-pvc -n $my_namespace # On the Milvus backend, delete both Milvus claims together — the segment # data and the etcd metadata that indexes it must be reset as a pair: # kubectl delete pvc -milvus-data -milvus-etcd-data -n $my_namespace ``` If you are using custom PVC names via existing claims, delete those claim names instead. - If you encounter any issues during the deployment process, check the Kubernetes logs for errors: ```bash kubectl logs -n $my_namespace ``` - For component-specific issues: - Video ingestion problems: Check the logs of the videoingestion pod - VLM inference issues: Check the logs of the vlm-inference-microservice pod - Database connection problems: Verify the PostgreSQL pod is running correctly - Storage issues: Check the MinIO server status and connectivity - Some issues might be fixed by freshly setting up storage. This is helpful in cases where deletion of PVC is prohibited by configuration on charts un-installation (when `global.keepPvc` is set to true): ```bash kubectl delete pvc -n $my_namespace ``` - If you are experiencing issues with the Hugging Face API, ensure your API token `global.huggingfaceToken` is valid and properly set in the `user_values_override.yaml` file. ## Related links - [How to Build from Source](./build-from-source.md) ## Monitoring and Metrics ### Metrics Manager live metrics With `global.metricsManager.enabled=true`, verify the same-origin routes through nginx: ```bash curl http://localhost:8081/metrics-manager/health curl -N -H "Accept: text/event-stream" \ http://localhost:8081/metrics-manager/metrics/stream ``` The stream supplies `cpu_usage_user`, `mem_used_percent`, `gpu_engine_usage_usage`, `npu_utilization`, and `dataprep_embeddings_per_second` to the UI. If system metrics are missing, check that the pod is privileged, uses `hostPID: true`, and can read the host device and sysfs mounts. If only embeddings/sec is missing, verify the DataPrep image supports `MM_DATAPREP_METRICS_MANAGER_URL` and inspect both DataPrep and Metrics Manager logs. ### OVMS Prometheus Metrics When OVMS is enabled, the application exposes Prometheus-compatible metrics at the `/ovms/metrics` endpoint. These metrics provide valuable insights into inference performance and can be used for monitoring and auto-scaling. **Accessing metrics:** ```bash # Port-forward to the nginx service (replace with your helm release name, e.g., "vss") kubectl port-forward svc/-nginx 8081:80 -n $my_namespace # Fetch metrics curl http://localhost:8081/ovms/metrics ``` **Available metrics:** | Metric | Type | Description | |--------|------|-------------| | `ovms_streams` | gauge | Number of OpenVINO™ execution streams | | `ovms_current_requests` | gauge | Requests currently being processed | | `ovms_requests_success` | counter | Total successful requests | | `ovms_requests_fail` | counter | Total failed requests | | `ovms_request_time_us` | histogram | Request processing time (microseconds) | | `ovms_inference_time_us` | histogram | Inference execution time (microseconds) | | `ovms_wait_for_infer_req_time_us` | histogram | Queue wait time (microseconds) | **Labels:** Metrics include labels for `api` (KServe, TensorFlowServing, V3), `interface` (REST, gRPC), `method`, `name` (model name), and `version`. **Prometheus integration:** Add the following scrape configuration to your Prometheus config: ```yaml scrape_configs: - job_name: 'vss-ovms' static_configs: - targets: ['-nginx..svc.cluster.local:80'] metrics_path: '/ovms/metrics' ``` > **Note:** Metrics are only available when OVMS is enabled (`ovms.enabled=true`). When using vLLM backend, this endpoint is not available.