Skip to Content

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:


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ớn

Cá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

ModelDimensionsMax TokensPrice (per 1M tokens)
text-embedding-3-large30728191$0.13
text-embedding-3-small15368191$0.02
text-embedding-ada-00215368191$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)}") # 1536

Google Embeddings

ModelDimensionsMax Tokens
text-embedding-0047682048
textembedding-gecko@0017683072
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)}") # 768

Open Source Models

ModelDimensionsĐặc điểm
all-MiniLM-L6-v2384Nhẹ, nhanh
all-mpnet-base-v2768Cân bằng chất lượng/tốc độ
bge-large-en1024Chất lượng cao
multilingual-e5-large1024Hỗ 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

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êng

Xem 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ới

Vector 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

DatabaseLoạiĐặc điểm
PineconeCloudDễ dùng, serverless
WeaviateSelf-hosted/CloudFull-text + vector search
ChromaSelf-hostedNhẹ, tốt cho prototyping
QdrantSelf-hosted/CloudRust, hiệu năng cao
pgvectorPostgreSQL extensionDù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 caseKhuyến nghị
Prototypingall-MiniLM-L6-v2 (miễn phí)
Production tiếng Anhtext-embedding-3-small
Đa ngôn ngữ (có tiếng Việt)multilingual-e5-large
Chất lượng cao nhấttext-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

  1. Cài đặt: pip install sentence-transformers
  2. Tạo embeddings cho 10 câu
  3. 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ất

Bà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
EmbeddingBiến text → vector số
DimensionsSố chiều của vector (384, 768, 1536…)
Cosine SimilarityĐo độ giống nhau (0-1)
Vector DatabaseDB chuyên lưu/tìm kiếm vectors
ChunkingChia 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