关于 model-scaffold
model-scaffold 是面向医学影像研究的技能,可生成可复现的 PyTorch 训练项目。它支持六类任务,并内置患者级数据划分、确定性随机种子和训练规范检查。
主要功能
- 01六类医学影像任务模板
- 02患者互斥的确定性划分
- 03带随机种子的训练与评估代码
- 04影像质控报告交接
- 05训练规范验证
适用场景
- 01从含患者 ID 的清单创建影像模型项目
- 02在临床数据上微调预训练骨干网络
- 03检查生成代码的可复现性保障
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ aperivue/ medsci-skills --skill model-scaffold安装后在 Claude Code 中输入/model-scaffold确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
skill.ymlreferences/finetuning_guide.mdmlops_guide.mdtraining_guide.mdscripts/check_training_hygiene.pyscaffold.pyscripts/scaffold_challenge/problem.mdverify.shscripts/scaffold_challenge/expected/split_assignment.csvscripts/scaffold_challenge/fixture/manifest.csvtests/test_imaging_qc_handoff.shtest_training_hygiene.shtests/fixtures/bad_evaluate.pybad_train.pytests/fixtures/finetune_no_provenance/train.py详细介绍
模型脚手架技能
用途
此技能可为医学影像任务生成一个可运行的 PyTorch 训练仓库——--task 可选 segmentation(U-Net)、classification(CNN / timm 主干网络)、detection(torchvision Faster
R-CNN / FPN)、synthesis(Pix2Pix 生成器 + PatchGAN)、ssl(SimCLR 编码器)或 finetune
(迁移学习:使用预训练主干网络,按冻结→解冻计划训练,并记录来源)——从设计上就内置了可复现性保障,因此在运行第一个 epoch 之前,构建过程就能避免数据泄漏并确保可复现。它相当于 /analyze-stats 生成可运行统计代码在影像领域的对应方案:生成器负责生成仓库,你在 GPU / Colab 上运行训练,而该流程的确定性门禁会验证无需联网的部分。
它是该流程中缺失的中间环节:/model-selection(选择)→ model-scaffold(构建)
→ /model-assessment(验证划分 / 设计,计算指标)→ /analyze-stats
→ /write-paper + /check-reporting(发布)。它会集成 MONAI / nnU-Net / TorchIO(在生成的 requirements.txt 中引用),而不是重新实现这些工具。
适用场景
- 你已有数据清单(每张图像一行,并包含患者 / 受试者 ID),想为分割、分类、检测、合成或自监督模型创建一个可复现且避免数据泄漏的起始仓库。
- 你想微调预训练主干网络(迁移学习——临床医生常见的工作流:将
timm/ MONAI / MedSAM 检查点适配到你收集的临床数据),并记录冻结计划、差异化学习率和预训练权重来源(--task finetune)。
不适用场景
- 审查已训练模型的验证设计 →
/model-assessment。 - 留出集指标 / 校准 / bootstrap 置信区间 →
/model-assessment,然后/analyze-stats。 - 为研究问题选择架构 →
/model-selection。 - 重新实现 MONAI / nnU-Net → 不在范围内(此脚手架会集成这些工具)。
- LLM / MLLM 评估 →
/mllm-eval。
工作流
阶段 1 — 准备数据清单
准备一个 CSV,其中每张图像占一行,并包含患者 / 受试者 ID 列(patient_id / subject_id /
case_id),以及图像和标签路径列。ID 列至关重要:划分会依据此列在患者级别进行。划分时以及生成的 dataset.py 中,都会先去除 ID 首尾的空白字符,再进行比较(P01 和
P01 会被视为同一位患者)。
阶段 2 — 生成代码仓库
python3 ${CLAUDE_SKILL_DIR}/scripts/scaffold.py \
--manifest <manifest.csv> --task segmentation --out model_repo --seed 42 \
--in-channels 1 --out-channels 1
# --task = segmentation | classification | detection | synthesis | ssl | finetune
# (out-channels = num classes for classification/finetune, target channels for synthesis;
# finetune uses a softmax CrossEntropy head, so it refuses --out-channels < 2 — binary = 2)
# fine-tuning a pretrained backbone (transfer learning) on collected clinical data:
python3 ${CLAUDE_SKILL_DIR}/scripts/scaffold.py \
--manifest <manifest.csv> --task finetune --out model_repo --seed 42 \
--out-channels <num_classes> --from-pretrained timm:resnet50.a1_in1k
# emits PRETRAINED.md (provenance) + a frozen→unfrozen train.py with discriminative LRs;
# record the exact pretrained source so the fine-tune is reproducible. build_model(pretrained=True)
# raises if timm is missing (never a silent random-init stand-in); best.pt records backbone_class.
# reuse the split /imaging-data's preprocessing gate checked (do not draw a new one):
python3 ${CLAUDE_SKILL_DIR}/scripts/scaffold.py \
--manifest <manifest.csv> --preprocessing-manifest preprocessing_manifest.json --out model_repo
# copies its split_assignment + split_seed into splits/, reading rows with the gate's own rules
# (patient key patient_id/subject_id/patient/id; split synonyms such as training/validation/holdout);
# exits 2 if a manifest patient has no split there, a patient sits in two splits, a split does not
# map to train/val/test, or split_seed is absent.
影像数据 QC 交接是强制执行的,不是建议。 使用 --preprocessing-manifest 时,脚手架还会从 <manifest dir>/qc/ 和 <manifest dir>/../qc/(先解析清单路径)读取 /imaging-data 的门控报告(check_dataset_profile、check_preprocessing_leakage、check_normalizer_domain JSON)。--imaging-qc <file|dir>(可重复指定)会取代上述搜索:如果指向空目录,则每个门控项都会记录为 NOT ASSESSED。只有在泄漏报告记录的清单文件名不同、解析后指向一个现有文件,且没有候选路径保存着与脚手架生成的清单逐字节相同副本时,才会跳过该报告(同时显示原因);其他情况——例如复制的项目,或其他位置存在同名清单——都会读取。
- Major 声明——或任何明显不属于 Minor/Flag 的严重级别,或
summary.n_major大于报告中列出的 Major 数量——都会导致拒绝:退出码为 1,不写入任何内容,并列出每个代码和报告。在上游解决问题并重新运行门控,或针对每个代码传入一次--ack-qc CODE='reason'。 - Minor / Flag 声明不会阻止操作;它们会作为警告一并保留。
- 没有可读取报告的门控项会标记为 NOT ASSESSED;
qc/中无法解析或格式不符的文件会列为 UNREADABLE(stderr + 记录),绝不会被丢弃。
所有内容都会写入 model_repo/IMAGING_QC.md,并在 config.yaml(imaging_qc:)和 REPRODUCIBILITY.md 中引用,因此训练、评估和 Methods 都能读取 /imaging-data 检查出的内容。绝不要编造用户未提供的 --ack-qc 原因。不使用这两个标志时,输出保持不变。
这会生成 model_repo/,其中包含 config.yaml、model.py(任务模型 — U-Net / CNN / Faster R-CNN / Pix2Pix / SimCLR 编码器)、dataset.py(读取冻结的数据划分)、losses.py(适用于任务的损失函数)、train.py、evaluate.py、requirements.txt、REPRODUCIBILITY.md、methods_stub.md(提供 imaging-data 输出时还会生成 IMAGING_QC.md),以及关键产物——splits/split_assignment.csv + splits/split_seed.txt。数据划分在设计上确保患者互不重叠(确定性的分组划分);生成的代码会为每个 RNG 设置种子、启用 cuDNN 确定性模式、仅使用训练集构建训练数据加载器,并在 model.eval() + torch.no_grad() 下进行推理。
阶段 3 — 验证构建(无需网络)
# this skill's own training-hygiene gate
python3 ${CLAUDE_SKILL_DIR}/scripts/check_training_hygiene.py --repo model_repo --strict
# the split-leakage gate (proves patient disjointness) — owned by /model-assessment
将生成的 splits/split_assignment.csv 传给 /model-assessment(check_split_leakage.py --splits model_repo/splits/split_assignment.csv --strict),以证明患者互不重叠;还可以选择在本地安装 torch 后运行 bash ${CLAUDE_SKILL_DIR}/scripts/scaffold_challenge/verify.sh,对前向传播进行冒烟测试。
阶段 4 — 接入数据并训练
根据数据模态实现 dataset.py 的 _load_image / _load_label(通过 nibabel / pydicom / tifffile / TorchIO / MONAI transforms 处理 DICOM / NIfTI / TIFF)。生产环境中,将 model.py 替换为 MONAI UNet / SegResNet 或 nnU-Net 方案(参见 ${CLAUDE_SKILL_DIR}/references/training_guide.md)。对于微调代码仓库(--task finetune),请填写 PRETRAINED.md 并设置冻结计划 / 差分学习率(参见 ${CLAUDE_SKILL_DIR}/references/finetuning_guide.md,其中也介绍了 MedSAM/SAM 适配和仅训练阶段使用的扩散增强)。运行 python train.py(在验证集上选出最佳模型),然后运行 python evaluate.py(在测试集上生成预测,仅执行一次)。
阶段 5 — 验证、评估、发布
移交给 /model-assessment(验证层级 + 比较器 + 指标选择审计;Dice +
HD95/NSD 及其置信区间)+ /analyze-stats、/make-figures 和 /write-paper
(填写 methods_stub.md 中的 [VERIFY] 占位符)+ /check-reporting(CLAIM 2024 / TRIPOD+AI)。有关实验跟踪(W&B / MLflow)、配置 / 数据 / 环境版本控制以及 MLOps 报告清单的可复现安全配置方法,请参阅 ${CLAUDE_SKILL_DIR}/references/mlops_guide.md
(配置 + 报告参考指南——它会指向相应框架,但不会取代它们)。
可运行性 — 诚实的约定
生成的仓库可运行,但可运行性不受 CI 保证。默认门禁通过解析生成的产物,验证不依赖网络的属性(生成的数据划分按患者隔离且使用固定随机种子;生成的训练代码符合规范)——不会执行 torch。torch 前向传播冒烟测试
(build + forward shape + gradients flow + reproducible loss)是 challenge verify.sh 中的自动跳过层级,也是有文档说明的本地命令;它绝不会被计为可运行性的 CI 覆盖。
防止幻觉
- 绝不捏造训练或评估指标。 脚手架会生成
[VERIFY]占位符;所有数值都必须来自用户实际执行的运行以及/model-assessment+/analyze-stats。 - 绝不生成未按患者隔离或未锁定随机种子的数据划分。 生成器在构造时就保证这一点;不要手动编辑划分表来引入重叠或移除随机种子。
- 绝不声称生成的仓库已训练或取得了某项结果——它只是供用户运行的起点。
- 如果不确定某个库的 API、默认值或架构细节,请标记
[VERIFY]并询问,而不要猜测。
确定性门禁
scripts/scaffold.py— 生成器(使用标准库 + numpy;给定清单 + 随机种子时具有确定性);也是影像数据 QC 移交入口(tests/test_imaging_qc_handoff.sh)。scripts/check_training_hygiene.py— AST 代码检查器:所有随机数生成器均已设定种子、cuDNN 具有确定性、推理使用eval()+no_grad()、不在非训练数据划分上训练,以及(微调时)加载预训练权重后记录其来源信息 (PRETRAINED_PROVENANCE_MISSING)。scripts/scaffold_challenge/verify.sh— 构建 → 验证流程,不依赖网络(torch 层级会自行跳过)。
check_training_hygiene.py 的已知局限
- 它只会在从脚本导入时语句可达的代码中检查随机种子 / cuDNN /
eval()/no_grad()。如果某个文件没有在导入时调用自身函数,则会检查所有未被引用的公开顶层函数,因此此类文件中未被调用的公开seed_everything仍会被计入。每个带装饰器的函数或方法(click/typer 命令、路由、@staticmethod)也都是入口点,因此未被调用的带装饰器随机种子辅助函数仍会被计入。 - 它不检查语句顺序:不会检测同一函数中的推理代码是否位于
model.eval()之前。 - 没有
train.py/evaluate.py的--repo会将相应检查报告为 NOT CHECKED;使用--strict时会以状态码 2 退出,而不是将其判定为通过。 - 数据集变量在整个文件中通过一个名称到数据划分的映射解析(按源码顺序以较后的赋值为准),而非按作用域解析;不会标记将训练集与验证集组合在一起的打乱数据加载器(训练集 + 验证集再拟合)。
边界
model-selection (choose)
└─ model-scaffold (this skill: generate the reproducible repo)
├─ check_training_hygiene.py (training-code hygiene)
├─ model-assessment -> analyze-stats (split-leakage proof, validation design, metrics + CIs)
└─ write-paper + check-reporting (Methods stub -> compliant manuscript)