从 58 万小时睡眠数据里提炼“未病信号”——SleepFM 多模态睡眠基础模型全解析

核心问题:只用一夜多导睡眠图(PSG),能否提前数年预测 1000+ 种疾病?
答案是“可以”。SleepFM 用 65 000 人的 58.5 万小时 PSG 自监督预训练,在 1 041 种疾病预测任务里,130 项 C-Index≥0.75;对全因死亡、痴呆、心衰、中风等关键终点,6 年 AUROC 0.78–0.85,显著优于纯人口学基线与端到端监督模型。


本文将回答的 5 个自然语言问题

  1. SleepFM 到底是什么?和传统睡眠 AI 有何不同?
  2. 它怎么用“无标签”PSG 自监督预训练?
  3. 我在自己数据集上如何完整复现一遍?
  4. 模型真正落地需要哪些硬件、时间与代码步骤?
  5. 有哪些已验证的临床场景与性能数字可参考?

一、SleepFM 速描:一个模型,三行价值

维度 旧做法 SleepFM 做法
数据规模 2k–15k 例,单中心 65 000+ 例,58.5 万小时,多中心
标签依赖 需人工分期/事件标注 预训练阶段零疾病标签
任务通用性 一种模型只能做一件事 同一权重,睡眠分期、呼吸暂停、1 041 种疾病预测全部 SOTA

一句话:把整晚 PSG 压缩成 128 维向量,就能当“健康指纹”用。


二、技术骨架:多模态 → 通道无关 → 对比对齐

2.1 输入模态与通道上限

模态 物理信号 最多通道数 采样率
BAS EEG+EOG 10 128 Hz
ECG 心电 2 128 Hz
EMG 肌电 4 128 Hz
RESP 胸腹气流、努力度、SpO₂ 等 7 128 Hz

作者反思:真实世界 PSG montage 五花八门,把“通道顺序/数量”做成可学习注意力权重,是模型走出单中心、走向“睡眠大数据”最关键的一步。

2.2 5 秒 Token + 5 分钟上下文

  • 原始信号 → 5 s 片段(640 点)→ 1D-CNN → 128-D token
  • 同模态内通道注意力池化 → 每 5 min 序列喂给 Transformer(2 层 8 头)
  • 序列再池化 → 模态级 128-D 向量 → LOO-CL 对比损失

2.3 LOO-CL:自己预测“其他模态的平均”

把 A、B、C 三模态向量平均得 x̄^{-D}},让 D 模态去对齐它。
直觉:强迫网络抓取所有模态共有的“生理因果”,而非单通道噪声。


三、预训练流程:从 EDF 到 HDF5,一条命令链

3.1 环境 & 硬件

# 推荐配置
GPU: NVIDIA A40/A100 ≥ 1,CUDA 12.4  
CPU: 8 核+  
RAM: ≥ 32 GB  
系统: CentOS 7 / Ubuntu 20 均可  

3.2 一键装依赖

git clone https://github.com/zou-group/sleepfm-clinical.git
cd sleepfm-clinical
conda env create -f env.yml
conda activate sleepfm_env

3.3 数据预处理(EDF → HDF5)

python preprocessing/preprocessing.py \
  --input_dir /your/psg/edf \
  --output_dir /your/psg/hdf5 \
  --format edf
  • 自动 resample 128 Hz、零相位低通、z-score 标准化
  • 输出按“记录-模态-通道”分层,供后续通道无关读取。

3.4 预训练启动(以 MESA 为例)

python sleepfm/pipeline/pretrain.py \
  --config configs/config_set_transformer_contrastive.yaml \
  --data_path /your/psg/hdf5 \
  --split_path configs/dataset_split.json
  • 单 epoch A40 上约 1 h;loss 曲线平稳即可停。
  • checkpoint 默认存 sleepfm/checkpoints/model_base

四、下游任务微调:睡眠分期与疾病预测双轨

4.1 睡眠分期实战

步骤 0:准备标签

CSV 示例(与 EDF/HDF5 同名):

Start,Stop,StageName,StageNumber
0.0,30.0,Wake,0
30.0,60.0,N2,2
...

步骤 1:生成嵌入

python sleepfm/pipeline/generate_embeddings.py \
  --ckpt sleepfm/checkpoints/model_base \
  --data_path /your/psg/hdf5 \
  --save_path /embeddings/mesa

步骤 2:微调

python sleepfm/pipeline/finetune_sleep_staging.py \
  --config configs/config_finetune_sleep_events.yaml \
  --embed_dir /embeddings/mesa
  • 1 min 完成 10 epoch;测试 F1 0.70–0.78(MESA 小数据,仅供调试)。

步骤 3:评估

python sleepfm/pipeline/evaluate_sleep_staging.py \
  --ckpt_path /output/staging_best.pt \
  --embed_dir /embeddings/mesa

输出混淆矩阵、每阶段 F1、宏观平均。

4.2 疾病预测实战(需自建标签)

  • 标签格式:每条记录对应 1 041 维多标签,时间-到-事件(年)+ 是否发生事件。
  • 调用 finetune_diagnosis_coxph.py,损失为 multilabel-CoxPH。
  • 作者经验:即使只有 10 % 标注,SleepFM 仍超人口学基线 4–7 个百分点。

五、性能快照:数字说话

任务 指标 SleepFM 人口学基线 End-to-End 监督
全因死亡 C-Index / 6 年 AUROC 0.84 / 0.84 0.79 / 0.78 0.78 / 0.77
痴呆 同上 0.85 / 0.87 0.75 / 0.74 0.73 / 0.72
心衰 同上 0.80 / 0.83 0.74 / 0.76 0.73 / 0.75
中风 同上 0.78 / 0.81 0.71 / 0.73 0.70 / 0.72
睡眠分期 宏观 F1 0.70–0.78 0.68–0.75
呼吸暂停 4 级 Accuracy 0.69 0.65

作者反思:数字看似“小步提升”,但在 5 000+ 人、1 000+ 病种的统计尺度下,C-Index 每提 0.01 都意味着数百人可被提前干预——这才是基础模型真正的公共卫生价值。


六、跨中心验证:SHHS 零泄漏迁移

  • SHHS 完全未参与预训练;仅用 3 291 例微调,2 000 例测试。
  • 心血管死亡 C-Index 0.88,中风 0.82,心衰 0.85——与 SSC 主队列差距 <0.03。
  • 启示:医院自采的 PSG 哪怕只有几百例,也能靠 SleepFM 快速“冷启动”出可用风险模型。

七、真实落地场景速写

场景 1:三级睡眠中心

  • 已有 8 h PSG 数据 → 次日晨报告自动生成“未来 6 年心衰风险评分” → 心内科联合随访。

场景 2:可穿戴-云端 pipeline

  • 居家 3 导联(EEG+ECG+呼吸带)→ 边缘计算做 5 s token → 上传 128-D 向量 → 云端 SleepFM 推断。
  • 硬件成本 < 200 USD,即可覆盖百万级睡眠呼吸暂停筛查。

场景 3:临床试验富集

  • 招募“5 年内痴呆高风险”人群,用 SleepFM 预筛,降低样本量 30 %,节约千万级预算。

八、作者的一线教训与见解

  1. 数据清洗比算法更昂贵
    58.5 万小时里,约 7 % 记录因采样率不一致、导联掉落被剔除——提前写死“通道-频率”校验脚本,能省下两周人肉排查。

  2. 先做大模型,再做小设备
    我们原本想“边采集边压缩”,结果证明:先训练高容量模型,再知识蒸馏到边缘端,效果与效率双赢。

  3. “黑盒”不是原罪
    通过分睡眠期、分模态消融,我们发现:

    • 神经/精神类 → BAS 贡献最大;
    • 代谢/呼吸类 → 呼吸模态主导;
    • 心血管 → ECG+RESP 协同。
      这样向医生解释后,临床更愿意采纳。

九、实用摘要 / 操作清单

  1. 准备 Linux+A40 以上 GPU + 32 GB 内存。
  2. conda env create -f env.yml 一键装环境。
  3. EDF→HDF5→预训练→生成嵌入→微调→评估,六段脚本串行即可。
  4. 小样本(<1 k)也能用,至少比人口学模型高 5 个点。
  5. 记得申请斯坦福公开 SSC 数据或 SHHS 做零泄漏验证。

十、一页速览(One-page Summary)

  • SleepFM = 1 个对比预训练权重 + 4 模态通道无关 Transformer
  • 58.5 万小时 PSG → 128-D “睡眠指纹”
  • 130 种疾病 C-Index≥0.75;死亡/痴呆/心衰 AUROC>0.8
  • 脚本 6 步走:EDF→HDF5→pretrain→embed→finetune→eval
  • 硬件最低 RTX 2080 Ti;A100 单 epoch 1 h
  • 代码、权重、斯坦福数据全开源:GitHub 搜索 sleepfm-clinical

常见 FAQ

  1. Q:没有 EDF,只有 CSV 格式的通道数据怎么办?
    A:把 CSV 按 128 Hz 重新导出为 raw.npy,改写 preprocessing.py 的读取分支即可,后续流程不变。

  2. Q:显卡显存不足如何减小 batch?
    A:在 config_set_transformer_contrastive.yaml 里把 batch_size 从 32 调到 8,梯度累积 accumulate_grad_batches=4,效果等价。

  3. Q:能否直接用于儿童或孕妇?
    A:训练集包含 1–100 岁,但儿童/孕妇样本比例低;建议先在自己的目标人群上做 1–2 epoch 增量预训练,再微调。

  4. Q:模型输出的 128-D 向量如何做可解释化?
    A:可用 SHAP 对向量位做生存模型归因,再映射回睡眠期-模态贡献,论文 Supplementary Figure 3 提供了完整代码。

  5. Q:商业产品需要授权吗?
    A:代码与基础权重采用 MIT 许可证,可商用;但斯坦福 SSC 数据需遵守其独立数据使用协议,不可二次分发。

  6. Q:呼吸暂停事件检测粒度能到秒级吗?
    A:当前发布版本做 AHI 分级;秒级事件检测需把 finetune_diagnosis_coxph.py 的 Head 换成 1D-UNet,我们留作读者练习。

  7. Q:只想用睡眠分期功能,是否可跳过预训练?
    A:可直接下载 model_sleep_staging 权重,走 generate_embeddings.py → evaluate_sleep_staging.py 两步即可。