Contents
深入理解AI模型的“软肋”:对抗性攻击实战
随着BERT、RoBERTa等大型预训练模型在NLP任务中取得SOTA表现,模型部署已成为AI基础设施的关键环节。然而,这些模型并非无懈可击,它们对对抗性扰动(Adversarial Perturbations)极其敏感。一个微小的、人眼难以察觉的文本修改,可能导致模型的预测结果彻底错误。
TextAttack 是一个强大的Python工具包,专为测试和评估NLP模型鲁棒性而设计。它提供了一套标准化框架,用于定义、执行和分析各种文本对抗性攻击。
1. TextAttack核心概念
TextAttack将一次攻击分解为四个核心组件:
- 目标(Goal):定义攻击成功的条件,例如:将模型的原始预测结果从“正面”改变为“负面”,或仅仅改变到任何非原标签(非目标攻击)。
- 变换(Transformation):定义如何生成新的候选对抗样本,例如:同义词替换、拼写错误、键盘距离最近的字符替换等。
- 约束(Constraint):限制变换的范围,确保生成的对抗样本在语义或语法上保持合理性。常见的约束包括Universal Sentence Encoder (USE) 相似度阈值、语法检查等。
- 配方(Recipe/Attacker):预定义的攻击策略组合,如 TextFooler, BERT-Attack, DeepWordBug 等。
2. 环境准备与安装
为了运行示例,我们需要安装TextAttack及其依赖库,包括Hugging Face的transformers和datasets库。
1 pip install textattack datasets transformers
3. 实战案例:使用TextFooler攻击BERT模型
我们将使用一个TextAttack内置的、在SST-2情感分析数据集上预训练的BERT模型,并采用经典的TextFooler攻击配方对其进行测试。
TextFooler是一种基于贪婪搜索(Greedy Search)的非目标攻击,它通过迭代地替换对模型分类影响最大的词语(使用同义词),直到模型预测失败。
3.1 攻击命令行执行
TextAttack提供了简洁的命令行接口(CLI),非常适合快速启动实验。
我们选择前10个样本进行攻击,以快速观察效果:
1
2
3
4
5
6 textattack attack \
--model textattack/bert-base-uncased-SST-2 \
--model-on-device \
--dataset glue^sst2 \
--recipe textfooler \
--num-examples 10
命令解释:
- –model textattack/bert-base-uncased-SST-2: 指定使用TextAttack维护的预训练BERT模型。
- –dataset glue^sst2: 指定使用GLUE数据集中的SST-2子集作为测试数据。
- –recipe textfooler: 指定使用的攻击策略。
- –num-examples 10: 只对前10个样本进行攻击。
3.2 攻击结果分析
执行完毕后,TextAttack将输出详细的攻击报告。一个典型的输出片段如下(结果会因运行环境有所不同):
1
2
3
4
5
6
7
8
9
10
11
12
13 +-----------------------+--------+
| Attack Results | |
+-----------------------+--------+
| Total number of trials| 10 |
| Number of successful | 9 |
| Number of failed | 0 |
| Number of skipped | 1 |
| Original accuracy | 90.0% |
| New accuracy | 10.0% |
| Attack success rate | 100.0% |
| Average perturbed word| 17.5% |
| Average time per attack| 3.2 s |
+-----------------------+--------+
核心指标解读:
- Original accuracy (90.0%): 在测试集子集上,模型初始的准确率。
- New accuracy (10.0%): 经过攻击后,模型保持正确预测的准确率。这个值越低,说明模型鲁棒性越差。
- Attack success rate (100.0%): 成功找到对抗样本的比例。这意味着在9个可攻击样本中,攻击者均成功欺骗了模型。
- Average perturbed word (17.5%): 平均而言,仅需修改原文本中17.5%的词语,即可导致模型错误。
3.3 在Python脚本中自定义攻击
虽然CLI易用,但在CI/CD或定制化评估场景中,我们通常需要使用Python脚本。下面是如何在代码中定义一个定制化的攻击流程:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 import textattack
from datasets import load_dataset
# 1. 加载模型和数据集
model_name = "textattack/bert-base-uncased-SST-2"
model = textattack.models.helpers.AutoPyTorchModel.from_pretrained(model_name)
tokenizer = textattack.models.helpers.AutoTokenizer.from_pretrained(model_name)
model_wrapper = textattack.models.wrappers.HuggingFaceModelWrapper(model, tokenizer)
# 2. 定义数据集 (使用SST-2的测试集)
dataset = load_dataset("glue", "sst2", split="validation")
# 限制样本数量
dataset = dataset.select(range(5))
# 3. 定义攻击配方:TextFooler (或自定义组件)
attack = textattack.recipes.TextFoolerJin2019.build(model_wrapper)
# 4. 执行攻击
attack_args = textattack.AttackArgs(num_examples=5, disable_stdout=True)
attacker = textattack.Attacker(attack, dataset, attack_args)
# 5. 运行攻击并获取日志
results = attacker.attack_dataset()
# 打印摘要结果
print(textattack.loggers.AttackLogManager(results).log_summary())
4. 结论
TextAttack为AI基础设施工程师提供了一个标准化的评估工具,用于量化和理解模型在恶意输入下的脆弱性。通过系统地执行TextAttack,我们可以识别出鲁棒性较差的模型,并为后续的对抗性训练(Adversarial Training)和模型加固提供关键数据支持。
汤不热吧