Flower 运行时自动安装 App 依赖:pyproject.toml 声明、uv sync 隔离环境与 SuperNode/SuperExec 启用方式

发布时间:2026/9/17 15:46:16
Flower 运行时自动安装 App 依赖:pyproject.toml 声明、uv sync 隔离环境与 SuperNode/SuperExec 启用方式 Flower 运行时自动安装 App 依赖pyproject.toml 声明、uv sync 隔离环境与 SuperNode/SuperExec 启用方式【免费下载链接】flowerFlower: A Friendly Federated AI Framework项目地址: https://gitcode.com/GitHub_Trending/flo/flower本文讲解 Flower 框架的运行时依赖安装runtime dependency installation机制Flower 如何读取 Flower App 在pyproject.toml中声明的 Python 依赖用uv sync在隔离的运行环境中自动安装这些依赖并在 App 执行完毕后清理环境。读完本文你将掌握如何在 SuperLink、SuperNode 以及 process 隔离模式下启用或关闭该机制并能结合源码理解$FLWR_HOME/runtime-envs隔离环境从创建、激活到删除的完整生命周期。机制定位不同 App 需要不同依赖时运行时自动补齐Flower App 在pyproject.toml中声明自己的 Python 包依赖。Flower 可以读取这份元数据在 App 被执行之前自动为其安装依赖来源文档how-to-install-app-dependencies-at-runtime.rst。这个机制解决的核心问题是宿主环境的依赖冲突与预装成本当不同 App 依赖不同的 Python 包甚至不同版本时运行时安装可以避免把所有 App 的依赖都塞进同一个宿主环境当运行 Flower 的机器没有预装全部 App 依赖时可以在 App 启动时按需补齐。对于生产部署文档同时给出了反向策略如果启动时间、网络访问条件或镜像内容需要精确控制仍然可以选择预装依赖 关闭运行时安装。三种组件的默认行为不同这是部署前必须知道的关键差异组件运行时依赖安装默认状态控制方式SuperLink默认开启传--disable-runtime-dependency-installation或设置环境变量FLWR_DISABLE_RUNTIME_DEPENDENCY_INSTALLATION1来关闭SuperNode默认关闭启动时传--allow-runtime-dependency-installation开启SuperGrid自动依赖安装已启用但不改变接入 SuperGrid 的 SuperNode 的默认值SuperNode 运维者仍需单独决定是否开启SuperLink 侧的默认值逻辑可以在源码中直接验证flower_superlink.py 中的_runtime_dependency_install_default()返回os.getenv(FLWR_DISABLE_RUNTIME_DEPENDENCY_INSTALLATION) ! 1即默认开启、仅当环境变量显式设为1时关闭。环境变量名定义在 constant.py。同时源码中保留了向后兼容如果用户仍传入旧的--allow-runtime-dependency-installationSuperLink 会打印弃用警告flower_superlink.py提示该行为现已默认开启、可用--disable-runtime-dependency-installation关闭。声明 App 依赖[project].dependencies要让运行时安装生效第一步是在 Flower App 的pyproject.toml中把依赖写进[project].dependencies段[project] name my-flower-app version 1.0.0 dependencies [ flwr2.0.0, torch2.12.0, torchvision0.27.0, ]这里有两个源码可佐证的行为细节flwr依赖会被跳过。Flower 读取这份列表做运行时安装时会剔除flwr项以免 App 声明的flwr版本要求把正在运行的 Flower 进程所依赖的安装给替换掉。实现见 dependency_installer.py 的_exclude_flwr_dependencies()它从 PEP 508 风格的依赖串中提取包名按下划线/连字符归一化并与flwr比对被跳过时会在日志中打一条 WARNING 说明原因。列表必须是合法的依赖列表。_get_project_dependencies()通过get_project_config读取pyproject.toml的[project].dependencies如果该字段不是列表会直接抛出RuntimeError因此依赖声明格式错误会导致启动失败而不是被静默忽略。实践建议文档原文 tip保持pyproject.toml与 App 实际需要的依赖同步。凡是没有写进[project].dependencies的包运行时自动安装不会替你装上——它只是忠实执行uv sync对这份声明的解析结果。在 SuperNode 上启用--allow-runtime-dependency-installationSuperNode 负责运行ClientApp代码。要让 SuperNode 为接收到的 App 安装其声明的依赖启动时需要显式传入--allow-runtime-dependency-installation。以下示例展示一个 SuperNode 连接本地 SuperLink 做原型验证的启动方式$ flower-supernode \ --superlink 127.0.0.1:9092 \ --insecure \ --allow-runtime-dependency-installation该命令行参数不是各组件各自手写的而是由公共的参数解析函数统一注入args.py 中的add_args_runtime_dependency_install()为 CLI 注册--allow-runtime-dependency-installationstore_true在 SuperLink 场景下还会额外注册与其互斥的--disable-runtime-dependency-installationstore_false二者共同写入同一个runtime_dependency_install属性。App 进程侧的通用参数解析add_args_flwr_app_common也调用了同一函数保证flwr-*app命令支持该标志。何时选择它当 SuperNode 宿主机允许在运行时安装 Python 包时使用如果宿主机无法访问包索引或你希望对已安装的包做更严格的管控文档给出的替代方案是在 SuperNode 环境里预装 ClientApp 的依赖而不是依赖运行时安装。process 隔离模式在flower-superexec上开启当以--isolationprocess运行 SuperLink 或 SuperNode 时App 实际运行在独立启动的 SuperExec 进程托管的子进程中此时传给flower-superlink/flower-supernode的运行时依赖安装标志不会传递到 App 进程。这种模式下需要在flower-superexec上单独开启$ flower-superexec \ --runtime-api-address runtime-api-address \ --plugin-type choice-of-plugin \ --allow-runtime-dependency-installation这条规则在源码调用链中有对应证据SuperLink 在 subprocess 隔离模式下自动拉起 SuperExec 时会依据自身的runtime_dependency_install开关决定是否在 SuperExec 命令中追加--allow-runtime-dependency-installation见 flower_superlink.py 的_get_superexec_command()而 SuperExec 侧的SubprocessExecutor只有在执行规格标记了runtime_dependency_install时才会在启动 App 子进程的参数列表中追加该标志subprocess_executor.py。这也解释了为什么 process 模式下谁启动 SuperExec谁就该负责把这个开关传给 SuperExec。安装流程源码解析六步机制如何落地文档对安装流程的官方描述共六步读取[project].dependencies→ 在$FLWR_HOME/runtime-envs下创建隔离运行环境 → 在 App 项目目录用当前 Python 可执行文件调用uv sync→ 将声明的依赖装入该环境 → 将该环境激活到当前 App 进程 → App 执行完毕后删除环境。这六步全部收敛在 dependency_installer.py 的install_app_dependencies()中L62-L167下面逐步对照源码说明其实现要点。1. 前置检查uv必须可用_ensure_uv_available()L264-L275会先执行sys.executable -m uv --version探测若失败则抛出RuntimeError要求先安装uv。也就是说运行时依赖安装以宿主 Python 环境中可通过-m uv调用uv为前提这是使用该机制时的硬性依赖。2. 读取依赖并剔除flwr_get_project_dependencies()解析pyproject.toml_exclude_flwr_dependencies()过滤掉flwr前文已述。若过滤后列表为空日志会记录未发现非 flwr 依赖继续创建隔离环境——即即使没有需要安装的第三方包仍会创建并激活一个隔离环境保证每次运行的环境边界一致。3. 创建按启动隔离的环境目录环境目录由_create_runtime_env_dir()L192-L208生成落在get_flwr_home() / runtime-envs / env_name下_RUNTIME_ENV_DIR runtime-envs对应文档所说的$FLWR_HOME/runtime-envs。目录命名策略保证每次运行各用一个环境有run_id时直接用str(run_id)作为目录名否则用项目路径 SHA-256 前 12 位 - 启动标识 SHA-256 前 12 位 - 随机 8 位 nonce拼接确保不同 App、不同启动之间目录不冲突。从源码结构看这一每运行一环境的设计正是文档所述并发运行的 App 不会互相修改对方 Python 包的实现基础。4. 执行uv sync并控制安装范围实际执行的命令L127-L141为当前Python -m uv sync \ --python 当前Python \ --no-install-project \ --no-install-package flwr \ --inexact参数含义与流程的对应关系--python sys.executable锁定使用当前正在运行的 Python 解释器创建环境保证 App 运行时的解释器版本与 Flower 进程一致--no-install-project不安装 App 项目本身App 代码来自 Flower App Bundle见下文--no-install-package flwr命令行层面再次排除flwr与 Python 层的_exclude_flwr_dependencies()形成双重保险通过环境变量UV_PROJECT_ENVIRONMENT指向本次运行专属的环境目录让uv sync把包装进该隔离环境而非宿主环境若上层提供了依赖索引 URL--index-url会追加到命令中在开源版中该解析钩子当前返回None_resolve_index_url_from_ee() 标注了对应解析器在flwr.ee侧尚未就绪默认走标准索引。uv sync的输出会流式转发到 Flower 日志并逐行解析 package前缀行记录实际安装到的包命令失败时抛出RuntimeDependencyInstallationErrorApp 启动随之失败。5. 激活环境改写sys.path、PATH与VIRTUAL_ENV_activate_runtime_env()L211-L230在当前进程内完成激活把新环境的site-packages按 Linux/macOS 的lib/pythonX.Y/site-packages与 Windows 的Lib/site-packages查找插入sys.path最前端把环境的bin/Scripts目录前置进PATH并设置VIRTUAL_ENV。之后 App 代码加载到的就是这次运行时安装的依赖版本。6. 退出时清理环境_register_runtime_env_cleanup()L245-L251在创建环境后立即向 Flower 的退出处理器注册cleanup_app_runtime_environment()App 执行完成后用shutil.rmtree(..., ignore_errorsTrue)尽力删除整个环境目录——即文档第六步删除环境。这是 best-effort 清理删除失败不会导致报错但正常路径下每次运行结束都会回收磁盘。两点边界说明来自文档与源码的一致结论App 代码本身不经过这套安装流程。App 代码来自 Flower App BundleFAB运行时依赖安装只负责装该 App 声明的包依赖并发安全由每运行独立环境 进程内sys.path前置激活共同保证。关闭机制与运维选型关闭运行时安装的方式按组件区分SuperLink启动参数加--disable-runtime-dependency-installation或在其启动前设置环境变量FLWR_DISABLE_RUNTIME_DEPENDENCY_INSTALLATION1。源码中两者等价——环境变量检查位于_runtime_dependency_install_default()flower_superlink.py命令行标志通过 args.py 中store_false写入同一属性SuperNode / SuperExec不传--allow-runtime-dependency-installation即为关闭App 进程级默认值RUNTIME_DEPENDENCY_INSTALL False见 constant.py。选型上的判断标准可以直接沿用文档的表述场景推荐做法多个 App 依赖不同/冲突的第三方包开启运行时安装让每次运行各用隔离环境宿主机没有预装全部 App 依赖开启运行时安装需保证可访问包索引生产环境启动时间敏感、网络受限、要求镜像内容精确可控预装依赖到 Flower 运行环境并关闭运行时安装SuperNode 宿主机禁止运行时装包在 SuperNode 环境预装 ClientApp 依赖不开启该标志相关测试用例可作进一步验证入口dependency_installer_test.py 覆盖了runtime-envs目录命名、安装失败抛错、索引 URL 解析等关键路径flower_superlink_test.py 则验证了环境变量与命令行标志对默认开关的组合行为。若你的 SuperNode 需要接入 SuperGrid接入方式的默认值与本机制的关系可参考 how-to-connect-supernodes-to-supergrid.rst。【免费下载链接】flowerFlower: A Friendly Federated AI Framework项目地址: https://gitcode.com/GitHub_Trending/flo/flower创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考