Flower 部署架构深度解析:SuperLink、SuperExec、SuperNode 与多租户 Multi-Run 协同机制
2026/9/17 11:20:46 网站建设 项目流程

Flower 部署架构深度解析:SuperLink、SuperExec、SuperNode 与多租户 Multi-Run 协同机制

【免费下载链接】flowerFlower: A Friendly Federated AI Framework项目地址: https://gitcode.com/GitHub_Trending/flo/flower

本文围绕 Flower 官方架构说明文档展开,讲清楚一个部署形态的 Flower 联邦学习系统中各核心进程(SuperLink、SuperExec、SuperNode)的职责边界与协作关系,并解释 SuperExec 如何按需管理多个短生命周期的训练应用进程、Multi-Run 如何实现多租户(multi-tenancy / multi-job)。读完本文,你可以基于仓库源码验证这套架构的真实实现细节,并理解为什么 AI 工程师只需编写ServerAppClientApp即可构建完整的联邦学习应用。

从 Hub-and-Spoke 拓扑到进程化架构

在联邦学习(Federated Learning, FL)中,典型形态是一个服务器(server)与大量客户端(clients)相连接,这组"服务器 + 多个客户端"的集合通常被称为一个联邦(federation)。其中:

  • 服务器的角色是协调训练过程(选择客户端、分发任务、聚合结果);
  • 每个客户端的角色是接收来自服务器的任务、在本地执行这些任务,并把结果返回给服务器。

这种结构常被称为Hub-and-Spoke(中心辐射)拓扑:中心 Hub 是服务器,周围的 Spoke 是各客户端。

但在真实生产部署中,同一个联邦上往往需要运行多个不同的项目,而每个项目可能使用:

  • 不同的超参数(如轮数、batch size);
  • 不同的模型架构(如 ResNet 与 MLP);
  • 不同的聚合策略(如 FedAvg 与 FedAvgM);
  • 甚至不同的机器学习框架(如 PyTorch 与 TensorFlow)。

为了让同一套基础设施承载这些互不相同的项目,Flower 把服务端和客户端都拆分为两部分

  1. 长生命周期部分(long-lived):负责跨网络的通信,常驻运行,与具体项目无关;
  2. 短生命周期部分(short-lived):执行任务特定的项目代码,随用随启、用完即弃。

这一拆分是整个 Flower 部署架构的核心设计思想,下文各组件正是围绕"长生命周期 = 通信骨架 / 短生命周期 = 项目代码"来组织的。

服务端三组件:SuperLink、SuperExec 与 ServerApp

一个 Flower服务器由以下三个部分组成:

组件生命周期职责
SuperLink长生命周期向客户端(SuperNode)转发任务指令,并接收任务结果返回;是联邦中所有节点间通信的枢纽
SuperExec长生命周期通过 SuperLink 按需调度、启动和管理多个应用进程(如ServerApp);默认由 SuperLink 自动拉起
ServerApp短生命周期包含项目特定的服务端代码,定制联邦学习的全部服务端逻辑(客户端选择、客户端配置、结果聚合);这是 AI 研究员与工程师构建 Flower 应用时实际实现的组件

SuperLink 的源码实现

从源码结构看,SuperLink 在当前仓库中位于 flwr/superlink。main.py 中的create_app()构建了 SuperLink 的 FastAPI 服务,其关键事实包括:

  • 中间件链中包含ControlAuthenticationMiddlewareControlLicenseMiddlewareProtobufTranslationMiddleware等(见 _get_middleware),说明 Control API 具备认证、License 与 Protobuf 报文翻译能力;
  • 路由注册了三类 API:健康检查(health.router)、Control API(control_router)、Runtime API(runtime_router,并附加了RuntimeVersionDependency版本校验,见 main.py#L209-L217)。Runtime API 正是 SuperExec 拉取任务所使用的接口;
  • Fleet 通信默认使用 gRPC(fleet_api_type = TRANSPORT_TYPE_GRPC_RERE,见 main.py#L124-L143);
  • LinkState(联邦运行时状态)通过对象存储工厂初始化,默认使用内存数据库(FLWR_IN_MEMORY_DB_NAME),也可通过FLWR_DATABASE配置外部数据库。

SuperExec 由 SuperLink 自动拉起的证据

文档声明 SuperExec "默认由 SuperLink 自动启动"。这一事实在源码中得到直接印证:flower_superlink.py 中的SuperLinkLifespan持有superexec_process: subprocess.Popen,并在 startup 阶段调用_start_superexec_if_needed()flower-superexec子进程方式启动 SuperExec;shutdown 时则会 terminate 该子进程。这与"由 SuperLink 自动管理 SuperExec 生命周期"的描述完全一致。

ServerApp:工程师实际编写的项目代码

ServerApp的实现在 flwr/serverapp/server_app.py,支持两种典型编写方式:

# 方式一:配合已有 Strategy 使用 def server_fn(context: Context): server_config = ServerConfig(num_rounds=3) strategy = FedAvg() return ServerAppComponents( strategy=strategy, server_config=server_config, ) app = ServerApp(server_fn=server_fn) # 方式二:自定义 main 函数 app = ServerApp() @app.main() def main(grid: Grid, context: Context) -> None: print("ServerApp running")

源码中还明确约束了两者不可同时提供(BOTH_MAIN_FN_SERVER_FN_PROVIDED_ERROR_MSG,见 server_app.py#L55-L77),这正对应文档中"ServerApp 定制客户端选择、配置与结果聚合"的定位:无论使用内置 Strategy 还是完全自定义的 Grid 主函数,项目相关逻辑都被封装在这个短生命周期进程中。

客户端三组件:SuperNode、SuperExec 与 ClientApp

一个 Flower客户端同样由三部分组成:

组件生命周期职责
SuperNode长生命周期连接 SuperLink、请求任务、执行任务(例如"用你的本地数据训练这个模型"),并把结果返回给 SuperLink
SuperExec长生命周期通过 SuperNode 按需调度、启动和管理多个应用进程(如ClientApp);默认由 SuperNode 自动拉起
ClientApp短生命周期包含项目特定的客户端代码,定制联邦学习的全部客户端逻辑(本地模型训练、评估、前后处理);这是 AI 研究员与工程师构建 Flower 应用时在客户端侧实现的组件

为什么叫 SuperNode?

官方文档给出的命名解释很直白:在联邦学习中,客户端才是真正的主角(the actual stars of the show)——它们持有训练数据、执行真正的训练。因此 Flower 决定将它们命名为SuperNode(超级节点);而SuperLink的职责则是充当连接所有 SuperNode 的"缺失的环节(missing link)"。

ClientApp 的源码形态

ClientApp实现在 flwr/clientapp/client_app.py。以最典型的用法为例,将自定义的Client实现包装进ClientApp

from flwr.app import Context class FlowerClient(NumPyClient): # ... 训练/评估/查询逻辑 def client_fn(context: Context): return FlowerClient().to_client() app = ClientApp(client_fn)

源码层面有两点值得注意:

  1. 签名检查与兼容适配:_inspect_maybe_adapt_client_fn_signature 会检查client_fn是否为def client_fn(context: Context)形式;若用户仍使用旧版client_fn(cid)签名,会触发弃用警告,并自动包装一个适配器,从context.node_configcontext.node_id中提取客户端标识——这体现了 Flower 对旧 API 的平滑兼容。
  2. 消息类型约束:当没有提供client_fn而使用@app.handle()方式时,消息类型必须是<category><category>.<action>形式,且<category>必须是train/evaluate/query之一(见 client_app.py#L146-L150)。

SuperNode 侧的 FastAPI 服务位于 flwr/supernode/main.py,其应用状态中同样携带superexec_auth_secret,用于 SuperNode 与其自动拉起的 SuperExec 之间的认证(详见下文)。

SuperExec 深度解析:短生命周期应用进程的管理器

SuperExec 是文档中两个部署侧组件(服务端与客户端)共用的机制,也是理解"长/短生命周期拆分"如何落地的关键。其主实现位于 flwr/supercore/superexec/run_superexec.py。

主循环:拉取 → 选择 → 认领 → 启动

run_superexec()的核心是一个while True轮询循环(run_superexec.py#L266-L312),每一轮执行:

  1. executor.reconcile():对现有任务进程做一致性检查;
  2. client.PullPendingTasks():向 Runtime API 拉取待处理任务列表;
  3. plugin.select_task(tasks):由插件的选择逻辑挑出一个任务;
  4. executor.wait_for_capacity(...):按任务类型等待执行容量;
  5. client.ClaimTask(ClaimTaskRequest(task_id)):认领任务,服务端返回 token 后才会真正启动应用(claim_res.token为空则本轮什么都不做);
  6. plugin.launch_task(token, task):启动对应的应用进程(ServerApp 或 ClientApp),并对启动结果(ACCEPTED/CAPACITY_REJECTED/FAILED/UNKNOWN)做日志与容错处理(见 _handle_launch_result)。

从源码结构看,PullPendingTasksClaimTask两个方法与 run_superexec.py#L54-L59 中定义的_SUPEREXEC_AUTH_METHODS完全对应——这两个接口受 HMAC 认证拦截器(SuperExecAuthHttpInterceptor)保护,即 SuperLink/SuperNode 与 SuperExec 之间通过superexec_auth_secret共享密钥进行鉴权。

轮询间隔配置

SuperExec 的任务轮询间隔由环境变量FLWR_SUPEREXEC_TASK_POLL_INTERVAL控制(_get_task_poll_interval):

配置项说明
环境变量FLWR_SUPEREXEC_TASK_POLL_INTERVAL(单位:秒)
默认值1.0
允许范围0.0160.0秒,且必须为有限数值,否则抛出ValueError
作用控制 SuperExec 向 SuperLink/SuperNode 轮询新任务的频率

与父进程的共生关系

run_superexec()接受一个parent_pid参数:一旦提供,就会调用start_parent_process_monitor(parent_pid)(run_superexec.py#L208-L210),在父进程退出时让 SuperExec 自动终止。这正是文档所述"SuperExec 默认由 SuperLink/SuperNode 自动启动"的配套机制——子进程随宿主生命周期共生死。

Multi-Run 与多租户:一个联邦承载多个项目

Flower 的multi-run能力允许:在同一个联邦(由单个常驻 SuperLink 与多个常驻 SuperNode 组成)中,同时运行多个ServerAppClientApp。这种能力也被称为multi-tenancy(多租户)multi-job(多作业)

理解 multi-run 的关键细节是:SuperNode 只有在被选中参与某次训练时才会启动对应的ClientApp。官方文档用两个 run 举例说明:

  • [run 1]ServerAppClientApp参与第一轮训练,本轮中所有 SuperNode 都被选中,因此每个 SuperNode 都运行各自的ClientApp
  • [run 2]:只有第 1、第 2 个 SuperNode 被选中参与训练,其余 SuperNode 保持空闲(不启动 ClientApp 进程)。

因此,借助 Flower multi-run,不同的 Flower App 项目可以运行在不同的客户端集合上——项目 A 训练时选中全部节点,项目 B 训练时只选中部分节点,两者共享同一套通信骨架(SuperLink + SuperNodes),而项目特定的计算进程(App)由各自的 SuperExec 按需拉起。这与上文 SuperExec "Pull → Select → Claim → Launch" 的任务模型形成了闭环:任务携带项目归属信息,SuperNode 侧的 SuperExec 只认领属于自己 run 的任务。

适用前提与延伸阅读

需要明确两个边界:

  1. 本文档覆盖范围:官方说明明确注明,本文覆盖的是Flower Deployment Runtime(部署运行时);针对 Flower Simulation Runtime(单机仿真运行时)的说明文档将另行提供(原文档 note 部分)。因此上述 SuperLink/SuperNode 部署形态不适用于纯本地仿真场景;
  2. 版本演进:Flower 团队在快速迭代中,该说明文档会持续更新,SuperExec 相关 API 与配置(如执行器类型、认证方式)以当前仓库源码为准。

建议结合以下仓库路径继续深入:

  • SuperLink 服务入口与 API 组织:framework/py/flwr/superlink/main.py;
  • SuperLink CLI 与 SuperExec 自动启动逻辑:framework/py/flwr/superlink/cli/flower_superlink.py;
  • SuperExec 主循环与任务认领:framework/py/flwr/supercore/superexec/run_superexec.py;
  • SuperNode 服务端入口:framework/py/flwr/supernode/main.py;
  • 开发者实际编写的两个应用组件:framework/py/flwr/serverapp/server_app.py 与 framework/py/flwr/clientapp/client_app.py。

小结

Flower 部署架构的本质,是把"通信"与"计算"解耦为两种生命周期的进程:SuperLink 与 SuperNode 构成联邦的常驻通信骨架,SuperExec 在两端按需拉起承载项目代码的 ServerApp / ClientApp,从而让单个联邦能够同时承载多个使用不同超参数、模型、聚合策略乃至不同 ML 框架的训练项目。理解这条"长生命周期管通信、短生命周期管业务"的主线,就能准确把握 Flower 中各个组件的职责边界,并在源码中快速定位任意部署问题的责任方。

【免费下载链接】flowerFlower: A Friendly Federated AI Framework项目地址: https://gitcode.com/GitHub_Trending/flo/flower

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询