AI/ML 详解:联邦与隐私学习

Day 40 · 2026-06-26
面向:有编程经验的非 AI 方向工程师

联邦学习Federated Learning

分布式训练数据本地性
一句话类比

传统机器学习是「把数据搬到计算」——所有数据汇总到中心机房再训练。联邦学习反过来,是「把计算搬到数据」——和你熟悉的 MapReduce 数据本地性(data locality)同一个思想:不动数据,下推代码。区别是这里 reduce 阶段聚合的不是数据,而是各节点本地算出的模型梯度,原始数据永远留在用户设备上。

它解决什么问题 + 工作机制

痛点:医院病历、手机输入法记录、银行交易流水——这些数据既敏感又分散,法律(GDPR)和商业利益都不允许集中上传,但不集中又训练不出好模型。联邦学习的答案是:模型去找数据,而不是数据去找模型。

机制就是 McMahan 等人 2016 年提出的 FedAvg(联邦平均),一个反复执行的循环:服务器把当前全局模型下发给一批客户端 → 每个客户端用本地数据训练几步 → 只把权重更新(不是数据)传回 → 服务器按数据量加权平均,得到新全局模型。

聚合公式很朴素:w ← Σ (n_k / n) · w_kw_k 是第 k 个客户端训练后的本地权重,n_k 是它的样本数,n 是总样本数。直觉:谁的数据多,谁的本地模型在平均里就更有发言权——本质就是一次加权 reduce。

FedAvg 一轮通信:
中心服务器 w
↓ 下发全局模型
手机A 医院B 银行C ← 各自本地训练,数据不出门
↑ 只上传权重更新 Δw
服务器按 n_k 加权平均 → 新 w
↑ 循环数十~数百轮。通信成本是主要瓶颈,不是算力
代码示例
import numpy as np

# FedAvg 的核心其实就是这个加权平均函数(框架可用 Flower/FedML)
def fedavg(client_weights, client_sizes):
    # client_weights: 每个客户端本地训练后的权重向量列表
    # client_sizes:   每个客户端的本地样本数 n_k
    total = sum(client_sizes)
    # 按样本量加权:数据多的客户端权重占比更大
    global_w = sum(
        (n_k / total) * w_k
        for w_k, n_k in zip(client_weights, client_sizes)
    )
    return global_w  # 这就是下一轮要下发的全局模型

# 模拟:3 个客户端,原始数据从未离开它们
w = fedavg([np.array([1.,2]), np.array([3.,4]), np.array([2.,2])],
            [100, 50, 200])  # 银行(200)发言权最大
print(w)  # [1.857 2.286] —— 偏向样本多的客户端
常见误区 + 实践场景
误区:「数据不出门 = 隐私安全」。。只传梯度也会泄密——研究表明,从上传的梯度可以反推出训练样本(gradient inversion / 模型反演攻击)。联邦学习只解决了「数据不集中」,没解决「上传内容是否泄密」——所以它几乎总要叠加后面三种密码学/统计手段。
📌 超级个体场景:你想用多台设备(工作笔记本、家用机、手机)上的私人笔记微调一个本地小模型,又不愿把笔记汇总到一处。联邦式的「各设备本地算更新、只合并权重」就是合适的心智模型——把它当成你个人数据的「分布式训练」。
Takeaway + 思考题
💡 联邦学习是「移动计算而非移动数据」的分布式系统范式,FedAvg 本质是一次按数据量加权的 reduce。
🤔 如果某个客户端上传的「更新」是恶意构造的(投毒),加权平均会被污染吗?你会怎么设计聚合端的拜占庭容错?

差分隐私Differential Privacy

隐私数学可量化保证
一句话类比

差分隐私像数据库查询的「可控脱敏」:你能问「平均工资是多少」,但系统会在答案里掺一点精心校准的噪声,让你无法通过「有张三 vs 没张三」两次查询的差值反推出张三的工资。关键是隐私不再靠「我觉得安全」,而是一个可以用数字 ε 量化、可以累加预算的数学保证——类似你熟悉的限流配额(token bucket):每次查询消耗预算,用完就不能再查。

它解决什么问题 + 工作机制

痛点:传统「匿名化」(删名字、删身份证)反复被攻破——靠几个旁路字段交叉比对就能重新识别个人。差分隐私给出一个更硬的定义:一个随机算法 M 满足 ε-差分隐私,当且仅当对任意只差一条记录的两个数据集 D、D′,以及任意输出 S:

Pr[M(D) ∈ S] ≤ eε · Pr[M(D′) ∈ S]

直觉拆解:加不加你这条记录,输出的概率分布几乎不变(被 eε 这个倍数夹住)。于是攻击者看到结果,也分不清你到底在不在数据集里——你的存在被「淹没」了。ε(隐私预算)越小,两个分布越像,隐私越强,但噪声越大、精度越低。这是隐私与可用性之间一个没法绕开的旋钮。

怎么实现?最经典的 Laplace 机制:在真实答案上加 Laplace 噪声,大小 = 敏感度 / ε。敏感度 = 改动一条记录最多让答案变多少(「计数」查询为 1)。用到深度学习就是 Abadi 等人 2016 的 DP-SGD:训练时先裁剪每个样本的梯度(控制敏感度),再加高斯噪声,并用「moments accountant」精确累计全程花掉的总 ε。

ε 这个旋钮的权衡:
ε=0.1 强隐私 噪声大、精度低
ε=1.0 平衡  常用区间
ε=8.0 弱隐私 噪声小、精度高
↑ 没有「免费隐私」:ε 是你必须显式定价的预算
代码示例
import numpy as np

# Laplace 机制:对一个「计数」查询做差分隐私发布
def private_count(true_count, epsilon, sensitivity=1.0):
    # 计数查询:增删一条记录最多让结果变 1,故 sensitivity=1
    scale = sensitivity / epsilon       # 噪声幅度 ∝ 1/ε
    noise = np.random.laplace(loc=0, scale=scale)
    return true_count + noise          # 发布加噪后的结果

true = 1000  # 真实有 1000 个患者得某病
print(private_count(true, epsilon=0.1))   # 强隐私 → 噪声大,可能 987 或 1013
print(private_count(true, epsilon=2.0))   # 弱隐私 → 噪声小,约 1000.4

# 训练神经网络时用官方库 Opacus(PyTorch)一行接管:
# from opacus import PrivacyEngine
# model, optim, loader = PrivacyEngine().make_private(...)  # 自动裁剪+加噪
常见误区 + 实践场景
误区:「ε 设多少都行,反正加了噪声」。。ε 没有统一安全阈值,而且会累加——同一份数据被查 10 次,隐私损耗是 10 个 ε 相加(组合定理)。ε 偷偷设到几十,等于没有保护。它是一笔要严格记账的预算,不是一次性开关。
📌 决策辅助场景:当你评估一份声称「已匿名化」的数据产品时,问对方一句「你们的 ε 是多少、怎么记账的」——能立刻区分真隐私工程与营销话术。这是把模糊的「安全感」换成可审计数字的思维方式。
Takeaway + 思考题
💡 差分隐私把「隐私」从形容词变成了可量化、可累加、可定价的数学保证 ε,核心是「有没有你这一条,结果几乎一样」。
🤔 联邦学习(Day 40 概念①)只传梯度仍可能泄密,而 DP-SGD 给梯度加噪。两者叠加时,噪声该加在客户端本地还是服务器聚合端?各有什么信任假设?

同态加密Homomorphic Encryption

密码学密文计算
一句话类比

普通加密像把数据锁进保险箱——要用就得先解锁,解锁瞬间明文就暴露给了服务器。同态加密(HE)是一个「带手套的保险箱」:你能隔着手套在箱子里直接操作,全程不打开。对应到你的世界:服务器能对加密的数据库字段直接做 SUM / 点积,算完返回的还是密文,只有持私钥的你能解开——而服务器从头到尾没见过一个明文

它解决什么问题 + 工作机制

痛点:你想用云端的算力或第三方模型处理敏感数据(病历、财务),但不信任对方。明文上传 = 泄密;本地算 = 没算力。HE 让你「把计算外包出去,又不交出数据」。

数学核心是「保持运算结构」:加密函数 E 满足 E(a) ⊕ E(b) = E(a + b)。也就是说,密文上的某种运算 ⊕,解密后正好对应明文的加法。能同时支持密文加法和乘法、且支持任意次的,叫全同态加密(FHE)——这是 Craig Gentry 在 2009 年用理想格(ideal lattices)首次构造出来的,是密码学几十年的里程碑。

为什么以前做不到?每次密文运算都累积噪声,乘法尤其涨得快,噪声超阈值就再也解不开。Gentry 的突破是 bootstrapping(自举):用同态运算「给密文自己解密再重新加密」把噪声重置,从而支持无限深度计算。代价是极慢——这也是 HE 至今没普及的根因。机器学习中更常用 CKKS 方案(Cheon 等人 2017),支持近似实数运算,适合容忍少量误差的神经网络推理。

同态推理流程(数据全程加密):
你: 明文 x → 加密 → 密文 E(x)
↓ 上传
云服务器: 在 E(x) 上跑模型 → E(y) 看不到 x,也看不到 y
↓ 返回密文
你: 用私钥解密 E(y) → 明文结果 y
↑ 安全代价 = 慢几个数量级;CKKS 牺牲精度换实用
代码示例
import tenseal as ts  # OpenMined 的 HE 库,封装了 CKKS

# 1) 建上下文 = 生成密钥 + 设定 CKKS 参数
ctx = ts.context(ts.SCHEME_TYPE.CKKS, poly_modulus_degree=8192,
                  coeff_mod_bit_sizes=[60, 40, 40, 60])
ctx.global_scale = 2**40
ctx.generate_galois_keys()

# 2) 加密两个向量(想象成你的私密特征)
a = ts.ckks_vector(ctx, [1.0, 2.0, 3.0])
b = ts.ckks_vector(ctx, [4.0, 5.0, 6.0])

# 3) 直接在密文上算点积——服务器侧可执行,看不到明文
enc_dot = a.dot(b)           # 全程是密文运算
print(enc_dot.decrypt())     # ≈ [32.0] = 1*4+2*5+3*6,近似但够准
常见误区 + 实践场景
误区:「有了 FHE,隐私计算就解决了」。现实:FHE 比明文计算慢成千上万倍,跑一个完整大模型推理至今不现实。所以它常被降级使用——只对最敏感的一小段(如最后的相似度匹配)做同态加密,其余配合 MPC / DP。把它当「核选项」,不是默认开关。
📌 跨学科思考场景:HE 是「可以在不理解内容的前提下正确操作内容」的纯粹范例——和你感兴趣的「形式 vs 语义」「计算是否需要理解」(中文房间论证)能直接呼应。一个系统能算对却「看不懂」,这本身就是关于心智与计算的哲学素材。
Takeaway + 思考题
💡 同态加密让「计算」与「看见」彻底解耦——服务器能算却看不到,代价是巨大的性能开销,靠 bootstrapping 续命。
🤔 如果某天 FHE 快到能跑完整模型推理,「云厂商必须可信」这个假设就被取消了。这会怎样重塑你对「数据主权」和 AI 商业模式的判断?

安全多方计算Secure Multi-Party Computation

密码学秘密分享
一句话类比

安全多方计算(MPC)要解决一个看似悖论的问题:几方一起算出一个共同结果,但谁都不暴露自己的输入。类比你熟悉的分布式 quorum:数据被切成若干「秘密份额(secret share)」散在各方手里,单份毫无意义,只有按协议合起来才有结果——但 MPC 更狠,它合出的是「计算结果」而非原始数据本身。经典启蒙题是姚期智的「百万富翁问题」:两个富翁想知道谁更有钱,又都不肯说出自己有多少。

它解决什么问题 + 工作机制

痛点:多家医院想联合统计某药疗效,但谁都不能看别家的病历;多家银行想联合反欺诈,又受竞争与合规所限。需要「合作计算,零信任共享」。

最易懂的机制是加性秘密分享(additive secret sharing):把私密数 x 拆成几个随机数之和 x = x₁ + x₂ + x₃ (mod p),每方只拿一个 xᵢ。单看任何一份都是均匀随机数、泄露零信息;但加法可各方在自己份额上独立做,最后把结果份额相加,就能还原 x + y 的真值——全程没人见过原始数 x、y。乘法更复杂(需 Beaver 三元组等协议),但思想一致。

联邦学习里最重要的落地是 Bonawitz 等人 2017 的 安全聚合(Secure Aggregation):客户端用配对掩码把梯度「加性分享」给服务器,服务器只能解出所有梯度之和、看不到任何单个客户端的梯度,还能容忍部分客户端掉线——正好补上概念①「只传梯度也泄密」的窟窿。

加性秘密分享:算 x+y 而不暴露 x、y
A 持 x=5 拆→ x₁=12 x₂=-7 (和=5)
B 持 y=3 拆→ y₁=-4 y₂=7 (和=3)
各方本地相加份额: 节点1: 12+(-4)=8   节点2: -7+7=0
公开合并: 8 + 0 = 8 = x+y ✓ 没人见过 5 或 3
代码示例
import random
P = 2**31 - 1  # 一个大素数,所有运算在 mod P 下进行

def share(secret, n=3):
    # 拆成 n 份随机份额,前 n-1 份随机,最后一份兜底使总和=secret
    parts = [random.randrange(P) for _ in range(n - 1)]
    parts.append((secret - sum(parts)) % P)
    return parts  # 任何单份都是均匀随机数,泄露零信息

# 两方各自把私密数拆成份额,分发到 3 个计算节点
sx, sy = share(5), share(3)  # Alice=5, Bob=3,互不告知

# 每个节点只在自己手里的份额上相加(本地、无需通信)
node_sums = [(a + b) % P for a, b in zip(sx, sy)]

# 最后公开合并各节点结果 → 还原 x+y,但 5 和 3 从未暴露
print(sum(node_sums) % P)  # 8 ✓
常见误区 + 实践场景
误区:「MPC 加密了,所以输出也安全」。。MPC 只保护过程(中间不泄露输入),不保护结果本身。如果最终输出的「联合统计量」本身能反推某人(比如某稀有病只有一个患者),照样泄密——所以 MPC 常要和差分隐私叠加:MPC 管过程,DP 管结果。
📌 个人项目场景:你和朋友想比较各自的投资收益率、又不愿露出本金与持仓,加性秘密分享就能算出「平均收益」而不暴露任何人的数字。这是「合作但不交底」类问题的通用模板,远不止技术场景。
Takeaway + 思考题
💡 MPC 用秘密分享实现「合作计算、零信任共享」,但它只保护计算过程,不保护输出——结果隐私要靠差分隐私补。
🤔 这四种技术(联邦/DP/HE/MPC)保护的对象不同:数据位置、个体可识别性、计算可见性、输入机密性。生产系统为什么往往要组合而非二选一?

四种技术怎么配合How They Combine

它们不是互斥的替代品,而是保护不同层面的积木,生产系统通常叠加:

技术保护什么主要代价信任假设
联邦学习数据不集中(位置)通信成本、Non-IID聚合服务器半可信
差分隐私个体不可识别(结果)精度下降加噪方可信
同态加密计算中不可见(过程)慢几个数量级无需信任算力方
安全多方计算各方输入机密(过程)通信轮次多多数方不合谋

典型组合:联邦学习定框架(数据不出门)→ 安全聚合 / MPC 让服务器看不到单个梯度 → 差分隐私给模型加噪防个体反推 → 必要时对最敏感片段加 HE。一句话:FL 管位置,MPC/HE 管过程,DP 管结果

深入资源Further Reading

深入思考Deep Questions

1. 联邦学习号称「数据不出门」,为什么仍需叠加 DP / MPC?只传梯度到底泄露了什么?
梯度不是数据的无害摘要,而是「数据如何影响模型」的高保真信号。gradient inversion(梯度反演)研究表明:在 batch 较小、模型结构已知时,可从上传的梯度近似重建出原始训练样本——能认出的人脸、能读出的文本。直觉上梯度 = 损失对参数的偏导,它编码了「为拟合这条样本,模型该往哪调」,信息量远超想象。所以联邦学习只解决了物理位置(数据没集中存储),没解决信息泄露。补法两层:(a) 安全聚合 / MPC 让服务器只看到「所有梯度之和」——单点反演失效;(b) DP-SGD 给梯度加噪,让反演即便拿到也重建不准。这正是三层防御要叠加的根本原因——任何单层都有缺口。
2. ε「隐私预算」会累加。这和你熟悉的限流配额、分布式资源记账有什么共通之处?
本质同构:都是有限资源的全局记账问题。差分隐私的「组合定理」说:对同一数据集做 k 次 ε-DP 查询,整体损耗最坏是 k·ε(高级组合可优化到 √k 量级)。这和令牌桶限流几乎一一对应:每次查询「扣预算」,耗尽即拒绝——区别是这里扣的是「隐私」这种不可再生资源,没有「桶会回填」,花掉就永久损失。工程含义和分布式记账一致:(a) 需要中心化预算账本记每个数据集累计花了多少 ε;(b) 要防「同一查询换皮再问」绕过预算;(c) 要设计预算分配策略,把有限 ε 优先给最有价值的分析。你做过的配额/速率限制系统,心智模型可直接迁移,只是把「QPS」换成「隐私损耗」。
3. 同态加密「能算但看不见」,安全多方计算「合作但不交底」——区别和取舍在哪?
都让「计算」与「数据可见性」解耦,但路线相反HE单方加密、外包算力:一个人把数据加密扔给云,云在密文上算,算力集中、通信极少(一来一回),但计算开销爆炸(慢几千到几万倍),且通常只有数据所有者能解密。MPC多方协作、分摊秘密:数据拆成份额散在多方,靠多轮通信协同算结果,单次运算比 HE 快得多,但通信轮次随计算深度增长,安全性依赖「多数方不合谋」。取舍:(a) 单方外包、网络差、计算浅(如一次加密相似度匹配)→ HE;(b) 多方对等、网络好、要反复交互(如多机构联合建模)→ MPC;(c) 现代系统常混合,按每段计算的「乘法深度」与「通信成本」挑最划算的。它们互补,不是谁取代谁。
4. 这四种技术都有「隐私 vs 可用性 / 成本」的硬权衡。有「免费的隐私」吗?
没有——而且这不是工程不够努力,是信息论层面的根本约束。直觉:隐私的本质是「让攻击者无法从输出区分个体」,而有用的结果必然携带输入的信息——想让结果有用就得反映数据,想保护隐私就得对单个数据「不敏感」,两个目标数学上直接对立。DP 用「加噪→降精度」付费,HE/MPC 用「密码学开销→降性能」付费,联邦学习用「不集中→通信成本 + Non-IID 收敛变差」付费。本质是一条帕累托前沿:只能在「隐私强度」和「可用性/成本」之间选点,不能同时拉满。所以工程上真问题从来不是「要不要隐私」,而是「这个场景能容忍多少损失,换多强的保证」——把它当显式定价的决策,而非能糊弄的合规复选框。这也是为什么「ε 是多少」比「我们很重视隐私」有价值得多。
5. 把「隐私」从直觉感受变成可量化的 ε,对其他领域有什么方法论启发?
这是值得跨学科品味的方法论事件。在差分隐私之前,「匿名」「隐私」是形容词、是法务话术,攻防各说各话、无法证伪——每个「匿名化」方案都被新攻击打穿,因为根本没有说清「安全」意味着什么的定义。Dwork 等人的贡献不只是算法,而是给隐私下了一个对抗式、可证明、可组合的数学定义(ε-DP),从此防御方能证明保证、攻击方的边界被框定。这种「把模糊概念形式化」的范式,往往是范式跃迁的标志:密码学把「安全」定义成「与随机不可区分」、复杂性理论把「难」定义成 NP、信息论把「信息量」定义成熵。启发有二:(a) 当一个领域陷入「各执一词、无法证伪」,缺的常不是更多方案,而是一个好定义;(b) 好定义的特征是可量化、可组合、对抗式(考虑最坏对手)。你关心的意识、对齐这些「难概念」,进展关键或许同样在于:能否找到那个让人「原来它就是这个意思」的形式化定义。