Embeddings & Vector Space
Khái niệm cơ bản
Tưởng tượng bạn là thủ thư của một thư viện khổng lồ…
Bạn cần sắp xếp triệu cuốn sách sao cho người đọc có thể tìm nhanh sách họ cần. Bạn sẽ làm gì?
- Cách cũ (Keyword): Xếp theo alphabet → “AI” xa “Trí tuệ nhân tạo” mặc dù cùng chủ đề!
- Cách mới (Embedding): Xếp theo chủ đề → Sách về AI nằm cạnh sách về ML, Deep Learning.
Embeddings = Tọa độ của từ ngữ trong không gian ý nghĩa.

Vector là gì?
Vector là một danh sách các con số thực. Ví dụ:
# Giả sử chúng ta dùng 3 chiều đơn giản
"mèo" = [0.9, 0.1, 0.5] # [dễ thương, nguy hiểm, gia đình]
"chó" = [0.8, 0.2, 0.7]
"hổ" = [0.6, 0.9, 0.1]
"cá mập" = [0.1, 0.9, 0.0]Trong thực tế, embedding models dùng hàng nghìn chiều:
- OpenAI
text-embedding-3-small: 1536 chiều - OpenAI
text-embedding-3-large: 3072 chiều - Cohere
embed-v3: 1024 chiều
Cosine Similarity (Độ tương đồng)
Để so sánh 2 vectors, ta dùng Cosine Similarity:
cosine_similarity(A, B) = (A · B) / (||A|| × ||B||)- Kết quả từ -1 (ngược hoàn toàn) đến 1 (giống hoàn toàn)
- Thường threshold 0.7+ được coi là “liên quan”
Ví dụ tính tay:
import numpy as np
# Giả lập embeddings
vec_king = np.array([0.8, 0.9, 0.1])
vec_queen = np.array([0.75, 0.95, 0.15])
vec_apple = np.array([0.1, 0.2, 0.9])
def cosine_sim(a, b):
return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
print(f"King vs Queen: {cosine_sim(vec_king, vec_queen):.3f}") # ~0.99
print(f"King vs Apple: {cosine_sim(vec_king, vec_apple):.3f}") # ~0.35Word Arithmetic (Phép tính từ ngữ)
Điều kỳ diệu của embeddings:
King - Man + Woman ≈ Queen
Paris - France + Japan ≈ TokyoĐiều này chứng minh embeddings đã capture được quan hệ ngữ nghĩa!
So sánh Embedding Models
| Model | Dimensions | Giá (per million tokens) | Ghi chú |
|---|---|---|---|
| OpenAI ada-002 | 1536 | $0.10 | Legacy |
| OpenAI text-embedding-3-small | 1536 | $0.02 | Recommended |
| OpenAI text-embedding-3-large | 3072 | $0.13 | Best quality |
| Cohere embed-v3 | 1024 | $0.10 | Multi-lingual |
| Voyage AI | 1024 | $0.08 | Affordable |
| BGE (local) | 1024 | Free | Self-hosted |
💡 Tip: Với tiếng Việt,
text-embedding-3-smallhoặcCohere embed-v3hoạt động tốt.
Code thực tế: Embed với OpenAI
from openai import OpenAI
client = OpenAI()
def get_embedding(text: str, model: str = "text-embedding-3-small") -> list:
response = client.embeddings.create(
input=text,
model=model
)
return response.data[0].embedding
# Sử dụng
vec1 = get_embedding("Phở Hà Nội rất ngon")
vec2 = get_embedding("Bún chả thủ đô tuyệt vời")
vec3 = get_embedding("iPhone 15 Pro Max")
# So sánh
import numpy as np
def cosine_sim(a, b):
return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
print(f"Phở vs Bún chả: {cosine_sim(vec1, vec2):.3f}") # Cao (~0.85)
print(f"Phở vs iPhone: {cosine_sim(vec1, vec3):.3f}") # Thấp (~0.25)Bài tập thực hành: Tính Cosine Similarity
Mục tiêu
Hiểu cách embeddings hoạt động bằng cách tự tay tính cosine similarity.
Bài tập 1: Tính bằng tay (không code)
Cho 2 vectors:
- A = [1, 2, 3]
- B = [4, 5, 6]
Tính cosine similarity:
- A · B = 1×4 + 2×5 + 3×6 = ?
- ||A|| = √(1² + 2² + 3²) = ?
- ||B|| = √(4² + 5² + 6²) = ?
- cosine_sim = (A · B) / (||A|| × ||B||) = ?
Đáp án: 32 / (3.74 × 8.77) ≈ 0.974 → Rất tương đồng!
Bài tập 2: So sánh embedding thực
sentences = [
"Tôi yêu lập trình Python",
"Python là ngôn ngữ yêu thích của tôi",
"Hôm nay trời đẹp quá",
"Thời tiết hôm nay thật tuyệt"
]
# TODO: Embed tất cả sentences
# TODO: Tạo similarity matrix 4x4
# TODO: In ra cặp nào giống nhấtKết quả mong đợi
Similarity Matrix:
S1 S2 S3 S4
S1 1.00 0.92 0.31 0.28
S2 0.92 1.00 0.29 0.26
S3 0.31 0.29 1.00 0.95
S4 0.28 0.26 0.95 1.00
Cặp giống nhất: S3-S4 (0.95) - cùng về thời tiếtTóm tắt
| Khái niệm | Ý nghĩa |
|---|---|
| Embedding | Biến text thành vector số |
| Vector | Danh sách số thực (1536+ dimensions) |
| Cosine Similarity | Đo độ giống nhau (0-1) |
| Semantic Search | Tìm theo ý nghĩa, không phải keyword |
Bài tiếp theo: Vector Database - Nơi lưu trữ hàng triệu vectors.