Get Started#
The Multimodal DataPrep microservice builds and stores frame-level, image, and text embeddings in the configured vector database — VDMS by default, or Milvus — while preserving the raw assets in the configured object storage — MinIO by default, or the local filesystem. This guide explains how to launch the service, configure runtime options, and exercise the primary APIs. Backend selection is covered in Pluggable Backends; this walkthrough uses the default VDMS + MinIO stack.
Configuration and Setup#
Multimodal DataPrep ships with Docker Compose manifests (docker/compose*.yaml) for different backends — for example docker/compose.yaml provisions the default MinIO + VDMS Vector DB + DataPrep stack, while docker/compose-milvus.yaml runs against Milvus. Always source the accompanying setup.sh script so the exported environment variables remain in your shell.
Prerequisites#
Before you begin, ensure the following:
System Requirements: Verify that your system meets the minimum requirements.
Docker Installed: Install Docker. For installation instructions, see Get Docker.
This guide assumes basic familiarity with Docker commands and terminal usage. If you are new to Docker, see Docker Documentation for an introduction.
Environment Variables#
The table below lists the core configuration knobs. setup.sh seeds defaults, but you can override them before sourcing the script. The defaults below assume the VDMS + MinIO backends; to run against Milvus or local filesystem storage, set the backend selectors below and see Pluggable Backends for the full backend-specific reference.
Variable |
Required |
Default |
Purpose |
|---|---|---|---|
|
Optional |
|
Active vector-database backend: |
|
Optional |
|
Active object-storage backend: |
|
Optional |
(none) |
Full Milvus URI (e.g. |
|
Optional |
(none) / |
Milvus host and port when |
|
Optional |
|
Vector similarity metric applied to both VDMS and Milvus (e.g. |
|
Optional |
|
Vector index type for backends that require it (e.g. Milvus |
|
Optional |
|
Root directory for the |
|
✅ |
(none) |
Credentials used to bootstrap MinIO. Required only when |
|
✅ |
|
Host:port string DataPrep uses to communicate with MinIO from inside the container. Required only when |
|
✅ |
|
Destination bucket for uploaded media and generated manifests. Override with |
|
✅ |
|
Connection information for VDMS Vector DB. Used only when |
|
✅ |
|
Vector-database collection/index that stores embeddings and metadata (applies to both VDMS and Milvus). |
|
✅ |
(none) |
Model identifier used by the in-process embedding pipeline (for example |
|
Optional |
|
Enables OpenVINO acceleration for embedding generation. Set |
|
Optional |
|
Device for the in-process embedding pipeline ( |
|
Optional |
|
Device override for object detection execution ( |
|
Optional |
|
Number of items sent per embedding batch. |
|
Optional |
(auto) |
Hard cap for parallel workers when auto-scaling is too aggressive for the host. |
|
Optional |
|
When |
|
Optional |
|
Extract every Nth frame during video processing. |
|
Optional |
|
Toggles YOLOX-based crop extraction. |
|
Optional |
|
Minimum confidence threshold for detections. |
|
Optional |
|
Enables ROI consolidation (merging overlapping detections). |
|
Optional |
|
IoU threshold used to group overlapping boxes into a single ROI. |
|
Optional |
|
Merge only boxes of the same class when |
|
Optional |
|
Expands merged ROIs by this fraction of their width/height. |
|
Optional |
|
Shared memory block count for the video decode and embedding pipeline. |
|
Optional |
|
Per-block shared memory size in bytes (default sized for 1080p RGB frames). |
|
Optional |
|
Decoder-side batch size used when extracting frames for processing. |
|
Optional |
|
Queue capacity for inter-stage pipeline buffers. |
|
Optional |
|
Queue capacity for completion/result handoff stage. |
|
Optional |
|
Local thread count used by object-detection worker stage. |
|
Optional |
|
Local thread count used by embedding worker stage. |
|
Optional |
|
Timeout in seconds for pipeline queue reads before retry loops. |
|
Optional |
|
Persist batch/stream runtime stats JSON artifacts for debugging and profiling. |
|
Optional |
|
Enables trace emission for decode/detect/embed/store stages. |
|
Optional |
|
Number of decoder workers used in frame extraction utilities. |
|
Optional |
|
Log level for decoder internals ( |
|
Optional |
|
Persistent mount that caches OpenVINO-optimized models. |
|
Optional |
(empty / disabled) |
Metrics Manager base URL. When set, each completed video pipeline publishes |
|
Optional |
|
Timeout for one Metrics Manager publish attempt. Publishing is asynchronous and never delays ingestion. |
|
Optional |
|
CORS configuration applied by FastAPI. |
Device selection (MM_DATAPREP_EMBEDDING_DEVICE, MM_DATAPREP_DETECTION_DEVICE)#
DataPrep configures its two compute stages independently — there is no baseline
device. Each variable defaults to CPU when unset:
MM_DATAPREP_EMBEDDING_DEVICE— device for the in-process embedding pipeline.MM_DATAPREP_DETECTION_DEVICE— device for object detection.
Important: These variables are read directly by the DataPrep container. You can
sourcea setup script (which exports theCPUdefaults) or set them explicitly before runningdocker compose up.
Examples (run before sourcing the setup script):
# Offload detection to NPU and embedding to GPU (independent per-component devices)
export MM_DATAPREP_DETECTION_DEVICE=NPU
export MM_DATAPREP_EMBEDDING_DEVICE=GPU
# Run both stages on GPU
export MM_DATAPREP_EMBEDDING_DEVICE=GPU
export MM_DATAPREP_DETECTION_DEVICE=GPU
# Embedding on GPU, but keep detection on CPU
export MM_DATAPREP_EMBEDDING_DEVICE=GPU
export MM_DATAPREP_DETECTION_DEVICE=CPU
When targeting NPU, confirm the selected model supports NPU inference via the
OpenVINO Supported Models page.
Running everything on NPU: Setting both embedding and detection to
NPU(viaMM_DATAPREP_EMBEDDING_DEVICE=NPUandMM_DATAPREP_DETECTION_DEVICE=NPU) is functionally supported — both stages run on NPU through OpenVINO. However, the host has a single NPU, so the embedding and detection stages contend for the same accelerator. It works, but it is not optimal for throughput. For best performance, split the load across accelerators (for example, keep embedding onNPUand detection onGPU/CPU, or vice versa).
Advanced tuning#
Additional environment variables are available for high-throughput scenarios:
MM_DATAPREP_ENABLE_PARALLEL_PIPELINE(defaulttrue) — disable to force single-threaded embedding.MM_DATAPREP_MAX_PARALLEL_WORKERS— hard cap on worker threads (auto-calculated when unset).MM_DATAPREP_OV_PERFORMANCE_MODE,OV_PERFORMANCE_HINT_NUM_REQUESTS,OV_NUM_STREAMS— forward performance hints to OpenVINO when running on CPU or GPU.MM_DATAPREP_VIDEO_SHM_MAX_BLOCKS,MM_DATAPREP_VIDEO_SHM_BLOCK_SIZE— tune shared-memory capacity for frame transport.MM_DATAPREP_VIDEO_EXTRACTION_BATCH_SIZE,MM_DATAPREP_PIPELINE_QUEUE_MAXSIZE,MM_DATAPREP_PIPELINE_QUEUE_GET_TIMEOUT_S— tune decode and queue backpressure behavior.MM_DATAPREP_DETECTION_WORKER_THREADS,MM_DATAPREP_EMBED_WORKER_THREADS— tune stage-local worker counts.MM_DATAPREP_SAVE_RUNTIME_PIPELINE_STATS,MM_DATAPREP_ENABLE_TRACING,MM_DATAPREP_VIDEO_FRAME_LOG_LEVEL— enable diagnostics and control verbosity.
Export overrides before sourcing the setup script:
export EMBEDDING_MODEL_NAME="CLIP/clip-vit-b-16"
export MINIO_ROOT_USER="minioadmin"
export MINIO_ROOT_PASSWORD="minioadmin"
export MM_DATAPREP_EMBEDDING_DEVICE="CPU"
export MM_DATAPREP_DETECTION_DEVICE="CPU"
source ./setup.sh --nosetup
Tip: When you only need long-form text embeddings—such as the combined
--allmode in the video search and summarization sample—setEMBEDDING_MODEL_NAME="QwenText/qwen3-embedding-0.6b"before sourcingsetup.sh. The script forwards this value to the DataPrep container asMM_DATAPREP_EMBEDDING_MODEL_NAME, enabling Qwen-backed text embeddings without any additional flags.
ROI consolidation (optional)#
ROI consolidation merges overlapping detections into a single crop and optionally expands that crop for more context. This can reduce duplicate crops and improve embedding coverage when multiple detections overlap the same object.
Enable it via environment variable (recommended for quick toggles):
export MM_DATAPREP_ROI_CONSOLIDATION_ENABLED=true
Or configure it in src/config.yaml under object_detection.roi_consolidation:
enabled: Master switch for ROI consolidation logic.iou_threshold: IoU threshold used to cluster overlapping boxes. IoU is $\frac{\text{intersection area}}{\text{union area}}$ for two boxes; higher values mean only tighter overlaps merge, lower values merge more aggressively.class_aware: Whentrue, only boxes of the same class can be merged. Whenfalse, overlapping boxes across classes can merge (useful for mixed-class clusters).context_scale: Expand merged ROI by this fraction of its size. Higher values include more surrounding context; lower values keep crops tighter to the merged box.
Use source ./setup.sh --conf to print the resolved Docker Compose configuration with your overrides applied.
Quick Start with Docker#
Important: Do not run
docker builddirectly againstdocker/Dockerfilefrom themultimodal-dataprepdirectory. Always execute./build.shso the build uses themicroservices/context and includes the localmultimodal-embedding-servingsource dependency.
The user has an option to either build the docker images or use prebuilt images as documented below.
Configure the registry: The Multimodal DataPrep microservice uses the registry URL and tag to pull the required image.
```bash
export REGISTRY_URL=intel
export TAG=2026.2.0-rc2
```
Clone the repository and enter the project.
git clone https://github.com/open-edge-platform/edge-ai-libraries.git -b release-2026.2.0 cd edge-ai-libraries/microservices/visual-data-preparation-for-retrieval/multimodal-dataprep
Export required secrets and model selection.
export MINIO_ROOT_USER="minioadmin" export MINIO_ROOT_PASSWORD="minioadmin" export EMBEDDING_MODEL_NAME="CLIP/clip-vit-b-32"
For text-only scenarios replace the last line with:
export EMBEDDING_MODEL_NAME="QwenText/qwen3-embedding-0.6b"
Start the stack.
Run
source ./setup.shto export the environment variables, then start the default stack (MinIO, VDMS, and DataPrep) withdocker compose -f docker/compose.yaml up -d --build. To run against Milvus instead, usedocker compose -f docker/compose-milvus.yaml up -d --build.Confirm the stack is healthy.
docker ps --format "table {{.Names}}\t{{.Status}}"
Open the interactive docs. Navigate to
http://localhost:6007/docs(adjust if you changedMM_DATAPREP_HOST_PORT) to view the OpenAPI schema.Shut everything down when finished. Use
source ./setup.sh --down(ordocker compose -f docker/compose.yaml down) to stop services.
Usage#
The FastAPI application is mounted under /v1/dataprep.
Health probe#
curl http://localhost:6007/v1/dataprep/health
Health responses include the embedding client preload status, model name, and device.
Upload and process a new video#
curl -X POST "http://localhost:6007/v1/dataprep/media/upload" \
-H "Content-Type: multipart/form-data" \
-F "file=@/path/to/video.mp4" \
-F "frame_interval=10" \
-F "enable_object_detection=true" \
-F "tags=intersection" -F "tags=night"
The service streams the asset to the configured object storage, extracts frames (and crops), generates embeddings, and persists metadata in the configured vector database.
Upload and process an image#
The same endpoint accepts images (.jpg, .jpeg, .png, .webp, .bmp,
.gif). Images are embedded directly (full image plus optional detected-object
crops) into the same vector collection as video frames, enabling cross-modal
search.
# Multipart file upload
curl -X POST "http://localhost:6007/v1/dataprep/media/upload?enable_object_detection=true" \
-F "file=@/path/to/image.jpg" -F "tags=cat"
# Inline base64 (data URL accepted) via the JSON typed-source endpoint
curl -X POST "http://localhost:6007/v1/dataprep/media/ingest" \
-H "Content-Type: application/json" \
-d '{"type": "image_base64", "image_base64": "data:image/png;base64,iVBORw0KGgo..."}'
# Remote URL (server downloads, size-capped at 50 MB)
curl -X POST "http://localhost:6007/v1/dataprep/media/ingest" \
-H "Content-Type: application/json" \
-d '{"type": "image_url", "image_url": "https://example.com/cat.jpg"}'
Process an existing video in MinIO#
curl -X POST "http://localhost:6007/v1/dataprep/media/process" \
-H "Content-Type: application/json" \
-d '{
"bucket_name": "video-summary",
"video_id": "traffic_cam_2024_10_21",
"frame_interval": 12,
"enable_object_detection": true,
"tags": ["traffic", "daytime"]
}'
Discover, download, and delete content#
You can use the following commands to discover, download, and delete content:
# List processed videos (video_id + filenames)
curl "http://localhost:6007/v1/dataprep/media"
# Download a processed clip (stream or attachment)
curl -L "http://localhost:6007/v1/dataprep/media/download?video_id=traffic_cam_2024_10_21" -o clip.mp4
# Delete a video (removes its storage object(s) + vector embeddings)
curl -X DELETE "http://localhost:6007/v1/dataprep/media/my-bucket/traffic_cam_2024_10_21"
Review processing telemetry#
The telemetry endpoint captures per-request wall-clock timings, stage durations, throughput, and batch-level stats. Query the most recent entries directly from the DataPrep service (or via the pipeline-manager proxy) with:
curl --location 'http://localhost:6016/telemetry?limit=5'
See the Telemetry Metrics reference for a complete breakdown of every field and how each value is calculated.
Validate Services#
Call
GET /v1/dataprep/health– expectstatus: ok, the embedding client status, model name, device, and OpenVINO flag.Upload a small MP4 via
/media/uploadand confirm:The response payload reports
success.GET /v1/dataprep/medialists the generatedvideo_idand manifests.The MinIO console (
http://localhost:6011) shows the raw asset, thumbnails, and crops.
Inspect the vector database to verify entries in the
video-rag-testcollection (for the default VDMS backend, usevdms_clior a custom client; for Milvus, use a Milvus client such aspymilvusor Attu).
Supporting Resources#
Media Ingestion Flow - Detailed flow diagrams of the video and image processing pipelines