Embedding
Embedding là cách biến đổi text (hoặc image, audio) thành các vector số trong không gian nhiều chiều, giúp máy tính “hiểu” và so sánh ngữ nghĩa.
📚 Bài viết liên quan:
- Generative AI - Token là gì, cách AI xử lý text
- RAG - Ứng dụng embedding trong retrieval
- Prompt Engineering - Viết prompt hiệu quả
Tại sao cần Embedding?
Máy tính không hiểu text như con người. Nó cần biểu diễn text dưới dạng số.
Cách cũ: One-Hot Encoding
# Vocabulary: ["apple", "banana", "orange"]
# One-hot encoding:
apple = [1, 0, 0]
banana = [0, 1, 0]
orange = [0, 0, 1]
# Vấn đề:
# - Không thể hiện được "apple" và "orange" đều là trái cây
# - Vector rất thưa (sparse) với vocabulary lớnCách mới: Embedding
# Embedding vectors (ví dụ 3 chiều, thực tế có 768-4096 chiều)
apple = [0.82, 0.15, 0.73] # Trái cây, màu đỏ
banana = [0.79, 0.21, 0.12] # Trái cây, màu vàng
orange = [0.85, 0.18, 0.68] # Trái cây, màu cam
car = [0.12, 0.95, 0.08] # Xe cộ
# Kết quả:
# - apple ≈ orange (gần nhau trong không gian vector)
# - apple ≠ car (xa nhau)Embedding hoạt động như thế nào?
Quá trình tạo Embedding
Similarity: Đo độ giống nhau
Hai text có nghĩa tương tự sẽ có vector gần nhau.
from sklearn.metrics.pairwise import cosine_similarity
text1 = "Python is a programming language"
text2 = "Python là ngôn ngữ lập trình"
text3 = "The weather is nice today"
embedding1 = get_embedding(text1) # [0.12, 0.45, ...]
embedding2 = get_embedding(text2) # [0.11, 0.47, ...]
embedding3 = get_embedding(text3) # [0.89, -0.32, ...]
cosine_similarity(embedding1, embedding2) # 0.92 (rất giống)
cosine_similarity(embedding1, embedding3) # 0.15 (rất khác)Cosine Similarity:
- 1.0 = Hoàn toàn giống nhau
- 0.0 = Không liên quan
- -1.0 = Hoàn toàn trái ngược
Các Embedding Model phổ biến
OpenAI Embeddings
| Model | Dimensions | Max Tokens | Price (per 1M tokens) |
|---|---|---|---|
| text-embedding-3-large | 3072 | 8191 | $0.13 |
| text-embedding-3-small | 1536 | 8191 | $0.02 |
| text-embedding-ada-002 | 1536 | 8191 | $0.10 |
from openai import OpenAI
client = OpenAI()
response = client.embeddings.create(
model="text-embedding-3-small",
input="Python is a great programming language"
)
embedding = response.data[0].embedding
print(f"Dimensions: {len(embedding)}") # 1536Google Embeddings
| Model | Dimensions | Max Tokens |
|---|---|---|
| text-embedding-004 | 768 | 2048 |
| textembedding-gecko@001 | 768 | 3072 |
import google.generativeai as genai
genai.configure(api_key="YOUR_API_KEY")
result = genai.embed_content(
model="models/text-embedding-004",
content="Python is a great programming language"
)
embedding = result['embedding']
print(f"Dimensions: {len(embedding)}") # 768Open Source Models
| Model | Dimensions | Đặc điểm |
|---|---|---|
| all-MiniLM-L6-v2 | 384 | Nhẹ, nhanh |
| all-mpnet-base-v2 | 768 | Cân bằng chất lượng/tốc độ |
| bge-large-en | 1024 | Chất lượng cao |
| multilingual-e5-large | 1024 | Hỗ trợ đa ngôn ngữ |
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('all-MiniLM-L6-v2')
sentences = [
"Python is a programming language",
"Java is also a programming language",
"The weather is nice today"
]
embeddings = model.encode(sentences)
print(f"Shape: {embeddings.shape}") # (3, 384)Ứng dụng của Embedding
1. Semantic Search
Tìm kiếm dựa trên ý nghĩa, không chỉ từ khóa.
# Query: "cách học lập trình hiệu quả"
# Kết quả trả về:
# ✅ "Phương pháp tự học code nhanh" (semantic match)
# ✅ "Tips học programming cho người mới"
# ❌ "Lập trình viên cần gì?" (không liên quan)2. RAG (Retrieval-Augmented Generation)
Sử dụng embedding để tìm documents liên quan trước khi hỏi LLM.
User Query: "Chính sách nghỉ phép của công ty là gì?"
↓
Embedding Query → Vector
↓
Tìm trong Vector DB → "HR Policy Document"
↓
Gửi document + query → LLM
↓
Response chính xác dựa trên data riêngXem thêm: RAG System
3. Recommendation System
# User đã đọc: "Python Tutorial for Beginners"
user_embedding = get_embedding("Python Tutorial for Beginners")
# Tìm bài viết tương tự
similar_articles = find_similar(
user_embedding,
all_article_embeddings,
top_k=5
)
# → ["Python List Comprehension", "Python Functions", ...]4. Clustering / Classification
# Phân nhóm emails tự động
email_embeddings = [get_embedding(email) for email in emails]
from sklearn.cluster import KMeans
clusters = KMeans(n_clusters=5).fit(email_embeddings)
# Cluster 0: Support tickets
# Cluster 1: Sales inquiries
# Cluster 2: Spam
# ...5. Duplicate Detection
# Tìm câu hỏi trùng lặp trên forum
def find_duplicates(new_question, existing_questions, threshold=0.9):
new_embedding = get_embedding(new_question)
for q in existing_questions:
similarity = cosine_similarity(new_embedding, q.embedding)
if similarity > threshold:
return q # Đã có câu hỏi tương tự
return None # Câu hỏi mớiVector Database
Để lưu trữ và tìm kiếm nhanh với triệu vectors, cần dùng Vector Database.
Các Vector DB phổ biến
| Database | Loại | Đặc điểm |
|---|---|---|
| Pinecone | Cloud | Dễ dùng, serverless |
| Weaviate | Self-hosted/Cloud | Full-text + vector search |
| Chroma | Self-hosted | Nhẹ, tốt cho prototyping |
| Qdrant | Self-hosted/Cloud | Rust, hiệu năng cao |
| pgvector | PostgreSQL extension | Dùng chung với PostgreSQL |
Ví dụ với Chroma
import chromadb
from chromadb.utils import embedding_functions
# Tạo client
client = chromadb.Client()
# Sử dụng OpenAI embedding
openai_ef = embedding_functions.OpenAIEmbeddingFunction(
api_key="YOUR_API_KEY",
model_name="text-embedding-3-small"
)
# Tạo collection
collection = client.create_collection(
name="documents",
embedding_function=openai_ef
)
# Thêm documents
collection.add(
documents=[
"Python là ngôn ngữ lập trình phổ biến",
"JavaScript dùng cho web development",
"Machine Learning là nhánh của AI"
],
ids=["doc1", "doc2", "doc3"]
)
# Tìm kiếm
results = collection.query(
query_texts=["Ngôn ngữ lập trình nào dễ học?"],
n_results=2
)
# → ["doc1", "doc2"]Best Practices
1. Chọn Model phù hợp
| Use case | Khuyến nghị |
|---|---|
| Prototyping | all-MiniLM-L6-v2 (miễn phí) |
| Production tiếng Anh | text-embedding-3-small |
| Đa ngôn ngữ (có tiếng Việt) | multilingual-e5-large |
| Chất lượng cao nhất | text-embedding-3-large |
2. Normalize vectors
Một số database yêu cầu vectors đã được normalize.
import numpy as np
def normalize(vector):
return vector / np.linalg.norm(vector)
normalized = normalize(embedding)3. Chunking cho documents dài
def chunk_text(text, chunk_size=500, overlap=50):
"""Chia text dài thành các chunks nhỏ hơn."""
words = text.split()
chunks = []
for i in range(0, len(words), chunk_size - overlap):
chunk = ' '.join(words[i:i + chunk_size])
chunks.append(chunk)
return chunks
# Document 10000 từ → 20-25 chunks
chunks = chunk_text(long_document)
embeddings = [get_embedding(chunk) for chunk in chunks]4. Cache embeddings
import hashlib
import json
def get_embedding_cached(text, cache={}):
"""Cache embedding để tránh gọi API lặp lại."""
key = hashlib.md5(text.encode()).hexdigest()
if key not in cache:
cache[key] = get_embedding(text)
return cache[key]Bài tập thực hành 🧪
Bài 1: Semantic Search đơn giản
- Cài đặt:
pip install sentence-transformers - Tạo embeddings cho 10 câu
- Tìm câu tương tự nhất với query
from sentence_transformers import SentenceTransformer, util
model = SentenceTransformer('all-MiniLM-L6-v2')
documents = [
"Python is great for beginners",
"JavaScript runs in browsers",
"Machine learning needs data",
# ... thêm câu
]
query = "Ngôn ngữ nào tốt cho người mới?"
# Tìm document tương tự nhấtBài 2: Visualize Embeddings
Sử dụng t-SNE hoặc UMAP để visualize embeddings trong 2D.
from sklearn.manifold import TSNE
import matplotlib.pyplot as plt
# Giảm từ 384 chiều xuống 2 chiều để vẽ
tsne = TSNE(n_components=2)
reduced = tsne.fit_transform(embeddings)
plt.scatter(reduced[:, 0], reduced[:, 1])
plt.show()Tóm tắt
| Khái niệm | Ý nghĩa |
|---|---|
| Embedding | Biến text → vector số |
| Dimensions | Số chiều của vector (384, 768, 1536…) |
| Cosine Similarity | Đo độ giống nhau (0-1) |
| Vector Database | DB chuyên lưu/tìm kiếm vectors |
| Chunking | Chia document dài thành phần nhỏ |
Bài tiếp theo: Fine-tuning - Tinh chỉnh model cho use case riêng.
Last updated on