从原始数值中识别嵌入模型
Jina AI 开发了一种基于小参数 Transformer 分类器的方法,仅通过读取嵌入向量的原始浮点数字符序列,即可以 87% 的准确率识别出产生该向量的具体模型及任务指令。该方法采用独特的字符级分词策略,将每个浮点数视为文本序列处理,从而避免了传统方法对数据分布或维度对齐的假设。实验结果表明,不同模型甚至同一模型的不同指令提示都会在数值输出中留下可被检测的独特“指纹”。
Markdown 内容:[嵌入指纹演示] 粘贴任意嵌入向量并识别是由哪个模型生成的。](https://embedding-inversion-demo.jina.ai/#fingerprint) 嵌入模型是黑盒。你输入文本,得到向量输出。这是一串没有标签、没有水印、也没有元数据告诉你它来自何处的浮点数列表。如果有人递给你一个 1024 维的向量,你能判断它是 BGE-M3、[jina-embeddings-v5-text-small](https://jina.ai/?sui&model=jina-embeddings-v5-text-small) 还是 Qwen3-Embedding 生成的吗?即使两个向量来自同一个模型,你也能分辨它们是使用检索指令还是分类指令生成的吗?事实证明你可以做到。嵌入向量中的数值模式携带了生成它的模型的惊人强烈的指纹,甚至包括推理过程中使用的指令提示。我们训练了一个小型 Transformer 分类器(80 万参数),仅通过阅读原始浮点数字符,就能从 25 多个嵌入模型中识别出 68 种不同的模型 - 任务组合,准确率达到 87%。你可以亲自尝试 [在线演示](https://embedding-inversion-demo.jina.ai/):粘贴任意嵌入向量,查看分类器认为是由哪个模型和任务生成的。 [](https://jina.ai/news/identifying-embedding-models-from-raw-numerical-values/#tokenization-treating-numbers-as-text "分词:将数字视为文本")分词:将数字视为文本 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 一个 1024 维的嵌入向量是 1024 个浮点数的序列。为了将其输入分类器,我们需要一种不对数值结构做任何假设的表示形式。我们采取了一种大胆的方法:将每个浮点数视为一串数字字符,并按字符进行分词。与 [更紧凑的替代方案](https://jina.ai/news/identifying-embedding-models-from-raw-numerical-values/#alternative-approaches) 相比,这听起来可能很浪费,但事实证明这是正确的权衡。对于像 `-0.1234` 这样的值,其 token 序列为:`- 0 . 1 2 3 4`。维度之间由 `[SEP]` token 分隔。完整序列以 `[CLS]` 开头。完整的词汇表包含 15 个 token: 浮点值的数字级分词。词汇表大小为 15。 | Token ID | 含义 | | --- | --- | | 0-9 | 数字 | | 10 | 负号 | | 11 | 小数点 | | 12 | [SEP] | | 13 | [CLS] | | 14 | [PAD] | 在保留 4 位小数精度的情况下,一个 1024 维的向量会产生大约 7,700 个 token。一个 384 维的向量会产生约 2,900 个 token。序列长度随嵌入维度自然变化,跨维度不需要填充或截断。由于分词器是一个直接的整数映射且没有学习组件,因此效率极高。 [](https://jina.ai/news/identifying-embedding-models-from-raw-numerical-values/#model-architecture "模型架构")模型架构 ------------------------------------------------------------------------------------------------------------------------------------------  4 层编码器-only Transformer,80 万参数。词汇表 15,序列长度高达 7,700 个 token。 该分类器是一个小型的编码器-only Transformer,具有 4 层、128 维、4 个注意力头(使用 RoPE)、SwiGLU FFN 和 RMSNorm。CLS token 被池化并投影到 68 类输出空间。总参数约为 80 万。尽管词汇表只有 15 个 token,但这本质上是一个长序列任务。单个 1024 维嵌入变成一个 7,700 个 token 的序列,比典型的 NLP 输入更长。模型必须关注数千个数字 token 以捕捉区分一个模型输出与另一个模型的统计模式。这使得即使在如此小的规模下,高效的注意力机制和位置编码(RoPE)也是必不可少的。 ### [](https://jina.ai/news/identifying-embedding-models-from-raw-numerical-values/#data "数据")数据 我们使用了 10,000 个多语言文本样本,每个样本由 25 多个模型使用各种任务前缀(如 `retrieval.query`、`retrieval.document`、`classification` 和 `clustering`)进行嵌入,产生了 68 个不同的类别。重要的是,这 68 个类别不仅包括不同的模型,还包括应用于同一模型的不同指令提示。例如,带有检索指令的 [jina-embeddings-v5-text-small](https://jina.ai/?sui&model=jina-embeddings-v5-text-small) 和带有分类指令的 [jina-embeddings-v5-text-small](https://jina.ai/?sui&model=jina-embeddings-v5-text-small) 被视为单独的类别。目标是仅从原始输出中检测模型身份和特定于任务的行为。每个类别分为 7,000 个训练样本和 3,000 个验证样本。这些模型跨越五个输出维度。 | 维度 | 类别数 | 示例模型 | | --- | --- | --- | | 384 | 8 | BGE-small, E5-small, MiniLM, GTE-small | | 512 | 2 | BGE-small-zh | | 768 | 24 | BGE-base, E5-base, [jina-embeddings-v5-text-nano](https://jina.ai/?sui&model=jina-embeddings-v5-text-nano), Nomic, INSTRUCTOR, LaBSE | | 1024 | 32 | BGE-M3, E5-large, [jina-embeddings-v3](https://jina.ai/?sui&model=jina-embeddings-v3), [jina-embeddings-v5-text-small](https://jina.ai/?sui&model=jina-embeddings-v5-text-small), Qwen3-0.6B, Snowflake, mxbai | | 1536 | 2 | GTE-Qwen2-1.5B | 仅在 1024 维组内就有 32 个类别需要区分,包括来自同一家族但具有不同任务前缀的模型。在此情况下,分类器不能依赖序列长度;它必须纯粹学习数值模式。 ### [](https://jina.ai/news/identifying-embedding-models-from-raw-numerical-values/#training "训练")训练 训练在 A100 40GB 上进行,使用混合精度、按长度桶化的批处理以及带有余弦调度表的 AdamW,达到每秒约 340K 个 token 和每 epoch 23,800 步的速度。 [](https://jina.ai/news/identifying-embedding-models-from-raw-numerical-values/#experimental-results "实验结果")实验结果 ------------------------------------------------------------------------------------------------------------------------------------------------  14 个 epoch(约 430 亿 token)的训练和验证曲线。训练准确率 87.3%,验证准确率 86.0%。紧密的训练/验证差距和持续改进表明这是可泛化的学习而非记忆。在 80 万参数的情况下,模型已接近其容量极限,更大的模型可能会将准确率推得更高。 ### [](https://jina.ai/news/identifying-embedding-models-from-raw-numerical-values/#confusion-matrix "混淆矩阵")混淆矩阵  完整验证集(每类 3,000 个样本,共 204,000 个)上的 68 类混淆矩阵。总体准确率为 87.0%。 总体准确率为 87.0%,是随机猜测(1.5%)的 59 倍。几个模型被完美分类,包括 GTE-large、[jina-embeddings-v3](https://jina.ai/?sui&model=jina-embeddings-v3)/[jina-embeddings-v5-text-small](https://jina.ai/?sui&model=jina-embeddings-v5-text-small) 的分类变体、LaBSE 和 Paraphrase MiniLM。最难处理的案例是同一基础模型的任务前缀变体。Qwen3-0.6B 在其 4 种任务类型中具有最多的家族内混淆,而 [jina-embeddings-v5-text-small](https://jina.ai/?sui&model=jina-embeddings-v5-text-small) 在 5 种任务中实现了 92% 的家族内准确率。同一模型上不同指令提示产生可区分的输出模式这一事实本身就是一个值得注意的发现,表明即使基础权重相同,任务适应也会留下可测量的数值痕迹。来自不同家族的模型(BGE vs. Jina vs. E5 vs. Nomic)比同一模型的任务变体更容易区分。核心架构和训练方法论留下的签名比特定任务的适配器更强。真正的挑战在于 1024 维组(32 个类别)和 768 维组(24 个类别),其中分类器必须完全依赖数值模式而不是序列长度。 [](https://jina.ai/news/identifying-embedding-models-from-raw-numerical-values/#alternative-approaches "替代方案")替代方案 ------------------------------------------------------------------------------------------------------------------------------------------------------ ### [](https://jina.ai/news/identifying-embedding-models-from-raw-numerical-values/#bucket-tokenizer "桶分词器")桶分词器 将每个维度量化为 K 个桶之一(例如 256 个),生成长度为 D 的紧凑序列,每个维度一个 token。这是 Embedding-Converter (ICLR 2025) 使用的方法。对于 1024 维向量,你会得到 1024 个 token 而不是 7,700 个。分桶对值分布施加了先验。你必须在看数据之前决定桶边界。但不同模型以根本不同的方式分布它们的值。有些将质量集中在零附近的狭窄范围内,有些则在 [-1, 1] 上均匀分布值,并且分布甚至在单个模型内的不同维度间也不同。任何固定的分桶方案要么在值聚集处浪费分辨率,要么在值分散处分辨率不足。针对每个模型的自适应分桶违背了目的,因为它要求事先知道模型身份。 ### [](https://jina.ai/news/identifying-embedding-models-from-raw-numerical-values/#fixed-length-mlp "固定长度 MLP")固定长度 MLP 直接将原始嵌入向量输入 MLP 分类器。根本问题超出了可变维度问题(我们的模型产生 384 到 1536 维的向量)。即使你将所有内容填充到固定长度,你也隐含地假设维度索引在不同模型之间是语义对齐的,即 BGE-M3 的第 1 维对应 [jina-embeddings-v5-text-small](https://jina.ai/?sui&model=jina-embeddings-v5-text-small) 的第 1 维。这个假设是错误的。不同的架构、训练数据和训练目标会产生完全不同的内部表示。这两种替代方案都强加了模型必须绕过的结构假设。数字级分词避免了所有这些。它是我们要找的最无假设的表示:这里是每个数字的确切数字,按顺序排列,用标记分隔。剩下的你自己解决。 [](https://jina.ai/news/identifying-embedding-models-from-raw-numerical-values/#conclusion "结论")结论 -------------------------------------------------------------------------------------------------------- 嵌入模型被训练用于将语义相似的文本映射到邻近的向量。训练目标并未提及使向量可识别,也未提及编码模型签名。然而,签名确实存在,足够强大以至于一个小分类器就能检测到。嵌入模型的“风格”,即其用于表示意义的特定数值模式,就像笔迹一样独特。即使是选择指令提示也会留下可检测的痕迹。这对于审计未知源模型的向量数据库、验证 API 是否实际使用了其声称的模型以及检测模型版本具有实用价值。
