对三台独立 Spark 的真实多中心试点,请使用新增的物理多站点部署手册。 本文的
SimEnv/ 三逻辑站点路径仅用于单机工程验证,不能代替真实跨院部署。
赛事提供的是一台可 SSH 登录的 DGX Spark 节点,而不是三家真实医院。演示环境在一台 Spark
上创建 site-a、site-b、site-c 三个逻辑院区,以验证联邦协议、模型聚合、隐私策略和
审计链路。真实落地时,每个逻辑站点对应一台部署在医院科室内的 Spark。
本项目不需要在 Spark 上部署 Step 3.7 权重。Step 3.7 使用兼容 OpenAI 协议的远程 API,且 只能接收脱敏协议、聚合指标和报告上下文。医学影像、标签、患者标识和站点级小样本明细不得 发送给 Step API。
| 能力 | 组件 | 用法 |
|---|---|---|
| 联邦编排 | NVIDIA FLARE 2.7.2 | FedAvgRecipe、SimEnv、Client API |
| 联邦优化 | NVIDIA FLARE | 官方 PTFedProxLoss |
| 医学影像 | MONAI | NIfTI transforms、SegResNet、DiceCE、DiceMetric |
| 张量训练 | PyTorch | CUDA/CPU 自动选择、AMP、AdamW |
| 影像文件 | nibabel | 合成 NIfTI 数据生成与读取 |
| 控制平面 | FastAPI、SQLModel、Pydantic | API、状态、配置和持久化 |
| 本地 Agent 推理 | NVIDIA TensorRT-LLM | Spark 上的 OpenAI 兼容端点,服务已脱敏的聚合研究上下文 |
| 协同 Agent 推理 | OpenAI Python SDK | 调用 Step 3.7 兼容接口;仅接收策略批准后的非敏感上下文 |
| 前端 | React、TanStack Query、Recharts | 科研流程控制台和指标图表 |
不要先安装依赖或上传数据。SSH 登录后,在仓库根目录运行:
bash scripts/inspect_spark.sh | tee spark-inventory.txt必须确认:
uname -m为aarch64;nvidia-smi能识别 Spark GPU 与驱动;- Python 版本不低于 3.11;
- 根目录及工作盘有足够空间;
- 当前统一内存占用安全,避免接近 90%;
- 如使用容器,Docker 已启用 NVIDIA runtime。
检查结果保存为比赛证据,但不得提交公网 IP、用户名、密码、API Key 或其他赛事凭据。
推荐直接在 Spark 上克隆代码。不要通过 SSH/SCP 上传医学影像或大体积模型。
仓库提供 deploy/Dockerfile.spark,默认以 NVIDIA NGC PyTorch 为基础镜像。先构建并确认
CUDA、MONAI 与 NVFLARE:
sudo docker build \
-f deploy/Dockerfile.spark \
-t rarelink-spark:latest \
.
sudo docker run --rm --gpus all \
rarelink-spark:latest \
python3 scripts/smoke_runtime.py如所在网络访问 PyPI 较慢,可在组织安全策略允许的前提下通过构建参数指定可信镜像:
sudo docker build \
--build-arg PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple \
-f deploy/Dockerfile.spark \
-t rarelink-spark:latest \
.如果 Docker daemon 被配置为本机代理但代理未运行,应由节点管理员修复代理或提供已经批准的 基础镜像。不要擅自修改共享节点的 daemon 配置。
bash scripts/bootstrap_spark.sh
cp .env.example .env只在 .env 中配置密钥。赛事领取的是 Step Plan 时使用 step_plan/v1;普通开放平台账号使用
v1。模型名必须以当前账号的 models API 返回值为准:
STEP_API_KEY=replace-with-secret
STEP_API_BASE=https://api.stepfun.com/step_plan/v1
STEP_MODEL=step-3.7-flash
RARELINK_FL_MODE=nvflare.env 已被 Git 忽略。演示不需要 Step Key:未配置时系统使用确定性的本地模板 Agent,联邦
训练仍可独立运行。配置完成后执行以下命令验证 endpoint 和模型权限;脚本只打印模型 ID,
不会输出 API Key:
.venv/bin/python scripts/verify_step_api.py
# 一次研究主任 Agent 的真实 JSON 结构化调用;回执仅保存元数据和输出哈希
.venv/bin/python scripts/verify_step_agent_runtime.py
# 实验设计、统计评审、隐私评审与科研写作四角色真实调用
.venv/bin/python scripts/smoke_step_agent_team.py若赛事 Key 的模型列表未返回 step-3.7-flash,应选择列表中的准确 ID,不要修改代码硬猜。
/api/system/step-agent 和证据驾驶舱只有在真实调用成功、且结构校验和输出安全门均通过后才显示
VERIFIED;“已配置 Key”本身不会被当作模型运行证据。
RareLink 不尝试部署没有公开权重的 Step 3.7;本地推理使用一个可公开获取的 NVIDIA 支持模型,
默认配置为 nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-NVFP4。模型由 Spark 直接下载,
不通过 SSH/SCP 上传。120B 是本项目用于展示本地统一内存、NVFP4 和 TensorRT-LLM 的工程目标,
不是“已运行 200B”或医疗能力的声明。
先在 Spark 私有目录创建环境文件,写入自己的 Hugging Face token;该 token 不进入仓库、录屏、 日志或前端:
cp deploy/spark-local-llm.env.example .env.spark-local-llm
chmod 600 .env.spark-local-llm
# 编辑 .env.spark-local-llm:只设置 HF_TOKEN,不要提交该文件
set -a; source .env.spark-local-llm; set +a
bash scripts/start_spark_trtllm.sh另开一个 Spark 终端确认本地服务;服务只绑定 127.0.0.1:8355,不得将它暴露到公网:
curl -s http://127.0.0.1:8355/v1/models启动 RareLink 时选择路由模式:
# spark_local:只调用 Spark 本地模型,端点未启动时请求应失败而非外发
# hybrid:本地可用时优先本地;否则退回已经过同一策略脱敏的 Step 或模板
# step_remote:仅 Step;template:仅确定性模板
RARELINK_AGENT_BACKEND=hybrid
RARELINK_SPARK_LLM_BASE=http://127.0.0.1:8355/v1
SPARK_LLM_MODEL=nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-NVFP4完成一次合成聚合任务后,Agent 会在 artifacts/spark-local-inference/last-inference.json
写入不含提示词或回答正文的模型名、延迟、用量、策略类别和输出哈希。也可独立采集固定的
无患者数据探针:
python3 scripts/capture_spark_local_inference_evidence.py \
--output artifacts/spark-local-inference/last-inference.json控制台会把“LOCAL INFERENCE READY”与“CAPTURED”分开显示:前者只说明服务在线,后者才说明
已完成一次本地、受门控的工程推理。没有证据时页面明确显示 NOT CLAIMED。
随后运行本地网关红队。它复用 26 条固定 Agent 安全用例:12 条输入用例会先脱敏、再调用 本地模型;14 条输出用例验证后置门控。回执不包含原始攻击 payload、提示词或模型回答:
python3 scripts/run_spark_local_llm_redteam.py \
--model "$MODEL_HANDLE" \
--output artifacts/spark-local-inference/redteam-summary.json最后由独立核验器同时检查运行回执、GPU 快照与 26 条本地网关红队结果。该命令不会补造或
seed 任何本地模型证据:缺任一回执、没有 GPU 快照或检查未通过都会以非零状态退出。成功后才会
在驾驶舱显示 VERIFIED:
python3 scripts/verify_spark_local_inference_evidence.py \
--artifact-root artifacts --write这项证据是主评审一键复现包之外的可选实机加分项;它不会让没有启动本地模型的快速演示失败。
如需展示 Spark 的本地并发服务能力,可在核验通过后运行固定、无患者数据的小负载基准。它会测试
1 / 2 / 4 三个并发档位,每档默认 4 个短请求,并只记录延迟分位数、吞吐、用量及 GPU 快照:
python3 scripts/benchmark_spark_local_llm.py \
--model "$MODEL_HANDLE" \
--concurrency 1 2 4 --requests-per-level 4 \
--output artifacts/spark-local-inference/concurrency-benchmark.json驾驶舱仅在该实测文件存在时显示“固定安全负载峰值”。请按实际模型、并发、GPU 快照口播;不要将这 个小负载结果表述为 200B 能力、生产压测或医学性能。
该结果只能证明 RareLink 的输入/输出安全门控包围了已运行的本地端点,不能宣称已完成模型 越狱评估、渗透测试、医疗安全认证或临床验证。
.venv/bin/python scripts/prepare_demo_data.py \
--output data/runtime/synthetic-demo-v1 \
--cases-per-site 4 \
--shape 32 32 32产物包含三个逻辑站点、四模态 NIfTI、分割标签和 SHA-256 清单。所有内容均为合成数据。
先运行单站点 MONAI,验证 CUDA、数据管道和模型:
.venv/bin/python scripts/train_monai_smoke.py \
--manifest data/runtime/synthetic-demo-v1/manifest.json \
--site site-a \
--epochs 1 \
--output artifacts/monai-spark-smoke再运行三站点真实聚合:
.venv/bin/python scripts/run_nvflare_simulation.py \
--manifest data/runtime/synthetic-demo-v1/manifest.json \
--strategy fedavg \
--rounds 2 \
--local-epochs 1 \
--workspace artifacts/nvflare-spark-fedavg.venv/bin/python scripts/run_nvflare_simulation.py \
--manifest data/runtime/synthetic-demo-v1/manifest.json \
--strategy fedprox \
--fedprox-mu 0.01 \
--rounds 2 \
--local-epochs 1 \
--workspace artifacts/nvflare-spark-fedproxnum_threads=1 是有意设计:同一台 Spark 上的三个模拟院区顺序执行,防止三个 3D 模型同时
争抢统一内存。真实三院部署时,每院独立训练,服务器只聚合模型更新,因此 Spark 的优势是
大统一内存、本地隐私计算和多 Agent/训练任务协同,而不是网络带宽。
成功标准不是终端中出现 “finished”,而是工作目录中存在聚合后的全局 .pt 模型。运行脚本
已内置这一后置条件,缺失模型会直接报错并附带服务端日志尾部。
合成数据只证明系统链路可运行,不足以证明方案能处理真实的公开影像格式。比赛演示应增加 Medical Segmentation Decathlon(MSD)Task01_BrainTumour 的工程基准。它是公开研究数据, 仍然属于患者影像数据:仅作研究工程验证,不上传到仓库、不传给 Step API、不作诊断结论。
严禁通过 SSH/SCP 上传这个数据集或任何大模型。 在 Spark 节点的仓库目录直接执行:
sudo docker exec -it rarelink-api python3 scripts/prepare_msd_brain_tumour.py \
--data-root data/raw/msd-task01 \
--output data/runtime/msd-brain-tumour-v1 \
--cases-per-site 8脚本会在节点直接下载公开归档,校验发布的 MD5,再记录归档 SHA-256 和每个入选文件的 SHA-256。
它按肿瘤体素量的低、中、高三分位创建 site-a、site-b、site-c,每站抽取固定数量病例;
这是可重复的非 IID 模拟,不代表真实医院人群分布。MSD Task01 原始增强肿瘤标签 3 会映射为 2,形成
背景、病灶区域、肿瘤核心三个工程类别;映射会写入 manifest。
先做本地/集中式上界,再做两种联邦策略。下列每一条都会输出 Dice、HD95、运行时长、峰值显存; 联邦汇总额外输出平均 Dice、最弱站点 Dice 和站点方差。
# 单站点基线(分别执行 site-a、site-b、site-c)
sudo docker exec -it rarelink-api python3 scripts/train_monai_smoke.py \
--manifest data/runtime/msd-brain-tumour-v1/manifest.json --site site-a --epochs 2 \
--output artifacts/msd-local-site-a
# 仅用于科研对照的集中式上界;不是实际跨院部署路径
sudo docker exec -it rarelink-api python3 scripts/train_monai_smoke.py \
--manifest data/runtime/msd-brain-tumour-v1/manifest.json --site centralized --epochs 2 \
--output artifacts/msd-centralized
sudo docker exec -it rarelink-api python3 scripts/run_nvflare_simulation.py \
--manifest data/runtime/msd-brain-tumour-v1/manifest.json --strategy fedavg --rounds 3 \
--local-epochs 1 --workspace artifacts/msd-fedavg
sudo docker exec -it rarelink-api python3 scripts/run_nvflare_simulation.py \
--manifest data/runtime/msd-brain-tumour-v1/manifest.json --strategy fedprox --rounds 3 \
--local-epochs 1 --fedprox-mu 0.01 --workspace artifacts/msd-fedprox录屏时展示 manifest 中的来源、许可证、分区规则和哈希即可;不要展示切片、患者影像内容、原始 数据目录或任何可识别信息。MSD 的授权与引用要求应在最终提交材料中保留。
赛事节点已完成 7.1 GiB 归档校验、24 例四模态几何验证、单站 CUDA 冒烟训练和三个逻辑站点
一轮 FedAvg。NVFLARE 聚合 3/3 站点并持久化全局模型,端到端耗时 69.0084 秒,峰值 GPU
内存 5240.349 MiB。该记录是单轮工程验证,不是临床性能结果;完整过程、指标与边界见
outputs/RareLink-2026-07-20-MSD真实影像Spark联邦运行报告.md。
仓库提供 deploy/compose.spark.yml。它同时启动 API 与前端,并且只在缺少运行证据时加载一份
明确标记为 evidence_snapshot=true 的脱敏证据快照;快照不含患者数据、模型、证书、token 或 API Key,
不会覆盖 Spark 上已有的实测产物。
sudo docker compose -f deploy/compose.spark.yml up --build -d
sudo docker compose -f deploy/compose.spark.yml exec api python3 scripts/verify_demo_evidence.py --artifact-root artifacts --write该命令会核验 25 项稳定性试验、样本级 DP-SGD、两物理设备 mTLS 负面对照和 26 条 Agent 红队
用例。若已在本地虚拟环境开发,也可运行 bash scripts/review_demo.sh。完整评审说明见
DEMO.md。停止时执行:
sudo docker compose -f deploy/compose.spark.yml down该包用于审阅已有工程证据,不会自动下载公开影像数据或重新启动耗时训练。
容器模式下启动后端:
sudo docker run -d \
--name rarelink-api \
--network host \
--gpus all \
-e RARELINK_FL_MODE=nvflare \
-v "$PWD:/workspace" \
-w /workspace \
rarelink-spark:latest前端可使用宿主机 Node.js,也可使用 Node 容器。容器方式:
sudo docker run --rm \
--user "$(id -u):$(id -g)" \
-e HOME=/tmp \
-v "$PWD/apps/web:/app" \
-w /app \
node:20-alpine \
npm install
sudo docker run -d \
--name rarelink-web \
--network host \
--user "$(id -u):$(id -g)" \
-e HOME=/tmp \
-e RARELINK_API_PROXY=http://localhost:9000 \
-v "$PWD/apps/web:/app" \
-w /app \
node:20-alpine \
npm run dev -- --host 0.0.0.0 --port 8888原生虚拟环境方式如下。
终端一:
.venv/bin/python -m uvicorn rarelink.api.main:app --host 0.0.0.0 --port 9000终端二:
RARELINK_API_PROXY=http://localhost:9000 \
npm --prefix apps/web run dev -- --host 0.0.0.0 --port 8888使用赛事分配的公网映射访问对应端口。不要额外开放数据库端口;SQLite 文件、原始数据目录和
训练产物只保留在节点内。演示结束后移除 .env 中的密钥。
如果前端运行在独立容器内,可使用 host network,或将 RARELINK_API_PROXY 指向容器可访问
的后端地址。代理目标只用于 Vite 开发服务器,不会写入浏览器端 JavaScript。
公网端口用于比赛演示时,建议配置一次性演示访问码,避免陌生访问者直接调用研究 API。它是 轻量访问门,不是生产级身份认证;真实医院应接入院内 SSO、VPN、审计和最小权限控制。
# 仅放入节点 .env,不提交仓库,不使用 Step API Key 作为访问码
RARELINK_DEMO_ACCESS_TOKEN=replace-with-a-random-demo-code前端启动时以同一个临时值设置 VITE_RARELINK_DEMO_TOKEN。该值会随比赛前端构建被使用,因此
只应作为演示防护,不得视为高强度密钥;演示结束后立即撤销。/api/health、/docs 和
/openapi.json 保持可访问,其他 API 需要请求头 X-RareLink-Demo-Token。
故障演示时,可临时设置下列开关并重启 API。系统会在模型和数据处理之前写入一个安全的
模拟失败、将研究置为 FAILED_RETRYABLE,并保留任务、错误和审计事件。控制台的“重试失败的
真实训练任务”会创建一个新的可追溯任务;演示完成后必须删除该开关再重试。
RARELINK_SIMULATE_TRAINING_FAILURE=trueSpark 镜像固定安装 Opacus 1.6.0。三轮 DP-SGD 工程验证:
sudo docker exec -it rarelink-api python3 scripts/run_nvflare_simulation.py \
--manifest data/runtime/synthetic-demo-v1/manifest.json \
--strategy fedavg_dpsgd --rounds 3 --local-epochs 1 \
--dp-noise-multiplier 1.2 --dp-max-grad-norm 1.0 --dp-delta 0.00001 \
--workspace artifacts/nvflare-dpsgd正式矩阵意外中断后,使用同一参数和 --resume。脚本只复用已经写入
trial-records.json 的完整种子—策略组合;没有记录的失败项会重跑:
sudo docker exec -it rarelink-api python3 scripts/run_repeated_benchmark.py \
--manifest data/runtime/synthetic-demo-v1/manifest.json \
--seeds 2026 2027 2028 2029 2030 \
--strategies local fedavg fedprox fedavg_svt fedavg_dpsgd \
--rounds 3 --local-epochs 1 --resume \
--workspace artifacts/repeated-benchmarkLocal 基线会自动使用 rounds × local_epochs,与联邦客户端获得相同的本地 epoch 机会。若旧工作区
已经保存了预算未对齐的 Local 记录,追加 --rerun-strategies local,只替换 Local,不重跑联邦策略。
录屏时应同时展示:
- 三个逻辑院区的数据均为本地路径,未上传原始影像;
- Agent 自动生成协议、可行性分析、训练契约和报告;
- egress policy 拦截患者标识和小样本明细;
- NVFLARE 服务端日志显示三个站点均返回更新并完成聚合;
- FedAvg 与 FedProx 生成各自全局模型;
- 导出的研究包包含协议、契约、实验、审计日志和复现配置。
- 本地 TensorRT-LLM 面板显示模型、服务状态和一次不含提示词的本地推理回执;断开 Step 后,
用
RARELINK_AGENT_BACKEND=spark_local完成一次合成聚合任务,证明该步骤不依赖云端生成。
合成数据上的低 Dice 只代表极短工程冒烟,不得包装成医学效果。正式展示应强调“链路真实、 数据不出院、证据可审计”,而不是宣称临床准确率。
MSD 数据完成节点直连下载、MD5/SHA-256 校验与 manifest 分区后,运行下列命令只输出聚合的 格式/几何验证回执:病例数、站点数、四模态结构、几何一致性与来源哈希是否存在。回执刻意不含 病例 ID、路径、影像、标签、像素或文件哈希明细。
sudo docker compose -f deploy/compose.spark.yml exec api python3 scripts/validate_public_msd_benchmark.py \
--manifest data/runtime/msd-brain-tumour-v1/manifest.json \
--evidence-path artifacts/public-benchmark/msd-task01-validation.json控制台会在“Public NIfTI Intake”卡片显示该回执。该动作只证明公开 NIfTI 的本地 intake 与几何检查, 不等于公开数据上的联邦训练结果、儿童罕见病验证或临床效果。