本章目标:你能区分 Hugging Face Hub、Transformers、SentenceTransformers 和
InferenceClient,并能解释当前项目为什么已经在使用 Hugging Face 模型生态。本章不做模型微调、LoRA、训练集处理或生产推理集群。先把“选择模型、下载模型、加载模型、推理”这条链跑明白。
权威来源
| 来源 | 本章采用的结论 |
|---|---|
| Hugging Face Hub inference guide | InferenceClient 是调用托管推理服务或兼容端点的 Python 客户端。 |
| Hugging Face Hub Models 文档 | 模型仓库提供模型卡;用模型卡确认任务、许可证、使用方式与可用推理选项。 |
| Transformers Pipeline | pipeline() 按任务加载预训练模型与预处理组件,适合快速推理验证。 |
| SentenceTransformer.encode 参考 | encode() 默认返回 NumPy 向量;可用参数改为 Tensor 或其他输出形式。 |
一句话理解
Hugging Face 不是一个模型,而是一套围绕模型仓库、模型加载库和推理服务组成的生态;你项目的本地 Embedding 已经在其中。
先看真实对象长什么样
| 名称 | 它是什么 | 最小代码形态 |
|---|---|---|
| Hugging Face Hub | 托管模型、数据集和 Space 的平台 | 浏览 组织名/模型名 的模型卡。 |
| 模型 ID | Hub 上模型的唯一仓库名 | "BAAI/bge-base-zh-v1.5" |
SentenceTransformer | 加载并编码句子的 Python 类 | SentenceTransformer(model_id) |
pipeline() | Transformers 提供的快速任务推理工厂函数 | pipeline("sentiment-analysis") |
InferenceClient | 通过 HTTP 调用托管或兼容推理端点的客户端类 | InferenceClient(token=...) |
先记住:模型 ID 是字符串;模型对象是 Python 内存中的对象;直接调用 model.encode() 默认得到 NumPy 的 ndarray,而本项目的 get_embedding() 再调用 .tolist() 后返回 Python list。三者不是同一个东西。
第一关:你的项目已经怎样使用 Hugging Face
打开 app/embedding.py:
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("BAAI/bge-base-zh-v1.5", device="mps")vector = model.encode("退款需要几天内申请?")这三行的实际含义:
"BAAI/bge-base-zh-v1.5" -> Hub 模型 ID
SentenceTransformer(...) -> 下载或读取本地缓存,创建 Embedding 模型对象
model.encode(...) -> 把文本变成 float 向量你的项目没有每个请求都重新下载模型。get_embedding_model() 用模块级 _model 缓存同一个 SentenceTransformer 实例,并用锁避免并发重复加载。这就是为什么启动日志会出现 Embedding 模型预加载。
第二关:先用本地 Embedding 做一次可验证实验
不用新装库,直接复用项目代码:
poetry run python - <<'PY'from app.embedding import get_embedding
vector = get_embedding("退款需要几天内申请?")print(type(vector).__name__)print(len(vector))print(vector[:5])PY你应看到:
list一个固定维度的长度前几个浮点数这里要分清两层输出:SentenceTransformer.encode() 在默认配置(也是项目显式传入的 convert_to_numpy=True)下返回 NumPy 的 ndarray;项目的 get_embedding() 接着调用 .tolist(),所以本章命令打印的是 Python list。这样更容易交给 LangChain、JSON 或向量库接口;它不是 encode() 本身的默认 Python 列表。
不要试图从单个浮点数读懂语义。语义比较发生在两个完整向量之间,例如余弦相似度;这正是你第 9、10 章已经学过的内容。
第三关:Transformers 的 pipeline() 长什么样
pipeline() 是快速试模型的入口,不是本项目 RAG 的主 Embedding 接口。
from transformers import pipeline
classifier = pipeline( task="sentiment-analysis", model="distilbert/distilbert-base-uncased-finetuned-sst-2-english",)
result = classifier("I like learning LangGraph.")print(result)对象关系:
task 字符串 -> 指定任务类型
model ID 字符串 -> 指定从 Hub 加载哪个模型
pipeline(...) -> 创建可直接调用的任务对象
classifier(text) -> 真正执行推理pipeline() 适合验证一个预训练任务能否跑通;当你需要控制 tokenizer、模型权重、batch、GPU 内存或训练时,再直接使用 Transformers 的更底层 API。
第四关:本地直接加载与 HTTP 推理客户端不是一回事
本地直接加载:权重进入当前 Python 进程
model = SentenceTransformer("BAAI/bge-base-zh-v1.5", device="mps")vector = model.encode("你好")模型权重需要下载到本机缓存,并由 SentenceTransformer 加载进当前 Python 进程;推理由你的 CPU、MPS 或 CUDA 执行。这正是当前项目 Embedding 的方式。
InferenceClient:把请求发给 HTTP 服务
import os
from huggingface_hub import InferenceClient
client = InferenceClient( provider="together", model="meta-llama/Meta-Llama-3-8B-Instruct", api_key=os.environ["HF_TOKEN"],)response = client.chat_completion( messages=[{"role": "user", "content": "Explain embeddings in one sentence."}], max_tokens=100,)print(response.choices[0].message.content)InferenceClient 是 HTTP 客户端,不会把模型权重加载进当前 Python 进程。它可以调用三类目标:云端 Inference Providers、你部署的专用 Inference Endpoint,或本机/内网的兼容 HTTP 服务(例如 OpenAI API 兼容服务器)。实际计算发生在该服务所在的机器上。
上例把 provider 和 model 都写明,避免客户端自动挑选提供方;HF_TOKEN 从环境变量读取,绝不写进代码或 Git。提供方与模型的可用组合会变化,示例不保证长期可运行。运行前打开该模型的 Hub 模型卡,查看 Inference Providers 面板,确认所选 provider 支持该模型和任务;再确认你账号的访问与计费条件。
第五关:模型卡应该先看什么
打开一个模型仓库时,按这个顺序检查:
- Task:它是 Embedding、文本生成、分类还是重排序模型?
- Languages:是否支持你的中文或多语言数据?
- License:能否用于你的目标场景?
- Usage:官方推荐使用
SentenceTransformer、pipeline()还是特定加载代码? - Hardware:模型大小、dtype、CPU/MPS/CUDA 是否可承受?
模型名称里有 embedding 不等于适合所有 RAG;必须用你自己的 eval_cases 检查检索效果。
常见坑
- 把 Hub 当作 Python 库:Hub 是模型仓库平台;
transformers、sentence-transformers、huggingface_hub才是 Python 包。 - 用生成模型的
pipeline()代替 Embedding:两者输出和用途不同。 - 把
HF_TOKEN写进代码或提交 Git:它是凭证,应放.env。 - 首次加载慢就认为代码卡死:模型下载、缓存和权重加载都可能耗时;观察日志和网络状态。
三遍主动练习
1. 读懂
指出 app/embedding.py 中哪个是模型 ID、哪个是模型对象、哪个调用真正产生向量。
2. 跟写
运行本章的 get_embedding() 命令,记录向量长度和前五个值。再用另一句中文文本运行一次,确认长度相同、数值不同。
3. 独立重写
从 Hub 选择一个中文 Embedding 候选模型,写下模型 ID、任务、语言、许可证和你准备如何用现有 eval_cases 验证它。先不要替换生产模型。
本章边界与检查点
本章学习使用和选择预训练模型,不学习训练、微调、量化或分布式推理。
你能回答下面四条,就算通过:
- Hub、模型 ID、
SentenceTransformer模型对象和向量分别是什么? - 当前项目的
_model缓存为什么存在? pipeline()与SentenceTransformer.encode()的典型任务差异是什么?- 本地加载与
InferenceClient远程推理的资源归属有什么不同?
教学方式:具体锚点优先。先运行项目已有的
get_embedding(),再理解模型仓库、缓存、设备和远程推理的分工。