Embeddings

Embedding(嵌入) 把一段文本变成固定长度的浮点向量。语义相近的句子,向量也相近。RAG 用它做近邻检索,不用它来聊天。

本课两条主路径,都不要求 GPU

路径模型何时选
云端 APIOpenAI text-embedding-3-small(默认 1536 维)有 Key、要省本机资源
本地Ollama bge-m3,或 Hub 上的 BAAI 模型数据不出网、中文 / 多语言

中文检索优先评估 bge-m3(Ollama 名 bge-m3,Hub 名 BAAI/bge-m3)。机器内存紧时,CPU 上可用更小的 BAAI/bge-small-zh-v1.5。细节与 /api/embed 见本站 Ollama Embeddings;模型卡与 sentence-transformersHugging Face

索引和查询必须用同一个模型。换模型 = 整库重嵌。


环境

python -m venv .venv
source .venv/bin/activate          # macOS / Linux
pip install openai ollama numpy
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install openai ollama numpy

OpenAI:设置 OPENAI_API_KEY。Ollama:先安装服务并 ollama pull bge-m3(CPU 可跑,首次较慢)。

export OPENAI_API_KEY="sk-..."     # bash
ollama pull bge-m3
$env:OPENAI_API_KEY = "sk-..."
ollama pull bge-m3

OpenAI:text-embedding-3-small

from openai import OpenAI

client = OpenAI()  # 读取 OPENAI_API_KEY


def embed_openai(texts: list[str]) -> list[list[float]]:
    resp = client.embeddings.create(
        model="text-embedding-3-small",
        input=texts,
    )
    return [item.embedding for item in resp.data]


vecs = embed_openai(["退款须在到货 7 日内申请。"])
print(len(vecs[0]))  # 1536

官方支持 dimensions 降维(例如 512)以省存储;建库后不可中途改维。批量时一次传入多条 input,不要在循环里逐条 HTTP。


本地:Ollama bge-m3

不必自己管 CUDA。Ollama 在 CPU 上也能 embed。

import ollama


def embed_ollama(texts: list[str], model: str = "bge-m3") -> list[list[float]]:
    out = ollama.embed(model=model, input=texts)
    return out["embeddings"]


vecs = embed_ollama(["退款须在到货 7 日内申请。", "客服在线 09:00–18:00。"])
print(len(vecs), len(vecs[0]))

REST 等价于 POST http://localhost:11434/api/embed,也可用 OpenAI 兼容的 POST /v1/embeddings。PowerShell:

Invoke-RestMethod -Method Post -Uri "http://localhost:11434/api/embed" `
  -ContentType "application/json" `
  -Body '{"model":"bge-m3","input":"天空为什么是蓝色的?"}'

聊天模型(llama3qwen 等)不要拿来当 embed:慢,而且不是为检索训练的。


本机 Python:BAAI / sentence-transformers(可选)

不跑 Ollama、又要开源权重时:

from sentence_transformers import SentenceTransformer

# CPU 即可;bge-m3 体积更大,内存紧则换 bge-small-zh-v1.5
model = SentenceTransformer("BAAI/bge-small-zh-v1.5")


def embed_bge(texts: list[str]) -> list[list[float]]:
    return model.encode(texts, normalize_embeddings=True).tolist()

pip install sentence-transformers 会拉 PyTorch CPU 轮子,第一次下载模型需要磁盘和耐心。GPU 能加速但不是必须


接到向量库

三种库都接受「已算好的向量」:

embeddings = embed_openai(chunks)          # 或 embed_ollama / embed_bge
# Chroma: collection.add(..., embeddings=embeddings)
# pgvector: INSERT ... embedding
# Qdrant: PointStruct(vector=embeddings[i])

也可以让 Chroma 用内置函数自动 embed;中文场景更稳妥的是自己传入 OpenAI 或 bge-m3 向量,避免默认英文小模型。


下一步

评论