Skip to content

联邦学习中的差分隐私

差分隐私(Differential Privacy, DP)为联邦学习提供严格的数学隐私保证。本文介绍 DP-SGD、DP-FedAvg 及隐私预算分析。

联邦学习差分隐私

差分隐私基础

(ε, δ)-差分隐私定义:

对于任意相邻数据集 D, D' 和任意输出 S:
P[M(D) ∈ S] ≤ e^ε × P[M(D') ∈ S] + δ

其中:
- ε: 隐私预算(越小越隐私)
- δ: 失败概率(通常设为 1/n^2)
- M: 随机化机制

DP-SGD

在梯度级别添加噪声:

python
class DPSGDOptimizer:
    def __init__(self, model, lr=0.01, noise_multiplier=1.0, max_grad_norm=1.0):
        self.model = model
        self.lr = lr
        self.noise_multiplier = noise_multiplier
        self.max_grad_norm = max_grad_norm

    def step(self, dataloader):
        for batch in dataloader:
            # 1. 计算每个样本的梯度(per-sample gradient)
            per_sample_grads = self.compute_per_sample_grads(batch)

            # 2. 裁剪梯度(限制敏感度)
            for i in range(len(per_sample_grads)):
                grad_norm = torch.norm(per_sample_grads[i])
                if grad_norm > self.max_grad_norm:
                    per_sample_grads[i] *= self.max_grad_norm / grad_norm

            # 3. 聚合裁剪后的梯度
            clipped_grad = torch.mean(per_sample_grads, dim=0)

            # 4. 添加高斯噪声
            noise = torch.normal(
                0, self.noise_multiplier * self.max_grad_norm,
                size=clipped_grad.shape
            )
            noisy_grad = clipped_grad + noise

            # 5. 更新参数
            for param, grad in zip(self.model.parameters(), noisy_grad):
                param.data -= self.lr * grad

DP-FedAvg

将 DP-SGD 与 FedAvg 结合:

python
class DPFedAvgServer:
    def __init__(self, model, noise_multiplier=1.0, z_clip=1.0):
        self.global_model = model
        self.noise_multiplier = noise_multiplier
        self.z_clip = z_clip

    def aggregate(self, client_updates, num_clients):
        # 1. 裁剪客户端更新
        for i, update in enumerate(client_updates):
            update_norm = compute_norm(update)
            if update_norm > self.z_clip:
                scale_update(update, self.z_clip / update_norm)

        # 2. 计算平均更新
        avg_update = average_updates(client_updates)

        # 3. 添加高斯噪声
        noise_std = self.noise_multiplier * self.z_clip / num_clients
        noise = torch.normal(0, noise_std, size=avg_update.shape)
        noisy_update = avg_update + noise

        # 4. 更新全局模型
        apply_update(self.global_model, noisy_update)

隐私预算计算

使用 Rényi 差分隐私(RDP)进行更紧的隐私分析:

python
from opacus.accountants import RDPAccountant

accountant = RDPAccountant()

# 每轮消耗的隐私预算
for round in range(num_rounds):
    accountant.step(
        noise_multiplier=1.0,
        sample_rate=0.01,  # 采样率
    )

# 转换为 (ε, δ)-DP
epsilon = accountant.get_epsilon(delta=1e-5)
print(f"总隐私消耗: ε = {epsilon:.2f}")

隐私-效用权衡

noise_multiplierε (100轮)模型精度隐私等级
0.5~50接近无DP极弱
1.0~8略降中等
2.0~3明显下降较强
5.0~1严重下降极强

隐私预算分配

  1. 确定可接受的 ε(通常 1-10)
  2. 根据总轮数反推 noise_multiplier
  3. 使用 RDP 会计师获得更紧的界
  4. 子采样本身提供隐私放大效应

精度损失

DP 对模型精度的影响不可忽视。对于复杂任务(如大模型微调),ε < 3 时精度下降显著。实际应用中需要仔细权衡隐私与效用。

相关资源

最近更新