1. 联邦学习系统工程导论

联邦学习(Federated Learning, FL)是一种在多个数据持有方之间协同训练机器学习模型、而原始数据始终保留在本地的方法。它的核心目标不是“把数据集中起来算”,而是“把计算搬到数据所在的地方”。一次典型的联邦训练轮次中,服务器下发全局模型参数,各客户端用本地数据训练若干步,仅上传模型更新(梯度或参数增量),服务器再聚合这些更新形成新的全局模型。数据不出域,是它与传统集中式训练最本质的区别。

但“数据不出域”并不等于“系统简单”。恰恰相反,联邦学习把原本集中在单机上的问题拆散到了网络、设备、组织和合规边界之间,由此产生了一类新的工程问题。本课程关注的正是这些工程问题:如何把联邦学习从论文里的算法,变成一个可部署、可观测、可维护的系统。

从算法视角到系统视角

算法视角关心的是:给定一组客户端和本地数据,聚合公式能否收敛、收敛速度多快。系统视角关心的则是另一组问题:客户端什么时候上线、网络带宽够不够、某台设备训练到一半掉线怎么办、不同客户端的数据分布差异会不会让全局模型退化、如何验证聚合结果没有被恶意客户端污染。这两类问题常常互相纠缠——例如客户端采样策略既影响收敛性,也影响通信开销。

因此,联邦学习系统工程可以理解为:围绕“数据不动、模型动”这一约束,对通信、计算、调度、安全、评估等环节进行整体设计与权衡的工程学科。它要求我们同时具备分布式系统、机器学习与安全隐私三方面的基本认知。

联邦学习系统运行闭环与关键工程约束 中央服务器 全局模型 / 聚合 / 调度 客户端 A 本地数据 / 本地训练 上传参数增量 客户端 B 本地数据 / 本地训练 上传参数增量 客户端 C 本地数据 / 本地训练 上传参数增量 下发全局模型 上传更新 关键工程约束 通信 带宽受限 / 轮次开销 压缩 / 稀疏化 异构 设备算力 / 数据分布 掉线 / 慢节点 安全隐私 梯度泄露 / 投毒 差分隐私 / 加密 评估与运维 全局指标 / 可观测 版本 / 回滚

联邦学习面临的四类工程挑战

通信效率。联邦训练的主要瓶颈往往不是本地计算,而是参数上传下载。一个百万参数的模型,每轮与上千客户端交换一次,通信量可达数百 MB 到数 GB。常见手段包括梯度量化、稀疏化、客户端本地多步训练(减少轮次)以及客户端采样。工程上需要权衡压缩率与模型精度,并监控每轮实际传输字节数。

系统异构。客户端设备算力、内存、网络差异巨大,且可能随时离线。慢节点会拖慢整轮聚合,掉线节点会导致更新缺失。工程上通常引入超时阈值、按比例采样、异步聚合或容错聚合策略。例如设置单轮等待上限为 60 秒,超时客户端本轮更新被丢弃,并在下一轮重新参与采样。

数据异构。各客户端数据分布不同(Non-IID),本地模型可能严重偏离全局最优。这会表现为全局模型在某些客户端上精度骤降。工程上需要监控各客户端本地损失分布,必要时调整聚合权重或引入个性化层。

安全与隐私。上传的梯度可能被反推出训练数据,恶意客户端也可能通过投毒破坏全局模型。工程上可叠加差分隐私噪声、安全聚合(Secure Aggregation)以及异常更新检测。这些机制会带来额外开销,需要在隐私预算与模型可用性之间取舍。

课程项目与工具链概览

本课程以一个贯穿式项目为主线:在多个模拟客户端上协同训练一个图像分类模型,并逐步加入通信压缩、容错调度、隐私保护与可观测性模块。项目不追求复现某个特定论文,而是让每个工程环节都能被单独观察和验证。

工具链方面,我们主要使用以下组件:

  • PyTorch:定义本地模型与训练循环,作为客户端计算的核心。
  • Flower (flwr):提供联邦学习的客户端/服务器抽象与通信原语,便于快速搭建可运行系统。
  • NumPy / SciPy:用于聚合权重计算、统计分析与指标处理。
  • TensorBoard 或 Weights & Biases:记录每轮全局精度、损失与通信量,支撑可观测性。
  • Docker:将服务器与客户端封装为可复现的运行环境,模拟真实部署边界。
本课程默认读者已具备 Python 与 PyTorch 基础。若尚未接触过分布式训练,建议先理解“参数服务器”与“数据并行”的基本概念,再进入联邦学习的具体实现。

一个最小可运行的联邦训练循环,其伪代码结构如下,后续章节会逐步替换其中的占位实现:

for round in range(num_rounds):
    # 1. 服务器采样客户端
    clients = sample_clients(all_clients, fraction=0.3)
    # 2. 下发全局参数
    global_params = server.get_params()
    # 3. 各客户端本地训练
    updates = []
    for c in clients:
        local_params = c.train(global_params, epochs=2)
        updates.append(local_params - global_params)
    # 4. 服务器聚合
    new_params = global_params + aggregate(updates)
    server.set_params(new_params)
    # 5. 记录指标
    log(round, evaluate(server.get_params()))

这段代码里,sample_clients、train、aggregate 和 evaluate 四个函数,恰好对应了本课程后续要深入的四条主线:调度与采样、本地训练与异构处理、聚合与容错、评估与可观测性。理解它们之间的输入输出关系,是理解整个联邦学习系统的起点。

注意:联邦学习并不能自动保证隐私。仅上传梯度仍可能泄露信息,实际系统需要结合安全聚合、差分隐私或可信执行环境等手段,并明确威胁模型。后续章节会专门讨论这些机制的工程代价。

总结来看,联邦学习系统工程的核心任务,是在“数据不出域”的约束下,让一个由异构、不可靠、可能恶意的节点组成的分布式系统,稳定地训练出可用的全局模型。这既需要算法层面的设计,也需要通信、调度、安全与运维层面的工程实现。本课程将沿着这条主线,从最小可运行系统出发,逐步补齐每一个工程环节。