Diffusers
ophthalmology
OCT
fundus
medical-imaging
diffusion
stable-diffusion-3
segmentation
instruction-tuning
Instructions to use MaybeRichard/OCTFlow with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Diffusers
How to use MaybeRichard/OCTFlow with Diffusers:
pip install -U diffusers transformers accelerate
import torch from diffusers import DiffusionPipeline # switch to "mps" for apple devices pipe = DiffusionPipeline.from_pretrained("MaybeRichard/OCTFlow", dtype=torch.bfloat16, device_map="cuda") prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" image = pipe(prompt).images[0] - Notebooks
- Google Colab
- Kaggle
OCTFlow v1 (2026-06-21): 13 weights (core+downstream) + S0-S7 report + experiment log; public release
941b719 verified OCTFlow 下游评测 — 实验日志(整段会话整理)
- 模型:SD3-medium(KL-VAE 16ch + 2B MMDiT,rectified flow)+ Vision-Banana 式指令微调
- 环境:8× NVIDIA L20Y 80GB(
h800,共享);base conda(torch2.10 / diffusers0.37 / sklearn / timm / smp / lpips);HF_HUB_OFFLINE=1 - 基座:
sd3_multimodal_base_v2/step-0240000.pt(探针 + 生成)、指令模型sd3_vb_stageC_v3a/step-0030000.pt、层分割锚sd3_vb_layer_100k/step-0030000.pt - 交付:
reports/octflow_downstream_report.html(§0–§7,宽屏,~20MB) + 本日志 - 总基调:逐维度诚实压到 competitive-非-SOTA;唯一独占能力 = 零样本指令泛化(§7) + 可共享数据。
一、实验时间线与结果
§2 多任务分类探针(14 任务 / 7 backend,冻结特征线性探针)
- 动机:作为眼科 foundation,对标 RETFound/MIRAGE/VisionFM/DINOv2/DINOv3。
- 方法:冻结编码器特征 + 线性探针;本会话从 7 任务扩到 14(+OCT-C8 8类/OCTDL/OCTID/Srinivasan/NEH/OLIVES/Messidor),头部 backend(ours/DINOv2/RETFound)3-seed。
- 结果(14 任务平均 top1):DINOv2 0.849 ≥ RETFound 0.844 ≥ ours 0.837 > DINOv3 0.824 > MIRAGE 0.808 > VisionFM 0.796 ≫ 随机 0.621。
- 结论:ours 第 3/7,落后 leaders 仅 ~0.01,但 14 任务逐项排名都 #2–#5、无一第一(MIRAGE 拿多数 OCT、DINOv2 拿眼底/UWF)。competitive-非-SOTA;远超只训 OCT 的 MIRAGE/VisionFM(它们在眼底/UWF 崩、我们三模态不崩)。
§3 分割:本模型 vs 公平微调 FM vs 监督 U-Net
- 关键修正:原先 FM 基线是冻结探针(eval@224)=不公平下界,导致"碾压 FM"的错误结论。本会话改成 端到端微调 FM(编码器解冻 + 稠密解码头 + CE+Dice,eval@512,3-seed,
fm_seg_ft.py)。 - 结果(miou_fg,ours vs 最强微调FM vs U-Net):9层 0.53 / 0.59 / —;血管 0.51 / 0.51 / 0.66;OCTA大血管 0.53 / 0.50 / 0.61;FAZ 0.66 / 0.72 / 0.70;积液 0.63 / 0.66 / 0.78;视盘杯盘 0.74 / 0.80 / 0.79;OCTA500 0.82 / 0.84 / 0.85。
- 结论(诚实,推翻旧版):公平后 ours 多数任务略逊于为单任务单独微调的最强 FM(尤 DINOv2,差 0.03–0.09),仅 OCTA 大血管领先、血管打平;团块任务微调 FM 常反超 U-Net;细血管两者都低于 CNN U-Net(ViT patch 分辨率瓶颈)。
§4 去噪:本模型(生成式)vs 公平微调 FM
- 方法:FM 也端到端微调 + L1+LPIPS(
fm_denoise_ft.py)。 - 结果:微调 FM 的 PSNR/SSIM 反而 ≥ 我们(MIRAGE-FT 28.2dB/0.77 vs 我们 27.6/0.71);我们只在感知 LPIPS 占优(0.135 vs 0.37–0.41,约 3×)。
- 修复:对比图里 FM 列伪彩 = 我的解码头预测 3 独立通道,对灰度 OCT 无约束。改为预测 1 通道亮度→复制 3 通道,全列通道差归 0。
§5 生成式数据增广(分类)
- 方法:
train_classifier.py加--mode aug(计数对齐的强经典增广对照);real / +经典增广 / +合成(我们 base 生成)× 数据量 × 3-seed。 - 结果:Kermany(易,95%):+合成 > 仅真实(+0.5)但 ≈ 经典增广;EyePACS DR 分级(难,50–66%):+合成 ≈ 仅真实、**明显输给经典增广(−1.6 平均)**。
- 结论:纯靠合成"涨点"不成立(易任务≈、难任务<经典增广)。
§6 生成式语义合成增广(分割,最完善范式)
- 方法:训 mask→image 生成器(
train_vb_sd3.py --mask2img:条件=彩色层图、生成=OCT;warmstart Stage A*;12k 步);用真 GT 掩膜(零噪声)生成多样外观 OCT →(真掩膜+合成图)对;ResNet-50 U-Net,real/经典增广/合成 × 标注预算 × 3-seed。 - 结果(miou_fg,N=100/250/500/1000):仅真实 14.5/25.3/27.3/45.5;+经典增广 18.3/31.7/49.0/56.6;+合成 18.6/32.4/38.5/54.2。+合成远好于不加(+4
+11),但 vs 经典增广:**低标注(100/250)打平、高标注(500/1000)输 −2−10**。 - 结论:即便最完善范式,合成增广"涨点"≈/<经典增广、不稳超越。
§7 零样本指令泛化(护城河,核心成果)
- 方法:
zeroshot_spectrum.py— 同一指令模型(只训 9/5/3 层),测训练从未见过的层数(8/7/6/4/2,加进seg_schemes.SCHEMES但不在SCHEME_WEIGHTS→训练永不采样)。 - 结果(N=120,miou_fg):见过均值 0.430 vs 未见均值 0.441(未见甚至略高);跨设备零样本 OCTA500 二值视网膜 IoU 0.897、5 类 mIoU 0.480。montage 肉眼可见层数随 prompt 从 9 带变到 2 区、几何保留。
- 结论:模型按 prompt 组合层数、非记忆。判别式 FM / U-Net 单一固定输出头做不到;换分割方案它们要重训一个网络,我们换一句 prompt 即可。这是论文真正且唯一独占的差异化。
二、失败 / 负结果 / 踩坑(诚实记录)
推翻的旧结论(本会话纠正)
- "生成式分割/去噪碾压 FM" → 仅因 FM 用了冻结探针;公平微调后多数任务略逊。
- hero 能力矩阵"分割顶尖 / 去噪第一" → 同因,需改/降级。
- "合成增广是真卖点(mixed>real)" → 旧单 seed 无对照夸大;严谨后 ≈/<经典增广。
- "线性探针打赢 RETFound" → 仅 kermany 单任务偶然;扩到 14 任务后 competitive-非-SOTA。
关键踩坑(供后续自检)
- 协议不对等:冻结探针 vs 端到端微调是巨大不公平(细血管 0.0→0.5);对比必须同协议。
- 饱和任务掩盖效应:kermany 95% 几乎无头部空间,增广效应测不出;难/低标注任务才显。
- 去噪伪彩:灰度模态别预测多通道,要 1 通道→复制。
- 半写 ckpt 竞态:16GB ckpt 写盘中被
ls -t|head -1读到 → "failed finding central directory";评测/生成前应确认 ckpt 写完(本会话靠"评测在训练后串行"+ §6 加sleep 40规避)。 - 掩膜粒度:mask→image 生成要用完整 9 层掩膜(与配对的 GT 标签一致),否则细层不匹配。
- DINOv2 分辨率:probe 用 224、其他处 518,注意一致性。
三、成功 / 正向结论
- §7 零样本指令泛化:未见层数 ≈ 见过(0.44/0.43)+ 跨设备 0.90 — 唯一独占能力,硬证据。
- 公平、诚实、完整的下游基准:§0–§7,全部带对照、多 seed(头部)、宽屏报告。
- mask→image 生成器:可生成匹配 9 层几何的真实 OCT(语义合成可行)。
- 统一基座:一个模型换 prompt 覆盖 生成 + 全部分割方案(含未见)+ 去噪。
四、诚实定位(论文叙事骨架)
单一生成式指令通才:逐任务 competitive-非-SOTA(分类/分割/去噪/增广都不是单点夺冠),但 ①统一基座一个 prompt 覆盖生成+7类分割+去噪;②零样本指令泛化(§7,判别式做不到);③可共享/可定制数据(隐私/补稀有类)。冲 Nature 的核心 = ②+③+覆盖面,而非任何单点 SOTA。
五、后续计划
- 手稿对齐(最高优先):把诚实结论同步进
octflow_main.tex—— 砍掉"碾压 FM / 分割去噪第一 / 增广真卖点"等过度声明;把 §7 零样本指令泛化立为主结果 + hero 矩阵据实重画。 - 临床(用户侧,外部 gate):多中心外部验证 + 医生 reader study(Nature 硬门槛)。
- 可选:补 octa/oct_enface 数据后重训分清两者(task #51,等医院数据);§7 再加单层选择/色彩跟随两条指令轴做厚。
- 磁盘清理:见下,~1TB 中间权重待清(需确认)。
六、产物 / 文件清理摘要
- 脚本(本会话,均
pilot/path1/scripts/foundation/或scripts/):fm_seg_ft.py/fm_denoise_ft.py(公平微调 FM)、train_vb_sd3.py --mask2img、gen_mask2img.py、compare_panels_ft.py/compare_denoise_ft.py、train_classifier.py(+aug/+label)、build_seg_aug_manifests.py、unet_seg_baseline.py(+strong-aug)、zeroshot_spectrum.py、multitask_probe.py(+7任务)、build_multitask_report.py(§0–§7)、各run_*.sh。 - 代码审查:无规则违反(
weights_only=False全部到位)、无致命 bug(实验均验证通过);仅robustness 提示(半写 ckpt 竞态、硬编码路径、seg_schemes.SCHEMES加了 eval-only 未见方案)。 - 磁盘清理(已执行 A+B,2026-06-21):
results/1.5T → 396G(释放 ~1.1T)。删 61 个中间步 ckpt(每个实验仅留最新/锚点)+ 2 个被取代的整目录(sd3_vb_vessel原始、sd3_vb_lesion_fluid)。保留:base_v2/240k、stageA_v3/20k、stageC_v3a/30k、layer_100k/30k、layer_100k_v3b/15k、mask2img/12k、long_9mod/150k、各下游 _100k/_v3b 最新(step-4000)、foundation/(24G 结果 json+图)。未删 Tier-C(privacy_gen×3 / denoise_ft / stageC_v3b2,用户选择保留)。脚本/tmp/cleanup_ckpts.sh(留存可复核)。