从向量里逆向出原始文本和模型来源

AITNT-国内领先的一站式人工智能新闻资讯网站
# 热门搜索 #
从向量里逆向出原始文本和模型来源
7022点击    2026-03-12 14:12

从向量里逆向出原始文本和模型来源


🔬 在线 Demo: embedding-inversion-demo.jina.ai

📊 技术报告: jina.ai/news/embedding-fingerprints 

📊 技术报告: jina.ai/news/embedding-inversion 

📄 论文: arxiv.org/abs/2602.11047 

💻 代码: github.com/jina-ai/embedding-fingerprints


用户把文本发到我们的 API,我们返回一串浮点数。没有标签,没有水印,没有任何元数据告诉你它从哪来、用的什么模型。大多数人看到这串数字,反应都是"不就是一堆浮点数嘛,能看出什么?"


过去两周,我们做了两项研究,发现能看出的东西远比想象中多:


  1. 模型溯源:我们训练了一个仅有 80 万参数的小模型。光看一串浮点数,就能判断出这是哪个模型生成的,准确率高达 87%,覆盖 68 个模型和任务组合。
  2. 文本逆向:我们用掩码扩散模型,直接从向量中反推出原始文本。Token 级还原准确率达到了 81%。


也就是说,向量不仅携带语义,还带着生成它的模型的基因,以及原始文本的大量信息残留。


从向量里逆向出原始文本和模型来源 demo: https://embedding-inversion-demo.jina.ai/


向量溯源:这串数字是谁生成的?


当有人给你一个 1024 维的向量,你能判断它是 BGE-M3 生成的,还是 jina-embeddings-v3,还是 Qwen3-Embedding 吗?


再往前走一步: 同一个模型,你能分辨推理时用的是 retrieval 指令还是 classification 指令吗?


直觉上这似乎不可能。向量就是一堆数字,模型之间的差别应该体现在语义空间的几何结构上,而不是数值本身的分布细节。但实验结果直接推翻了这个直觉。


不同模型产生的浮点数,在统计上有非常显著的差异。值域范围、各小数位数字出现的频率、维度间的相关模式...... 这些特征拼在一起,构成了模型独特的数字指纹。这有点像笔迹鉴定,同一段话让不同人抄写,内容一样,但笔画的力度、倾斜和连笔方式都会无意间暴露书写者的身份。


把浮点数当文本来读


这个方法最反直觉的地方在于输入表示。我们没有把向量当成一堆浮点数,而是把每个数字转成了字符串,像处理文本一样,逐个字符拆开喂给模型。


如下图所示,-0.1234 会变成 token 序列 [CLS] - 0 . 1 2 3 4,维度之间用 [SEP] 隔开。整个词汇表极简,只有 15 个 Token:数字 0 到 9、负号、小数点、几个特殊分隔符。


从向量里逆向出原始文本和模型来源

位级别分词(Digit-level Tokenization)


为什么不使用更直观的量化分桶(Binning):把数据范围划分为 256 个区间(bin),一个维度对应一个 Token,这样 1024 维的向量只需 1024 个 Token 就能表达完。


因为量化需要预设边界,而不同模型的数值分布天差地别:有的集中在 0 附近,有的铺满整个 [-1, 1] 区间,同一个模型不同维度的分布也完全不同。任何固定的分桶方案,都会在某些模型上造成严重的分辨率损失,掩盖掉最关键的特征。


所以我们选了最“无假设”的方案:位级别分词(Digit-level Tokenization)。虽然这会让一个 1024 维向量膨胀成 7700 个 Token 的长序列,但它原样呈现了数字的每一位,保留了所有的统计痕迹,不预设规律,让模型自己去学习其中的统计特征。


比如某些模型在特定位上出现数字 7 的频率更高,或者某些维度的排列模式更独特。这些看似无意义的微观特征,恰恰构成了模型的数字指纹。


模型架构


分类器本身是个 4 层 Transformer,128 维,4 个注意力头,总共约 80 万参数 。用 RoPE 做位置编码,SwiGLU 做 FFN,RMSNorm 归一化。CLS token 池化后投影到 68 个输出类别。


从向量里逆向出原始文本和模型来源

模型架构图,比 GPT-2 小 150 倍,但对 15 token 词汇表的分类任务完全够用。


80 万参数是什么概念?比 GPT-2 小两个数量级。但这个任务词汇表只有 15 个 token,分类目标是 68 个类别,瓶颈不在模型大小,而是如何从 7700 个 token 的长序列里提取出能区分 68 个类别的统计特征。


训练数据方面,我们准备了一万条多语言文本,分别送入 25 个以上的模型,配合不同 task prefix 编码,产生 68 个类别。每类 7000 条训练样本,3000 条验证样本。


这 68 个类别不只是 68 个模型。其中包含了同一个模型搭配不同 instruction prompt 的组合,比如 jina-embeddings-v5-text-small 配 retrieval 指令和配 classification 指令算两个不同类别。如果分类器能区分它们,说明仅仅换一个 instruction prompt,就足以在输出数值上留下可检测的痕迹。


在这些类别中,最难的分组是 1024 维度,包含 32 类模型,分类器无法通过序列长度投机取巧,必须纯粹依赖数值模式。


从向量里逆向出原始文本和模型来源


68 类分类,87% 准确率


我们在 A100 上跑了 14 个 Epoch,处理了大约 430 亿个 Token。


从向量里逆向出原始文本和模型来源

14 个 epoch 的训练和验证曲线


最终,训练准确率达到了 87.3%,验证准确率为 86.0%。两条曲线贴得很近,说明模型真的学到了真实的数值规律,而不是在死记硬背训练集。


87% 准确率,随机猜的话是 1.5%。比瞎猜好 59 倍。


从向量里逆向出原始文本和模型来源

68 类验证集混淆矩阵,每类 3000 样本,共 20.4 万样本。对角线越亮说明分类越准确。


观察这 20.4 万个样本的混淆矩阵,能看到几个有趣的现象:GTE-large、LaBSE、Paraphrase MiniLM 等模型被 100% 准确识别。跨系列的区分(如 BGE vs Jina)非常容易,模型底层的架构和训练方法留下的指纹最深。最难分辨的是同一个基础模型搭配不同的任务前缀。


最让人意外的是,同一个模型、完全相同的权重,仅仅是推理时换了一个 instruction prompt,输出的数值分布就会产生可检测的差异。jina-embeddings-v5-text-small在 5 个不同 task prefix 之间达到了 92% 的区分准确率。任务适配(Task adaptation)不只是在语义空间里挪了个位置,它实际上改变了数值的统计分布。


这件事有非常直接的用途。接手了一个向量数据库但不知道当初用的什么模型?取出一条向量送进分类器就能识别。怀疑某个 API 声称用的是 model A 但实际偷偷换成了 model B?向量指纹可以验证。向量模型的提供商悄悄升级了版本?指纹同样会暴露这个变化。


从向量逆向文本


如果识别模型来源只是让人意外,那接下来的事就有点狠了:从向量里逆向出原始文本。


给你一个 1024 维的向量,还原出生成它的那段文本。


这不是全新的问题。2023 年 Morris 等人做的 Vec2Text 用 T5 编解码器(Encoder-Decoder)在 32 token 的序列上做到了 92% 的精确匹配(Exact Match)。但那个方法有个根本限制:它需要反复调用目标模型的 API 进行迭代修正,动辄 20 多轮,推理成本直接翻了一个数量级。


我们的目标更激进: 只看向量本身,不碰目标模型,一次性把文本还原出来。


用掩码扩散逆向出文本


我们将这个问题重新定义为一个条件掩码扩散(Conditional Masked Diffusion)问题。


从一个全 [MASK] 的序列开始,模型在每一步同时预测所有位置的 token,逐步替换成真实词汇。整个过程只需要 8 步。不是从左到右一个个生成,而是所有位置并行去噪。


步骤 8/8 [MASK] [MASK] [MASK] [MASK] [MASK]

步骤 6/8 [MASK] quick [MASK] [MASK] [MASK]

步骤 3/8 The  quick brown [MASK] jumps

步骤 1/8 The  quick brown fox  jumps


去噪过程: 从全掩码出发,每一步同时预测所有位置,8 步内完成还原。


我们通过自适应层归一化(Adaptive Layer Normalization,AdaLN) 将目标向量注入到 Transformer 的每一层。向量先经过一个投影层,然后在每一层生成缩放(Scale)和位移(Shift)参数,用来调制层归一化的输出。时间步也通过同样的机制注入。两个信号相加,模型同时知道"当前去噪到了哪一步"和"目标向量长什么样"。


从向量里逆向出原始文本和模型来源

条件掩码扩散语言模型的架构。上半部分是训练流程: 输入文本经 embedding encoder 编码后,通过 MLP 投影注入 Transformer。下半部分是去噪过程: 从全掩码序列出发,逐步还原。


这个设计一举解决了 Vec2Text 的两个问题。第一,推理时完全不需要接触原始模型,向量是唯一的输入。第二,所有位置并行预测,避免了自回归从左到右的误差累积。而且 AdaLN 的条件注入方式天然不挑编码器:不管目标向量来自什么模型、什么维度,过一遍投影 MLP 就能注入同一个 Transformer。


底座模型我们选用了 22 层、3.8 亿参数的多语言 BERT。在冻结预训练权重后,我们只训练投影层、AdaLN 模块和输出层,实际训练参数量约 1.9 亿。训练数据是 mC4 的 200 万条多语言样本,统一截断到 32 个 token。


# 训练核心伪代码

for text, embedding in dataloader:

  t = uniform(0, 1)       # 随机采样时间步

  masked = random_mask(text, t)  # 按比例随机掩码

  cond = mlp_project(embedding)  # 投影 embedding

  logits = model(masked, t, cond) # 条件预测

  loss = cross_entropy(logits[masked_pos], text[masked_pos])


训练流程: 随机掩码 + 条件去噪。噪声调度用 log-linear schedule,集中在后期掩码,前期保留结构。


81% 的 Token 级还原准确率


我们分别在三个主流模型上进行了实测,还原率都很惊人。


从向量里逆向出原始文本和模型来源

三个编码器上的 token 还原准确率,使用顺序贪心解码(Sequential Greedy Decoding),序列长度 32 token。每个编码器单独训练。


从向量里逆向出原始文本和模型来源

四个编码器配置的训练准确率曲线。所有模型在 50K 步后趋于收敛。


为了看清这个数字的含金量,我们设定了一个基准对照组:让一个普通的语言模型在完全不看向量的情况下盲猜文本。它能写出非常流畅的句子(BLEU 分数很高),但 Token 准确率只有 2.1%。随机 token 更惨,0.02%。


"能说人话"和"说对的话"是两回事。 模型必须从向量中真正提取语义信息,才能在最低的编码器上也做到 76% 的还原。


在解码策略上,我们测试了五种方案。表现最好的是欧拉 + 重掩码(Euler + Remasking):模型每一步去噪后,都会自我检视一遍,把置信度最低的 5% 重新掩码,交给下一步去修正。相当于把 Vec2Text 的外部修正循环内化到了扩散过程里。


实验证明 5% 是一个最优平衡点,比例太多丢掉正确的预测,太低则修正力度不够。


从向量里逆向出原始文本和模型来源

不同解码策略在 10 种语言上的平均余弦相似度。需要注意,这里衡量的是还原文本与原始文本的向量相似度,而非 Token 级准确率。两个指标下的最优策略不完全一致。综合来看,Sequential Greedy 在大多数编码器上表现得最为稳健,是目前最可靠的还原主力。


一个 1024 维的 float32 向量只有 4KB。但这 4KB 足以让一个扩散模型还原出 32 个 token 中超过 80% 的内容。


向量并非不可逆


在很多人的认知中,向量是一道天然的脱敏屏障:文本转化为高维坐标后,原始信息便不可回溯。很多系统也都宣称:“我们只存向量,不存原文,所以用户隐私是绝对安全的。”


这两项研究动摇的正是这个假设。向量不是不可逆的哈希,而是一个有损但信息密度极高的压缩表示。模型的身份、原始文本的内容,都编码在里面,提取的门槛也在不断降低。


指纹研究(Fingerprint)证明了每个模型编码语义的数值风格各不相同,区分度高到一个 80 万参数的小模型就能认出 68 个来源。逆向研究(Inversion)则证明了这些数字里编码的原始信息,足够扩散模型还原出 80% 以上的内容。两个工作串联起来,先用指纹分类器锁定编码器,再用对应的逆向模型还原文本,就构成了一条完整的攻击链路。


对模型开发者来说,这些发现迫使我们直面一个此前被忽视的问题:向量模型的安全边界到底在哪里?过去我们把精力都投在提升语义检索性能上,但从来没认真想过这些向量在安全性上到底暴露了多少。


我们是否该在训练中引入某种信息瓶颈?在保留检索能力的同时,降低向量的可逆性,或者至少让模型的数值指纹不再那么容易被识破?


当然,硬币有另一面。在 API 提供商可以悄悄换模型的世界里,能从数值本身验证模型来源,本身就是一种有价值的审计能力。


两个项目的代码和在线 demo 均已开源:

🔬 在线 Demo: embedding-inversion-demo.jina.ai

💻 代码仓库: github.com/jina-ai/embedding-fingerprints


文章来自于“Jina AI”,作者 “Jina AI”。

AITNT-国内领先的一站式人工智能新闻资讯网站
AITNT资源拓展
根据文章内容,系统为您匹配了更有价值的资源信息。内容由AI生成,仅供参考
1
AI数据分析

【开源免费】DeepBI是一款AI原生的数据分析平台。DeepBI充分利用大语言模型的能力来探索、查询、可视化和共享来自任何数据源的数据。用户可以使用DeepBI洞察数据并做出数据驱动的决策。

项目地址:https://github.com/DeepInsight-AI/DeepBI?tab=readme-ov-file

本地安装:https://www.deepbi.com/

【开源免费airda(Air Data Agent)是面向数据分析的AI智能体,能够理解数据开发和数据分析需求、根据用户需要让数据可视化。

项目地址:https://github.com/hitsz-ids/airda

2
知识库

【开源免费】FASTGPT是基于LLM的知识库开源项目,提供开箱即用的数据处理、模型调用等能力。整体功能和“Dify”“RAGFlow”项目类似。很多接入微信,飞书的AI项目都基于该项目二次开发。

项目地址:https://github.com/labring/FastGPT

3
RAG

【开源免费】graphrag是微软推出的RAG项目,与传统的通过 RAG 方法使用向量相似性作为搜索技术不同,GraphRAG是使用知识图谱在推理复杂信息时大幅提高问答性能。

项目地址:https://github.com/microsoft/graphrag

【开源免费】Dify是最早一批实现RAG,Agent,模型管理等一站式AI开发的工具平台,并且项目方一直持续维护。其中在任务编排方面相对领先对手,可以帮助研发实现像字节扣子那样的功能。

项目地址:https://github.com/langgenius/dify


【开源免费】RAGFlow是和Dify类似的开源项目,该项目在大文件解析方面做的更出色,拓展编排方面相对弱一些。

项目地址:https://github.com/infiniflow/ragflow/tree/main


【开源免费】phidata是一个可以实现将数据转化成向量存储,并通过AI实现RAG功能的项目

项目地址:https://github.com/phidatahq/phidata


【开源免费】TaskingAI 是一个提供RAG,Agent,大模型管理等AI项目开发的工具平台,比LangChain更强大的中间件AI平台工具。

项目地址:https://github.com/TaskingAI/TaskingAI

4
prompt

【开源免费】LangGPT 是一个通过结构化和模板化的方法,编写高质量的AI提示词的开源项目。它可以让任何非专业的用户轻松创建高水平的提示词,进而高质量的帮助用户通过AI解决问题。

项目地址:https://github.com/langgptai/LangGPT/blob/main/README_zh.md

在线使用:https://kimi.moonshot.cn/kimiplus/conpg00t7lagbbsfqkq0