Flower 退出码 202(SERVERAPP_STRATEGY_AGGREGATION_ERROR):ServerApp 聚合失败的定位与排查
【免费下载链接】flowerFlower: A Friendly Federated AI Framework项目地址: https://gitcode.com/GitHub_Trending/flo/flower
在 Flower 中,进程退出码是跨组件的故障语义契约。本文围绕官方参考文档 202.rst 展开,解释退出码 202SERVERAPP_STRATEGY_AGGREGATION_ERROR的确切含义:当 ServerApp 内所选的聚合策略(Strategy)在执行聚合(aggregation)阶段发生错误时,进程会以该退出码终止。读完后,你将能够准确区分 202 与相邻退出码 200/201/203 的边界,知道它由哪个异常类触发、哪些内置策略会抛出它,以及"检查日志"之外可以按什么线索去定位聚合失败。
文档定义:202 是什么
官方参考页对 202 的原始定义非常凝练(202.rst):
- Description:The strategy encountered an error during aggregation.(策略在聚合过程中遇到了错误。)
- How to Resolve:Check the logs for more details on the specific aggregation error encountered.(检查日志以获取所遇到具体聚合错误的更多细节。)
即 202 专指"策略聚合阶段出错"这一种失败,而不是客户端回复本身不一致(那是 200),也不是 ServerApp 代码里抛出的通用未处理异常(那是 201)。
源码中的定义位置与语义边界
退出码在 exit_code.py 中按组件分段编号,ServerApp 专属区间为 200–249:
# ServerApp-specific exit codes (200-249) SERVERAPP_STRATEGY_PRECONDITION_UNMET = 200 SERVERAPP_EXCEPTION = 201 SERVERAPP_STRATEGY_AGGREGATION_ERROR = 202 SERVERAPP_RUN_START_REJECTED = 203同一文件中还维护了每个退出码的简短帮助信息EXIT_CODE_HELP,其中 202 的官方提示语(exit_code.py)为:
ExitCode.SERVERAPP_STRATEGY_AGGREGATION_ERROR: ( "The strategy encountered an error during aggregation. Please check the logs " "for more details." ),触发 202 的异常类是AggregationError,定义在 serverapp/exception.py:
class AggregationError(AppExitException): """Exception triggered when aggregation fails.""" exit_code = ExitCode.SERVERAPP_STRATEGY_AGGREGATION_ERROR def __init__(self, reason: str): super().__init__(reason)它的基类AppExitException(app/exception.py)说明了退出行为:所有 ServerApp/ClientApp 应用级错误都继承自它,被抛出且未被捕获时,进程会退出并上报携带对应退出码的遥测事件(telemetry event);且子类必须覆盖exit_code属性,否则在类创建时就会抛出ValueError。这意味着 202 不是"打印错误后继续",而是 ServerApp 进程的确定性终止信号——在容器编排或 CI 场景下,你可以直接监控该退出码来判断"本轮聚合失败"。
AggregationError的构造函数接受reason: str参数并写入异常消息,这正是参考文档建议"检查日志"的原因:日志中记录的reason会给出聚合失败的具体原因(哪个键、哪个张量形状不匹配等)。
哪些策略、在什么情况下抛出 202
在 framework/py/flwr/serverapp/strategy/ 下,AggregationError被多个需要"跨轮次状态"或"参数级操作"的策略使用,典型如:
- FedOpt 系(FedAdam / FedAdagrad / FedYogi 共用的基类 fedopt.py):在
_compute_deltat_and_mt聚合阶段做三重校验,任何一项不满足即抛出AggregationError:self.current_arrays is None—— 聚合前未调用configure_train,无法计算delta_t = aggregated_arrays - current_arrays;- 聚合结果数组的键集合与策略内部保存的当前数组键集合不一致;
- 同名键的张量形状(shape)不一致——源码注释明确说明这是"故意避免广播(broadcasting)",只允许形状完全相等的数组相减。
- FedAvgM(fedavgm.py):维护动量状态时做同类一致性检查;
- Q-FedAvg(qfedavg.py)、FedTrimmedAvg(fedtrimmedavg.py)、差分隐私自适应裁剪(dp_adaptive_clipping.py):各自在其特有的聚合逻辑失败点抛出。
从源码结构看,可以这样归纳 202 的典型触发场景:策略需要把本轮客户端回复的聚合结果与自己上一轮保存的状态(当前数组、动量、裁剪尺度等)做逐键、逐形状的运算,一旦两者在键或形状上对不上,就抛AggregationError并以 202 退出。常见诱因包括:客户端上报的模型参数结构在服务端中途发生了变化(例如某客户端漏报/多报某个张量)、不同客户端的层结构或命名不一致导致聚合出的键与策略缓存的键错位、以及训练配置变更导致轮次之间张量形状变化。
对应的测试用例也印证了这一点:fedopt_test.py 中test compute_deltat raises AggregationError when there is a mismatch断言键不匹配时pytest.raises(AggregationError)成立。
如何排查 202(在"看日志"基础上给出可操作线索)
参考文档给出的解决步骤是"查看日志中具体的聚合错误细节"。结合源码,可以把这句建议落实为一条明确的排查链:
找到
AggregationError的reason日志:该 reason 是策略在抛出点手写的定位文本(如"Keys of the aggregated arrays do not match those of the arrays stored at the strategy"、"Shape of aggregated array '...' does not match..."),它直接指明是键不匹配还是形状不匹配,以及涉及哪个键。确认是训练轮而非评估轮:202 发生在聚合阶段,通常意味着训练轮回复中携带的
ArrayRecord与策略期望不一致。与相邻退出码做边界区分,避免查错方向(对照 200.rst、201.rst、203.rst 及 serverapp/exception.py):
- 200
SERVERAPP_STRATEGY_PRECONDITION_UNMET:由InconsistentMessageReplies抛出,指客户端回复本身无法进入聚合(记录数量/类型不对、各回复键不一致、缺少加权平均所需键)。这是"聚合的前置条件不满足"; - 201
SERVERAPP_EXCEPTION:ServerApp 代码中任意未处理异常; - 202
SERVERAPP_STRATEGY_AGGREGATION_ERROR:回复已通过前置检查,但策略聚合逻辑本身失败; - 203
SERVERAPP_RUN_START_REJECTED:SuperLink 拒绝启动 run,与聚合无关。
简单记忆:200 是"输入不合格",202 是"加工时出错"。
- 200
检查各客户端模型一致性:若 reason 指向键/形状不匹配,重点核对各 ClientApp 构建模型的方式、上报的数组键名与形状是否逐客户端一致,以及是否存在中途改变模型结构或参数的操作。
小结
退出码 202 是 Flower 为"策略聚合阶段失败"专门保留的 ServerApp 退出码:由 AggregationError 触发、经 AppExitException 的退出机制上报,并在 ExitCode 与EXIT_CODE_HELP中登记。当你部署的 ServerApp 以 202 退出时,先读日志中AggregationError携带的reason,再按"键是否一致、形状是否一致、客户端模型结构是否一致"三个方向核查,通常可以快速定位到聚合失败的根因。
【免费下载链接】flowerFlower: A Friendly Federated AI Framework项目地址: https://gitcode.com/GitHub_Trending/flo/flower
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考