Troubleshooting RAG Embedding Dimension Mismatch (1024 vs 768) & Zombie VRAM Allocation
Fix the two most common post-setup local AI failures: Chroma/PGVector dimension mismatch errors after changing embedding models, and GPU VRAM staying 95% full when ollama ps shows zero models.
Linux / macOS / Windows WSL2 · Ollama 0.5.7 · Open WebUI / Dify / Continue (ChromaDB, Qdrant, PGVector)
All vector dimension probes and GPU process checks run locally via curl and nvidia-smi.
- Vector spaces are mathematically incompatible across models: even if two models share the same dimension (`bge-m3` is 1024-dim and `mxbai-embed-large` is 1024-dim), querying an index built with model A using model B returns pure random noise!
- In WSL2 on Windows, freeing CUDA memory inside Linux does not always immediately shrink `vmmemWSL` on Windows Task Manager without `OLLAMA_KEEP_ALIVE=0` or `wsl --shutdown`.
1. Local Embedding Model Dimension & Context Matrix (`768` vs `1024` vs `384`)
| Embedding Model | Vector Dimension | Max Context Window | Best Use Case & Caveat |
|---|---|---|---|
| all-MiniLM-L6-v2 (Built-in default) | 384-dim | 256 tokens (Very short!) | Weak on Chinese/CJK; switch to bge-m3 + re-index |
| nomic-embed-text | 768-dim | 8192 tokens | Fast English code/docs; incompatible with 1024-dim tables |
| bge-m3 (Recommended Bilingual) | 1024-dim | 8192 tokens | Top CJK + English recall; requires ~1.2GB VRAM |
| mxbai-embed-large | 1024-dim | 512 tokens | Same 1024-dim as bge-m3, but DIFFERENT vector space! |
# 1. Probe exact vector dimension returned by your local Ollama embedding model
curl -s http://127.0.0.1:11434/api/embeddings \
-d '{"model": "bge-m3", "prompt": "dimension check"}' | jq '.embedding | length'
# Expected output for bge-m3: 1024 (nomic-embed-text: 768)
# 2. Immediately unload a model from VRAM without restarting the Ollama service
curl -s http://127.0.0.1:11434/api/generate -d '{"model": "qwen2.5:14b", "keep_alive": 0}'2. Diagnosing "Zombie VRAM": Why GPU Memory Stays Full When `ollama ps` Is Empty
3. Coordinating Dual-Model VRAM (`Chat LLM` + `bge-m3` Embedding) on Single GPUs
Frequently Asked Questions & Edge Cases
Q: How do I fix `InvalidDimensionException: Embedding dimension 1024 does not match collection dimension 384` in Open WebUI?
Open **Workspace -> Knowledge**, delete the old collections that were created when the 384-dim default model was active (or click **Reset Vector Storage** in Admin -> Settings -> Documents), and re-upload your documents so ChromaDB creates fresh 1024-dimensional tables.
Q: Why does Windows Task Manager still show `vmmemWSL` using 12GB of RAM even after I unloaded my Ollama model?
Linux inside WSL2 caches filesystem pages (including `.gguf` model weights) in RAM and only returns freed memory to Windows gradually. Add `autoMemoryReclaim=gradual` under `[experimental]` in `%USERPROFILE%\.wslconfig`, or run `echo 3 | sudo tee /proc/sys/vm/drop_caches` inside WSL2.
Local RAG Embedding Dimension, Bilingual Recall & Zombie VRAM Diagnostic Script
Probes exact output vector dimensions (e.g. 1024 for bge-m3 vs 768 for nomic-embed-text), checks dual-model VRAM residency, and verifies non-empty embeddings.
#!/usr/bin/env bash
# Tinker AI — RAG Embedding Dimension & Multi-Model VRAM Healthcheck (Guide #20)
set -euo pipefail
EMBED="bge-m3:latest"
EXP_DIM="1024"
API="http://127.0.0.1:11434/api/embed"
echo "=== [1/3] Probing Vector Dimension for $EMBED ==="
RESP=$(curl -sS "$API" -d "{
\"model\": \"$EMBED\",
\"input\": [\"Tinker AI Lab bilingual RAG verification\", \"本地知识库跨语言向量检索测试\"],
\"keep_alive\": \"5m\"
}")
echo "$RESP" | python3 -c "
import sys, json, math
data = json.load(sys.stdin)
vecs = data.get('embeddings', [])
if not vecs:
print('[FAIL] Empty embeddings array returned! Check model tag.')
sys.exit(1)
dim = len(vecs[0])
exp = int('$EXP_DIM')
status = 'OK' if dim == exp else f'MISMATCH (Expected {exp}, Got {dim} -> Must re-index Vector DB!)'
dot = sum(a*b for a, b in zip(vecs[0], vecs[1]))
norm0 = math.sqrt(sum(a*a for a in vecs[0]))
norm1 = math.sqrt(sum(b*b for b in vecs[1]))
cos = dot / (norm0 * norm1) if (norm0 and norm1) else 0.0
print(f'Vector Dimension : {dim} [{status}]')
print(f'EN-ZH Cosine Sim : {cos:.4f} (Expect > 0.55 for multilingual models like bge-m3)')
"
echo "=== [2/3] Inspecting Co-Loaded Models & VRAM Split ==="
ollama ps
echo "=== [3/3] Checking OLLAMA_MAX_LOADED_MODELS Policy ==="
echo "Tip: Ensure OLLAMA_MAX_LOADED_MODELS>=2 so $EMBED and your Chat LLM do not thrash disk on every RAG query."