本地嵌入模型怎么选

25MB 中文优先、23MB 英文优先、120MB 中英混排,三档怎么取舍。附维度与体积的关系、量化带来的精度代价,以及换模型为什么必须重建索引。

作者 SecureRAG Team · · 9 分钟阅读

本地嵌入模型负责把每个文本块变成一串定长的数字,选哪一档,决定了哪些问题能找到哪些段落。本站提供三档:25MB 的中文优先、23MB 的英文优先、120MB 的中英混排;在它们之间做选择,主要看你文档的语言构成,跟“谁更强”关系不大。

嵌入模型到底做了什么

嵌入这一步,是让检索能在“意思”上工作,而不是只认字面。文档被切成的每一块都会过一遍一个小神经网络,输出一个向量——本站这三档是 384 维或 512 维的浮点数——向量连同文本一起存进浏览器的 IndexedDB。向量在输出时已经做过 L2 归一化,所以后面比较两个向量时,只是在算点积。

这个设计带来两个后果:

  • 模型是每个文档库的长期决策。 一个模型算出的向量,对另一个模型没有意义,因为坐标里编码的是特定模型的相似度观念。换模型,已存的向量全部作废。
  • 模型只下载一次,之后走缓存。 首次访问用一个普通的 GET 取权重,之后浏览器缓存直接命中,断网也能继续用。

三档对照

模型 下载体积 维度 语言 适合 要注意
bge-small-zh-v1.5 约 25MB 512 中文 纯中文资料库,中文文档的默认选择 对纯英文段落和代码标识符较弱
all-MiniLM-L6-v2 约 23MB 384 英文 英文资料库,三档里最小最快 基本不懂中文,混排库会明显掉点
multilingual-e5-small 约 120MB 384 100+ 种 同一个库里确实中英混排 首次下载是前者的五倍,逐块嵌入也慢一些

表里是真实的下载体积。超过 30MB 的那一档不会在你不点确认的情况下开始下载,也就是说,代价总是先摆在你面前再发生。

下载一次要花什么,之后又占多少

有两笔账要分开算,它们不是同一笔。

一次性下载。 首次访问用普通的 GET 取权重,不经过任何第三方 CDN,文件和页面同一个源。权重会进浏览器的 HTTP 缓存,之后再来,网络面板基本是安静的。

每个文档库的常驻开销。 向量不太能压缩。按 32 位浮点算,384 维模型下一个块约占 1.5KB,512 维约 2KB。往前推一下:

库的规模 典型块数 384 维的向量占用 512 维的向量占用
一份合同,约 30 页 约 120 约 0.2MB 约 0.25MB
十份文档混排 约 1,200 约 1.8MB 约 2.5MB
四十份文档,总量接近 200MB 约 6,000–12,000 约 9–18MB 约 12–25MB
顶到 20,000 块上限 20,000 约 31MB 约 41MB

也就是说,向量比多数人想的便宜,占地方的大头往往是模型权重,不是索引。这个结论有两个用法:内容真的需要跨语言时,120MB 花得值;只是“以防万一”,在计流量的手机网络上就不值得。

维度和体积不是一回事

很容易把 512 维读成“比 384 维更好”。维度决定一个向量能承载多少细节,但实际使用中,另外两件事往往更要紧:

  • 词表覆盖。 以中文为主的模型,对英文标识符、错误码、产品名产生的向量质量很差。维度再高,也修不好一个把你的术语切成碎片的切词器。
  • 训练数据。 512 维的 bge-small-zh-v1.5 在中文检索上能赢过通用的 768 维模型,因为它是拿中文句对训出来的。

中英混排那一档正好说明了这点:384 维,文件更大,多出来的字节全花在词表和多语言训练上,而不是花在维度上。体积买到的是覆盖面,不是分辨率。

q8 量化改了什么

这里下载的权重是 8 位量化(q8),大概是 float32 全精度权重的四分之一。两条要如实讲清楚的代价:

  • 检索质量会略微下降。 对嵌入模型来说,这个损失小到在 top-6 结果里通常看不出来,但它不是零。如果你要横向评测两套检索方案,这不该是评测时使用的设置。
  • 内存表现变好,而这是它存在的真正理由。 一个 120MB 的下载如果在标签页里展开成五百多 MB 常驻内存,那就是另一个产品了。量化是浏览器方案能成立的前提——可选生成档用 4-bit 也是同一个道理。

一分钟做决定

  1. 文档全是中文?bge-small-zh-v1.5。25MB、512 维,这里没有需要妥协的地方。
  2. 文档全是英文?all-MiniLM-L6-v2。23MB 是三档里最小的下载,逐块嵌入也最快,导入一份三百页的 PDF 时这点差别能感觉到。
  3. 中英混排,或者你用中文提问、文档是英文?multilingual-e5-small,120MB 忍一次。一个 30% 英文、70% 中文的库,小模型在少数语言那一侧会明显失手,而混排库恰恰会把这个失手放大成答错。
  4. 拿不准? 先导入三四份文档,用你真正会问的问题试一遍,看引用对不对。如果正确的段落总是出现在前面,模型是称职的;如果你明知文件里有某段却总也召不回来,先换混排档,再回头怀疑分块。

换模型等于重建索引

真的要换,先知道会发生什么:文本块还在,向量不在。每个块都要过一遍新模型重新嵌入——一份两百页的文档是几百个块,在单线程 WASM 上,等待时间按几十秒计,不是瞬间完成。网络慢的话,还要加上重新下载 120MB 的时间。

几条实操建议:

  • 在规模变大之前定下来。 两份文档时换模型是几秒钟的事,导入四十份之后再换,就是几分钟。
  • 不会重新上传。 重建用的是浏览器里已经解析好的文本,你甚至可以断网重建。
  • 原始文件不会被改动。 索引坏了就重建,你导入的那份文件始终原样。

在工具里试,而不是对着表格想

对照表读得再熟,也替代不了自己试一遍,而把问题定下来的流程只花二十分钟。选一档模型,导入三份你熟悉的文档,问六个你能手工核对答案的问题,数一数正确的段落出现在前三名引用里几次。

六次里中了五次或六次,就不用再调了,这已经是这份语料能达到的上限,而且够用。只中两三次,瓶颈通常在语言混排或分块边界,跟维度数量没多大关系。如果你明知文件里有那段内容、它却一次都没出现过,先去怀疑解析:没有被抽出来的文字,三档模型里的任何一档都嵌不进去,也召不回来。

动手前知道一个不对称会有帮助。23MB 的 all-MiniLM-L6-v2 嵌入几百个块很快,重新导入几乎无感;120MB 的混排档差不多把这件事反过来。所以省事的测试顺序是先上小的那档,看清哪些问题答不出来,再决定要不要为多语言付那 120MB。

这些选择解决不了什么

再多嵌入模型也救不了一份解析失败的文档。PDF 没有文字层,任何模型都嵌入不了它——你得先在工具之外做 OCR。表格在抽取时丢了表头,嵌入会忠实地表示出一列没有含义的数字,检索还会理直气壮地在错误的提问下把它返回给你。选模型是第二位的决定,切分和解析才是第一位的。