Repository navigation
Service Multi2vec Clip
Multimodal CLIP vectorizer module for Weaviate. It runs the semitechnologies/multi2vec-clip image and exposes POST /vectorize and GET /meta on internal port 8080. The Docker repo has no -inference suffix; the GitHub source repo has it.
Weaviate is the only consumer, through its multi2vec-clip module (CLIP_INFERENCE_API=http://multi2vec-clip:8080). Every container on backend-network can also reach /vectorize.
Image: semitechnologies/multi2vec-clip:sentence-transformers-clip-ViT-B-32-1.5.1 (the MULTI2VEC_CLIP_IMAGE default in .env.example). Tags name the model. The -1.5.1 suffix pins the inference-server build; the un-suffixed …-ViT-B-32 tag moves to the newest build.
Container port: 8080, internal only (no host port). The default container-cpu source sets ENABLE_CUDA=0. container-gpu sets ENABLE_CUDA=1 but does not request a GPU, so it does not work yet (§6).
The bootstrapper runs CLIP only when WEAVIATE_SOURCE=container; with any other Weaviate source it scales CLIP to 0.
| Path | URL | Notes |
|---|---|---|
| Direct | — | No host port. Internal-only by design. |
| Internal | http://multi2vec-clip:8080/vectorize |
What Weaviate (and future consumers) call. |
| Kong | — | Infra module; no Kong route. |
| Meta | GET http://multi2vec-clip:8080/meta |
Returns model config; useful as a health probe. |
Canonical port table: Ports and Routes.
MULTI2VEC_CLIP_SOURCE=container-cpu # container-cpu | container-gpu | disabled
CLIP_INFERENCE_API=http://multi2vec-clip:8080
MULTI2VEC_CLIP_SIGLIP2_IMAGE=semitechnologies/multi2vec-clip:google-siglip2-so400m-patch16-512-1.5.1The bootstrapper keeps Weaviate's module list in step with the source. The default list is:
WEAVIATE_ENABLE_MODULES=text2vec-openai,text2vec-ollama,multi2vec-clip,generative-openai,generative-ollama,backup-filesystem
CLIP_INFERENCE_API=http://multi2vec-clip:8080To disable CLIP, set MULTI2VEC_CLIP_SOURCE=disabled (or pass --multi2vec-clip-source disabled). The bootstrapper then removes multi2vec-clip from WEAVIATE_ENABLE_MODULES and clears CLIP_INFERENCE_API. Do not edit those two values by hand; the bootstrapper overwrites them. Collections that use multi2vec-clip as their vectorizer fail on the next ingest.
SigLIP 2 opt-in image. The ViT-B/32 image stays the default so existing collections keep their vector space. To test Weaviate's SigLIP 2 so400m image, copy the reference value into the live image variable:
MULTI2VEC_CLIP_IMAGE=semitechnologies/multi2vec-clip:google-siglip2-so400m-patch16-512-1.5.1
MULTI2VEC_CLIP_SOURCE=container-cpu
CLIP_INFERENCE_API=http://multi2vec-clip:8080Use container-cpu: container-gpu does not reserve a GPU yet, so the container exits and Weaviate never becomes ready (§6).
Do not change MULTI2VEC_CLIP_IMAGE on a stack with multi2vec-clip collections without a migration plan. ViT-B/32 emits 512-d vectors; the SigLIP 2 image emits 1152-d vectors. Recreate the collections, or revectorize them into new ones, before you use SigLIP 2. Only the image changes: the endpoint, port, topology row and track stay the same.
Call shape.
POST /vectorize
Content-Type: application/json
{
"texts": ["a red sports car"],
"images": ["<base64 PNG>"]
}
→ 200 OK
{
"textVectors": [[...512 floats...]],
"imageVectors": [[...512 floats...]]
}Weaviate calls this endpoint internally on every POST /v1/objects against a collection whose vectorizer: multi2vec-clip. The CLIP module knows nothing about Weaviate — it's a pure embedding service.
Network. Joined to backend-network. Any container on that network can POST /vectorize directly. Weaviate is the declared consumer. Other services have no direct integration.
Volumes / state. None. The model is baked into the image; the container is stateless and trivially restartable.
Manifest layout. services/multi2vec-clip/ holds only documentation. The container, image, env vars and wizard row belong to the weaviate family (services/weaviate/service.yml, services/weaviate/compose.yml).
The default model is sentence-transformers-clip-ViT-B-32 (English-only ViT-B/32). One endpoint embeds both text and images, so one call can vectorize a {texts, images} batch for cross-modal similarity search.
- Vector dimension is fixed by the model. ViT-B/32 gives 512; SigLIP 2 gives 1152. Changing the model needs a new or revectorized collection.
- Measure before sizing. Latency depends on hardware, image size and batch shape. Benchmark the exact image and payload before you set capacity or timeout budgets.
container-gpu leaves Weaviate not-ready. container-gpu sets ENABLE_CUDA=1, but the compose fragment requests no GPU (no runtime: nvidia, no device reservation). The CLIP container exits at startup (Torch not compiled with CUDA enabled or no visible CUDA device). Weaviate, with multi2vec-clip enabled, then waits for it forever. Use container-cpu or disabled. GPU wiring is tracked in #1373.
Container OOMs on CPU. Memory use grows under load and with large batches. Raise the Docker memory budget, or send smaller batches. container-gpu is not usable until GPU device requests are wired.
Weaviate ingest fails with connection refused to multi2vec-clip:8080. MULTI2VEC_CLIP_SOURCE is disabled, or the container is down. CLIP has no host port, so query /meta from a sibling container (commands below). The Weaviate image has wget but no curl.
Embeddings look random / clustering broken. Confirm that /meta returns the configuration of the expected model. A stale image cache after a model change can pin you to the old checkpoint. docker compose pull multi2vec-clip && docker compose up -d --force-recreate multi2vec-clip.
Module not available in Weaviate. WEAVIATE_ENABLE_MODULES must list multi2vec-clip. Check docker exec <project>-weaviate env | grep ENABLE_MODULES.
docker compose ps multi2vec-clip
docker compose logs -f multi2vec-clip
docker exec <project>-weaviate wget -qO- http://multi2vec-clip:8080/meta | jq .For general startup and routing issues, see Troubleshooting.
Smoke-test from a sibling container.
docker exec <project>-backend curl -s http://multi2vec-clip:8080/meta | jq 'keys'
# → ["clip_model", "text_model"] (the Hugging Face configs of the loaded model)Embed a text + image batch.
docker exec <project>-backend curl -s -X POST http://multi2vec-clip:8080/vectorize \
-H 'content-type: application/json' \
-d "$(jq -n --arg img "$(base64 < ./photo.png)" '{texts:["red car"], images:[$img]}')"
# → {"textVectors":[[...512 floats...]], "imageVectors":[[...512 floats...]]}Output vectors are 512-d for ViT-B/32. Cosine similarity between a text vector and an image vector gives the canonical CLIP score.
Restart without rebuilding. Stateless — docker compose restart multi2vec-clip is safe. The model file is in the image, so restart reuses the same packaged weights without a rebuild.
No upstream calls.
| Service | Category |
|---|---|
| weaviate | data |

Open the full-size diagram for a full-screen view.
-
multi2vec-clip ↔ backend — Why: backend has no direct path to multimodal embeddings; today it can only reach CLIP indirectly by writing through Weaviate. Direct
/vectorizecalls unlock zero-shot image tagging, image-vs-text similarity scoring, and ad-hoc embedding without round-tripping through a collection. Mechanism:POST http://multi2vec-clip:8080/vectorizewith{texts, images}. Effort: small. Confidence: high. -
multi2vec-clip ↔ minio — Why: MinIO hosts artifact buckets (comfyui, backend, n8n, jupyter, docling) but none of those image artifacts are indexed for semantic retrieval. A small ingest worker streams new objects through CLIP into Weaviate. Mechanism: MinIO bucket-notification webhook → fetch object → base64 →
POST /vectorize→ upsert into aMediaAssetsWeaviate collection. Effort: medium. Confidence: medium. -
multi2vec-clip ↔ comfyui — Why: ComfyUI images stay unindexed in volumes. Embedding each one into Weaviate enables prompt-similarity search, dedup and "find prior renders that look like X". Mechanism: ComfyUI custom SaveImage post-hook → call backend ingest endpoint → backend forwards bytes to
multi2vec-clip:8080/vectorizeand upserts. Effort: medium. Confidence: medium. -
multi2vec-clip ↔ jupyterhub — Why: notebook users today spin up their own CLIP model to experiment with multimodal embeddings; the stack already runs one. Mechanism: JupyterHub user pods reach
http://multi2vec-clip:8080/vectorizeoverbackend-network; document a one-cell helper in the notebook starter image. Effort: small. Confidence: high. -
multi2vec-clip ↔ n8n — Why: n8n workflows handling inbound email/Slack attachments or webhook-uploaded images can vectorize on-the-fly for routing, classification, or RAG. Mechanism: n8n HTTP Request node →
POST http://multi2vec-clip:8080/vectorize→ branch on cosine-similarity to label-vectors. Effort: small. Confidence: high. -
multi2vec-clip ↔ doc-processor — Why: docling extracts figures/diagrams from PDFs but discards the visual signal. CLIP-embedding extracted figures alongside text chunks enables true multimodal RAG over document corpora. Mechanism: docling post-extraction step → for each figure, base64 →
POST /vectorize→ store with parent-chunk metadata. Effort: medium. Confidence: medium.
No high-confidence opportunities identified.
-
GPU mode (
MULTI2VEC_CLIP_SOURCE=container-gpu) — Why pursue: the variant setsENABLE_CUDA=1but gets no GPU; wire the NVIDIA device request (#1373). Effort: small. -
Model variant selection beyond ViT-B-32 — Why pursue: upstream ships SigLIP 2, multilingual XLM-R+ViT, LAION ViT-B-16; we hard-pin
sentence-transformers-clip-ViT-B-32. ExposingMULTI2VEC_CLIP_IMAGEchoices in the wizard unlocks multilingual + higher-recall regimes. Effort: small. -
Multi-field weighted vectors — Why pursue: the CLIP module supports per-field weights (
image_fieldsweight 0.9,text_fieldsweight 0.1); no collection inweaviate-initexercises this. Effort: small. -
/metahealth surfacing — Why pursue: container exposes/metawith model config; not scraped or shown in the wizard's service-table health column. Effort: small. -
trust_remote_codefor custom CLIP variants — Why pursue: enables loading community models (Qwen3-VL, ColPali) already supported by the upstream loader. Effort: medium (security review needed).
Atlas documentation.
- 1. Overview
- 2. Quick Start
- 3. Core Concepts
- 4. Tracks
-
5. Services
- 5.1. Service Catalog
-
5.2. Service Guides
- 5.2.1. airflow
- 5.2.2. asset-baker
- 5.2.3. asset-worker
- 5.2.4. backend
- 5.2.5. backup
- 5.2.6. blender-mcp
- 5.2.7. celery
- 5.2.8. chatterbox
- 5.2.9. cloud-providers
- 5.2.10. cloudflared
- 5.2.11. comfyui
- 5.2.12. crawl4ai
- 5.2.13. doc-processor
- 5.2.14. docling
- 5.2.15. docling-lightrag-adapter
- 5.2.16. fal
- 5.2.17. globals
- 5.2.18. grafana
- 5.2.19. hermes
- 5.2.20. iceberg-rest
- 5.2.21. jenkins
- 5.2.22. jupyterhub
- 5.2.23. kong
- 5.2.24. label-studio
- 5.2.25. langfuse
- 5.2.26. lightrag
- 5.2.27. litellm
- 5.2.28. llm-graph-builder
- 5.2.29. local-deep-researcher
- 5.2.30. loki
- 5.2.31. mcp-servers
- 5.2.32. minio
- 5.2.33. mlflow
- 5.2.34. multi2vec-clip
- 5.2.35. n8n
- 5.2.36. neo4j
- 5.2.37. ollama
- 5.2.38. open-webui
- 5.2.39. openclaw
- 5.2.40. otel-collector
- 5.2.41. parakeet
- 5.2.42. prometheus
- 5.2.43. ray
- 5.2.44. redis
- 5.2.45. redpanda
- 5.2.46. searxng
- 5.2.47. spark
- 5.2.48. speaches
- 5.2.49. stt-provider
- 5.2.50. supabase
- 5.2.51. supavisor
- 5.2.52. tei-reranker
- 5.2.53. tempo
- 5.2.54. tika
- 5.2.55. trino
- 5.2.56. trueforge
- 5.2.57. tts-provider
- 5.2.58. verba
- 5.2.59. vllm-metal
- 5.2.60. weaviate
- 5.2.61. zeppelin
- 5.3. Provider And Extension Guides
- 6. Configuration
- 7. Operations
- 8. Architecture
- 9. Development
- 10. Reference