想象你是一家餐厅的熟客,最钟爱大厨那道“江南秘制鱼”。有天你想在家复刻这道菜,但大厨的厨房从不对外开放,你拿不到配方。你唯一的办法是:一遍遍去店里点这道菜,细细品味咸淡、火候、配料,记住每一次入口的感觉;有时坐在不同位置观察上菜次序,甚至偷偷计时等待时长。几十次之后,你竟然在家做出一道几乎一模一样的秘制鱼——虽然你从未走进厨房。这正是“模型窃取攻击”的镜像:一个商业AI模型就像那位大厨,它的“配方”是训练好的神经网络参数;攻击者没有权重文件,却能通过无数次 API“点菜”,训练出一个行为几乎一致的“替代模型”。本文将带你以“美食侦探”的视角,拆解模型窃取的套路、原理、攻防与实战。
模型窃取是 AI 商业化后最隐蔽的资产流失方式之一。理解攻击原理与防御手段,是算法工程师守住模型核心价值、参与安全风控体系设计的必备能力。
目录
可视化演示
展示模型窃取攻击的端到端工作流、方程求解与学习型范式对比、多层防御策略,支持步进式探索攻击各阶段。
本节配有交互动效(进入视口后自动加载,约 3KB)。
攻击工作流五阶段 侦察:收集目标模型API信息与限制 查询:生成输入样本发送查询请求 训练:用输入输出对训练替代模型 成功率 ∝ 查询量 × 模型复杂度 端到端攻击分五步完成模型窃取
攻击概述——一位“偷学”的大厨粉丝
老饕小陈爱上了“满堂春”大厨的招牌菜。他每周去点三次,尝遍火候与佐料,三个月后自己在家复刻出九成相似的味道。这个过程中,小陈从未拿到过厨房的配方,他唯一的“接口”就是点菜和上菜。这正是模型窃取攻击的起点:看似只能“输入问题、得到答案”的黑盒,其实藏着一座金山。
模型窃取攻击(Model Stealing Attack)指攻击者在无法获得目标模型内部参数的前提下,仅通过查询接口获取输入输出对,训练一个“替代模型”来复制目标模型功能的过程。这里的关键假设是:目标模型以 API 形式对外提供服务时,“输入-输出”通道是完全暴露的。攻击者不需要理解模型内部如何运转,只需要足够的(输入,输出)样本,就能训练出一个功能等价物。
按攻击目标不同,模型窃取可以大致分为“功能复制”和“信息提取”两类:前者要的是“行为像”,后者要的是“参数知”。威胁模型上,黑盒攻击假设攻击者没有权重、没有梯度、没有训练数据,只有查询权;白盒攻击则假设攻击者可以拿到部分内部表征。真实攻击场景非常普遍——商业 API(图像分类、语音识别、风控评分)一旦上线,就暴露在全世界“食客”的目光下,任何一次正常调用都可能为攻击者积累素材。
正如小陈每次点菜都在为“复刻计划”积累情报,攻击者的每一次“正常查询”都在描绘目标模型决策边界的等高线。最危险的攻击往往不是突然的暴力破解,而是藏在成千上万次普通调用里的“温柔试探”。
窃取类型——偷尝的四种姿势
想知道大厨的秘方,有人选择反复点菜自己试味,有人买通后厨内应偷看配方,有人盯着服务员上菜顺序反推流程,还有人竖起耳朵听后厨煎炒的节奏。四种姿势,殊途同归。
对应到攻击技术,四种主要类型是:黑盒窃取、白盒窃取、置信度泄露利用、侧信道窃取。
- 黑盒窃取(Black-box Stealing):攻击者只拿到硬标签或概率输出,通过大量采样 + 替代模型蒸馏实现功能近似。这是最普遍的形态,也是本文演示动画展示的典型场景。
- 白盒窃取(White-box Stealing):当模型权重、梯度或中间特征因事故/内鬼泄露时,攻击者可以直接在本地对模型进行微调、压缩,甚至删除签名后转卖。
- 置信度泄露(Confidence Leakage):API 返回 softmax 概率向量时,“最可能类别”以外的概率异常值会暴露样本到决策边界的距离信息,让蒸馏攻击效果成倍提升。
- 侧信道窃取(Side-channel Stealing):利用输出长度、响应时间、内存占用、功耗等物理信号,反推模型结构(如层数、宽度、量化位数),再在本地重建近似模型。
白盒是直接“拿到配方本”,黑盒是“纯靠嘴尝”,置信度泄露相当于“点菜时偷偷看了别人的点评卡”,侧信道则像“听后厨声音判断是爆炒还是慢炖”。四种方式泄露的信息量和隐藏难度各不相同,攻击者会按现实条件选择最顺手的一种。
核心原理——靠品尝还原配方
小陈要复刻一道菜,最关键的不是“记住好吃”,而是搞清楚“为什么好吃”:多咸、多辣、什么火候。模型窃取的精髓也一样:把输出行为还原成决策几何。
决策边界提取是基础。二分类器的输出标签本质上是在回答“这个样本落在决策边界的哪一侧”,每次查询就是一次“边界触碰实验”。攻击者只要在边界两侧多探几针,就能把边界形状勾勒出来。模型蒸馏则更进一步——如果 API 返回的是 softmax 概率,攻击者就用概率分布作为“软标签”来训练替代模型,让替代模型不只在类别上一致,在每个类别的置信度上也逼近目标模型:
替代模型训练是最后一步。攻击者用一个公开数据集或主动采样得到的样本集,以目标模型的输出为监督信号,训练自己的模型:
查询预算控制是攻击的现实约束:商用 API 按次计费、有风控限速,攻击者必须在有限预算内最大化信息收益,因此倾向于主动采样——不确定性采样、边界采样、生成式对抗采样。每一次品尝都告诉小陈“这道菜的某个维度对不对”,软标签则告诉他“差多少”。当替代模型的决策边界逐渐贴上目标模型,一份“复刻版秘制鱼”就诞生了。
- 最小化目标寻找替代模型参数 $\theta'$,使整体误差最小,相当于不断调整复刻配方里的每一种调料比例。
- 平均误差用 $\frac{1}{N}\sum$ 对所有查询样本取平均,避免样本数量影响损失值。
- 目标模型输出$f(x_i)$ 是目标模型(大厨)对第 i 个样本的判定结果,是攻击者的“标准答案”。
- 平方误差$\|\cdot\|^2$ 对误差取平方,放大较大偏差,让优化方向更关注“差得远”的样本。
攻击流程——从点菜到复刻
小陈的复刻不是心血来潮的乱尝,而是有一套精密流程:先摸清餐厅招牌菜的稳定菜单(确认输入格式与输出种类),再有计划地覆盖不同口味(主动采样),同步记录口感笔记(标签采集),最后请朋友盲测对比真假(性能评估)。
模型窃取的攻击流程同样分为四步:
1. 目标探测:确认 API 的输入输出维度、类别数量、限速规则。相当于“看菜单、数菜品、了解上菜规矩”。
2. 样本生成:生成能覆盖决策边界的高信息量样本。常用方法包括边界扰动、对抗样本、生成对抗网络、公开数据集增强。这一步决定了查询预算的使用效率。
3. 标签采集:批量查询目标模型,记录输出并去重去噪。注意控制查询频率以躲避风控,必要时使用代理池分散来源。
4. 性能评估:用独立的测试集比较替代模型与目标模型的预测一致性。准确率(accuracy)衡量替代模型自身水平,一致性(agreement)衡量它是否真的“继承了原模型的脾气”。
这四步听起来简单,真正的技术含量在于“第二步怎么选样本”和“第四步怎么判断像不像”。高手与小白的差距,不在查询次数,而在每一问是否问在决策边界的刀刃上。
防御对策——给秘方上锁
大厨发现食客在复刻他的菜,会怎么办?他会在菜里藏一个只有自己人知道的“暗号”(水印),会盯住一天来点十次同一道菜的可疑熟客(指纹检测),会规定每桌限量供应(限速),还会故意把口味调得有点飘忽(输出扰动)。
- 模型水印:训练时在特定触发器样本上植入独特行为,事后通过触发器样本集验证某模型是否衍生自自己的模型。这相当于在菜里埋入“只有自己人尝得出的暗号”,即使菜被复刻,暗号也会被一起带走,成为维权的铁证。
- 指纹验证:记录查询 IP、频率、样本相似度,异常模式触发告警。相当于服务员熟记熟客面孔,发现形迹可疑的“打卡狂人”就重点盯防。
- 查询限速:限制单一账户的查询并发与总量,强制攻击者拉长攻击时间、抬高查询成本,让“偷学”在经济上变得不划算。
- 输出扰动:对置信度向量取整、加噪或截断,减小软标签的信息量。最常见的做法是保留小数点后一位:
以上对策不能完全阻止窃取——就像暗号和限购也挡不住最执着的食客——但能把攻击成本从“点三次菜”抬升到“点三百次菜”,让攻击者在投入产出比面前主动放弃。
- 原始置信度$p_j$ 表示目标模型认为样本属于第 j 类的概率,是攻击者最想得到的“细腻口感描述”。
- 放大取整$\lfloor 10^k \cdot p_j \rfloor$ 先把概率放大 $10^k$ 倍再向下取整,去掉多余的小数位。
- 还原输出除以 $10^k$ 得到保留 k 位小数的近似概率,k 越小,泄露的信息越粗糙。
实战应用——真实战场的攻与防
从街角小馆到连锁集团,“被偷菜谱”的故事每天都在上演。AI 领域同样如此。
- 语音识别 API 窃取:攻击者用公共语音数据集查询商业 ASR 服务,蒸馏出可部署在本地设备的紧凑模型,避开按分钟计费的商业授权。研究表明,只需数千小时查询即可获得接近商用模型的词错误率。
- 图像分类复刻:某云服务商图像分类 API 被攻击者用约 1 万次查询克隆,替代模型与目标模型的决策一致性超过 92%,攻击成本不到官方授权费的五分之一。
- API 商业化防盗版:API 供应商集成水印与用量监控,检测到分布式攻击后动态调整置信度输出精度,将单次查询的信息量压到最低。
- 合规评估:安全审计团队使用模拟攻击评估模型资产的可盗性,输出风险报告,指导风控策略和保险定价。
在这个“点菜就能偷学”的时代,没有哪个模型是绝对安全的。安全是持续博弈的艺术:了解攻击者的手法,就是握住防守的主动权。
AI 应用场景
商业 API 安全红队评估
阶段:模型部署与运维
解决的问题:企业发布付费 API 后,攻击者可低成本复制模型功能。传统渗透测试只关注接口越权,忽略了“合法查询也可以偷走模型”。红队主动模拟攻击,量化窃取风险,为限速、扰动、水印策略提供数据依据。
具体案例:某金融科技公司的反欺诈模型 API,红队用“不确定性采样”策略在 800 次查询内训练出替代模型,与目标模型在测试集上达成 90% 以上一致率。团队据此将置信度输出从浮点改为一位小数,并将单 IP 日查询上限从 5000 降到 500,攻击成本上升约 6 倍。
模型版权归属鉴定
阶段:事后审计取证
解决的问题:怀疑竞品模型复制了自家能力,但拿不出直接证据。利用模型水印触发器样本集作为“验钞笔”,在盲测中验证对方模型是否携带自家唯一的水印行为。
具体案例:某语音助手厂商在训练时植入 12 个特殊音频触发器,使其在特定噪声下必然输出特定短语。厂商对竞品 App 发送触发器样本,发现其中 8 个被竞品以相同方式响应,据此申请司法鉴定,促成庭外和解。
模型资产防窃取部署
阶段:模型上线阶段
解决的问题:如何在保证正常用户体验的前提下,提高模型窃取成本。单纯关停 API 不现实,需要在“服务可用”与“信息泄露”之间取平衡。
具体案例:某图像分类 SaaS 上线时集成三层防护:置信度取整加动态抖动、按 Key 限速、分布式风控。上线三个月内检测到 3 起疑似窃取尝试,攻击者均在查询量达到约 2000 次后因成本过高而放弃。
Python 演示
"""模型窃取攻击模拟: 通过主动采样查询训练替代模型"""import numpy as npfrom sklearn.linear_model import LogisticRegressionfrom sklearn.datasets import make_classificationfrom sklearn.model_selection import train_test_split class TargetModel: """模拟一个商业AI分类API, 只暴露predict接口""" def __init__(self): self.model = LogisticRegression(C=1.0) def train(self, X, y): self.model.fit(X, y) def predict(self, X): """返回置信度向量, 模拟软标签输出""" return self.model.predict_proba(X) class Attacker: """攻击者: 通过有限次查询偷学目标模型""" def __init__(self, target, budget=80): self.target = target self.budget = budget self.queries = [] self.labels = [] def active_sample(self, X_pool, K=5): """不确定性采样: 选择模型最拿不准的K个样本""" proba = self.target.predict(X_pool) uncertainty = 1 - np.max(proba, axis=1) idx = np.argsort(uncertainty)[::-1][:K] return idx def steal(self, X_pool, seed=42): """执行窃取: 主动采样 -> 查询 -> 训练替代模型""" rng = np.random.default_rng(seed) used = set() steps = 0 while len(self.queries) < self.budget and steps < 100: steps += 1 remain = [i for i in range(len(X_pool)) if i not in used] if len(remain) < 5: break Xc = X_pool[remain] idx = self.active_sample(Xc, K=5) for i in idx: if len(self.queries) >= self.budget: break self.queries.append(Xc[i]) self.labels.append(self.target.predict(Xc[i].reshape(1, -1))[0]) used.add(remain[i]) Q = np.array(self.queries) if len(Q) == 0: return None L = np.array(self.labels) y = np.argmax(L, axis=1) surrogate = LogisticRegression() surrogate.fit(Q, y) return surrogate def main(): X, y = make_classification( n_samples=500, n_features=4, n_informative=3, n_classes=2, random_state=42 ) X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.3, random_state=42 ) target = TargetModel() target.train(X_train, y_train) attacker = Attacker(target, budget=80) X_pool = X_train[:-10] surrogate = attacker.steal(X_pool) if surrogate is None: return pred_sur = surrogate.predict(X_test) pred_tgt = np.argmax(target.predict(X_test), axis=1) true_acc = np.mean(pred_sur == y_test) clone_acc = np.mean(pred_sur == pred_tgt) target_acc = np.mean(pred_tgt == y_test) print(f"目标模型精度: {target_acc:.3f}") print(f"替代模型精度: {true_acc:.3f}") print(f"替代模型一致率: {clone_acc:.3f}") if __name__ == "__main__": main()
self.model = LogisticRegression(C=1.0)用最基础的逻辑回归充当“大厨的秘方”,结构简单但能直观展示窃取链路。return self.model.predict_proba(X)API 只暴露置信度向量,不暴露任何内部参数。uncertainty = 1 - np.max(proba, axis=1)不确定性越高说明样本越靠近决策边界,查询价值越大。self.queries.append(Xc[i])` / `self.labels.append(...)记录查询样本与目标模型响应,攒“品尝笔记”。surrogate = LogisticRegression(); surrogate.fit(Q, y)用收集到的记录训练替代模型,完成“复刻”。clone_acc = np.mean(pred_sur == pred_tgt)替代模型与目标模型在测试集上的决策一致性,是衡量窃取成功度的核心指标。
常见误区
误区“既然是黑盒,攻击者两眼一抹黑,只能靠瞎猜碰运气,攻击成功的概率应该很低吧?”
正解黑盒只是看不到内部参数,但输出本身携带大量信息——每次查询的类别标签就是“在决策边界上踩中一个点”的证据,置信度向量更相当于边界的软性坐标。攻击者用数百次精心挑选的查询就能复刻出与目标高度一致的模型。就像食客虽然进不了厨房,但通过反复点菜能猜出七八成配料。
为何常见:“黑盒”这个翻译让人联想到“完全不可知”,忽略了输入输出通道本身就是一个信息通道。
误区“反正最终都是归一化成概率,跟只给类别相比差不了多少。”
正解软标签泄露的是整个概率空间的几何信息,而硬标签只是概率最大者的索引。在二分类边界附近,硬标签只告诉你是 A 还是 B,软标签告诉你“72% 像 A、28% 像 B”,相当于告诉你离边界有多远。用软标签的蒸馏攻击精度远高于硬标签。
为何常见:人习惯用“最终答案”思考,忽略了连续概率中蕴含的细微距离信息。
误区“部署了限速和取整,模型就偷不走了。”
正解防御只能提高攻击成本,不能消灭攻击。取整、限速之后,攻击者可以用更多查询和主动采样策略逼近;水印能帮助溯源但无法阻止复制。安全是概率博弈,不是二值开关。攻击成本从 100 元升到 10000 元,已经是一次成功的防御。
为何常见:厂商宣传“防窃取”时,大家容易把“提高门槛”理解成“绝对安全”。
误区“没拿到模型文件就不算被偷,顶多被模仿。”
正解模型的价值在于功能。攻击者只要复刻出高一致性的决策行为,就已经实现了“功能窃取”,即使没有拿到一个字节的权重。在 API 商业化时代,行为复制就等于资产流失——模仿者用百分之一的成本,提供九成相似的服务。
为何常见:传统软件盗版靠“复制文件”衡量,但模型是一种可以被行为克隆的资产。
误区“多问 API 要几次输出,堆一批数据训练就行。”
正解数据不是越多越好,关键是分布。随机的查询样本往往大量落在易分类区域,信息冗余;主动采样选在决策边界附近的样本,每一问都“问在刀刃上”。同样的预算,边界采样的一致性远超随机采样,差距可达 10 个百分点以上。
为何常见:直觉认为“量变产生质变”,忽略了样本的信息密度差异。
面试题
Q1. 模型窃取攻击中,“黑盒”场景意味着攻击者?
- A.完全无法获得模型的任何信息
- B.只能通过输入输出接口与模型交互← 正确答案
- C.拥有模型全部训练数据
- D.可以直接读取模型权重
答案:B。黑盒场景中攻击者拿不到权重、梯度和训练数据,只能像普通用户一样通过 API 提交输入、获取输出。注意“完全无法获得任何信息”是不对的,输出本身就是宝贵信息;C 和 D 分别是把训练数据和参数误当成黑盒外可得之物。
Q2. 相比硬标签(最终类别),软标签(置信度向量)?
- A.泄露的信息量反而更少
- B.与硬标签完全等同
- C.泄露更多决策边界信息← 正确答案
- D.对攻击者完全没有价值
答案:C。软标签不仅告诉攻击者“属于哪一类”,还表达了对所有类别的确信程度。两个样本如果硬标签相同,软标签可能截然不同——一个在边界附近摇摆,一个在类别中心笃定。这些细微差异正是蒸馏攻击最需要的信息。
Q3. 以下哪些策略属于主动采样?
- A.随机在输入空间采样
- B.不确定性优先采样← 正确答案
- C.基于梯度的边界采样← 正确答案
- D.对全部数据暴力度量
答案:BC。主动采样的核心是挑选信息量最大的样本。不确定性采样选择模型置信度最低的样本,梯度边界采样选择对决策边界影响最大的样本,二者都尽量贴近决策边界。随机采样和暴力穷举不具目标性,会浪费宝贵的查询预算。
Q4. 模型蒸馏攻击的核心思想是?
- A.用目标模型输出训练替代模型← 正确答案
- B.直接逆向破解目标模型权重
- C.复制目标模型的全部训练数据
- D.暴力破解目标模型的接口密码
答案:A。蒸馏攻击把目标模型的输出(尤其是软标签)当作监督信号,训练一个结构更简单的替代模型,让它在行为上逼近大模型。它不需要进入“厨房”,也不需要拿到“配方本”,只需大量“点菜品尝”。
Q5. 对置信度向量做取整(保留一位小数)属于什么防御?
- A.可以完全消除模型窃取风险
- B.减少信息泄露但攻击仍可进行← 正确答案
- C.只影响正常用户且无副作用
- D.必然导致模型精度大幅下降
答案:B。取整降低了软标签的精度,攻击者无法从一位小数中精确推测边界距离,但通过多次查询取平均仍可恢复近似分布。它显著提高攻击成本,但不能消除攻击,且对正常用户的体验影响很小。
Q6. 模型水印的作用包括?
- A.证明模型版权归属← 正确答案
- B.完全阻止模型被窃取
- C.追溯模型泄露来源← 正确答案
- D.提升模型的预测精度
答案:AC。水印通过植入独特触发器行为实现两个目的:一是当替代模型继承了水印行为时,可以证明它衍生自目标模型;二是可以定位是哪一次泄露渠道流出的。水印不阻止窃取行为,也不参与模型精度优化。
Q7. 窃取攻击中“查询预算”通常指?
- A.攻击者可用最大查询次数← 正确答案
- B.目标模型的训练轮数
- C.数据集里的总样本数
- D.模型的参数量多少
答案:A。商用 API 按次计费且带风控,攻击者只能在有限的查询次数内收集信息,这就是预算。主动采样、边界探测等策略都是为了“省着花”——把每次查询都用在信息量最大的样本上。
Q8. 最能衡量替代模型窃取成功度的是?
- A.替代模型在测试集上的准确率
- B.与目标模型的预测一致性← 正确答案
- C.查询目标模型API的总耗时
- D.替代模型的参数规模大小
答案:B。准确率只能说明替代模型自己“手艺不错”,一致性才是“是否学到了原模型脾气”的证据。即使替代模型准确率更高,如果在决策边界处与目标模型分歧很大,说明它没有复刻出原模型特有的行为模式。
Q9. 白盒模型窃取是指?
- A.攻击者获取了模型的内部参数← 正确答案
- B.攻击者使用纯白色输入样本
- C.攻击者只能获得最终类别标签
- D.攻击者通过侧信道获取信息
答案:A。白盒对应“厨房开放”——模型权重、结构等信息因泄露或内鬼而暴露,攻击者可以直接在此基础上微调、压缩或转卖,攻击难度远低于黑盒,危害也更直接。
Q10. 侧信道窃取可以利用哪些信息?
- A.目标API的响应时间← 正确答案
- B.推理时的内存访问模式← 正确答案
- C.设备运行时的功耗变化← 正确答案
- D.模型访问的网络流量← 正确答案
答案:ABCD。侧信道窃取利用模型推理时的物理与时序特征反推结构:响应时间暗示网络深度,内存访问模式暗示张量形状,功耗变化暗示计算密度,流量大小暗示输入输出维度。这些信号单独看很微弱,组合起来却能重建近似模型架构。