Embeddings 與向量搜尋:初學者入門指南
你想為應用程式加入語義搜尋——使用者輸入查詢後,根據意義而非精確關鍵字獲得結果。但你不太確定從何開始:什麼是 embeddings?你需要向量資料庫嗎?如何衡量相似度?這份指南將透過實用步驟和你可以立即執行的程式碼來回答這些問題。
什麼是 Embeddings?
Embedding 是一個由浮點數組成的稠密向量,用來表示輸入(文字、圖像、音訊等)的意義。對於文字,像 text-embedding-3-small 這樣的模型或開源替代方案(例如 all-MiniLM-L6-v2)會將句子轉換為例如 384 維的向量。意義相似的詞或句子在這個向量空間中會彼此靠近。
舉例來說:「cat」和「kitten」的向量會比「cat」和「airplane」的向量更接近。這個特性實現了語義搜尋:你將文件和查詢都嵌入,然後找到最接近的文件向量。
向量搜尋如何運作
向量搜尋(也稱為相似度搜尋)會在你的資料集中找出與查詢向量最相似的向量。相似度通常以餘弦相似度或點積來衡量。對於正規化後的向量,餘弦相似度和點積是等價的。
暴力搜尋會將查詢與每個向量進行比較——對於數千個向量來說沒問題,但對於數百萬個向量就太慢了。這就是近似最近鄰(ANN)演算法發揮作用的地方,例如 HNSW(Hierarchical Navigable Small World)或 IVF(Inverted File Index)。它們犧牲一點點準確度來換取大幅的速度提升。
逐步教學:建立語義搜尋原型
- 選擇 embedding 模型。對於英文文字,可以從 Sentence Transformers 的小型快速模型如
all-MiniLM-L6-v2(384 維)開始。在正式環境中,可以考慮 OpenAI 的text-embedding-3-small(1536 維)或text-embedding-3-large(3072 維)。 - 嵌入你的文件。將長文字切分成區塊(例如 200–500 字),讓每個區塊包含一個連貫的概念。將原始文字與向量一起儲存。
- 選擇向量儲存方案。快速入門可以使用記憶體內函式庫如 FAISS 或簡單的 NumPy 陣列。正式環境則選擇專用的向量資料庫(見下方表格)。
- 嵌入查詢。使用相同的模型來嵌入使用者的搜尋查詢。
- 搜尋。計算查詢向量與所有文件向量之間的相似度(或使用 ANN 索引),並傳回前 k 個結果。
- 反覆調整。評估結果,調整區塊大小、模型或相似度度量。
使用 Sentence Transformers 和 FAISS 的簡易 Python 範例
from sentence_transformers import SentenceTransformer
import faiss
import numpy as np
# 1. 載入模型
model = SentenceTransformer('all-MiniLM-L6-v2')
# 2. 範例文件
docs = [
"The cat sat on the mat.",
"A kitten is playing with yarn.",
"The stock market crashed today.",
"Investors are worried about inflation."
]
# 3. 建立 embeddings
embeddings = model.encode(docs, convert_to_numpy=True)
# 4. 建立 FAISS 索引
dim = embeddings.shape[1]
index = faiss.IndexFlatL2(dim) # L2 距離;若要用餘弦相似度,請先正規化
index.add(embeddings)
# 5. 搜尋
query = "feline resting"
query_vec = model.encode([query], convert_to_numpy=True)
D, I = index.search(query_vec, k=2)
print([docs[i] for i in I[0]])
# 輸出可能為:['The cat sat on the mat.', 'A kitten is playing with yarn.']
選擇向量資料庫
對於小型專案,你可以將向量儲存在簡單的檔案或記憶體索引中。隨著規模擴大,專用的向量資料庫提供持久化、篩選和 ANN 索引。以下是一個快速比較:
| 資料庫 | 類型 | 最適合 |
|---|---|---|
| FAISS | 函式庫 | 原型開發、本機實驗 |
| Chroma | 嵌入式 / 客戶端-伺服器 | 中小型應用、易於設定 |
| Pinecone | 託管雲端 | 正式環境、無伺服器擴展 |
| Weaviate | 開源 / 雲端 | 混合搜尋、GraphQL API |
| Qdrant | 開源 / 雲端 | 高效能、篩選 |
| pgvector | PostgreSQL 擴充 | 現有 Postgres 技術堆疊 |
最佳實踐與常見陷阱
- 正規化向量如果使用餘弦相似度——許多函式庫在點積時假設單位向量。
- 明智地切分區塊:太大會失去具體性;太小會失去上下文。嘗試不同的重疊大小。
- 使用相同的模型來處理文件和查詢。混合模型會破壞相似度。
- 考慮降維(例如 PCA)僅在儲存空間或速度至關重要時;這可能會損害準確度。
- 混合搜尋(結合關鍵字和向量)通常能改善精確匹配的結果。
常見問題
小型專案需要向量資料庫嗎?
不需要。對於最多幾千個向量,你可以使用記憶體內函式庫如 FAISS 甚至 NumPy 陣列。當你需要持久化、篩選或超出記憶體的規模時,向量資料庫才會變得有用。
如何選擇 embedding 模型?
原型開發時,從小型快速模型如 all-MiniLM-L6-v2 開始。如果你需要更高的準確度且能負擔 API 費用,可以嘗試 OpenAI 的 text-embedding-3-small 或 text-embedding-3-large。務必在自己的資料上進行評估。
餘弦相似度和歐幾里得距離有何不同?
餘弦相似度衡量向量之間的角度,忽略大小。歐幾里得距離衡量直線距離。對於正規化後的向量,它們給出相同的排名。餘弦相似度常用於文字 embeddings,因為它關注方向(意義)而非長度。
下一步
現在你已經了解基礎知識,試著在你自己的筆記或文件上建立一個小型語義搜尋。嘗試不同的區塊大小和模型。隨著規模成長,遷移到託管的向量資料庫並加入混合搜尋。這個領域發展迅速,但這些基礎知識將持續保持相關性。
當你需要格式化 API 回應或除錯來自 embedding 服務的 JSON 酬載時,JSON Formatter 可以幫助你快速檢查和驗證資料。