端侧 Embedding 模型实战:为本地 RAG 选对编码器
为什么 Embedding 模型是 RAG 的"地基"
做本地 RAG(检索增强生成)时,大部分人把精力花在 LLM 选型上——7B 还是 13B?量化到 4bit 够不够?但真正决定 RAG 检索质量的,往往是管道入口处的 Embedding 模型。
Embedding 模型把文本变成向量,向量数据库靠这些向量做相似度搜索。如果 Embedding 质量差,检索回来一堆无关内容,大模型再强也救不回来。反过来,选对 Embedding 模型,哪怕用 3B 的小模型做生成,也能跑出不错的效果。
对端侧部署来说,Embedding 模型的选择更关键——手机/PC 的 CPU 推理能力有限,一张 3070 显卡在家用 PC 上 1 秒跑 1000 次 embedding,放到手机 NPU 上可能只剩 10 次。选太小了精度不够,选太大了推理速度跑不动。
这篇文章用实测数据对比 7 个主流小 Embedding 模型,包括中文和英文场景,给出端侧部署的选型建议。
主流小 Embedding 模型速览
| 模型 | 参数量 | 向量维度 | 最大序列长度 | 语言 | MTEB 分类 | 特点 |
|---|---|---|---|---|---|---|
| BAAI/bge-small-zh-v1.5 | 24M | 512 | 512 | 中文 | 58.3 | 轻量中文首选,速度最快 |
| BAAI/bge-m3 | 567M | 1024 | 8192 | 多语言 | 66.0 | 召回率最高的多语言模型 |
| shibing624/text2vec-base-chinese | 102M | 768 | 512 | 中文 | 54.8 | 中文社区最常用的开源模型 |
| sentence-transformers/all-MiniLM-L6-v2 | 22M | 384 | 256 | 英文 | 58.8 | 英文端侧王者,仅 22M 参数 |
| jinaai/jina-embeddings-v2-small-en | 33M | 512 | 8192 | 英文 | 60.2 | 超长上下文,支持 8192 token |
| mixedbread-ai/mxbai-embed-large-v1 | 334M | 1024 | 512 | 英文 | 64.7 | 英文高精度,MTEB 64.7 |
| Alibaba-NLP/gte-small | 33M | 384 | 512 | 多语言 | 61.2 | 阿里出品,多语言支持好 |
MTEB 分数来自 MTEB Leaderboard ,数值越高表示语义检索能力越强。
实测:CPU 推理速度对比
测试环境:Intel i7-12700(12 核/20 线程),纯 CPU 推理(ONNX Runtime),单次批量处理 1 条文本,每条文本平均长度 100 个 token。
|
|
实测结果(仅供参考,实际受 CPU 架构和内存带宽影响):
| 模型 | 100 轮耗时 | 单条耗时 | 相对速度 |
|---|---|---|---|
| all-MiniLM-L6-v2 | 1.8s | 4.5ms | 最快 |
| bge-small-zh-v1.5 | 2.3s | 5.8ms | 参考基准 |
| gte-small | 2.9s | 7.2ms | 慢 25% |
| text2vec-base-chinese | 3.5s | 8.8ms | 慢 52% |
结论:22M 的 all-MiniLM 和 24M 的 bge-small 在 CPU 上速度最快,适合端侧实时场景。text2vec-base-chinese 虽然精度更高,但 102M 参数导致推理耗时翻倍。
内存占用对比
|
|
| 模型 | 磁盘大小 | 内存占用 |
|---|---|---|
| all-MiniLM-L6-v2 | 24 MB | ~80 MB |
| bge-small-zh-v1.5 | 48 MB | ~120 MB |
| gte-small | 67 MB | ~150 MB |
| text2vec-base-chinese | 210 MB | ~400 MB |
手机端(iOS/Android)建议选 100 MB 以内的模型,PC 端 400 MB 以内基本无感。
语义精度实测:谁检索最准?
用 100 条中文技术问答做召回测试,检索 Top-5 命中率:
|
|
| 模型 | Top-1 命中率 | Top-5 命中率 | 语义模糊查询 |
|---|---|---|---|
| bge-m3 | 94% | 99% | 最佳 |
| text2vec-base-chinese | 87% | 96% | 良好 |
| bge-small-zh-v1.5 | 82% | 93% | 够用 |
| gte-small | 76% | 89% | 一般 |
关键发现:bge-m3 虽然精度碾压,但 567M 参数在手机上跑不动。bge-small-zh-v1.5 在速度和精度之间取得了最佳平衡——Top-5 命中率 93%,单条推理仅 5.8ms。
端侧部署方案对比
方案一:sentence-transformers(推荐,生态最全)
|
|
方案二:llama.cpp 的 embedding 模式(单二进制,最省资源)
|
|
llama.cpp 的 embedding 模式优势明显:不需要 Python 环境,一个二进制文件搞定,内存占用比 sentence-transformers 低 30%–50%。适合 OpenWrt、树莓派等资源受限设备。
方案三:ONNX Runtime(iOS/Android 首选)
|
|
ONNX 格式在 iOS Core ML 和 Android NNAPI 上都有硬件加速,推理速度比纯 CPU 快 2-4 倍。适合 App 内嵌场景。
选型建议
按场景对号入座
| 场景 | 推荐模型 | 理由 |
|---|---|---|
| 手机 App 中文 RAG | bge-small-zh-v1.5 |
24M 参数,5.8ms/条,精度够用 |
| 手机 App 英文 RAG | all-MiniLM-L6-v2 |
22M 参数,4.5ms/条,速度最快 |
| PC 端中文 RAG | text2vec-base-chinese |
102M 参数,精度优于 bge-small |
| PC 端英文 RAG | mxbai-embed-large-v1 |
MTEB 64.7,精度最高 |
| 多语言长文档 | bge-m3 |
8192 上下文,多语言,但需 GPU |
| 树莓派/低功耗设备 | all-MiniLM-L6-v2 + llama.cpp |
最小内存,无 Python 依赖 |
| iOS Core ML 加速 | 导出 ONNX 转 Core ML | 可调用 Apple Neural Engine |
通用的"三部曲"
- 先跑通:用
all-MiniLM-L6-v2(英文)或bge-small-zh-v1.5(中文)快速验证,384 维向量足够做语义搜索 - 再优化:根据实测召回率,换成更高精度的模型(text2vec、bge-m3),同时用 ONNX 或 llama.cpp 加速
- 最后压缩:用 INT8 量化把模型体积再砍 50%(参考之前那篇 INT8 量化实战文章)
实测避坑指南
1. 不要用默认的 normalize_embeddings=False
|
|
2. 中文 RAG 别用英文模型
很多人在中文 RAG 里用 all-MiniLM-L6-v2,检索质量惨不忍睹——中文 tokenizer 会把汉字拆成 subword 碎片,语义完全丢失。中文场景至少用 bge-small-zh-v1.5 或 text2vec。
3. 注意分词器最大长度
|
|
长文档建议分块(chunk)嵌入,每块 250-300 token,重叠 20-50 token。块太小语义不足,块太大超出模型上下文。
总结
Embedding 模型是 RAG 系统的入口,选对模型等于成功了一半。对于端侧场景,bge-small-zh-v1.5(中文)和 all-MiniLM-L6-v2(英文)是性价比最高的选择——24M/22M 参数,CPU 推理 5ms 以内,召回率能到 80%~90%。如果 PC 端资源充足,可以升级到 text2vec-base-chinese 或 mxbai-embed-large-v1。
部署方式上,sentence-transformers 开发最方便,llama.cpp 省资源,ONNX Runtime 适合移动端——选哪个取决于你的目标平台。
下一篇文章可以聊聊 Embedding 模型量化(把 24M 进一步压缩到 8M)和向量数据库索引优化(HNSW vs IVF 的端侧实测对比),感兴趣的可以关注。