LLM+卫星遥感:实现疾病爆发提前两周预警的完整实践 去年年中团队接到一个很折腾的需求结合LLM和卫星遥感数据做一个能提前两周预判疾病爆发的系统。最开始大家都不太看好——卫星看到的是地表环境信号疾病爆发是公共卫生事件中间隔着一条很长的因果链。但几个月的实践做下来我们发现这种组合不仅能跑通而且比传统单一序列模型更适合真实预警场景。这篇文章不聊论文式的漂亮话只讲我们实际踩过的坑、选过的型、以及最终运行的完整pipeline希望给做遥感应用、公共卫生预警和时序预测的人一点参考。1. 项目整体思路与方案选型1.1 为什么卫星数据能进入疾病预测先回答最核心的问题卫星数据凭什么能预测疾病。传染病爆发并不是随机事件尤其对虫媒传染病和水源性疾病来说环境因子几乎决定了传播链的每一环。降雨增加会带来积水和植被生长蚊虫繁殖量随之上升温度偏高会让蚊虫发育周期缩短病原体在外潜伏期也会缩短水体面积变化则直接改变人群接触受污染水源的概率。这些驱动因子是可以用光学遥感连续观测的。我们最终选定的变量组包括归一化植被指数NDVI、地表温度LST、归一化水体指数NDWI以及降雨距平。中分辨率光学遥感数据大概在10到30米空间分辨率重访周期一周左右。它们不是直接检测病原体而是刻画“适合爆发的环境状态”。对区域级预警来说这种信号已经足够形成稳定的先行指标。举个例子某热带地区的蚊媒传染病有明显的季节规律旱季结束、雨季刚开始后的4到6周病例数会集中上升。遥感数据里的NDVI和NDWI在这个窗口里会提前出现异常抬升。这个时间差本质上就是预警窗口的来源。所以我们常说提前两周不是模型凭空算出来的而是环境因子本身比病例统计走得快我们要做的是把这个时间差稳定地捕获下来。1.2 LLM在这个任务里到底扮演什么角色LLM的职责在项目里被反复讨论过。最初有同事建议直接把遥感影像丢给多模态大模型让它看图预测疾病。试过之后发现完全不可用——单张影像信息密度太低模型只能看到云的纹理和地表色块根本无法理解时序变化更谈不上预测。后来我们调整了设计思路LLM不是预测数值的主体而是多源信号的语义融合器。具体的工作方式是一个轻量化的时序编码器先把过去8周的环境特征压成向量再通过映射层变成语言模型的输入与此同时区域档案和历史爆发记录通过检索增强方式拼进上下文。模型在给定环境背景的情况下输出结构化的风险概率和简短解释。这样做的好处是LLM可以调用预训练阶段积累的流行病学、生态学常识把离散的数据特征转换成可解释的判断而不是像黑盒模型那样只输出一个数字。从工程角度看选择LLM还有一个很实际的理由少样本和域外泛化。传统LSTM在某个区域指标很好换一个区域效果就崩而语言模型在预训练里见过大量环境-疾病关系的文本描述微调后能更快适应新区域。我们在两个不同气候特征的区域上做过迁移测试LLM混合架构的掉点幅度明显小于纯时序模型。1.3 方案对比与最终取舍做方案评审时我们列过几条路线经典SIR模型、表格型机器学习模型、纯时序深度模型以及LLM混合架构。SIR模型需要准确的病例基数和传播参数在数据稀疏地区完全推不动XGBoost能处理表格特征但无法融合非结构化的历史档案和事件描述LSTM擅长时序可输出天生不可解释公共卫生专家不敢直接采信。方案多源数据融合可解释性跨区域泛化落地成本SIR模型弱较强但依赖参数假设差中XGBoost中等弱一般低LSTM中等弱中等中LLM混合架构强强较好高LLM混合架构不是所有指标都碾压它计算成本高、调试复杂但输出天然是决策者能看懂的语言。考虑到预警系统的最终用户是疾控人员而不是算法工程师可解释性决定了这套系统能不能真正落地。这个取舍是我们在项目里最看重的一次选择。2. 数据获取与特征工程细节2.1 卫星数据源与预处理流程数据源方面我们用的是公开的中分辨率光学遥感产品空间分辨率10到30米重访周期5到7天。考虑到云污染和多云天气影响单日影像经常残缺所以统一按周做合成处理。选择周合成本身不是精度最优而是为了和疾病周报的时间粒度对齐。预处理流程大概分五步一是几何配准到统一网格二是云掩膜把不满足质量条件的像元剔除三是计算NDVI、NDWI等指数四是按行政区划或固定网格做聚合五是计算距平和历史百分位数。距平这一步非常关键因为植被绝对值在不同生态区差异很大直接用NDVI数值跨区域比较会产生严重误导。我们采用的是“当前值与过去5年同期均值的比值”比如NDVI_ratio1.35表示植被异常偏高35%。气象数据用的是公开再分析网格产品变量选了降水距平和温度距平。这些数据没有卫星那么高的空间分辨率但胜在时间连续、滞后小。我们把两类数据统一重采样到同一套网格上每个区域最终形成一张特征表行是周列是NDVI、NDWI、LST、降雨距平、温度距平等。2.2 环境特征构造与标签设计标签的定义要非常小心。我们的目标是风险等级而不是精确的病例数。对每个区域先把过去5年同期的周病例数做成一个基线如果当前周病例数低于基线75分位定义为平静高于95分位定义为爆发。中间状态虽然存在但为了避免标注噪声建模时只保留0和1两类样本。构造特征时的关键设计是滞后窗口。疾病从环境暴露到发病有潜伏期病例上报再到进数据库又有报告延迟。以蚊媒疾病为例最佳关联窗口通常在降雨事件后的4到8周。所以我们用当前周往前推2周到8周的滑动窗口作为输入特征相当于给模型一个时间记忆。还有一个很多人忽略的点预测目标不是当周而是未来第2周。假设今天是第t周公开病例数据通常到t-2周才完整我们要给出的是t2周的风险等级。模型能看到的最新信息是t-2周而预测目标在t2周中间隔了4周。这个间隔不是凭空留出的延迟而是疾病潜伏期、报告延迟和决策提前量的叠加。特征工程必须严格服从这个时间轴。2.3 数据泄漏与滞后窗口控制这个领域最隐蔽的坑是数据泄漏。我见过一个方案随机把样本分成训练集和测试集AUC能到0.94换成时间验证立刻跌到0.7。原因很简单同一个区域相邻几周的样本高度相关随机划分相当于让模型“抄近道”从训练集里的邻近时间推断验证集。我们改成按时间前向验证用前4年训练最近1年测试并且保证训练集中任何样本的时间戳都早于验证集。这样才能评估真实部署效果。另外不建议用过细的网格颗粒度做样本比如每个1公里网格当独立样本相邻网格互相传染评估结果虚高。最终我们选择县域级聚合一个区域一个时间点作为一个样本。注意做时间序列预测时数据泄漏比模型选型更容易毁掉项目。离线指标漂亮但上线失效多数不是模型问题而是数据时间轴没对齐。3. 模型架构与训练过程3.1 LLM输入构造遥感时间序列如何token化LLM输入构造是整个方案里最需要花心思的地方。直接输入原始浮点数序列语言模型无法理解如果硬转成自然语言长句又容易丢失数值范围。我们实践下来有两个有效方案建议组合使用。方案A是基于文本的语义token序列。每个区域每周生成一条记录形如AREA_207|WEEK_23|NDVI_ratio_1.18|LST_anomaly_0.9|NDWI_ratio_1.42|precip_anomaly_0.78连续8条记录拼成一个上下文输入。为了让模型理解数值指标需要先做分箱比如ratio高于均值0.5个标准差时定义为moderate_high高于1.5个标准差时定义为very_high。直接用原始数字也可以但分箱后的token更稳定也能避免模型对小数精度过度敏感。方案B是embedding映射。用一个轻量GRU把每周的特征向量编码得到8个隐状态再用一个线性层映射到语言模型输入空间的维度作为soft token插入到prompt中。方案B在指标上略好但隐状态不透明可解释性差一些。最终我们采用双通道设计文本token给模型读取向量token帮模型把握数值细节两者拼接后一起训练。3.2 训练策略冻结主干、LoRA与检索增强基础模型选了一个7B参数级别的开源语言模型冻结大部分参数只加LoRA适配。选择冻结的原因很简单显存和稳定性。当时只有两张24GB显卡全参数微调7B模型非常勉强而且容易出现灾难性遗忘。LoRA的秩设为16alpha为32dropout为0.05实际更新的参数不到总量的0.5%。训练目标是双任务联合。第一个任务是区域周序列的风险二分类输出logit损失函数为交叉熵第二个任务是生成最多20个词的解释句子用语言模型损失。总损失按0.8和0.2加权。权重倾斜给分类任务因为预警系统第一追求是判断准理由文本是辅助产物不能让它带偏主目标。RAG检索增强在这个项目里不是可选项。每个区域的历史爆发记录是一堆非结构化文本比如“某年雨季第20周开始出现聚集病例当时NDVI异常偏高”。预训练模型并不知道这些本地档案。推理时我们根据当前特征序列在历史档案库中做向量检索取最相似的3条事件片段拼接到提示词里让模型参考过去类似环境条件下发生了什么。这一步做完少样本场景下的表现提升非常明显。提示词模板大致长这样你是一个区域疫情风险研判助手。 请根据以下8周环境特征判断目标区域未来第2周的爆发风险。 【环境特征】 ... 【历史相似事件】 ... 只输出JSON格式包含risk_probability和evidence两个字段。训练时也套用这个模板避免推理和训练分布不一致。3.3 超参数设置与基线对比训练超参数方面输入序列长度128batch size 8学习率2e-4使用余弦调度训练10个epoch并加了早停。因为样本量不大网络容易过拟合我们还对历史样本做了随机dropout操作只保留对分类最有用的特征。评估指标除了AUC和F1额外定义了一个“提前两周命中率”在验证集所有爆发事件中系统在真正爆发前14天到前10天窗口内发出高风险的占比。这个指标比AUC更贴合业务判断价值。模型AUCF1提前两周命中率逻辑回归0.620.4138%XGBoost0.680.4944%LSTM0.730.5552%LLM混合方案0.810.6461%数值上LLM混合方案比LSTM高出约8个点的AUC这个差距在公共卫生预警场景里已经很有意义。更重要的是同一个模型可以输出证据链让基层防疫人员知道是降雨异常还是水体变化触发了预警这完全改变了系统在业务侧的使用方式。4. 实操过程与踩坑记录4.1 数据对齐与滞后效应的坑第一版pipeline里我们直接以自然周作为连接键把卫星周合成数据、气象数据和病例数据放在一起训练。离线验证表现很好但部署到试运行环境后频繁出现“预测今天但特征实际来自未来”的错位。原因是病例数据入库有延迟不同区域延迟天数不一样统一按自然周拼接时某些区域已经把未来一周的病例当成历史数据用了。解决办法是建立一张数据可用性日历每个区域、每个变量都记录最新更新时间所有特征读取统一通过“到t-2周为止”的视图。虽然牺牲了一点数据新鲜度但换来了时间坐标的绝对一致。后来所有模型和统计脚本都只读这个统一视图不再直接访问原始表。第二个坑是卫星重访周期与云遮蔽。热带雨季经常连续几天乌云光学影像一周合成后仍有空洞。我们最初只用光学数据某个月NDVI特征缺失率高达40%。后来加入了不受云影响的数据源来估测降雨和土壤湿度才把特征连续性问题解决。不要迷信单一卫星数据源缺失率超过20%时模型很容易学到虚假的周期性模式。4.2 LLM幻觉与概率校准问题试运行阶段我们发现如果允许模型用自然语言输出“高风险”它看起来很有道理实际却很危险。同一个区域模型可能因为一条模糊的“水体指数偏高”就给出90%的风险但特征里的水体指数其实只比历史均值高一点点。LLM天然倾向于生成更像人话的结论而不会严格反映数据。解决办法有三步。第一把风险判断从文本生成中剥离模型先输出logit理由部分由另一个任务头生成但这个任务头被训练成只能从固定的变量列表里挑选证据词。第二对模型输出的logits做温度缩放校准。我们在验证集上找到合适的温度系数是0.75校准后模型在低风险区间不再过度自信。第三增加一个规则校验层如果模型输出的证据变量在最近8周特征里没有超过设定阈值就拒绝该条理由并要求重新生成。这三步做完人工抽检50条证据链完全可追溯的比例从68%提升到了93%。这里想提醒一句不要单纯依赖模型的可解释性。如果解释是模型现编的还不如没有。公卫人员只要发现一次解释与实际数据对不上就会对整个系统失去信任。4.3 算力、部署与批量推理训练阶段用两张24GB显卡LoRA加半精度跑单个区域数据约需6小时全量区域约20小时。部署阶段做了三个关键压缩模型量化到6bit精度几乎没有下降推理速度提升约2倍输入序列长度从128降到64因为8周窗口本身内容不多再长没有额外收益批量推理时把相同模板的prompt拼接在一起一次前向处理32个区域。最终单卡平均每秒能处理约40个区域样本全部几百个区域的预警一轮推理大约10秒对周级预警来说完全够用。推理时关闭随机采样使用贪心解码max_tokens设为64。理由文本不需要很长超过20个词的内容基本都是废话。提示词生成必须固定模板不要每次加随机前缀否则同一份特征在不同时刻可能得到不同结果。5. 结果表现与应用场景5.1 一个雨季预警的实际案例说一个符合实际模式的案例。某热带地区在2023年雨季初期系统在第22周对北部一个区域输出风险概率0.83证据链是连续8周降水距平超过历史90分位NDWI异常抬升并且与2021年一次爆发前的环境特征序列相似度排名第一。当时当地病例数据还没有明显上升趋势人工判断认为只是普通雨季。到了第24周该区域报告病例数快速上升到基线3倍左右实际爆发时间比我们的预警晚了约15天。单案例说明不了全部问题但试运行期内系统标记的高风险区域实际发生爆发的命中率约62%而随机预警只有不到30%。更让我在意的是基层人员的反馈。以前收到红色预警时不知道具体要做什么现在系统会给出“水体面积异常扩大建议关注周边积水区”这类具体指向巡逻和灭蚊工作可以提前布置。从风险分数到行动指令的闭环才是预警系统真正的价值。5.2 预警结果如何在公卫决策中落地系统最终输出三类交付物。第一类是区域风险热力图决策层能一眼看到重点区域。第二类是每个高风险区域的关键因子排序判断这次预警主要由温度还是降雨驱动。第三类是可执行建议。建议动作由预先定义的事件-行动映射表生成不是LLM自由发挥。比如当降雨距平和NDWI同时偏高时映射表会自动附加“加强周边积水清理”和“提前补充检测试纸”两条动作。LLM负责解释为什么规则表负责做什么两者分工明确。这样既发挥了语言模型的推理和表达能力又用规则限制了它自由发挥的风险。5.3 当前局限与后续扩展方向必须承认这套方法有边界。对没有明显环境驱动、主要通过人传人的呼吸道疾病卫星变量贡献有限模型表现会退化到接近随机。对从未出现过的新型疾病RAG检索不到历史相似事件LLM只能靠模糊的先验知识给参考。空间分辨率也决定了它不适合做街区级精细预警更适合县域到省级的宏观风险评估。后续比较可行的方向有三个加入人口流动数据刻画人群聚集变化引入网络搜索指数作为非传统信号把遥感预训练模型和语言模型做更深层的多模态对齐而不只是embedding拼接。如果数据权限和算力成本允许从提前两周走向准实时预警甚至提前三周不是没有可能。项目做下来我最大的体会是LLM在这里不是用来替代流行病学模型而是把多源异构数据翻译成决策者能行动的语言。两个最容易被低估的环节一个是时间坐标对齐一个是概率校准它们决定了系统上线后是稳跑还是事故频发。最后分享一个小技巧让所有特征都通过一个统一的“数据可用性接口”读取接口里维护每个区域、每个变量的最新更新时间戳模型永远看不到比截止时间更晚的数据。就这一条能挡掉八成数据泄漏和特征穿越问题。