Mục lục
- Mục tiêu bài học
- Vector và embedding — tóm tắt nhanh
- Bài toán vector DB giải quyết
- Khác biệt với SQL
- Khác biệt với NoSQL
- Bảng so sánh 3 loại storage
- ANN — tại sao approximate
- Pipeline RAG — vai trò của vector DB
- Khi nào CẦN vector DB riêng
- Khi nào KHÔNG cần vector DB riêng
- Landscape vector DB hiện tại
- Sai lầm phổ biến khi mới dùng
- Bài tiếp theo
Mục tiêu bài học
Sau bài này, bạn cần:
- Giải thích được tại sao SQL/NoSQL không phù hợp cho similarity search và vector DB giải quyết vấn đề đó thế nào.
- Biết ANN là gì, tại sao chấp nhận "approximate", và recall@K có nghĩa gì trong ngữ cảnh RAG.
- Mô tả pipeline RAG từ góc độ storage: ingest flow và query flow.
- Biết khi nào nên dùng vector DB riêng và khi nào numpy/pgvector đủ.
- Nhận diện ~8 vector DB phổ biến và biết use case phù hợp của từng cái ở mức tổng quan.
Vector và embedding — tóm tắt nhanh
Một embedding (vector biểu diễn) là mảng số thực n chiều đầu ra của một model — thường 384, 768, 1536, hoặc 3072 chiều tùy model. Embedding đã được xây dựng sao cho các đầu vào có ý nghĩa tương đồng (câu hỏi tương tự nhau, hình ảnh trông giống nhau) sẽ cho ra vector nằm gần nhau trong không gian n chiều đó.
Series 4 đã đi qua cách chọn embedding model và cách dùng trong RAG. Bài này không lặp lại; điểm cần nhớ duy nhất: vector là dữ liệu thô mà vector DB cần lưu và tìm kiếm trên đó.
Bài toán vector DB giải quyết
Cho một tập N vectors đã lưu và một vector query q, bài toán là: tìm top-K vectors gần nhất với q theo một distance metric (cosine, L2, dot product).
Đây gọi là bài toán K-Nearest Neighbor (KNN) search trong không gian high-dimensional.
Use case trong AI:
- Semantic search / RAG — tìm đoạn văn nào trong corpus gần nghĩa nhất với câu hỏi.
- Recommendation — tìm sản phẩm/phim/bài nhạc tương tự item user đang xem.
- Image search — cho ảnh query, tìm ảnh tương tự trong gallery.
- Deduplication — tìm các document gần giống nhau để loại bỏ trùng lặp.
- Clustering — nhóm vector gần nhau để phân tích hoặc phân loại.
Cách naive nhất: tính cosine similarity giữa q và từng vector trong store, rồi sort. Complexity là O(N × d) với d là số chiều. Ở N = 1 triệu và d = 768, mỗi query cần ~768 triệu phép nhân — quá chậm cho latency realtime (thường yêu cầu < 100ms).
Vector DB giải quyết vấn đề này bằng cách xây index chuyên biệt — sẽ nói ở mục ANN.
Khác biệt với SQL
SQL (PostgreSQL, MySQL...) được thiết kế cho structured data với câu hỏi dạng exact match hoặc range:
-- SQL: exact match và range — hoạt động tốt
SELECT * FROM products WHERE category = 'laptop' AND price < 20000000;
Index B-tree của SQL tối ưu cho các truy vấn trên giá trị rời rạc hoặc dãy số. Khái niệm "tìm row nào giống nhất với row này" không tồn tại trong SQL truyền thống.
Có thể tính cosine similarity bằng SQL không? Được, nhưng phải viết tay và full scan:
-- PostgreSQL thuần: tính cosine similarity thủ công
-- Không có index → full scan O(N)
SELECT id, (v1*q1 + v2*q2 + ...) / (sqrt(v1^2+...) * sqrt(q1^2+...)) AS sim
FROM items
ORDER BY sim DESC
LIMIT 10;
Không có index ANN → mỗi query vẫn O(N). SQL không phải công cụ phù hợp cho similarity search ở scale lớn.
Ngoại lệ: pgvector — extension cho PostgreSQL thêm kiểu vector và index HNSW/IVF. Khi đã có Postgres và dataset vừa phải (dưới vài chục triệu vector), đây là lựa chọn thực tế, tránh phải vận hành DB thứ hai. Sẽ đề cập thêm ở mục landscape.
Khác biệt với NoSQL
NoSQL (MongoDB, Redis, DynamoDB...) giải quyết vấn đề schema linh hoạt và scale ngang của SQL, nhưng mô hình truy vấn vẫn là exact match hoặc range trên field:
// MongoDB: query theo field — vẫn là exact/range
db.products.find({ category: "laptop", price: { $lt: 20000000 } })
MongoDB và một số NoSQL gần đây đã thêm vector search (MongoDB Atlas Vector Search, Redis Stack vector module). Tuy nhiên đây là tính năng được ghép thêm — không phải kiến trúc cốt lõi — nên thường kém tối ưu hơn vector DB thuần về latency và throughput ở scale lớn.
Điểm chung: cả SQL lẫn NoSQL không có index chuyên cho ANN search. Vector DB xây toàn bộ engine storage và index xung quanh bài toán similarity search từ đầu.
Bảng so sánh 3 loại storage
| Tiêu chí | SQL (PostgreSQL, MySQL) | NoSQL (MongoDB, Redis) | Vector DB (Qdrant, Pinecone...) |
|---|---|---|---|
| Data model | Bảng có schema cố định, row/column | Document, key-value, graph — schema linh hoạt | Vector float array + metadata tùy ý |
| Query type | Exact match, range, JOIN, aggregate | Exact match trên field, array query | Similarity search top-K, kết hợp filter metadata |
| Index type | B-tree, Hash, GIN, GiST | B-tree, Hash, TTL | HNSW, IVF, Flat (brute-force) |
| Transaction / ACID | Đầy đủ ACID, foreign key, JOIN | Tuỳ; một số có ACID (MongoDB 4.x+) | Không có concept transaction; insert/upsert/delete by ID |
| Use case AI | Lưu metadata, result, user data — query bình thường | Cache, session, log, document unstructured | Semantic search, RAG retrieval, recommendation, dedup |
| Scaling | Scale dọc tốt; scale ngang qua read replica, sharding phức tạp | Scale ngang dễ hơn SQL | Một số managed (Pinecone, Qdrant Cloud) tự scale; self-host cần sharding rõ ràng |
Trong hệ thống thực tế, vector DB không thay thế SQL/NoSQL — nó chạy song song. Ví dụ: Postgres lưu user data, order, metadata; vector DB lưu embedding cho search. Hai loại giải quyết hai bài toán khác nhau.
ANN — tại sao approximate
Tìm top-K vector gần nhất bằng cách quét toàn bộ store gọi là exact NN (hoặc brute-force / Flat index). Đây là cách duy nhất đảm bảo recall = 100%, nhưng O(N) cho mỗi query. Với N = 1 triệu vector 768 chiều, mỗi query mất vài trăm ms ngay cả trên CPU mạnh. Không khả thi cho realtime.
ANN — Approximate Nearest Neighbor đánh đổi một phần recall lấy tốc độ. Thay vì tìm đúng top-K, ANN tìm gần đúng top-K trong thời gian sub-linear (O(log N) với HNSW hoặc tốt hơn). Đánh đổi được đo bằng recall@K:
recall@K = (số item trong top-K của ANN cũng có trong top-K của exact NN) / K
Trong RAG, recall@10 ≥ 0.95 là chấp nhận được — miss 1 trong 10 chunk gần nhất không làm LLM tạo ra câu trả lời tệ hơn đáng kể. Đây là lý do ANN được ưu tiên.
Hai thuật toán ANN phổ biến nhất:
- HNSW (Hierarchical Navigable Small World) — graph-based, tổ chức vector thành đồ thị nhiều lớp, tìm kiếm từ lớp thưa xuống lớp dày. Paper: Malkov & Yashunin, arXiv 1603.09320, 2016. Nhanh và accurate; dùng nhiều RAM vì giữ graph trong memory. Default của ChromaDB, Qdrant, Weaviate, Milvus.
- IVF (Inverted File Index) — cluster tất cả vector thành
nlistcụm bằng k-means; khi query chỉ scannprobecụm gần nhất. Dùng ít RAM hơn HNSW; accuracy phụ thuộc vàonprobe. Faiss của Meta (facebook/faiss) là thư viện chuẩn cho IVF.
Chi tiết về index types (HNSW hyperparameter, IVF + PQ, ScaNN) sẽ ở bài 17.
Pipeline RAG — vai trò của vector DB
Nhìn từ góc độ storage layer, RAG có hai flow:
── INGEST FLOW ──────────────────────────────────────────────────────────
Documents (PDF, web, DB...)
│
▼
Chunking (chia thành đoạn nhỏ 256-1024 token)
│
▼
Embedding model (mỗi chunk → vector float[d])
│
▼
Vector DB ← lưu vector + metadata (source, page, timestamp...)
──────────────────────────────────────────────────────────────────────────
── QUERY FLOW ───────────────────────────────────────────────────────────
User question
│
▼
Embedding model (question → vector float[d])
│
▼
Vector DB search (top-K chunks gần nhất với question vector)
│
▼
Context assembly (ghép top-K chunks vào prompt)
│
▼
LLM (sinh câu trả lời dựa trên context)
──────────────────────────────────────────────────────────────────────────
Vector DB là retrieval layer — nằm giữa data và LLM. Chất lượng retrieval (recall, precision) ảnh hưởng trực tiếp đến chất lượng câu trả lời. Một LLM tốt không bù được context sai.
Hai điểm vector DB phải làm được trong pipeline này:
- Ingest: insert vector nhanh, không block, cập nhật được khi data thay đổi.
- Query: trả top-K trong latency thấp (mục tiêu thực tế: < 100ms p95), hỗ trợ filter metadata nếu cần.
Khi nào CẦN vector DB riêng
Các dấu hiệu cho thấy nên dùng vector DB riêng (ChromaDB, Qdrant, Pinecone... thay vì giải pháp tạm):
- Dataset > 100K vectors — brute-force trong numpy hoặc in-memory bắt đầu chậm; cần ANN index.
- Latency yêu cầu < 100ms cho top-K — vector DB với HNSW index thường trả kết quả trong 1-10ms cho dataset triệu vector.
- Cần update liên tục — insert/delete vector thường xuyên khi data mới vào hoặc document bị xóa/sửa.
- Filter metadata phức tạp — kết hợp vector search với điều kiện như
source = 'doc_abc' AND year >= 2024 AND tenant_id = 'user_123'. - Nhiều collection / nhiều tenant — cần isolation và quản lý collection riêng biệt.
Khi nào KHÔNG cần vector DB riêng
Không phải mọi project đều cần vector DB chuyên dụng. Các tình huống có thể dùng giải pháp đơn giản hơn:
- Dataset < 10K vectors —
sklearn.metrics.pairwise.cosine_similarityhoặc numpy tính trực tiếp đủ nhanh (< vài ms) và không cần infra thêm:import numpy as np # store: (N, d) float32 array, đã normalize # query_vec: (d,) float32 scores = store @ query_vec # dot product = cosine nếu đã normalize top_k_idx = np.argsort(scores)[-10:][::-1] - Đã có PostgreSQL — cài
pgvectorextension, thêm cộtvector(1536), dùng index HNSW của pgvector. Tránh vận hành DB thứ hai. Hợp lý khi scale dưới vài chục triệu vector. - Demo / prototype 1 lần — ChromaDB in-memory hoặc FAISS local file đủ, không cần server.
- Batch offline, không realtime — nếu chỉ chạy similarity search mỗi đêm lúc ít traffic, exact NN không phải vấn đề.
Rule of thumb: bắt đầu đơn giản nhất đủ dùng. Khi đụng giới hạn cụ thể (latency, scale, feature) mới migrate.
Landscape vector DB hiện tại
Tổng quan các lựa chọn phổ biến — mỗi cái sẽ được đào kỹ hơn ở bài tiếp theo trong module này:
- ChromaDB — open-source, embedded (chạy chung process Python), không cần server riêng. Python-native API đơn giản. Phù hợp cho prototype và local development. Sẽ học chi tiết ở bài 14.
- Pinecone — fully managed, không tự host. Có Serverless tier (pay-per-use) và Pod tier (reserved resource). Khởi tạo nhanh, scale và backup do Pinecone lo. Phù hợp khi không muốn vận hành infra. Sẽ học chi tiết ở bài 15.
- Qdrant — open-source, viết bằng Rust, HNSW index, filtered search mạnh, hybrid sparse+dense native. Self-host qua Docker hoặc Qdrant Cloud managed. Sẽ học ở bài 16.
- Weaviate — open-source, có module vectorizer built-in (tự embed bằng model gắn kèm), GraphQL API, hybrid search. Self-host hoặc Weaviate Cloud. Sẽ học ở bài 16.
- Milvus / Zilliz — open-source (Milvus) hoặc managed (Zilliz Cloud), kiến trúc distributed tách compute/storage, phù hợp scale tỷ vector. Dùng nhiều index khác nhau từ Faiss.
-
pgvector — extension PostgreSQL, thêm kiểu
vectorvà index HNSW/IVF. Không cần DB mới nếu đã có Postgres. Đáng cân nhắc khi dataset vừa phải và muốn JOIN với dữ liệu quan hệ. - FAISS (Facebook AI Similarity Search) — thư viện C++/Python của Meta, không phải database đầy đủ (không có API server, không có persistence tự động), nhưng là thư viện ANN index phổ biến nhất. Dùng cho in-memory search hoặc làm nền tảng cho DB khác.
- Vespa — của Yahoo, hỗ trợ hybrid search mạnh (vector + structured + BM25), phức tạp hơn để vận hành. Phù hợp khi đã quen với Vespa ecosystem hoặc cần tính năng hybrid rất tinh chỉnh.
Ngoài ra còn LanceDB (serverless, file format Lance trên S3/local), MongoDB Atlas Vector Search, Elasticsearch/OpenSearch với kNN plugin, Redis Stack vector module. Đây là landscape phát triển nhanh — kiểm tra phiên bản mới trước khi đưa vào production.
Sai lầm phổ biến khi mới dùng
1. Dùng lẫn vector từ các model khác nhau
Mỗi embedding model tạo ra vector trong không gian riêng của nó. Vector từ all-MiniLM-L6-v2 và vector từ text-embedding-3-small (OpenAI) không so sánh được về mặt cosine similarity — chúng ở hai không gian hình học khác nhau. Một collection trong vector DB chỉ nên chứa vector từ một model duy nhất. Khi muốn đổi model, re-index toàn bộ collection mới.
2. Quên normalize vector trước khi dùng cosine
Cosine similarity đúng nghĩa là: cos(θ) = (a · b) / (|a| × |b|). Một số DB (Qdrant với Distance.COSINE) tự normalize nội bộ; một số DB khác dùng raw dot product. Nếu không chắc, normalize thủ công trước khi insert:
import numpy as np
def normalize(vec):
norm = np.linalg.norm(vec)
return vec / norm if norm > 0 else vec
Không normalize nhất quán dẫn đến kết quả search lộn xộn mà khó debug.
3. Index cả document dài thay vì chunk
Embedding của một tài liệu 10 trang là vector "trung bình hóa" toàn bộ nội dung — quá nhiều thông tin nén vào một điểm, retrieval sẽ mơ hồ. Cần chia document thành chunk (256-1024 token) trước khi embed, mỗi chunk một vector. Chiến lược chunking ảnh hưởng lớn đến chất lượng RAG — sẽ được đào ở bài về chunking strategy trong Series 4.
4. Không kiểm tra recall sau khi deploy ANN index
ANN index có hyperparameter ảnh hưởng đến recall vs latency trade-off (HNSW: ef_search; IVF: nprobe). Default không phải lúc nào cũng phù hợp với dataset cụ thể. Nên đo recall@10 bằng cách so sánh kết quả ANN với exact NN trên một tập query mẫu trước khi đưa lên production.
5. Nhầm "similarity" với "relevance"
Vector gần nhau về cosine similarity không đồng nghĩa với "câu trả lời đúng". Embedding chỉ nắm bắt semantic similarity theo kiểu mà model được train. Nếu model không tốt với domain cụ thể (tiếng Việt, lĩnh vực y tế, code...), kết quả retrieval vẫn kém dù vector DB và index hoàn hảo. Chọn model phù hợp domain quan trọng không kém chọn vector DB.
Bài tiếp theo
Bài 14: ChromaDB — local vector DB cho prototype — cài đặt, tạo collection, add document, query top-K, metadata filter, persistent client và server mode.
- Malkov, Yashunin — Efficient and robust approximate nearest neighbor search using HNSW (arXiv 1603.09320, 2016)
- Faiss — Wiki (IVF, PQ, Flat index types)
- pgvector — PostgreSQL extension for vector similarity search
- ChromaDB — Documentation
- Pinecone — Documentation
- Qdrant — Documentation
- Weaviate — Documentation
- Milvus — Overview
- Pinecone — What is a Vector Database (conceptual overview)
- ANN Benchmarks — ann-benchmarks.com (recall vs QPS tradeoff)
