1. FLGo 跑实验时算法和模型配置到底卡在哪
FLGo 是一个轻量级的联邦学习框架,能让你用几行代码就把 FedAvg、FedProx 这类算法跑起来,也能自由替换 CNN、MLP 等模型结构,适合做联邦学习实验的学生和算法工程师。但真正上手时,很多人会卡在同一个地方:算法和模型都写对了,训练却跑不通,或者跑出来的结果和预期对不上。原因往往不在算法本身,而在运行配置这一层——config.toml里的 benchmark 参数、settings.json里的运行选项、模型初始化接口的写法,任何一处对不上,实验就会静默失败或者报一堆看不懂的错。
更现实的问题是,当你想在 FLGo 里接入一个远程模型服务来做对比实验,或者让联邦训练过程中的某些环节调用统一的大模型 API 通道时,Key 的管理会变得很乱。每个实验脚本里硬编码一个 Key,换环境就要改一遍,集群上跑多个任务时更是容易串。这篇就聚焦 FLGo 的算法与模型运行配置环节,给出config.toml和settings.json的可复制骨架,演示怎么通过 TaoToken 统一 Key 通道完成模型调用配置,最后附上启动验证和报错排查的具体动作。目标很直接:让你一次跑通算法与模型的组合,不用在配置上反复试错。
2. 前置准备:TaoToken 统一 Key 通道与 FLGo 环境
在动 FLGo 的配置之前,先把 Key 通道这件事理清楚。TaoToken 提供的是统一的模型调用入口,你只需要一个 Key,就能在多个模型之间切换,不用为每个模型单独申请和管理凭证。对 FLGo 这种需要反复跑不同算法、不同模型组合的实验场景来说,这一点很实用——实验脚本里只引用一个环境变量,换模型时改配置就行,不用动代码。
你需要先拿到 API Key。访问 https://taotoken.net/api-keys 创建,然后把它写进环境变量,不要硬编码在脚本里:
export TAOTOKEN_API_KEY="sk-你的key"FLGo 本身的安装很简单,用 pip 就行:
pip install flgo如果你要用 GPU 跑,确认 PyTorch 版本和 CUDA 对得上。FLGo 对 PyTorch 的依赖比较直接,装好 torch 之后 flgo 会自动识别设备。我试过在 CPU 和单卡环境上跑,配置逻辑是一样的,只是gpu参数要对应改。
TaoToken 的 API 地址是 https://taotoken.net/api,这个地址在后面的配置里会用到。注意 API 地址不带任何查询参数,保持干净。模型对话入口在 https://taotoken.net/models ,接入文档在 https://taotoken.net/doc ,配置过程中遇到参数不确定的可以对照文档查。
3. 可复制配置:config.toml 与 settings.json 骨架
FLGo 的运行配置分两层:任务级的config.toml定义 benchmark 和数据划分,运行级的settings.json定义训练超参和模型选择。下面给出可直接复制的骨架。
先看config.toml,它通常放在你的任务目录下:
[benchmark] name = "flgo.benchmark.mnist_classification" para = {} [partitioner] name = "IIDPartitioner" para = { num_clients = 100 } [model] name = "cnn" para = {}这里benchmark.name决定数据集和默认模型,partitioner决定客户端数据怎么分。IIDPartitioner 是均匀划分,做基线实验最常用。如果你要换非独立同分布,把 name 改成DirichletPartitioner,para 里加alpha = 0.5。
再看settings.json,它定义训练过程:
{ "num_rounds": 30, "num_epochs": 1, "batch_size": 8, "learning_rate": 0.1, "gpu": 0, "algorithm": "fedavg", "model": "cnn", "api_base": "https://taotoken.net/api", "api_key_env": "TAOTOKEN_API_KEY" }关键点在于api_base和api_key_env这两个字段。api_base指向 TaoToken 的统一入口,api_key_env告诉 FLGo 从哪个环境变量读 Key。这样你的实验脚本里不需要出现任何明文 Key,集群上跑多个任务时也不会串。
如果你要在代码里直接初始化,等价写法是:
import flgo import flgo.algorithm.fedavg as fedavg import os task = './flgo_exp' config = { 'benchmark': {'name': 'flgo.benchmark.mnist_classification'}, 'partitioner': {'name': 'IIDPartitioner', 'para': {'num_clients': 100}} } if not os.path.exists(task): flgo.gen_task(config, task_path=task) option = { 'num_rounds': 30, 'num_epochs': 1, 'batch_size': 8, 'learning_rate': 0.1, 'gpu': 0 } runner = flgo.init(task, fedavg, option=option) runner.run()这段代码跑的是 FedAvg 加默认 CNN。要换算法,把fedavg换成fedprox就行;要换模型,在flgo.init里加model=参数。
4. 算法与模型接入:从 FedAvg 到自定义模型
FLGo 的算法接入靠flgo.init的第二个位置参数。内置算法都在flgo.algorithm下,常用的有 fedavg、fedprox、fedopt 等。切换算法不需要改任务配置,只改这一处:
import flgo.algorithm.fedprox as fedprox runner = flgo.init(task, fedprox, option=option) runner.run()模型接入稍微复杂一点,因为 FLGo 把模型视为 benchmark 的一部分。每个 benchmark 的model子模块里放着适配该数据集的模型。MNIST 分类任务下有 cnn 和 mlp 两个可选。切换方式是在 init 时传model参数:
import flgo.benchmark.mnist_classification.model.cnn as cnn import flgo.benchmark.mnist_classification.model.mlp as mlp cnn_runner = flgo.init(task, fedavg, option=option, model=cnn) mlp_runner = flgo.init(task, fedavg, option=option, model=mlp)自定义模型时,需要继承FModule,并实现init_local_module和init_global_module两个接口。前者给客户端分配本地模型,后者给服务器分配全局模型。经典横向联邦里只有 Server 持有全局模型,所以init_global_module里判断一下类名即可:
from torch import nn from flgo.utils.fmodule import FModule class Model(FModule): def __init__(self): super().__init__() self.encoder = nn.Sequential( nn.Conv2d(1, 32, 5, padding=2), nn.ReLU(), nn.MaxPool2d(2), nn.Conv2d(32, 64, 5, padding=2), nn.ReLU(), nn.MaxPool2d(2), nn.Flatten(1), nn.Linear(3136, 512), nn.ReLU(), ) self.head = nn.Linear(512, 10) def forward(self, x): return self.head(self.encoder(x)) def init_local_module(object): pass def init_global_module(object): if 'Server' in object.__class__.__name__: object.model = Model().to(object.device) class MyCNN: init_local_module = init_local_module init_global_module = init_global_module然后在 init 时传model=MyCNN。FLGo 0.0.17 之后还提供了flgo.convert_model函数,能把普通 nn.Module 快速转成可用的模型类,省去手写两个接口的步骤:
model = flgo.convert_model(Model) runner = flgo.init(task, fedavg, option=option, model=model)这一步的坑在于:convert_model只做封装,不改变模型结构,如果你的 forward 里有自定义逻辑,转换后要确认输入输出维度对得上。
5. 验证请求与成功结果
配置写完之后,先做一次最小验证,确认 Key 通道和 FLGo 都能正常工作。最直接的方式是跑一个短轮次的实验:
option = {'num_rounds': 2, 'num_epochs': 1, 'batch_size': 8, 'learning_rate': 0.1, 'gpu': 0} runner = flgo.init(task, fedavg, option=option) runner.run()如果一切正常,终端会输出每轮的 loss 和 accuracy,类似:
Round 1/2, Loss: 2.301, Accuracy: 0.112 Round 2/2, Loss: 2.289, Accuracy: 0.135同时任务目录下会生成record文件夹,里面有训练日志和模型检查点。你可以用flgo.analysis里的工具画收敛曲线,确认训练确实在推进。
验证 TaoToken 通道是否生效,可以在脚本里加一段独立的调用测试:
import os, requests api_key = os.environ.get("TAOTOKEN_API_KEY") resp = requests.post( "https://taotoken.net/api/v1/chat/completions", headers={"Authorization": f"Bearer {api_key}"}, json={"model": "gpt-4o-mini", "messages": [{"role": "user", "content": "ping"}]} ) print(resp.status_code, resp.json()["choices"][0]["message"]["content"][:50])返回 200 并且有内容输出,说明 Key 通道没问题。这一步单独跑,不要混在 FLGo 训练里,方便定位问题。
6. 本篇常见错排查
跑 FLGo 配置时,报错集中在几个地方。下面按现象列出来,对照排查。
报错一:ModuleNotFoundError: No module named 'flgo.algorithm.xxx'
算法名拼错了,或者你用的 FLGo 版本里没有这个算法。先确认版本:pip show flgo。内置算法列表可以查接入文档 https://taotoken.net/doc 里的说明,或者直接看flgo/algorithm目录。
报错二:KeyError: 'model'或模型维度不匹配
自定义模型的输出维度和数据集类别数对不上。MNIST 是 10 类,你的 head 层输出必须是 10。另外确认init_global_module里确实给 Server 赋了模型,否则服务器端拿不到全局模型。
报错三:requests.exceptions.ConnectionError或 401
Key 没读到,或者环境变量名写错了。检查echo $TAOTOKEN_API_KEY有没有输出。如果是在 Jupyter 里跑,环境变量可能没继承,用os.environ手动设一下。401 一般是 Key 无效,去 https://taotoken.net/api-keys 重新生成一个。
报错四:训练跑完但 accuracy 一直是 0.1 左右
学习率太大或者 batch_size 太小导致不收敛。MNIST 上 lr=0.1 配 batch_size=8 有时会震荡,把 lr 降到 0.01 试试。另外确认 partitioner 的 num_clients 和实际客户端数一致,不一致会导致部分客户端没数据。
报错五:GPU 显存不够
gpu参数设了但显存不足。把 batch_size 调小,或者改成gpu: -1用 CPU 跑。FLGo 默认会占满指定 GPU,多任务并行时要注意错开。
排查顺序建议:先单独验证 Key 通道,再跑最小轮次实验,最后加算法和模型组合。这样出问题时能快速定位是配置层还是代码层。
7. 下一步:把配置固化下来
配置跑通之后,建议把config.toml和settings.json固化到任务目录里,不要每次在脚本里手写。这样换算法和模型时只改配置文件,代码保持不动。长期做联邦学习实验或者要跑 Agent 类任务的话,可以考虑用 Coding Plan 来管理多个实验的 Key 和配额,入口在 https://taotoken.net/coding-plan 。模型对话的调试入口在 https://taotoken.net/models ,接入相关的参数细节查 https://taotoken.net/doc 。把 Key 通道和 FLGo 配置分开管理,实验复现会省很多事。