Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

Review Assignment Due Date

MedCLIP MindSpore Migration

本仓库基于原始 MedCLIP 项目进行课程迁移实践:保留原 PyTorch 代码,同时新增一套 MindSpore 版本实现,用于复现 MedCLIP 的医学图文对比学习主链路。

原论文:

Wang, Zifeng; Wu, Zhenbang; Agarwal, Dinesh; Sun, Jimeng. MedCLIP: Contrastive Learning from Unpaired Medical Images and Texts. EMNLP 2022.

论文链接:MedCLIP paper

项目目标

MedCLIP 的核心任务是学习胸部 X 光图像与放射报告/疾病提示语之间的共享语义表示,用于零样本疾病识别、图文检索、少样本迁移和后续医学影像分析。相比普通 CLIP,MedCLIP 需要处理医学场景中的几个特殊问题:

  • 医学图像与报告常常不是完整一一配对数据。
  • 胸片疾病标签是多标签、多病灶、多不确定性监督。
  • 不同患者可能具有相同影像发现,普通 InfoNCE 容易制造伪负样本。
  • 报告文本含否定、不确定性、历史比较和专业医学术语。

本项目的迁移重点不是简单替换 API,而是尽可能保留原 MedCLIP 的数据处理、图文编码、语义匹配损失、训练、评估、checkpoint 和最终验收逻辑。

仓库结构

.
├── medclip/                         # 原始 PyTorch MedCLIP 代码,保留用于对照
├── medclip_ms/                      # 新增 MindSpore 迁移实现
│   ├── constants.py                 # CheXpert 标签、图像尺寸、默认权重名等常量
│   ├── dataset.py                   # 图文训练集、zero-shot 验证集、collator、batch loader
│   ├── evaluator.py                 # binary / multiclass / multilabel 指标评估
│   ├── image_processing.py          # X-ray 图像读取、灰度化、padding、resize、归一化
│   ├── losses.py                    # hard CLIP loss 与 MedCLIP soft semantic matching loss
│   ├── modeling_medclip.py          # MindSpore 双塔模型、prompt classifier
│   ├── prompts.py                   # CheXpert 疾病 prompt 构造
│   ├── tokenization.py              # simple tokenizer 与 MindNLP tokenizer 适配
│   ├── trainer.py                   # MindSpore value_and_grad 训练循环
│   └── utils.py                     # context、seed、Tensor 转换等工具
├── examples/
│   ├── run_medclip_pretrain.py      # 原始 PyTorch 训练入口
│   ├── run_medclip_ms_pretrain.py   # MindSpore 训练/评估入口
│   └── run_medclip_torch_baseline.py# PyTorch baseline 指标导出入口
├── tools/
│   ├── prepare_medclip_data.py      # 官方 CheXpert/MIMIC 数据准备与 metadata 校验
│   ├── preflight_migration_run.py   # 云端运行前环境/数据/依赖预检
│   ├── convert_torch_medclip_to_mindspore.py # PyTorch 权重到 MindSpore ckpt 转换
│   ├── export_torch_checkpoint_to_npz.py     # PyTorch 权重导出为 npz 桥接格式
│   ├── run_migration_acceptance_pipeline.py  # PyTorch-vs-MindSpore 验收流水线
│   ├── audit_migration_acceptance.py         # 最终指标/manifest/转换报告审计
│   ├── verify_evaluator_parity.py            # 指标口径一致性验证
│   └── verify_mindspore_migration.py         # 静态迁移校验
├── requirements.txt                 # 原始 PyTorch 依赖
├── requirements_ms.txt              # MindSpore 迁移版依赖
├── MINDSPORE_MIGRATION.md           # MindSpore 快速说明
└── MINDSPORE_CODE_GUIDE.md          # 迁移代码详细说明

MindSpore 迁移架构

MindSpore 版本采用并行包设计:medclip/ 保留原 PyTorch 实现,medclip_ms/ 实现 MindSpore 复现链路。这样既方便逐文件对照,也避免破坏原仓库结构。

整体数据流如下:

official CSV / images / reports
  -> ImageTextContrastiveDataset / ZeroShotImageDataset
  -> ImageTextContrastiveCollator / ZeroShotImageCollator
  -> NumPy batch
  -> tree_to_tensor
  -> MindSpore Tensor batch
  -> MedCLIPModel
  -> ImageTextContrastiveLoss
  -> Trainer.value_and_grad
  -> optimizer update
  -> Evaluator
  -> metrics + manifest + checkpoint

1. 数据处理

medclip_ms/dataset.py 对齐原 MedCLIP metadata 约定,训练 metadata 需要包含:

  • imgpath
  • report
  • CheXpert 14 个标签列

训练样本输出:

image:      float32, shape (1, 224, 224)
report:     str
img_label:  float32, shape (14,)
text_label: float32, shape (14,)

图像预处理位于 medclip_ms/image_processing.py:

image path / PIL image
  -> grayscale
  -> pad to square
  -> resize to 224 x 224
  -> center crop / train augmentation
  -> normalize
  -> output shape (1, 224, 224)

文本处理位于 medclip_ms/tokenization.py。正式可比实验使用 --backbone mindnlp,加载 MindNLP 的 BioClinicalBERT/Swin 等资产;simple 后端只保留为开发调试路径,不作为最终提交说明中的性能复现方案。

2. 模型前向

medclip_ms/modeling_medclip.py 实现 MindSpore 版本 MedCLIPModel:

pixel_values -> vision encoder -> projection -> L2 normalize -> img_embeds
input_ids    -> text encoder   -> projection -> L2 normalize -> text_embeds
img_embeds x text_embeds -> logits_per_image

返回字段与原 CLIP/MedCLIP 风格保持一致:

img_embeds
text_embeds
logits
loss_value
logits_per_text

3. 语义匹配损失

medclip_ms/losses.py 中的 ImageTextContrastiveLoss 支持两种模式:

hard CLIP:
  image_i <-> text_i

soft MedCLIP:
  label_sim = img_labels @ text_labels.T
  target = softmax(label_sim)
  loss = bidirectional soft cross entropy(logits, target)

第二种模式对应 MedCLIP 的关键思想:不是简单把非配对样本全部当负样本,而是根据疾病标签语义构造软目标,从而缓解医学图文对比学习中的伪负样本问题。

4. 训练器

medclip_ms/trainer.py 使用 MindSpore 原生训练方式:

forward_fn
  -> mindspore.value_and_grad
  -> clip_by_global_norm
  -> optimizer(grads)
  -> periodic evaluation
  -> save mindspore_model.ckpt

训练结束后会再次运行 evaluator,并将最终评估结果写入 metrics_json。这比只记录训练中间日志更适合做 PyTorch-vs-MindSpore 最终验收。

5. 评估器与 manifest

medclip_ms/evaluator.py 支持:

  • binary
  • multiclass
  • multilabel

MindSpore 入口可以输出:

  • eval_scores.json
  • run_manifest.json
  • mindspore_model.ckpt

run_manifest.json 会记录 framework、backbone、device、数据列表、初始化方式和 metrics 来源,用于最终审计比较。

环境安装

PyTorch 原始版本

如果只运行原始 MedCLIP:

pip install -r requirements.txt

原始 PyTorch 代码中部分路径依赖 CUDA,建议在 NVIDIA GPU 环境运行 PyTorch baseline。

MindSpore 版本

先安装与目标运行环境匹配的 MindSpore。不同硬件需要匹配不同 wheel、CANN 或 CUDA 版本,建议以 MindSpore 官方安装选择器为准:

https://www.mindspore.cn/install

随后安装本项目 MindSpore 依赖:

pip install -r requirements_ms.txt

如需正式可比训练的 --backbone mindnlp:

pip install mindnlp

云端运行前自检

1. 静态迁移校验

该脚本用于检查源码结构、关键 API 和数据契约,提交前可作为静态质量检查:

python tools/verify_mindspore_migration.py

2. 云端依赖与数据预检

在正式训练前,先检查 MindSpore、MindNLP、metadata 和图像路径是否齐全:

python tools/preflight_migration_run.py \
  --check_mindspore \
  --require_mindnlp \
  --check_mindnlp_assets \
  --data_root ./local_data \
  --sample_images 20 \
  --report_json ./migration_acceptance/preflight_mindspore_report.json

3. 指标口径一致性校验

用于确认 MindSpore evaluator 的 acc、precision、recall、F1 等计算口径与 PyTorch-style 公式一致:

python tools/verify_evaluator_parity.py

官方数据准备

本仓库不包含真实 CheXpert/MIMIC-CXR 图像和报告。需要先按官方要求申请授权并下载数据:

  • CheXpert: Stanford AIMI / CheXpert 官方入口
  • MIMIC-CXR-JPG 与 MIMIC-CXR reports: PhysioNet credentialed access

查看数据准备说明:

python tools/prepare_medclip_data.py instructions

CheXpert metadata

python tools/prepare_medclip_data.py build-chexpert-meta \
  --chexpert_csv /path/to/CheXpert-v1.0-small/train.csv \
  --chexpert_root /path/to/CheXpert-v1.0-small \
  --absolute_imgpaths \
  --data_root ./local_data \
  --report_json ./local_data/chexpert_meta_report.json

MIMIC-CXR metadata

python tools/prepare_medclip_data.py build-mimic-meta \
  --mimic_jpg_root /path/to/mimic-cxr-jpg/2.1.0 \
  --mimic_report_root /path/to/mimic-cxr/2.1.0 \
  --data_root ./local_data \
  --frontal_only \
  --absolute_imgpaths \
  --report_json ./local_data/mimic_meta_report.json

训练前 metadata 校验

python tools/prepare_medclip_data.py validate-medclip-metadata \
  --data_root ./local_data \
  --sample_images 20 \
  --report_json ./local_data/metadata_validation_report.json

如果 CSV 中 imgpath 是相对路径,增加:

--image_root /path/to/dataset-root

MindSpore 训练

正式 MindSpore 训练

使用已授权真实数据,并启用 MindNLP backbone:

python examples/run_medclip_ms_pretrain.py \
  --device_target Ascend \
  --mode pynative \
  --backbone mindnlp \
  --vision_model vit \
  --data_root ./local_data \
  --train_data chexpert-train mimic-cxr-train \
  --eval_data chexpert-5x200-val \
  --batch_size 100 \
  --eval_batch_size 256 \
  --epochs 10 \
  --lr 2e-5 \
  --weight_decay 1e-4 \
  --warmup 0.1 \
  --eval_steps 1000 \
  --save_steps 1000 \
  --n_prompts 10 \
  --save_best_model \
  --load_best_model_at_last \
  --output_path ./checkpoints_ms/vision_text_pretrain \
  --metrics_json ./checkpoints_ms/vision_text_pretrain/eval_scores.json \
  --manifest_json ./checkpoints_ms/vision_text_pretrain/run_manifest.json

如果在 NVIDIA GPU 的 MindSpore 环境:

--device_target GPU

Eval-only 测试

已有 MindSpore checkpoint 时,可以直接评估:

python examples/run_medclip_ms_pretrain.py \
  --device_target Ascend \
  --mode pynative \
  --backbone mindnlp \
  --vision_model vit \
  --data_root ./local_data \
  --eval_only \
  --checkpoint ./checkpoints_ms/vision_text_pretrain/mindspore_model.ckpt \
  --eval_batch_size 256 \
  --n_prompts 10 \
  --metrics_json ./checkpoints_ms/eval_only/eval_scores.json \
  --manifest_json ./checkpoints_ms/eval_only/run_manifest.json \
  --output_path ./checkpoints_ms/eval_only

PyTorch baseline

为了证明迁移质量,需要在同一数据、同一超参和同一初始化策略下跑 PyTorch baseline。入口如下:

python examples/run_medclip_torch_baseline.py \
  --device cuda:0 \
  --vision_model vit \
  --data_root ./local_data \
  --train_data chexpert-train mimic-cxr-train \
  --eval_data chexpert-5x200-val \
  --batch_size 100 \
  --eval_batch_size 256 \
  --epochs 10 \
  --lr 2e-5 \
  --weight_decay 1e-4 \
  --warmup 0.1 \
  --eval_steps 1000 \
  --save_steps 1000 \
  --n_prompts 10 \
  --output_path ./migration_acceptance/torch \
  --metrics_json ./migration_acceptance/torch/eval_scores.json \
  --manifest_json ./migration_acceptance/torch/run_manifest.json

PyTorch 权重转 MindSpore

为了保证 PyTorch 与 MindSpore 使用同一初始化来源,可以先把 PyTorch checkpoint 导出为 npz,再转成 MindSpore .ckpt。

python tools/export_torch_checkpoint_to_npz.py \
  --torch_checkpoint ./migration_acceptance/torch/initial_pytorch_model.bin \
  --output_npz ./migration_acceptance/torch/pytorch_model.npz \
  --report_json ./migration_acceptance/torch/pytorch_model.npz.report.json
python tools/convert_torch_medclip_to_mindspore.py \
  --torch_checkpoint ./migration_acceptance/torch/pytorch_model.npz \
  --output_ckpt ./migration_acceptance/mindspore/converted_from_torch.ckpt \
  --vision_model vit \
  --backbone mindnlp \
  --validate_load \
  --report_json ./migration_acceptance/mindspore/converted_from_torch.report.json

转换报告会记录:

  • 源参数数量
  • 目标 MindSpore 参数数量
  • 成功映射数量
  • 未匹配参数
  • 歧义参数
  • match_ratio
  • validate_load_result

这一步用于防止静默错映射。

最终验收流水线

tools/run_migration_acceptance_pipeline.py 会按同一配置生成 PyTorch 与 MindSpore 的完整验收命令。默认先预览命令;确认无误后加 --run 才会执行。

python tools/run_migration_acceptance_pipeline.py \
  --data_root ./local_data \
  --work_dir ./migration_acceptance \
  --convert_checkpoint \
  --use_npz_bridge \
  --check_mindnlp_assets \
  --torch_python /path/to/torch-env/bin/python \
  --mindspore_python /path/to/mindspore-env/bin/python \
  --converter_python /path/to/mindspore-env/bin/python \
  --checkpoint_exporter_python /path/to/torch-env/bin/python \
  --audit_python /path/to/base-env/bin/python

确认后执行:

python tools/run_migration_acceptance_pipeline.py \
  --run \
  --data_root ./local_data \
  --work_dir ./migration_acceptance \
  --convert_checkpoint \
  --use_npz_bridge \
  --check_mindnlp_assets \
  --torch_python /path/to/torch-env/bin/python \
  --mindspore_python /path/to/mindspore-env/bin/python \
  --converter_python /path/to/mindspore-env/bin/python \
  --checkpoint_exporter_python /path/to/torch-env/bin/python \
  --audit_python /path/to/base-env/bin/python

最终审计命令:

python tools/audit_migration_acceptance.py \
  --data_root ./local_data \
  --torch_metrics ./migration_acceptance/torch/eval_scores.json \
  --mindspore_metrics ./migration_acceptance/mindspore/eval_scores.json \
  --torch_manifest ./migration_acceptance/torch/run_manifest.json \
  --mindspore_manifest ./migration_acceptance/mindspore/run_manifest.json \
  --conversion_report ./migration_acceptance/mindspore/converted_from_torch.report.json \
  --min_conversion_match_ratio 0.95 \
  --metric_tolerance 0.0 \
  --report_json ./migration_acceptance/audit_report.json

审计工具会检查:

  • metadata 是否齐全
  • 采样图像路径是否可解析
  • PyTorch/MindSpore metrics 是否存在
  • 两侧 manifest 是否同协议
  • 初始化来源是否一致
  • metrics 来源是否为训练后评估
  • checkpoint 转换报告是否达标
  • MindSpore 指标是否达到比较要求

常见问题

找不到图像文件

如果 metadata 中 imgpath 是相对路径,使用:

--image_root /path/to/dataset-root

数据加载器会尝试多个候选路径,并在失败时给出清晰错误。

--backbone mindnlp 加载失败

优先检查:

  • 是否安装 mindnlp
  • 是否能访问模型权重
  • 云端缓存中是否已有 BioClinicalBERT / Swin 权重
  • MindSpore、MindNLP、CANN/CUDA 版本是否匹配

正式训练前建议运行:

python tools/preflight_migration_run.py \
  --check_mindspore \
  --require_mindnlp \
  --check_mindnlp_assets \
  --data_root ./local_data \
  --report_json ./migration_acceptance/preflight_mindspore_report.json

云端预检通过但真实训练失败

通常优先检查:

  • local_data/sentence-label.csv 是否存在
  • 训练 metadata 是否有 report 列
  • 是否包含 CheXpert 14 个标签列
  • imgpath 是否可通过 --image_root 定位
  • 云端是否有真实图像文件和报告文件

提交与数据边界

作业仓库只应提交源码、配置和面向真实数据的说明文档,不应提交真实医学数据、临时 checkpoint、运行缓存、报告渲染中间文件、本机运行截图、合成/伪造数据产物,或只服务于个人机器临时验证的脚本。

已在 .gitignore 中排除:

local_data
synthetic_medclip/
checkpoints_ms*/
migration_acceptance*/
report_assets/
report_rendered_pages*/
report.docx
report.pdf
tools/verify_mindspore_runtime.py
*.ckpt
*.bin

本 README 中的训练和验收命令均面向授权真实数据及云端可复现实验,不包含合成数据生成、伪造数据构造或仅能在本机自证的运行流程。

参考

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages