多模态大型语言模型(MLLM),例如GPT-4V或开源的LLaVA,结合了强大的视觉理解和语言生成能力。然而,正如传统的计算机视觉模型一样,MLLM也容易受到“对抗性攻击”的影响。这些攻击通过向图片添加人眼难以察觉的微小扰动(即对抗性像素),就能使模型产生完全错误的判断。这种漏洞对于依赖MLLM进行安全审查或关键决策的AI基础设施构成了严重的风险。
本文将深入探讨如何利用最基础且有效的快速梯度符号方法(FGSM)来生成针对MLLM视觉编码器的对抗性样本,并提供具体的PyTorch实现代码。
1. MLLM的攻击面分析
MLLM(如LLaVA)通常由三个核心组件构成:
1. 视觉编码器(Vision Encoder):通常是一个预训练的Transformer模型(如CLIP的ViT),负责将图像转换为特征向量。
2. 连接器(Connector):将视觉特征映射到LLM的嵌入空间。
3. 大型语言模型(LLM):处理整合后的文本和视觉特征,生成回复。
对抗性攻击主要针对视觉编码器。如果视觉编码器被欺骗,生成错误的特征向量,那么后续的LLM无论推理能力多强,都会基于错误的输入得出错误的结论。
2. 快速梯度符号方法 (FGSM) 原理
FGSM是一种高效的单步攻击方法。其核心思想是利用模型损失函数相对于输入图像的梯度,沿着梯度上升的方向对原始图像进行微小修改。这确保了修改后的图像(对抗性样本)能够最大化模型的预测误差。
对抗性样本 $x’$ 的计算公式如下:
$$x’ = x + \epsilon \cdot \text{sign}(\nabla_x J(\theta, x, y))$$
其中:
* $x$ 是原始输入图像。
* $\epsilon$ 是扰动强度(人眼不可见的关键参数)。
* $J(\cdot)$ 是模型的损失函数。
* $\nabla_x J$ 是损失函数相对于输入 $x$ 的梯度。
* $\text{sign}(\cdot)$ 是符号函数,取梯度的方向。
3. 实操:使用PyTorch生成对抗性图像
为了演示这个过程,我们使用一个标准的预训练图像分类模型(如ResNet)作为MLLM内部视觉编码器的代理目标。在实际攻击中,您需要针对具体的开源MLLM(如LLaVA)的视觉编码器执行相同的梯度计算。
环境准备
pip install torch torchvision pillow
Python 代码实现
以下代码展示了如何加载模型、定义FGSM函数,并生成对抗性扰动。
import torch
import torch.nn as nn
from torchvision import models, transforms
from PIL import Image
import numpy as np
# 1. 定义FGSM攻击函数
def fgsm_attack(image_tensor, epsilon, data_grad):
"""生成FGSM对抗性扰动"""
# 收集梯度的符号
sign_data_grad = data_grad.sign()
# 生成对抗性样本
perturbed_image = image_tensor + epsilon * sign_data_grad
# 裁剪到有效范围 [0, 1] (取决于原始图像的标准化)
perturbed_image = torch.clamp(perturbed_image, 0, 1)
return perturbed_image
# 2. 设置模型和数据
# 使用预训练的ResNet18作为MLLM视觉编码器的代理目标
model = models.resnet18(pretrained=True)
model.eval()
# 假设我们加载了一张图片,并进行了标准化处理
# 注意:在实操中,您需要加载实际图片并进行正确的预处理
# 这里使用随机张量作为演示输入,假设其原始标签为 'Target Class Index'
input_tensor = torch.randn(1, 3, 224, 224)
# 假设原始图片真实标签的索引是 208 (e.g., 'Labrador retriever')
target_label = torch.tensor([208])
# 启用梯度追踪
input_tensor.requires_grad = True
# 3. 执行攻击步骤
# 前向传播
output = model(input_tensor)
# 计算损失 (针对真实标签,我们希望最大化这个损失)
loss_criterion = nn.CrossEntropyLoss()
loss = loss_criterion(output, target_label)
# 梯度清零并反向传播,计算损失相对于输入的梯度
model.zero_grad()
loss.backward()
# 获取梯度数据
data_grad = input_tensor.grad.data
# 4. 生成对抗性样本
epsilon = 0.01 # 扰动强度参数,通常很小
adversarial_image = fgsm_attack(input_tensor, epsilon, data_grad)
# 5. 验证攻击效果
print(f"原始预测类别: {torch.argmax(output).item()}")
# 重新运行前向传播,使用对抗性样本
new_output = model(adversarial_image)
new_prediction = torch.argmax(new_output).item()
print(f"对抗性样本预测类别: {new_prediction}")
# 如果攻击成功,new_prediction 将是一个与 target_label 完全不同的类别,
# 这意味着模型被植入的对抗性像素欺骗了。
4. 影响与防御
这种攻击展示了AI模型的脆弱性。对于MLLM而言,如果它们部署在需要高可靠性的场景(如自动驾驶的场景理解或医疗图像分析),这种视觉欺骗可能导致灾难性的后果。
防御措施(AI Infra层面):
- 对抗性训练 (Adversarial Training):将对抗性样本纳入模型的训练集,提高模型对微小扰动的鲁棒性。
- 输入预处理:在图像进入视觉编码器之前,使用滤波、降噪或像素深度随机化等技术,试图消除或减弱对抗性扰动。
- 模型蒸馏或量化:有时模型的鲁棒性与模型复杂度或精度有关。部署时使用更鲁棒的部署格式可能有所帮助,但这不是对抗性攻击的根本解决方案。
汤不热吧