| 名称 | nv-segment-ct-finetune |
| 描述 | 在CT NIfTI影像/标签数据集上运行NV-Segment-CT VISTA3D的标准或固定通道softmax微调,支持可选的MONAI原生MLflow跟踪和检查点证据。softmax用于预定义的互斥类别;当需要点提示或运行时变量类别时,保留标准工作流。不用于临床验证。 |
| 开源协议 | Apache-2.0 allowed-tools: Bash, Read, Write, WebFetch, Env metadata: |
| 作者 | “NVIDIA MedTech noreply@nvidia.com” tags: - MedTech - CT - finetuning - segmentation |
NV-Segment-CT 微调
目的
- 用于对 NV-Segment-CT VISTA3D 模型在 CT NIfTI 标签上进行冒烟测试或数据集微调,包括上游固定通道 softmax 工作流和可选的 MLflow 跟踪。不用于临床验证。
- 封装上游 MONAI bundle 入口点;请勿用手写的训练或推理代码替换它。
- 清单输入是
dataset_dir、datalist、target_anatomy、label_mapping、smoke、sanity、auto_seg、softmax、skip_formal_eval、mlflow_tracking_uri、mlflow_experiment_name和mlflow_run_name。 - 清单输出是
finetuned_ckpt和经过 schema 检查的result_json。
说明
- 运行
scripts/run_finetune.py;在正常技能使用中,不要修补bundle/或上游检查点下的文件。 - 对于独立 Bash,请在包装器之前添加全新环境设置行;基准 venv 启动时为空。
- 在仓库根目录运行已提交的脚本。不要将此技能复制到运行时目录,也不要在生成的调用中使用
rm或清理命令。 - 如果主机提供了
run_script,请使用run_script("scripts/run_finetune.py", args=[...]);否则从仓库根目录运行。 - 对于最短的工作流检查,请使用
--smoke;对于 MSD Task06 肺肿瘤复现,请使用--sanity。 - 基于以下标准在标准工作流和
--softmax工作流之间选择。不要将--softmax与--auto-seg或--sanity结合使用。 - 设置
--mlflow-experiment-name以在任一工作流的训练阶段启用 MLflow。--mlflow-tracking-uri和--mlflow-run-name需要实验名称。正式预/后评估不会收到 MLflow 凭据。 - 仅在需要 Task06 参考细节、输出字段定义或手动 bundle 设置说明时,才阅读
references/task06-and-results.md。
选择工作流
仅当以下所有条件成立时才使用 --softmax:
- 在训练前已知完整类别集,并且在推理请求之间不会变化。
- 标签是互斥的:每个体素是背景或恰好一个前景类别。
- 每个前景数据集标签都映射到现有的 VISTA3D 类别 ID,并且需要传统的固定通道输出。
如果必须保留点提示(point prompts)、推理时动态选择类别、标签可以重叠,或需要 Task06 --sanity 复现,请保持标准工作流。
对于 --label-mapping '[[1,3],[2,13]]',通道 0 是背景,通道 1 表示从 VISTA3D 类 3 初始化的数据集标签 1,通道 2 表示从 VISTA3D 类 13 初始化的数据集标签 2。使用生成的 model_softmax.pt 与上游 configs/inference_softmax.json 时,请保留条目及其顺序。nv-segment-ct 和 nv-segment-ctmr 推理技能目前不暴露该固定通道推理路径。
可用脚本
| 脚本 | 用途 | 参数 |
|---|---|---|
scripts/run_finetune.py |
skill_manifest.yaml 声明的主要入口点;暂存配置、运行 MONAI 并写入 output.json。 |
[FIXTURE_OR_DATASET] --output-dir OUT_DIR [--smoke] [--sanity] [--auto-seg] [--softmax] [--dataset-dir DIR] [--datalist JSON] [--target-anatomy TEXT] [--label-mapping JSON] [--patch-size JSON] [--mlflow-experiment-name NAME] [--mlflow-tracking-uri URI] [--mlflow-run-name NAME] |
先决条件
- Python 3.10+,GPU 运行需要支持 CUDA 的 Torch。
- 来自
skill_manifest.yaml的运行时包,特别是monai==1.4.0、numpy<2、nibabel、scipy、typer、PyYAML、fire、pytorch-ignite、einops和huggingface_hub。启用 MLflow 跟踪时,请安装mlflow>=2.10,<4。 - 可选环境变量:
CUDA_VISIBLE_DEVICES限制可见 GPU;NPROC_PER_NODE覆盖 GPU 数量,值>=2为非 sanity 运行选择多 GPU 模式;NVSEG_FINETUNE_AUTO_VENV=0禁用缓存的 MONAI 1.4 兼容环境。远程跟踪可能使用DATABRICKS_CONFIG_PROFILE、DATABRICKS_HOST、DATABRICKS_TOKEN、MLFLOW_TRACKING_CLIENT_CERT_PATH、MLFLOW_TRACKING_INSECURE_TLS、MLFLOW_TRACKING_PASSWORD、MLFLOW_TRACKING_SERVER_CERT_PATH、MLFLOW_TRACKING_TOKEN或MLFLOW_TRACKING_USERNAME;这些变量仅在显式启用 MLflow 时转发,且无关的凭据不会转发。 --softmax还需要固定的 NVIDIA-Medtech 源码检出。设置NV_SEGMENT_CT_ROOT指向其NV-Segment-CT目录,或设置NV_SEGMENT_CTMR_ROOT指向同级NV-Segment-CTMR目录。包装器会就地读取官方 softmax 配置和实现,并仅在--output-dir下写入生成的覆盖。- 副作用:在
skills/nv-segment-ct-finetune/bundle/configs/下写入生成的 bundle 配置,包括skills/nv-segment-ct-finetune/bundle/configs/auto_override.json、skills/nv-segment-ct-finetune/bundle/configs/train_continual_task06_lung.json和skills/nv-segment-ct-finetune/bundle/configs/dfw_no_logging.json;在--output-dir下写入检查点/证据;启用时在本地<output-dir>/mlruns写入跟踪数据;可能创建~/.cache/nvidia-skills/venvs/nv-segment-ct-finetune-monai14/下的 MONAI 兼容环境;可能缓存~/.cache/huggingface/下的模型资产;可能联系https://huggingface.co、https://raw.githubusercontent.com或显式启用远程跟踪时的https://<调用者提供的 mlflow-or-databricks-workspace>。
全新环境设置:
python -m pip install "monai==1.4.0" "numpy<2" pytorch-ignite einops nibabel scipy typer PyYAML fire huggingface_hub
启用 MLflow 跟踪时,还需要安装:
python -m pip install "mlflow>=2.10,<4"
已知上游兼容性约束:
- DFW Task06 参考:Python
3.10.16、MONAI1.4.0、Torch2.7.0+cu126。 - 对于冒烟、sanity 和证据运行,请使用精确的
monai==1.4.0;MONAI 1.5.x 可能会导致上游微调损失在布尔标签上崩溃。 - 不要在生成的命令中将依赖项浮动为
monai>=1.4,<1.6。 - softmax 工作流保留上游默认的 100 个 epoch 和学习率
1e-4,除非调用者覆盖它们。
一次性源码设置(适用于 --softmax):
export NV_SEGMENT_CTMR_COMMIT=cb921f5c58837c0f42a713855d68b32af88e1cdd
export NV_SEGMENT_CTMR_CHECKOUT="$HOME/.cache/nvidia-skills/upstreams/NV-Segment-CTMR-cb921f5"
if [ ! -d "$NV_SEGMENT_CTMR_CHECKOUT/.git" ]; then
git clone https://github.com/NVIDIA-Medtech/NV-Segment-CTMR.git "$NV_SEGMENT_CTMR_CHECKOUT"
fi
git -C "$NV_SEGMENT_CTMR_CHECKOUT" checkout --detach "$NV_SEGMENT_CTMR_COMMIT"
export NV_SEGMENT_CT_ROOT="$NV_SEGMENT_CTMR_CHECKOUT/NV-Segment-CT"
用法
冒烟级工作流检查:
python -m pip install "monai==1.4.0" "numpy<2" pytorch-ignite einops nibabel scipy typer PyYAML fire huggingface_hub && \
python skills/nv-segment-ct-finetune/scripts/run_finetune.py \
PATH_TO_DATASET \
--smoke \
--patch-size '[64,64,64]' \
--output-dir runs/nvseg_smoke
使用暂存数据集作为 PATH_TO_DATASET。对于微型夹具,使用 skills/nv-segment-ct-finetune/fixtures/spleen_micro。冒烟模式用于验证接线、配置生成、检查点加载和运行时兼容性;它不是质量基准。
MSD Task06 肺肿瘤 sanity 复现:
python skills/nv-segment-ct-finetune/scripts/run_finetune.py \
/path/to/Task06 \
--sanity \
--output-dir runs/nvseg_task06_sanity
Sanity 预设遵循单 GPU DFW 配方:折叠 0 验证、标签映射 [[1, 23]] 用于 lung tumor、自动类提示分割、patch [128,128,128]、5 个 epoch,以及训练前后的原始间距 configs/evaluate.json 评分。预期参考范围:预训练 Dice 约 0.6697,训练最佳 Dice 约 0.6905,微调后正式 Dice 约 0.6836。
用户数据微调:
python skills/nv-segment-ct-finetune/scripts/run_finetune.py \
--dataset-dir /path/to/dataset \
--datalist /path/to/datalist.json \
--target-anatomy "lung tumor" \
--auto-seg \
--epochs 5 \
--patch-size '[128,128,128]' \
--output-dir runs/nvseg_user_finetune
当本地标签值为自定义或解剖名称有歧义时,使用 --label-mapping '[[1, 23]]'。
可选的本地 MLflow 跟踪:
python skills/nv-segment-ct-finetune/scripts/run_finetune.py \
--dataset-dir /path/to/dataset \
--datalist /path/to/datalist.json \
--target-anatomy "lung tumor" \
--epochs 5 \
--mlflow-experiment-name nvseg-finetune \
--mlflow-run-name trial-01 \
--output-dir runs/nvseg_mlflow
这使用 MONAI 文档化的 --tracking mlflow 路径和内置的 rank-zero 处理器。如果没有 --mlflow-tracking-uri,数据会保留在 <output-dir>/mlruns。仅当打算远程跟踪时,才传递调用者批准的远程 URI(包括 databricks)。MLflow 不会改变 patch 大小、变换、优化器值、DataLoader 设置或其他训练配置。
固定通道 softmax 微调(用于互斥标签):
export NV_SEGMENT_CT_ROOT="$HOME/.cache/nvidia-skills/upstreams/NV-Segment-CTMR-cb921f5/NV-Segment-CT"
python skills/nv-segment-ct-finetune/scripts/run_finetune.py \
--dataset-dir /path/to/dataset \
--datalist /path/to/datalist.json \
--label-mapping '[[1,3],[2,13]]' \
--softmax \
--epochs 100 \
--output-dir runs/nvseg_softmax
这将委托给上游 configs/train_continual_softmax.json。它会产生 checkpoints/model_softmax.pt;源 model.pt 初始化网络,但不与 configs/inference_softmax.json 兼容。因此包装器在成功运行后建议使用生成的 softmax checkpoint。
示例
在暂存的小数据集上进行冒烟运行:
python skills/nv-segment-ct-finetune/scripts/run_finetune.py \
runs/with_vs_without_nv/_inputs/nv_segment_ct_finetune/input_dataset \
--smoke \
--patch-size '[64,64,64]' \
--output-dir runs/nvseg_smoke
在本地 MSD 缓存上进行 Task06 sanity 运行:
python skills/nv-segment-ct-finetune/scripts/run_finetune.py \
.workbench_data/datasets/Task06_Lung \
--sanity \
--output-dir runs/nvseg_task06_sanity
数据契约
- 首选布局:
dataset/imagesTr/*.nii.gz和dataset/labelsTr/*.nii.gz。 - 标签必须按 basename 与图像一一对应。
- 训练标签中必须存在目标标签值。
- 当患者级划分很重要时,请使用 datalist。bundle 默认
fold为0,因此fold: 0条目用于验证,所有其他 fold 用于训练。 - 每个训练的前景标签必须映射到
bundle/label_dict.json中现有的 VISTA3D 全局类别 ID;此技能无法发明新类别。 - 在
--softmax模式下,第一个映射列是保存的数据集标签,第二个是预训练的 VISTA 类别 ID。映射顺序固定通道布局,在推理期间必须保持不变。
结果
首先检查运行目录中的 output.json:
formal_pretrained_val_dice和formal_finetuned_val_dice:启用正式评估时的原始间距前/后分数。training_start_val_dice、val_dice_per_epoch和training_best_val_dice:训练时验证轨迹。finetuned_ckpt_matches_pretrained_weights:当val_at_start=true时,检测标准工作流的 epoch-0 检查点陷阱;softmax 使用不同的检查点架构。recommended_ckpt:要保留的检查点。在未检查记录的工作流和指标时,不要盲目使用最后一个 epoch、model_finetune.pt或model_softmax.pt。invocation.mlflow_tracking:选定的跟踪 URI、实验名称和可选运行名称;如果禁用跟踪,则为null。runtime.oom、runtime.peak_gpu_mb和阶段日志:区分 OOM、慢验证和进程故障。
决策规则:如果存在正式原始间距前/后分数,则优先采用;对于 sanity 恢复,拒绝张量相同的“微调”检查点;将 improved: false 视为有效证据,而不是包装器失败。
限制
- 薄包装器。训练、验证、变换和检查点保存都委托给
bundle/中的上游 bundle。 - 仅复现记录:成功的五 epoch Task06 运行在单块 NVIDIA RTX 6000 Ada 48 GB GPU 上使用了 Python
3.12.3、PyTorch2.12.0+cu130,CUDA13.0、MONAI1.4.0、NumPy1.26.4、PyTorch-Ignite0.5.4、NiBabel5.4.2、SciPy1.16.0、einops0.8.2、Fire0.7.1、Hugging Face Hub0.36.2、Transformers4.57.6、Typer0.25.1、PyYAML6.0.3和 MLflow3.14.0。这些版本记录了证据环境;它们不是额外的包约束,也不是声称其他版本无法工作。 - 自动推导的计划是启发式的;调用者提供的
--patch-size、--cache-rate、--epochs和--learning-rate优先。 --softmax与--sanity不兼容:Task06 参考分数和原始间距前/后评估属于标准 VISTA3D 持续学习工作流。Softmax 运行记录训练验证轨迹,但在质量声明之前需要单独的任务特定评估。- Task06 sanity 配方有意强制单 GPU 执行以匹配 DFW 参考。其他数据集的多 GPU 模式需要主机
torchrun支持。 - 配对的验证器仅 CPU,审计证据包;不会重新运行 GPU 分割。
- MLflow 支持是可选的,并使用 MONAI 内置跟踪处理器。跟踪错误是上游 MONAI 运行的一部分,因此可能导致微调命令失败。
- 不用于临床部署、临床解释、自主诊断或监管提交。
故障排除
| 错误 | 原因 | 修复 |
|---|---|---|
| 缺少依赖或导入错误 | 与 skill_manifest.yaml 存在运行时漂移。 |
安装上述包或使用文档化环境。 |
| Task06 预训练 Dice 低 | 配置错误、检查点错误、数据划分漂移或依赖漂移。 | 在更改训练逻辑之前,比较环境字段和暂存配置。 |
model_finetune.pt 与预训练匹配 |
val_at_start=true 将 epoch 0 选为最佳。 |
使用 recommended_ckpt;除非更改后的检查点提高正式 Dice,否则将 sanity 恢复视为失败。 |
| 缺少正式 Dice 字段 | 正式评估失败或跳过。 | 检查 eval_pretrained.log、eval_finetuned.log 和 metrics.csv。 |
| GPU 内存不足 | patch/缓存设置过大。 | 减小 --patch-size、降低 --cache-rate 或减少工作线程。 |
| 无验证案例 | datalist 缺少 fold: 0。 |
至少提供一个验证条目。 |
--softmax requires the pinned ... checkout |
八月 softmax 配置/实现缺失或检出位于不同提交。 | 检出 cb921f5c58837c0f42a713855d68b32af88e1cdd 并设置 NV_SEGMENT_CT_ROOT 或 NV_SEGMENT_CTMR_ROOT。 |
| MLflow 跟踪失败 | MLflow 缺失、凭据无效或实验不可访问。 | 检查 finetune.log,修复 MLflow 客户端配置并重新运行;省略 --mlflow-experiment-name 以禁用跟踪。 |
验证
当涉及质量门时,运行已实现的验证器:
python -m eval_engine.run_trusted skills/nv-segment-ct-finetune \
--fixture skills/nv-segment-ct-finetune/fixtures/spleen_micro \
--out runs/nvseg_trusted