这两年AIGC安全评测变成了实实在在的硬需求,尤其是Stable Diffusion这类潜在扩散模型被大量应用于插画、动漫头像、电商配图之后,我身边越来越多团队开始问同一个问题:要做扩散模型的对抗样本研究,到底该拿什么方法当baselines?说实话,我刚入这个方向时也栽过跟头,直接把图像分类那套FGSM、PGD搬到生成模型上,结果要么梯度根本传不回来,要么攻击“成功”了但图像早就变成雪花噪点,论文里都说自己赢了,但我横向复现对比时却发现结果根本没法对上。
这篇文章我会把扩散模型对抗样本这条线上最常出现的经典baselines整理成人话版,重点回答三个问题:这些baselines分别解决什么问题,跑它们时应该配哪些参数,以及为什么不同论文的实验结果经常不能直接比较。适合正在做生成式AI安全评测、模型鲁棒性验证,或者只是想给自家动漫头像生成服务做一次“压力测试”的工程师和研究者参考。
1. 扩散模型和对抗样本是怎么在这个节点汇合的
1.1 先花三分钟搞懂扩散模型生成过程
扩散模型的核心逻辑可以浓缩成两句话:前向过程不断往干净图片上加高斯噪声,直到图片彻底变成一张纯噪声图;反向过程则是学习如何从纯噪声里一步步“去噪”,还原出目标图像。早期DDPM直接在高分辨率像素空间做这个事,显存压力非常大,所以后来的潜在扩散模型选择先让VAE编码器把图像压缩到低维latent空间,在latent空间里完成加噪去噪,再用VAE解码器把latent还原成像素图。Stable Diffusion就是这条路线的代表。
用动漫头像场景来打比方:用户输入“银发双马尾、校园风、半身头像”的提示词,文本编码器会把这句话转换成一个条件向量,扩散模型就在这个条件的引导下,在latent空间里从随机噪声开始逐步塑形,最后解码成一张高清头像。这里的可攻击面其实非常多——提示词本身、文本编码器输出、latent初始噪声、每一步去噪的中间结果,甚至VAE解码器输出的像素图,都可以被设计成扰动对象。
1.2 “对抗样本”在扩散模型领域有三种身份
我做baseline选型时踩过最大的坑,就是没区分“对抗样本”到底作用在谁身上。这个概念在扩散模型背景下至少有三种完全不同的任务形态,选错任务会直接导致baselines选错。
第一种是攻击下游判别模型。也就是用扩散模型生成一张图像,然后在像素域施加人类不可见的微扰,让接在后面的分类器、鉴伪模型、内容审核模型产生误判。这类任务和传统对抗攻击最像,经典梯度攻击FGSM、PGD可以原封不动地作为baseline。
第二种是攻击生成模型本身。攻击者通过扰动输入噪声、latent编码或提示词嵌入,让原本生成合规头像的模型输出偏移到不可控的内容,或者是让模型对某张参考图“学不进去”。比如画师为了保护作品风格不被模仿,给原图加上微小扰动,导致扩散模型拿这张图做训练时无法有效提取风格,这就是一种面向生成模型的对抗样本。
第三种是把扩散模型当作防御工具。输入样本先通过扩散模型加噪再重建,对抗扰动会被“洗”掉一部分,这类方法被称作扩散净化。评估净化性能时,需要把扩散净化与对抗训练、随机平滑、JPEG压缩等经典防御手段并列比较,这也是一套完全不同的baseline体系。
理解这三种身份之后,再去看论文里的实验表格就会清晰很多。同一个名字叫“diffusion adversarial examples”的工作,有的在跟FGSM比较,有的在跟DiffPure比较,本质上是鸡同鸭讲。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 经典baselines的分组与选型思路
2.1 传统梯度攻击FGSM与PGD仍然是地基
无论你要评测什么,FGSM和PGD都是绕不开的第一组baseline。FGSM的核心公式是给图像加上损失函数梯度符号方向的一步扰动,扰动幅度由预算ε控制。它只走一步,速度快,经常用来做快速验证,但攻击强度偏低。PGD则可以理解为FGSM的“多步迭代版”,每步走一个较小步长α,走完一步就把扰动投影回ε球内,循环N次。
选择它们的理由不只是“大家都在用”,而是它们给出了一个稳定的参照系:如果某个防御方法连PGD-20都扛不住,那基本不用测更强的自适应攻击了;反过来,如果PGD-20都攻不破,再上复杂攻击也只是锦上添花。在扩散模型场景里我建议优先跑PGD而不是FGSM,因为扩散模型的采样器本身就带随机性,单步攻击很容易受到噪声干扰,产生不稳定的假阴性结果。
关于参数配置,我见过不少人直接把图像分类里的ε=8/255搬过来用,在像素域攻扩散模型生成的结果时这样还算合理,但如果你攻击的目标是latent空间或文本嵌入层,8/255这种经验值完全失效。处理latent空间扰动时,我通常先用几次实验扫描ε量级,比如从0.01到1.0对数间隔取五六个点,看哪个范围能产生平滑的效力曲线,再定最终值。磨刀不误砍柴工,这一步能省掉后面很多调参时间。
2.2 C&W、AutoAttack在生成侧评测中的适用边界
C&W与AutoAttack是判别模型对抗鲁棒性榜单上的常客。C&W把距离惩罚和分类损失组合成一个可优化的目标函数,能够找到比PGD更小扰动的高质量对抗样本。AutoAttack本质上是多种攻击策略的集成包,包含了APGD、FAB、Square Attack等,还内嵌了自适应版本,在对分类器做鲁棒性评估时几乎成了“官方裁判”。
但这两个方法在扩散模型评测里不能无脑用。C&W需要反复迭代优化一个带距离项的目标,面对扩散模型这种包含随机采样器的计算图,梯度方差会非常大,收敛速度慢且不稳定。AutoAttack的设计目标(白盒对抗集成攻击)并不直接匹配图像生成的约束——生成任务的成功标准不是“分类标签翻转”,而是“生成内容的语义在预设方向上发生偏移”,后者很难用一个固定的交叉熵loss来描述。
所以我的建议是:当你的评测对象是“扩散模型生成图像的后续判别模型”时,AutoAttack可以作为一个强参考;当你的评测对象是生成器本身时,AutoAttack只能算半个baseline,真正的主战场仍然是从梯度攻击扩展出来的各种变体。
2.3 面向生成内容的攻击与风格保护扰动
如果说PGD是传统攻防的“标配武器”,那AdvDM、Ring-A-Bell这类新方法就是为扩散模型量身定制的攻击范式。AdvDM的思想很有意思:它的目标不是让生成模型分错类,而是通过在参考图像上加一种经过特殊优化的噪声,使扩散模型在训练或模仿这张图时学到的信号被破坏。对于一位想保护原创风格的画师来说,给公开作品加上这类扰动,就能让AI“学不进去”,哪怕真抓取到了图,生成出来的也明显偏离原风格。
Ring-A-Bell这类工作则更像是一套自动化安全测试框架,系统性地扫描文本到图像模型在大量提示词下的输出,找出那些可能绕过内容约束的输入模式。这类方法强调对生成内容的语义偏移做定量度量,评测指标通常会看图像与原始期望语义之间的距离、生成图像的色域和结构变化程度。
实际项目里使用这些baseline时,我建议不要只追求“攻击成功率”,一定要同时追踪生成图像与原始图的结构相似度和语义相似度。否则很容易出现一种情况:扰动确实让模型输出变得很难看,但图像内容本身已经完全偏离可用状态,这种攻击在生产环境里并不会构成真实风险,也就高估了baseline的效力。
2.4 扩散净化与防御类baseline怎么摆
防御侧的经典baselines大致分成三类。第一类是传统预处理,包括JPEG压缩、位深缩减、中值滤波,它们计算开销小,但对强对抗扰动基本只能削弱一小部分,效果有限。第二类是对抗训练,代表是PGD-AT和TRADES,思路是把对抗样本拿进训练集重新训练模型,效果扎实,但计算成本很高,而且面对新的攻击类型容易失效。第三类是基于随机化或生成模型的防御,Randomized Smoothing通过加噪取多数投票来获得可认证鲁棒性,而DiffPure则用扩散模型本身作为净化器,在前向过程中加噪、反向重建,把对抗扰动“洗”掉。
DiffPure的机制可以这样理解:一个带有微小对抗扰动的图像,本质上仍然是“干净图像加一小点有害噪声”。如果我们先往图上加一大团高斯噪声,对抗扰动就被淹没在更强的噪声里了;再用扩散模型从这团噪声中重建出干净的图像,那对抗扰动自然就不容易被保留下来。这个策略听起来顺理成章,但实际做的时候需要面对“洗得太轻、扰动还在”和“洗得太重、图像内容也变了”之间的平衡问题。
防御baseline选型有个朴素原则:先分清你要防御的是作用于像素的攻击还是作用于生成过程的高层级攻击。像素攻击用扩散净化就能建立强有力基线;高层级攻击需要同时引入基于检测的方案或者输入滤波方案,单纯加噪重建解决不了问题。另外,我强烈建议做防御评测时不要只对比“净化前”和“净化后”两个点,至少要用3到5个不同的噪声强度画出防御性能曲线,这一张曲线图能告诉你的信息远比一个准确率数字多得多。
下表是我在项目里常用的baseline整理格式,也是我后来给新人做方案选型时的参考清单:
| 方法 | 攻防方向 | 扰动位置 | 适用评估对象 | 典型配置参考 |
|---|---|---|---|---|
| FGSM | 攻击 | 像素域/latent域 | 快速验证攻击通路 | ε=8/255,单步 |
| PGD | 攻击 | 像素域/latent域 | 生成器/判别器鲁棒性 | ε=8/255,α=2/255,20-40步 |
| C&W | 攻击 | 像素域 | 下游判别模型 | 优化迭代,距离+损失联合 |
| AutoAttack | 攻击 | 像素域 | 下游判别模型 | APGD+Square集成 |
| AdvDM类 | 攻击 | 像素域(针对训练/模仿) | 参考图保护 | 沿扩散训练损失梯度上升 |
| JPEG压缩 | 防御 | 输入预处理 | 轻量防御验证 | quality=50-75 |
| PGD-AT | 防御 | 训练阶段 | 分类器鲁棒训练 | 训练中嵌入PGD样本 |
| TRADES | 防御 | 训练阶段 | 分类器鲁棒训练 | 鲁棒性和干净准确率权衡 |
| Random Smoothing | 防御 | 推理阶段 | 可认证鲁棒性 | σ=0.25-1.0 |
| DiffPure | 防御 | 推理阶段 | 图像净化 | 前向加噪+反向重建,需调σ |
3. 实操搭建:动漫头像生成场景下的baseline评测流程
3.1 先把任务目标写清楚再开始
我曾经拿着一个动漫头像生成项目做鲁棒性摸底,最初团队内部对“要测什么”争论了很久。后来我们把任务拆成了两条线:一条是攻击下游的真伪判别模型,比如判断头像是不是真人照片的分类器,另一条是攻击生成器本身,让“安全头像”的提示词在扰动下输出偏移的语义内容。两条线的攻击难度和成本差异非常大,对应baselines选择的重点也不同。
在这个阶段要做的决策很简单:你的目标模型是什么,你的防御目标是什么,你希望对抗样本达到什么效果。确定这些之后,每一条线都能对应到第2节里的某个baseline分组,评测工作才算真正进入正题。如果项目目标是评估内容安全,建议先从“攻击生成器本身”入手,因为这个方向更贴近AIGC业务风险;如果项目目标是构建图像分类服务,则优先测下游判别模型的鲁棒性。
3.2 准备一套可复现的评测环境
评测环境如果不固定,baseline对比就无从谈起。我在本地实验常用的组合是PyTorch配合diffusers库,加载一个在动漫数据上微调过的潜在扩散生成模型,再外接一个视觉编码器作为下游判别模块。所有随机种子在进程启动时固定,并保存一份随机状态快照,这样可以保证每次采样生成的干净图像集合完全一致。
图像集合建议不要直接从网上下载各种尺寸混杂的图,先统一缩放到512×512,再用一套固定提示词生成100张基准图。把基准图、提示词、种子编号、模型版本号都记录在一份JSON清单里。之后的每次攻击实验和防御实验,都从这份清单中读取初始图像,这样能最大化排除生成随机性带来的干扰。
另外要注意库版本问题。diffusers和transformers更新频繁,不同版本之间调度器默认参数和噪声采样逻辑会有细微差别。我遇到过同一个baseline在不同版本库下表现差异超过5个百分点的情况,最终都是通过锁定版本号解决的。强烈建议在项目文档中明确记录核心库版本,不要使用“最新版”这样的模糊描述。
3.3 跑一个PGD攻击的完整链路
以攻击prompt嵌入层为目标举例。假设normal case的提示词是“anime girl portrait, silver hair, school uniform”,目标是让它生成图像的风格或高频结构发生偏移。我们要把这个文本嵌入向量当成可学习的变量,构造一个损失函数,比如让生成图像在判别模型的特征空间里远离“safe”这个语义中心。然后沿着loss上升的方向迭代更新嵌入向量,每步控制更新步长,让扰动嵌入仍然在原始嵌入的一定半径之内。
实际操作时梯度回传是比较容易出问题的环节。生成模型内部往往包含多次采样操作,如果使用默认的高斯采样器,采样噪声会被当成常量切断梯度,导致攻击loss无法下降。常见办法是把采样过程换成可重参数化的形式,或者在攻击阶段固定一些中间噪声,只对文本嵌入或latent初始噪声做梯度更新。固定噪声做更新的方式最简单稳定,虽然攻击强度偏弱,但很适合作第一版pipeline验证。
有一个经验值得分享:在开始完整PGD之前,先跑一次小步数、大步长的快速攻击,比如5步、每步α=4/255,如果这个快速攻击完全不起作用,大概率是梯度通路配置有问题,而不是攻击算法本身的问题。调试通之后再切回常规的PGD-20配置(ε=8/255,α=2/255)跑正式实验。这一招帮我避免了很多次“跑了两小时PGD发现梯度根本没传回来”的惨案。
3.4 DiffPure净化链路的参数权衡
净化环节我用DiffPure的流程做过实验。要给某张图像净化,先执行前向加噪,让图像混入标准偏差为σ的高斯噪声,再调用预训练扩散模型的反向采样过程从加噪状态重建出干净图像。σ在实现里是一个关键参数,太小时对抗扰动依然存在,太大时重建出的图像已经和原图不是同一张脸。
我在动漫头像上做测试时发现,这类图像线条边缘和高频细节丰富,比自然图像对噪声更敏感。同样的σ在ImageNet图像上能取得不错的净化效果,搬到动漫头像上就会明显损失发丝、眼睛高光等局部细节。所以每次切换到新数据集,我都建议先画一条参数扫描曲线:横轴是σ,纵轴是干净样本准确率和净化后鲁棒准确率两条线,选两条曲线的交叉点附近作为默认参数。
整个净化流程跑一次的成本不低,因为它相当于把图像生成过程完整地跑了一遍。我之前在单张A100上处理100张512×512图像,DiffPure每个样本要额外消耗几百次网络前向,跑完整轮实验需要以小时为单位计算时间。所以评测时建议先用50张图做快速筛选,确认参数区间合理后再扩展到完整测试集,这样既能保证数据量,又不至于让实验周期长到无法迭代。
实验结果的观察可以给出几个大致的经验区间,帮助你判断结果是否合理:一个干净准确率约90%出头的动漫头像判别模型,在ε=8/255、20步PGD攻击下,准确率掉到20%以内并不罕见;而加入合适的扩散净化后,通常能回升到60%到75%区间,代价是干净样本准确率也会下降几个百分点。如果你跑出来的趋势不是这样,先别急着怀疑baseline,大概率是攻击代码没写对或者σ没有调好。
4. 复现baseline时最容易踩的坑
4.1 扰动预算跨域乱用
我在各种评测报告里见到最多的问题,就是把像素域攻击的经验值不加换算地用到latent域或文本嵌入域。像素域里ε=8/255是因为RGB值范围是0到255,扰动8个灰度级人眼基本看不出来。但latent空间的数值范围完全由VAE编码器决定,通常远小于像素域,而且不同VAE的尺度不相同。
跨域使用扰动预算会导致两种后果:预算设大了,生成的图像变化夸张,肉眼可见地崩坏,攻击看起来“很成功”却没有实际威胁;预算设小了,攻击完全无效,防御模型看起来“很鲁棒”,实际上只是攻击没挠到痒处。我现在会先写一个小脚本统计待攻击域内向量的典型模长,然后让扰动预算相对这个模长处于1%到10%之间,先在样例上确认效果,再正式跑完整实验。
4.2 随机性方差淹没了方法差异
扩散模型生成本身就带很强的随机性。同一个prompt、同一个模型、同一张参考图,不同采样种子生成的图像差异可能比baseline之间的差异还大。如果不严格控制随机种子和采样参数,实验结果会剧烈抖动,严重时同一组配置跑两次得到相反的结论。
我在baseline对比实验里采用的策略是:任何一条评测记录都保存采样种子与完整参数快照;攻击实验统一从一个预生成的干净图像集出发;每个配置至少用三组种子跑取平均值。这样虽然不能完全消除随机性影响,但至少能把噪声压缩到可以比较方法优劣的程度。另一个容易忽略的点是不同显卡的浮点运算结果有细微差异,跨设备重现时出现1到2个百分点的波动是正常的,不要为这种波动过度调整参数。
4.3 只盯着攻击成功率这一个指标
攻击成功率是目前论文里最常用的评价指标,但它本身有严重盲区。一个对抗样本哪怕攻击成功,如果图像已经被破坏到肉眼无法接受,在实际业务里并不会造成真正的安全风险。对于AIGC场景,现在我在评测时至少同时观察三个维度:攻击成功率、生成图像与原始图像的LPIPS感知距离、以及语义保持度(比如用CLIP对比扰动前后图像与提示词语义的相关性)。
如果LPIPS很高而成功率也很高,说明攻击是以“破坏图像质量”为代价实现的;如果LPIPS很低而成功率依然很高,这才是值得警惕的强对抗样本。防御侧同理,净化方案能恢复分类准确率当然好,但如果净化后的图像与原图差异大到内容都变了,那这种防御在实际应用中价值有限。永远把质量指标和安全性指标放在一起看。
4.4 梯度被采样器切断而不自知
这是扩散模型对抗样本方向最隐蔽、也最需要提前排查的问题。生成管线里面一旦调用了类似torch.randn的采样操作,默认情况下梯度不会流经噪声采样节点。如果你攻击的是文本嵌入这类输入,而整个前向过程中噪声采样完全被当成常数处理,虽然理论上梯度仍可以通过UNet传播回来,但如果采样步骤过多,梯度会严重衰减。
要排查这个问题,最直接的方法是让模型跑一次前向,然后手动调用loss对攻击变量的backward,检查梯度值是否为有效非零的大数组。如果梯度值已经小到接近机器精度,就考虑减少反向传播经过的去噪步数,或者用“先采样固定噪声、再对输入计算梯度”的方式做近似。做对抗攻击的pipeline,第一优先级永远是确认梯度链路是通的,然后才谈得上调参。
4.5 忽略“成功”定义的一致性
不同论文对“对抗攻击成功”的定义差异极大,有的只看分类标签是否翻转,有的要求目标类别置信度超过某个阈值,有的要求图像在感知层面保持高相似度且语义偏移到指定方向。定义不一致时,成功率数字根本没有横向可比性。
我在复现baseline时会把成功判定条件写成一个独立的可配置函数,比如is_attack_success(origin_img, adv_img, target_label),并明确定义评判阈值。不同baseline之间比较时,确保调用的是同一个判定函数,而不是直接拿论文里的现成数字做对比。论文之间数字差几个点,很多时候不是方法优劣,而是成功标准不同。
5. baseline记录规范与后续建议
5.1 给每个项目建立一张baseline卡
跑过足够多实验之后,我的体会是baseline对比最大的敌人不是方法本身,而是实验记录混乱。现在我会给每个项目强制建立一张baseline卡,记录内容包括统一使用的初始图像集合、采样种子清单、diffusers与transformers的精确版本号、扰动预算定义域、成功判定函数代码、运行设备与耗时。
这张表看起来简单,但在项目三个月后回看结果时价值巨大。我经常遇到的情况是,过了几个月再看旧实验记录,根本想不起来当时所谓的“ε=0.1”到底作用在哪个向量上。如果把baseline卡建立成项目标准流程,这种事就能完全避免。下面给一个可以直接抄的baseline管理表头:
| 项目名 | 任务类型 | 模型与版本 | 初始数据集 | 扰动域 | 成功判定 | 评估指标 | 运行状态 |
|---|---|---|---|---|---|---|---|
| AnimeFace-PGD | 攻击生成模型 | SD1.5动漫微调 v3 | 100张512头像 | text embedding | CLIP语义偏移>0.15 | ASR/LPIPS | 已跑完 |
| AnimeFace-DiffPure | 防御净化 | SD1.5动漫微调 v3 | 100张512头像 | 像素域 | 恢复分类正确 | Acc/RobAcc | 已跑完 |
5.2 这个方向接下来会怎么扩展
扩散模型模态和接口越来越多,从文生图到图生图、ControlNet、视频生成。不同接口的攻击面各不相同,单一“像素域+分类准确率”的baseline体系已经不够用了。我最近在关注的是多模态联合攻击,即同时扰动文本输入和图像输入,让模型在保持表面语义不变的前提下输出风险内容。这类任务目前在baseline层面还没有完全统一的方案,传统PGD只能覆盖其中一部分。
另外,提示词层面的可迁移攻击也是热点。文本空间不像像素空间有连续的ε球结构,没法直接套用PGD的投影规则,需要设计专门的语义扰动策略。经典baseline只会越来越多,但方法论内核仍然是一样的——清晰的定义、可控的随机性、多维度指标评估。
我的个人建议是:如果你准备进入这个方向,先从FGSM和PGD这一对最基础的攻击跑通全流程,再用DiffPure建一条防御基线,然后把AutoAttack用在判别模型上作为强攻击参照。这组组合虽然朴素,却能覆盖从攻击到净化、从判别到生成的主流评估需求。
最后再分享一个小技巧。做对抗样本评测时,把干净图、对抗图、放大的扰动残差图和对应的梯度热力图一起保存下来,归档到同一个目录里。这样当你调试出奇怪的结果时,可以直接看图判断到底发生了什么——是扰动集中在文本区域而没有影响视觉内容,是梯度被随机采样器淹没导致图像只有噪点,还是模型真的被成功误导。这条经验帮我节省了大量排查时间,也让我在给别人review实验结果时能快速定位问题出在哪个环节。
