城市中心的“百味楼”有一道镇店名菜“百味鸡”,配方锁在保险柜里。每天坐在窗边的神秘食客老周,总是点同一道菜、要求后厨反复微调佐料、尝一口就放下筷子。其实老周是隔壁“山寨轩”派来的“配方侦察员”——他想通过反复点菜、观察味道变化,逆向拼出百味鸡的秘密配方。店长阿福渐渐发现:普通食客点菜随机、浅尝辄止;老周点菜却像在做实验,同一道菜微调配料连点几十次,专挑别人不点的刁钻组合。于是阿福建立了一套“点餐行为巡查系统”:实时观察每张桌子的点菜序列、记录口味偏好、在菜里埋下只有自己人认识的暗号调料。当某个食客的行为强烈偏离正常画像时,系统就会拉响警报——这就是“模型提取检测”的生动写照。 在 AI 世界里,“百味鸡”就是深度学习模型,它由海量数据和算力训练而成,是公司的核心资产。“配方侦察员”就是模型提取攻击者:他们通过公开的预测 API 反复提交精心构造的查询,观察模型的“品菜反应”(输出标签与置信度),训练出一个功能相近的“影子模型”,从而盗走模型的核心能力。而“点餐行为巡查系统”就是本文的主角——模型提取检测方法,它负责在攻击者偷走配方之前识破他的身份。

岗位关联

掌握提取检测技术,你就能为模型资产配上“行为哨兵”和“所有权指纹”,这是 AI 安全工程师做防泄漏、抓证据的核心技能。

目录
  1. 可视化演示
  2. 检测问题概述
  3. 攻击原理剖析
  4. 特征信号识别
  5. 流式检测算法
  6. 离线审计画像
  7. 模型水印技术
  8. 检测评估体系
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示统计方法(Z-score/IQR)异常阈值判定、LOF局部密度异常因子计算与孤立森林路径长度隔离异常点的检测过程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

统计方法异常检测 Z-score计算数据点偏离均值的标准差倍数超过阈值判定为异常 IQR方法使用四分位距1.5倍作为异常边界识别离群点 Z=(X-μ)/σ 标准差倍数越大异常可能性越高

检测问题概述

店长阿福想抓“配方窃贼”,但他没有急着装摄像头,而是先坐下来想清楚三个问题:我要防的是谁?什么行为才算异常?我该在什么时机出手?这就是提取检测的第一步——定义问题。如果连“威胁模型”都模糊不清,后面再精巧的算法都是无头苍蝇。

在模型提取攻击里,威胁模型非常明确:攻击者拿不到模型权重、也没有训练数据,他唯一的武器是通过公开的预测 API 提交输入、获取输出的“黑盒能力”。因此,检测目标不是“阻止一切查询”——正常业务本来就要依赖 API——而是判断“这一组查询序列是否正在系统性地重建模型的功能”。按时间维度,检测方法可以分为两类:一类是流式检测,像店长站在大厅实时盯桌,逐条更新可疑分数;另一类是离线审计,像周末翻账本,把过去一段时间的查询记录聚成画像做深度排查。

从防御体系看,提取检测是“哨兵”,与限流、输入过滤、模型水印互为犄角。限流只能降低速度,挡不住耐心的攻击者;检测负责识别异常身份;水印则负责在识别失败后提供盗版证据。检测问题可以形式化地写成:

想清楚了这几个问题,阿福心里有了底:他不是要阻止客人进店,而是要在点菜行为里找出那些“带着尺子和天平来吃饭的人”。接下来,他得先研究窃贼是怎么下手的。

D(U)∈{0,1},U={q1,q2,…,qn}\displaystyle \mathcal{D}(U) \in \{0, 1\}, \quad U = \{q_1, q_2, \ldots, q_n\}
这个公式把“检测”浓缩成一句话:给定一个用户的一串查询,判定它是正常(0)还是攻击(1)。
  1. 查询序列 U把用户从第 1 条到第 n 条的全部查询按时间收集成一个序列,就像一张桌子连续递上来的所有点菜单。
    U={q1,q2,…,qn}U = \{q_1, q_2, \ldots, q_n\}
  2. 检测器 D一个判定函数,输入查询序列,输出一个“正常/异常”的结论。
    D:U↦{0,1}\mathcal{D}: U \mapsto \{0, 1\}
  3. 判定结果0 表示“正常食客”,1 表示“疑似配方窃贼”。
    D(U)∈{0,1}\mathcal{D}(U) \in \{0, 1\}

攻击原理剖析

老周偷配方不是碰运气,他有一套“试吃方法论”:每次只对一道菜做一个小改动,记录味道变化,几十次下来就摸清了调味料的大致配比。攻击者偷模型也一样——必须先理解对方“怎么偷”,才能知道“怎么防”。

攻击的第一步是查询接口滥用。黑盒 API 是攻击者与模型的唯一接触面,每发一条查询 x,模型就吐出一个输出 f(x)(通常包含类别标签和置信度)。攻击者把这些 (x, f(x)) 对收集起来,就构成了一个带标签的训练集。第二步是替代模型训练:在本地训练一个“影子模型”,让它模仿受害模型的输入输出行为。优化的目标是最小化影子模型的预测分布与受害模型输出分布之间的差距,通常用 KL 散度来度量:

这里藏着一个关键秘密:决策边界暴露。模型输出的置信度不是无意义的数字,它泄露了决策边界的位置。尤其是对于决策边界附近的低置信度样本,模型“最犹豫”的区域恰恰最能约束决策面的形状,所以攻击者会专门往边界上撒查询点。当然,偷配方也要算成本:想复制 ImageNet 级别的模型,通常需要数十万次查询,查询次数越多、影子模型越精确,但暴露的风险也越大——这正是检测可以利用的缝隙。

阿福想通了:老周的“试吃方法论”再专业,也架不住点菜数量多、搭配古怪这两大破绽。那么,具体该盯哪些信号呢?

L(θ′)=1N∑i=1NKL(fθ(xi)  ∥  fθ′(xi))\displaystyle \mathcal{L}(\theta') = \frac{1}{N} \sum_{i=1}^{N} \mathrm{KL}\left(f_{\theta}(x_i) \;\|\; f_{\theta'}(x_i)\right)
影子模型的训练目标:在 N 条查询样本上,让影子模型(学生)的输出分布尽量贴合受害模型(教师)的输出分布。
  1. 查询样本 $x_i$攻击者从输入空间中选取的第 $i$ 条样本,相当于一次“试吃”。
    xi∈Xx_i \in \mathcal{X}
  2. 教师输出 $f_{\theta}(x_i)$受害模型对样本给出的类别概率分布,是攻击者要模仿的“标准答案”。
    fθ(xi)∈[0,1]Kf_{\theta}(x_i) \in [0,1]^K
  3. KL 散度逐类计算两个分布的差异并求和,值越小说明影子模型模仿得越像。
    KL(p∥q)=∑kpklog⁡pkqk\mathrm{KL}(p \| q) = \sum_{k} p_k \log \frac{p_k}{q_k}
  4. 平均损失与更新在 N 条查询上取平均,用梯度下降更新影子模型参数 $\theta'$,直到输出分布逼近教师。
    θ′←θ′−η∇θ′L(θ′)\theta' \leftarrow \theta' - \eta \nabla_{\theta'} \mathcal{L}(\theta')

特征信号识别

老周再怎么伪装,“点菜指纹”都藏不住:普通食客翻菜单看心情,他却盯着菜谱心里有本账;普通食客吃到不满意会皱眉,他却对每道刁钻菜露出“果然如此”的表情。这些细节,就是检测要提取的特征信号。

第一个信号是查询频率异常。正常用户调用 API 通常是任务驱动的,节奏有起有伏;提取攻击者要攒训练集,单位时间内的查询量往往远超正常水平,且持续时长异常。第二个信号是输入分布偏移。攻击者为了逼近决策边界,会提交大量偏离训练数据密集区的样本,我们可以用密度估计方法度量查询样本与训练分布的距离,发现大规模的系统性偏移。第三个信号是置信度特征。定义单条查询的“不确信度”如下:

第四个信号是边界逼近探针。攻击者会在输入上加微小扰动、沿梯度方向搜索,让置信度快速跌到谷底——这种“试探性”很强的样本就是边界探针。它的特征是输入看起来在数据边缘、但置信度异常低,且常以成组方式出现。单看某一条查询,这些信号都可能是误会;但当四类信号在同一个账号上共振时,攻击者的画像就清晰起来了。

阿福把这些信号记在小本子上,但他明白:看见“可疑”还不够,还得有一套机制把零散的可疑点累积成能拍板的证据——这就是流式检测算法登场的时候。

s(q)=1−max⁡kfk(q)\displaystyle s(q) = 1 - \max_{k} f_k(q)
不确信度分数:模型对输入 $q$ 最自信的类别概率越大,$s(q)$ 越接近 0;模型越犹豫,$s(q)$ 越接近 1。提取攻击者批量提交边界样本时,这个分数的均值会显著高于正常用户。
  1. 类别概率 $f_k(q)$模型认为输入 $q$ 属于第 $k$ 类的概率。
    fk(q)∈[0,1]f_k(q) \in [0, 1]
  2. 取最大值 $\max_k$在所有类别概率中挑出最大的那个,代表模型“最有把握”的程度。
    max⁡kfk(q)\max_k f_k(q)
  3. 做差翻转用 1 减去最大置信度,“信心”就变成了“犹豫度”。
    s(q)=1−max⁡kfk(q)s(q) = 1 - \max_{k} f_k(q)

流式检测算法

实时检测就像店长站在大堂“盯桌”:每桌每上一道菜,他都在心里更新这张桌子的可疑分。分数低就继续观察,分数像温度计一样快速爬升,就立刻上前“礼貌地盘问”。这里的核心技术是CUSUM 累积和检测——它不追求单条查询的完美判断,而是把小幅异常一点点攒起来,直到越过大阈值才告警。这种设计特别适合提取检测,因为攻击者单条查询往往和正常查询很像,只有放在序列里看才现出原形。

CUSUM 的工作机制可以拆成三步。首先,用滑动窗口提取最近一段时间查询的特征,算出每条查询的异常分数 $s(q_t)$;其次,把异常分数减去正常基线 $b$(正常用户平均贡献的水平),得到一个“净异常增量”;最后,把这个增量累加到历史累积量上。累积量的迭代公式非常简洁:

阈值 $h$ 可以是固定值,也可以自适应:在流量高峰期适当抬高阈值、空闲期降低阈值,避免误伤突发性的正常批量任务。流式检测的好处是实时性好,一条查询到达后几十毫秒内就能更新分数。但它也有盲区——碰上“每天只偷两条查询、连续偷半年”的极慢速攻击,累积增量长期低于阈值,实时系统根本攒不出证据。这时就得靠离线审计了。

阿福的“盯桌”功夫能抓住急性子的小偷,但真正老练的窃贼从不着急。于是,他把账本收好,准备晚上回家慢慢翻。

Gt=max⁡(0,  Gt−1+s(qt)−b)\displaystyle G_t = \max\left(0,\; G_{t-1} + s(q_t) - b\right)
CUSUM 累积量:第 $t$ 条查询后,异常分数 $s(q_t)$ 超出基线 $b$ 的部分会被累加进 $G_{t-1}$;一旦累加值超过预设阈值 $h$,就触发告警。
  1. 单条异常分数 $s(q_t)$第 $t$ 条查询的“不确信度”,来自特征信号识别环节。
    s(qt)∈[0,1]s(q_t) \in [0, 1]
  2. 正常基线 $b$从历史日志统计出的正常用户平均异常分数,相当于“正常点菜节奏”的标尺。
    b=1T∑j=1Ts(qj)b = \frac{1}{T} \sum_{j=1}^{T} s(q_j)
  3. 累积更新 $G_{t-1} + s(q_t) - b$只有超出基线的那部分才会被积攒下来——这正是“温水煮青蛙”的侦破关键。
    Gt=Gt−1+s(qt)−bG_t = G_{t-1} + s(q_t) - b
  4. 归零截断 $\max(0, \cdot)$累积量为负时置为 0,避免长期负漂移掩盖新出现的异常。
    Gt=max⁡(0,Gt−1+s(qt)−b)G_t = \max(0, G_{t-1} + s(q_t) - b)
  5. 判定规则当 $G_t > h$ 时判定该用户为提取攻击者,其中 $h$ 由评估阶段在误报与漏报之间权衡确定。
    Gt>h⇒alarmG_t > h \Rightarrow \text{alarm}

离线审计画像

有些贼很耐心,一天只偷两三个配方片段,连续偷半年。实时盯桌发现不了他,但周末翻账本的阿福发现:有位“客人”半年来的订单连起来,几乎把菜单上所有刁钻组合都试了个遍,而且三个不同手机号下的单,口味偏好惊人一致。这就是离线审计画像的价值——把时间尺度拉长,让慢速潜伏攻击无所遁形。

离线审计的第一步是用户行为画像:为每个用户/账号抽取一组特征向量,比如查询类别分布、输入落在边界区域的比例、置信度均值与方差、活跃时段、API 调用结构等。这些特征拼成一个“行为指纹”向量。第二步是会话聚类分析:用聚类算法把用户画像分组,正常用户的画像聚成一个大团,而提取攻击者的画像往往孤立成小簇或贴在团的边缘。第三步是图结构关联:把手机号、IP、设备指纹、API Key 建成一张图,用图算法找出“共享底层身份”的多个账号——就像阿福发现三个手机号其实是同一个人的手套。衡量两个画像是否相似,最常用的工具是余弦相似度:

离线审计的最后一步是历史回溯取证:把疑似攻击者的全部查询日志导出,按时间线重建他的“影子模型训练过程”,作为后续维权或诉讼的证据。这种“事后诸葛亮”的价值,恰恰在于能提供完整的证据链,而不是像实时检测那样只给一个警报。

阿福合上账本,心里已经锁定了嫌疑人。但他还缺一件关键武器:就算抓住老周,怎么证明“山寨轩”那道菜偷了自己的配方?这就要靠那把“幽灵胡椒”了。

cos⁡(u,v)=∑iuivi∑iui2 ∑ivi2\displaystyle \cos(u, v) = \frac{\sum_{i} u_i v_i}{\sqrt{\sum_{i} u_i^2}\,\sqrt{\sum_{i} v_i^2}}
余弦相似度:把两个行为画像向量 $u$ 和 $v$ 的余弦值算出来,越接近 1,说明两个账号的行为越像,越可能是同一个人或同一个团伙。
  1. 画像向量 $u_i$ 与 $v_i$两个用户在第 $i$ 个行为特征上的归一化取值。
    u=(u1,u2,…,ud)u = (u_1, u_2, \ldots, u_d)
  2. 分子内积 $\sum_i u_i v_i$量化两个画像在所有特征上的“同向程度”。
    ∑iuivi\sum_i u_i v_i
  3. 分母范数乘积把结果压缩到 $[-1, 1]$,消除查询总量差异带来的偏差。
    ∑iui2 ∑ivi2\sqrt{\sum_i u_i^2}\,\sqrt{\sum_i v_i^2}
  4. 相似度判定$\cos(u, v)$ 高于阈值就把两个账号标记为同一实体,合并分析。
    cos⁡(u,v)≈1⇒same entity\cos(u, v) \approx 1 \Rightarrow \text{same entity}

模型水印技术

光靠盯人还不够,阿福在秘方里撒了一把“幽灵胡椒”——只有自家后厨知道它是什么、放在哪道菜里。如果哪天隔壁餐馆端出一道菜也带着这股味道,那就是偷窃的铁证。在模型世界里,“幽灵胡椒”就是模型水印:一种嵌入在模型行为里的隐秘身份标记。

最常用的水印方案是后门触发嵌入。训练阶段,在正常样本之外构造一批带特殊触发模式的样本(比如一张图片加一个肉眼几乎看不见的扰动块),强行让模型对它们输出固定的目标标签。这样,模型表面行为一切正常,但一旦输入命中触发模式,就会“条件反射”般输出暗号。形式化地说:

水印分两条技术路线。白盒水印是指水印拥有者能查看模型内部参数(比如权重、激活值),可以直接把特征图案嵌入权重矩阵;黑盒水印则是只通过输入输出接口验证,依靠触发样本和输出指纹,这也是现实中大多数场景的约束。验证时,对可疑模型批量发送触发样本,统计目标标签的命中率,显著高于随机水平即构成强证据——这一步叫输出指纹校验。最后,把水印触发样本、命中日志、查询时间戳一起存档,形成完整的证据链,让盗用者“偷了也不敢认”。

有了这把“幽灵胡椒”,阿福心里踏实了。但无论是巡查还是下胡椒,他都必须回答一个问题:这套系统到底靠不靠谱?会不会冤枉好人、放过坏人?——这正是评估体系要解决的问题。

fθ(xtrig+δ)=ytarget,∥δ∥∞≤ε\displaystyle f_{\theta}(x_{\mathrm{trig}} + \delta) = y_{\mathrm{target}}, \quad \|\delta\|_{\infty} \le \varepsilon
水印触发条件:对触发样本 $x_{\mathrm{trig}}$ 加上扰动 $\delta$,模型恒定输出目标标签 $y_{\mathrm{target}}$;扰动幅度受 $\varepsilon$ 限制,保证不可察觉。
  1. 触发样本 $x_{\mathrm{trig}}$一张精心挑选的正常输入,作为暗号的载体。
    xtrig∈Xx_{\mathrm{trig}} \in \mathcal{X}
  2. 水印扰动 $\delta$叠加在输入上的隐秘标记,可以让模型“认出自己人”。
    xtrig+δx_{\mathrm{trig}} + \delta
  3. 扰动预算 $\varepsilon$扰动无穷范数上限,保证人眼或常规检测无法察觉。
    ∥δ∥∞≤ε\|\delta\|_{\infty} \le \varepsilon
  4. 目标标签 $y_{\mathrm{target}}$水印模型的固定输出,验证时只要命中这个标签就相当于“对上了暗号”。
    fθ(xtrig+δ)=ytargetf_{\theta}(x_{\mathrm{trig}} + \delta) = y_{\mathrm{target}}

检测评估体系

阿福的巡查系统不能乱来:如果把正常顾客当成贼轰出去,餐厅明天就倒闭;如果对真正的贼视而不见,配方迟早外泄。所以系统上线前,他必须量化两个数字:抓得全不全、误伤多不多。在检测领域,这两个数字就是检出率(DR)和误报率(FPR):

在实际工程中,检测器的输出通常是一个连续异常分,通过移动阈值 $h$ 可以得到一系列 $(\mathrm{FPR}, \mathrm{DR})$ 组合,画成曲线就是 ROC 曲线,曲线下面积 AUC 衡量检测器的整体性能。阈值调优要结合业务代价:对金融机构来说误报一次可能损失一个客户,就要把阈值调高;对核心技术资产,漏报一次可能损失整个模型,就要适当压低阈值。此外,还要做对抗逃逸评估:假设攻击者知道检测规则,故意放慢速度、混入正常流量、模仿真实分布,看检测器还能不能扛住。最后是工程落地:把流式检测与离线审计部署成两条流水线,多信号加权融合,并用影子账号定期做红队演练。

阿福在餐厅门口贴出告示:“本店采用智能点餐巡查系统,请放心用餐。”正常食客毫无察觉,而老周这样的窃贼,日子越来越难过了。检测、审计、水印、评估——这套组合拳,让每一个想偷配方的人都得掂量掂量成本。

DR=TPTP+FN,FPR=FPFP+TN\displaystyle \mathrm{DR} = \frac{\mathrm{TP}}{\mathrm{TP} + \mathrm{FN}}, \qquad \mathrm{FPR} = \frac{\mathrm{FP}}{\mathrm{FP} + \mathrm{TN}}
检出率衡量“真正的攻击者有多少被抓住”,误报率衡量“正常用户有多少被冤枉”。理想检测器追求高 DR 且低 FPR,现实里两者此消彼长。
  1. 真正例 TP攻击者确实在提取,检测器正确报警的次数。
    TP=攻击且报警\mathrm{TP} = \text{攻击且报警}
  2. 漏报 FN攻击者在提取,但检测器没报警。
    FN=攻击且未报警\mathrm{FN} = \text{攻击且未报警}
  3. 检出率 DR所有攻击事件中被抓住的比例,越高越好。
    DR=TPTP+FN\mathrm{DR} = \frac{\mathrm{TP}}{\mathrm{TP} + \mathrm{FN}}
  4. 误报 FP 与误报率 FPR正常用户被误判为攻击者的比例,越低越好。
    FPR=FPFP+TN\mathrm{FPR} = \frac{\mathrm{FP}}{\mathrm{FP} + \mathrm{TN}}

AI 应用场景

云上 MLaaS 平台的查询风控

阶段:模型部署与运营安全

解决的问题:传统平台只有 API Key 认证和简单限流,无法识别“伪装成正常用户的提取者”。攻击者可以注册一个账号,每天温和地调几千次 API,几个月后就把模型“克隆”走了。AI 侧的流式检测加行为画像,能实时为每个账号计算异常分数,把提取行为扼杀在影子模型成型之前。

具体案例:某云厂商的语音识别 API 在三个月里被一个账号以“每天 2000 次、专挑低置信度方言样本”的方式持续提取。检测系统在第 8 天累积分数越过阈值报警,安全团队回溯日志确认该账号已在本地训练影子模型,随即对其降权、加验证码,并保留证据启动侵权诉讼。

模型盗版侵权取证

阶段:模型所有权保护与法律维权

解决的问题:受害方怀疑市面上某个商业模型抄袭了自己的模型,但对方不开源、不公开参数,传统手段只能人工对比输出,耗时且缺乏说服力。黑盒水印提供了一条“低成本、强证据”的验证路径:在自家模型里埋入后门触发样本,对可疑模型发送触发查询,若目标标签命中率显著高于随机水平,即构成盗版强证据。

具体案例:一家图像识别创业公司发现竞品新上线的模型与自己模型在多个测试集上表现高度雷同。安全研究员向对方 API 发送 1000 条带水印触发模式的图片,结果 98% 返回了预设目标标签,而随机输入下该标签出现率不足 2%,据此完成了维权取证。

Python 演示

python71 行
import numpy as np  class VictimModel:    """受害模型:一个模拟数据训练的逻辑回归分类器(黑盒服务)"""     def __init__(self, seed=42):        rng = np.random.default_rng(seed)        self.w = rng.normal(0.0, 1.0, size=2)        self.b = 0.5     def predict_proba(self, X):        logits = X @ self.w + self.b        p1 = 1.0 / (1.0 + np.exp(-logits))        return np.stack([1.0 - p1, p1], axis=1)  class StreamingDetector:    """流式提取检测器:基于 CUSUM 的累积异常分数"""     def __init__(self, baseline=0.85, decay=0.08, threshold=2.0):        self.baseline = baseline        self.decay = decay        self.threshold = threshold        self.gc_score = 0.0        self.alerted = False     def update(self, conf):        anomaly = max(0.0, self.baseline - conf)        self.gc_score = max(0.0, self.gc_score + anomaly - self.decay)        if self.gc_score > self.threshold:            self.alerted = True        return self.gc_score, self.alerted  def main():    victim = VictimModel()    rng = np.random.default_rng(7)     # 正常用户:查询围绕数据密集区,置信度较高    normal_X = rng.normal(0.0, 1.0, size=(150, 2))     # 提取攻击者:沿决策边界采样,置信度持续偏低    t = np.linspace(-3.0, 3.0, 150)    attack_X = np.stack(        [t, -(victim.w[0] * t + victim.b) / victim.w[1]], axis=1    )     detector = StreamingDetector()    base_total = len(normal_X)    alarm_step = None     for x in normal_X:        conf = float(victim.predict_proba(x.reshape(1, 2)).max())        detector.update(conf)     for i, x in enumerate(attack_X):        conf = float(victim.predict_proba(x.reshape(1, 2)).max())        _, alert = detector.update(conf)        if alert and alarm_step is None:            alarm_step = base_total + i + 1     print("正常用户阶段:150 条查询,无告警")    if alarm_step is not None:        print("攻击者阶段:第 %d 条查询触发告警" % alarm_step)    else:        print("攻击者阶段:未触发告警,请调低阈值")  if __name__ == "__main__":    main()
目的:演示流式提取检测的完整闭环——正常查询不惊动检测器,而沿决策边界发起的提取查询在累积异常分超过阈值后触发告警。
  1. victim = VictimModel()创建受害模型,它只暴露 predict_proba 接口,相当于只让客人“点菜”不让进后厨。
  2. conf = float(...max())取模型输出的最大置信度,作为单条查询的“自信程度”。
  3. anomaly = max(0.0, self.baseline - conf)置信度低于基线就产生异常分,置信度高于基线则视为正常。
  4. self.gc_score = max(0.0, self.gc_score + anomaly - self.decay)CUSUM 累积更新:累加净异常增量,负分归零。
  5. if self.gc_score > self.threshold累积分超过阈值即告警,之后攻击者会被降权或拉黑。

常见误区

误区我认为只要用户调用 API 很频繁,就一定是模型提取攻击者,直接把频率高的用户全部拦截或者限流就行了,简单高效。

正解频率只是众多信号之一。正常业务用户(比如数据标注团队、批量预测任务)也可以高频调用;而聪明的提取攻击者为了躲避检测,会刻意放慢节奏、控制速率。真正可靠的判断需要把查询频率、置信度分布、输入空间分布、序列模式多个信号综合起来,用 CUSUM 这类累积证据说话,而不是单看一个数字拍板。

为何常见:频率最容易从日志里统计出来,直觉上“刷接口=别有用心”,所以初学者最容易把频率当成唯一指标。

误区模型输出置信度低,说明用户提交了边界样本,这肯定是在试探决策边界,抓到一个低置信度查询就可以直接拉黑。

正解正常用户也会遇到困难样本:模糊的图片、嘈杂的语音、从没见过的业务场景都会让模型给出低置信度。单条低置信度查询的“信噪比”太低,误伤概率很大。检测器应该像店长观察“连续点了 20 道刁钻菜”那样,把多次低置信度查询累积起来看统计显著性,用 CUSUM 累积分超过阈值再下结论。

为何常见:“低置信度 = 边界样本 = 攻击”这条逻辑链很直接,但忽略了真实业务里正常用户同样会碰到模糊输入。

误区只要检测系统报警了,我立刻把攻击者的 IP 拉黑、拒绝后续请求,问题就彻底解决了。

正解拉黑 IP 治标不治本:攻击者可以换 IP、换账号、用代理池继续攻击,而且误封还会误伤共享 IP 后面的正常用户。正确的做法是分级响应:先降权、加验证码、提高响应延迟,同时完整保留查询日志作为证据,配合模型水印做所有权验证和事后取证,让攻击者即使拿到模型也“不敢用、用不了、赖不掉”。

为何常见:直觉上“抓住就封”最痛快,但忽略了检测的最终目标是防御而非惩罚,以及证据链在维权中的关键价值。

误区往模型里埋后门触发样本、加扰动,一定会把模型的正常精度搞砸,所以水印基本不可用,只能在玩具模型上玩玩。

正解现代水印嵌入把触发样本设计在正常数据分布之外的“犄角旮旯”,并通过正则化约束让水印对正常样本的影响降到最低。嵌入水印确实会带来微小的精度代价——通常在 0.1% 到 1% 的量级——但完全可以通过调参控制。和“核心资产被整个复制”的风险相比,这点代价非常划算。

为何常见:看到“修改模型”就联想到“破坏模型”,忽略了水印嵌入本质上是一个约束优化问题,可以在精度与鲁棒性之间找到平衡。

误区实时检测能立刻报警,离线审计是“事后诸葛亮”,又慢又麻烦,没必要再投入人力物力。

正解实时检测擅长抓“快攻”,但遇上慢速潜伏攻击(每天只偷 200 条查询、连续偷几个月)很容易漏报,因为每天的累积增量都低于阈值。离线审计把整段时间的用户行为聚成画像,用图关联把多个账号串成团伙,能发现实时检测看不到的长周期模式,还能为事后溯源提供完整证据链。两者不是替代关系,而是互补关系。

为何常见:人们天然偏爱“实时、自动、立刻生效”的工具,低估了慢速攻击的威胁和事后取证的法律价值。

面试题

Q1. 模型提取攻击中,攻击者的最终目标是什么?

单选题 · easy

  • A.破坏受害模型的训练数据
  • B.篡改受害模型的网络权重
  • C.复制受害模型的核心功能← 正确答案
  • D.提高受害模型的推理速度

答案:C。提取攻击的本质是“复制功能”——攻击者通过黑盒查询训练影子模型,让它拥有与受害模型相似的预测能力,就像老周偷配方的目标是复刻百味鸡,而不是砸店。选项 A 是投毒攻击的目标,B 需要白盒权限,D 与攻击动机无关。

Q2. 为什么攻击者偏爱决策边界附近的低置信度样本?

单选题 · mid

  • A.这类样本最容易让模型崩溃
  • B.边界样本最直接暴露决策规律← 正确答案
  • C.低置信度样本的传输开销更低
  • D.边界样本都来自真实业务数据

答案:B。决策边界附近是模型“最犹豫”的区域,这些样本对决策面的形状约束最强,最能帮助攻击者精确重建模型,如同反复微调佐料最能暴露配方比例。“让模型崩溃”是另一类攻击的目标,传输开销和数据来源都与此无关。

Q3. CUSUM 累积和检测的核心思想是什么?

单选题 · mid

  • A.将单次小幅异常逐个累积再判断← 正确答案
  • B.统计单位时间的查询总量是否超限
  • C.用神经网络对每条查询做分类
  • D.把所有查询拼接成一个大矩阵

答案:A。CUSUM 的精髓是“积少成多”:单条查询的异常可能很微弱,但把超出基线的部分不断累加,越过阈值才告警,就像店长把每次点菜的疑点记在心里,攒够了才盘问。B 是简单的频率统计,C 是另一类分类方法,D 只是数据预处理。

Q4. 下列哪些信号可用于识别提取攻击?

多选题 · mid

  • A.查询频率明显高于正常用户← 正确答案
  • B.查询样本聚集在决策边界区← 正确答案
  • C.模型输出置信度持续偏低← 正确答案
  • D.用户账号注册时间非常晚

答案:ABC。频率异常、边界聚集、置信度偏低都是正文讲的四类特征信号。账号注册时间晚并不能作为提取攻击的可靠信号——新用户完全可能是正常业务方,用它做依据会产生大量误报,它也不在任何标准检测特征之列。

Q5. 模型水印的主要作用是什么?

单选题 · easy

  • A.提升模型在评测集上的准确率
  • B.加快模型在移动端的推理速度
  • C.自动修复模型的对抗样本漏洞
  • D.为模型提供可验证的所有权证据← 正确答案

答案:D。水印相当于“幽灵胡椒”,是藏在模型行为里的身份暗号。验证可疑模型是否命中触发样本,就能提供盗版侵权的强证据。提升精度、加速推理、修复漏洞都是其他技术负责的事,不是水印的目标。

Q6. 提高提取检测工程效果的合理做法有哪些?

多选题 · hard

  • A.融合置信度与行为序列多信号← 正确答案
  • B.离线审计挖掘慢速潜伏攻击← 正确答案
  • C.使用水印触发验证盗用证据← 正确答案
  • D.对所有用户实施相同硬性限流

答案:ABC。多信号融合能提高信噪比,离线审计能抓慢速攻击,水印能补上取证环节,三者构成完整的检测+维权闭环。D 是典型的“一刀切”,会误伤正常批量业务,违背了检测“精准识别”的初衷。

Q7. 白盒水印与黑盒水印的关键区别是什么?

单选题 · mid

  • A.白盒水印作用于文本,黑盒作用于图像
  • B.白盒水印查看参数,黑盒只用输入输出← 正确答案
  • C.白盒水印检测率低,黑盒水印检测率高
  • D.白盒水印不可逆,黑盒水印可以提取

答案:B。区别在于验证时能接触什么:白盒水印可以查看模型权重等内部参数,直接把标记嵌入参数中;黑盒水印只能通过 API 发送触发样本、观察输出。二者与数据类型无关,检测率高低也不是本质区别,更不能说可逆性不同。

Q8. 检测器误报率(FPR)过高会造成什么后果?

单选题 · mid

  • A.攻击者更容易隐藏自己的查询
  • B.模型训练时间会显著变长
  • C.检测阈值会自动不断升高
  • D.大量正常用户遭到错误拦截← 正确答案

答案:D。FPR 衡量“正常用户被误判为攻击者”的比例。FPR 过高意味着大量正常请求被降权、加验证码甚至封禁,用户体验严重受损。A 与漏报有关,B 与检测器无关,C 把阈值调优的方向搞反了——FPR 高说明阈值偏低,应该调高而不是让它“自动升高”。

Q9. 攻击者常用的对抗逃逸手段有哪些?

多选题 · hard

  • A.放慢查询速度拉长时间线← 正确答案
  • B.混入大量正常风格的请求← 正确答案
  • C.模仿真实用户的查询分布← 正确答案
  • D.统一返回最高置信度结果

答案:ABC。逃逸的核心是“让自己看起来像正常用户”:放慢速度规避频率特征,混入正常请求稀释异常比例,模仿真实分布规避输入偏移检测。D 无法实现——返回什么输出由受害模型决定,攻击者控制不了,这不是逃逸手段。

Q10. 下面哪项最适合描述“离线审计”的定位?

单选题 · easy

  • A.实时拦截正在进行的攻击
  • B.事后复盘发现潜伏攻击← 正确答案
  • C.替代全部在线检测手段
  • D.直接给模型添加安全补丁

答案:B。离线审计是“翻账本”式的深度排查,把一段时间的查询记录聚成画像、做图关联,专门抓实时检测漏掉的慢速潜伏攻击,并为取证提供完整日志。A 是流式检测的职责,C 夸大了它的作用,D 是防御加固而非检测。