
模型隐私攻击与防护:你的模型在泄露什么?
模型即数据库:你的模型在泄露训练数据 LLM 训练数据包含大量敏感信息:个人身份信息、商业机密、医疗记录、法律文件。模型"记住"这些数据的程度远超预期——研究表明,GPT-2 (1.5B) 可以被引导逐字输出训练数据中的个人电话号码和邮箱地址。 模型隐私攻击的核心理念:模型不是黑盒,它是一个可以被查询的数据库。 四大攻击类型 攻击全景 攻击类型 目标 前提条件 危害等级 成员推断 (MIA) 判断样本是否在训练集中 黑盒查询 高 模型提取 复制模型功能 大量查询 高 训练数据提取 恢复训练数据原文 模型访问 严重 属性推断 推断训练集统计属性 黑盒查询 中 1. 成员推断攻击(Membership Inference Attack) 核心问题:“这条数据是否被用于训练你的模型?” 攻击原理:模型对训练数据和非训练数据的置信度不同——训练数据通常置信度更高(过拟合)。 import numpy as np from sklearn.metrics import roc_auc_score class MembershipInferenceAttack: def __init__(self, target_model, shadow_model=None): self.target = target_model self.shadow = shadow_model # 攻击者训练的影子模型 def compute_loss(self, model, inputs, labels): """计算模型在输入上的损失""" outputs = model(inputs) loss = cross_entropy(outputs, labels) return loss.detach().cpu().numpy() def attack_via_loss_threshold(self, member_data, non_member_data): """基于损失阈值的简单 MIA""" member_losses = [self.compute_loss(self.target, x, y) for x, y in member_data] non_member_losses = [self.compute_loss(self.target, x, y) for x, y in non_member_data] # 寻找最佳阈值 all_losses = member_losses + non_member_losses all_labels = [1]*len(member_losses) + [0]*len(non_member_losses) best_threshold = 0 best_auc = 0 for t in np.linspace(min(all_losses), max(all_losses), 100): preds = [1 if l < t else 0 for l in all_losses] auc = roc_auc_score(all_labels, preds) if auc > best_auc: best_auc = auc best_threshold = t return {"threshold": best_threshold, "auc": best_auc} def attack_via_reference_model(self, target_inputs, shadow_inputs): """基于参考模型的 MIA(更高级)""" # 训练一个攻击分类器,输入 = (目标模型loss, 影子模型loss) attack_features = [] attack_labels = [] for x, y in target_inputs: # 训练集 target_loss = self.compute_loss(self.target, x, y) shadow_loss = self.compute_loss(self.shadow, x, y) if self.shadow else 0 attack_features.append([target_loss, shadow_loss, target_loss - shadow_loss]) attack_labels.append(1) for x, y in shadow_inputs: # 非训练集 target_loss = self.compute_loss(self.target, x, y) shadow_loss = self.compute_loss(self.shadow, x, y) if self.shadow else 0 attack_features.append([target_loss, shadow_loss, target_loss - shadow_loss]) attack_labels.append(0) # 训练攻击分类器 from sklearn.ensemble import RandomForestClassifier attack_clf = RandomForestClassifier() attack_clf.fit(attack_features, attack_labels) return attack_clf LLM 场景的 MIA: ...