利用 NVIDIA Earth-2 将最新观测数据转化为及时的气象决策
对天气高度敏感的行业如今能获取更丰富、更及时的观测数据,从而更早、更本地化地感知环境变化。能源企业可采集风力和光伏资产的运行数据,应急管理团队依赖雷达与本地传感器,卫星服务商则持续监测地球。这些数据有助于各机构理解和管控资本市场、保险、农业、物流等多个领域面临的物理风险。
借助 NVIDIA Earth-2 中的 AI 数据同化工具,你可以更高效地处理这些观测数据。通过引入自有或第三方数据,你可以利用这些工具提高预报频率,确保预估与实时状况保持一致,并针对特定区域和场景定制预报流程。
本教程涵盖两种技术:
- 用点状观测约束扩散模型,通常适用于区域模型。
- 将异构数据集同化为统一状态,通常适用于全球模型。
前置条件
开始本教程前,你需要:
- 已安装 Earth2Studio 的开发环境
- 一块 NVIDIA RTX PRO 或数据中心 GPU
- 基础的 Python 知识
- 约 30 分钟时间
利用观测数据提升区域预报精度
你可能正在运行一套区域天气预报流水线,用于管理能源的生产与需求,数据源包括风电场、光伏电站、输电走廊或人口密集区域。借助 AI 数据同化,你可以利用这些观测数据在本地精度最关键的地方约束预报结果,从而优化运行决策。同样的技术也可服务于其他行业,例如利用生产现场、活动场馆、物流网络或其他资产处的观测数据,在本地条件直接影响决策的场景中提供支持。
你可以使用 基于得分函数的数据同化(SDA)将观测数据融入基于扩散的 AI 降尺度与预报模型(如 CorrDiff 和 StormCast)。SDA 能引导模型输出与观测数据一致的预测结果,且无需重新训练模型。
下图的图 1 展示了这一过程背后的运作机制。Diffusion 模型通过一系列去噪步骤生成高分辨率预测。在每个步骤中,SDA 将中间预测结果与你观测到的数据对比,并将模型调整至正确方向。SDA 的输出具有概率性,其不确定性在观测点附近较小,在远离观测点的区域则显著增大;在这些区域,预测主要受其他模型输入及底层 AI 模拟的控制。
为了将模型调整至正确方向,需要定义一个观测算子(observation operator),它将模型输出映射为各观测点预期检测到的量。对于温度或风速等物理量的原位测量,这一过程尤为直接。在这种情况下,最简单的算子形式是将附近网格值插值到各观测点。也可以为替代测量值或观测影响创建算子。例如,风力发电机的功率输出可作为风速的替代测量值。
SDA 解锁了两项关键能力:
- 更快速地更新预报。数值分析需要大量计算时间,且按固定时间表发布。SDA 让你能够持续融入观测数据。下图(图 2)展示了一个具体示例:该流水线每小时预报一次,并依赖一份每六小时发布一次的全球分析数据。
- 融入自有、区域或特定领域的观测数据。数值分析依赖广泛来源的观测数据,而 SDA 让你可以接入自己的数据源,把预报聚焦到特定资产位置或下游应用上。
SDA 的效果取决于几个因素:观测数据的数量、空间分布和精度;你所预测场 characteristic 的特征长度尺度;以及观测算子的质量和适定性。
如何在 Earth2Studio 中运行 CorrDiff-SDA
CorrDiff 是一种基于 AI 的降尺度技术。Earth2Studio 提供了预训练好的欧洲地区 CorrDiff 模型,可将 0.25° 分辨率的气象场转化为 2.2 km 分辨率的预测结果。利用 AI 数据同化,你可以在对局部精度要求较高的场景中,结合观测数据进一步提升预测质量。经过优化的输出结果可用于初始化区域预报,或生成再分析数据集以校准下游模型。
首先加载预训练模型。此处将研究区域限定为荷兰部分地区及德国西北部,并选择同化 10 米高度的风速数据。
from datetime import datetime
from earth2studio.data import GHCNHourly
from earth2studio.models.da import CorrDiffCosmoEra5SDA
domain = dict(lat_min=50.2, lat_max=53.8, lon_min=4.6, lon_max=10.4)
sda = CorrDiffCosmoEra5SDA.load_model(
CorrDiffCosmoEra5SDA.load_default_package(),
assimilate_variables=("u10m", "v10m"),
resolution="rea2",
domain=domain,
number_of_samples=1,
sampler_steps=12,
amp=True,
).to("cuda")
获取用于低分辨率条件输入的 ERA5 数据,以及该区域内 GHCN 的风速观测数据。
# Fetch and regrid ERA5 inputs onto the high resolution regional grid # Follow the link to the example below for the full implementation init_time = datetime(2024, 1, 26) x = fetch_and_regrid_era5(init_time, domain) # Fetch GHCN hourly 10-m wind observations over the model domain lat, lon = sda.model.lat_output_numpy, sda.model.lon_output_numpy bbox = lat.min(), lon.min(), lat.max(), lon.max() ghcn = GHCNHourly(stations=GHCNHourly.get_stations_bbox(bbox)) obs = ghcn(init_time, ["u10m", "v10m"]).dropna(subset=["observation"])
最后,使用输入数据运行模型。我们进行了两次运行,以评估额外观测数据对结果的影响。
prior = sda(x) # free downscaling, no observations analysis = sda(x, obs) # guide the diffusion toward the observations
如需完整实现,请查阅 Earth2Studio 示例,上述代码即基于该示例改编。
```html
如何在 Earth2Studio 中运行 StormCast-SDA
StormCast 是一种与 CorrDiff 类似的技术,专为高分辨率区域预报设计。Earth2Studio 包含一个基于美国本土(CONUS)预训练的 StormCast 模型,该模型使用 HRRR 进行初始化,并以 3 公里分辨率做出预测。虽然计算并发布新的 HRRR 分析需要一定时间,但你可以使用 SDA 将当前可用的分析数据与最新观测相结合,从而更新你的预报。
首先加载预训练模型。我们将区域限定在美国中部。
```
import numpy as np
from earth2studio.data import GHCNHourly
from earth2studio.models.px import StormCastCONUS
# 将计算域限制在美国中部
hrrr_lat_lim, hrrr_lon_lim = (305, 785), (595, 1203)
model = StormCastCONUS.load_model(
StormCastCONUS.load_default_package(),
hrrr_lat_lim=hrrr_lat_lim, # 如需完整 CONUS 域可注释掉
hrrr_lon_lim=hrrr_lon_lim, # 如需完整 CONUS 域可注释掉
num_diffusion_steps=18,
num_sda_diffusion_steps=96, # SDA 步数越多越稳定
sda_std_obs=0.15,
sda_gamma=1e-3,
).to("cuda")
接下来,获取用于模型初始化的 HRRR 分析场,并在模型域内定义观测数据源。
# 获取 HRRR 初始条件
# 完整实现请参考下方示例链接
init_time = datetime(2026, 4, 17, 18)
x, coords = fetch_hrrr(init_time)
# 定义模型域内的 GHCN 小时数据源
lat, lon = model.lat, model.lon
bbox = lat.min(), lon.min(), lat.max(), lon.max()
ghcn = GHCNHourly(
stations=GHCNHourly.get_stations_bbox(bbox),
time_tolerance=timedelta(minutes=15),
)
现在就可以运行模型了:在初始的 rollout 步骤中使用观测数据,之后再转入不依赖观测的预报。与上文图 2 所示类似,这种做法利用观测数据衔接最新分析场与当前实况之间的时间差,之后的预报则独立进行。
对于以 HRRR 初始化的流程,在新分析场到来之前通常只需执行一个 SDA 步骤。如果用全球分析场做初始化,则多个 rollout 步骤都可以从 SDA 中受益。
# 初始化生成器并获取首个输出(直接透传分析场)
gen = model.create_generator(x.clone(), coords.copy())
x, coords = next(gen)
# rollout 的前半部分使用 SDA
for step in range(nsteps_sda):
valid_time = np.array(
[coords["time"][0] + coords["lead_time"][0] + np.timedelta64(1, "h")]
)
obs = ghcn(valid_time, ["u10m", "v10m", "t2m"])
x, coords = gen.send(obs) # 结合观测前进一步
# rollout 的剩余部分不使用 SDA
for step in range(nsteps_non_sda):
x, coords = next(gen) # 不用观测,前进一步
你可以在 Earth2Studio 示例库中找到该示例的完整实现。
如何将 SDA 应用于自定义模型
你可以通过扩展其 Earth2Studio 模型包装器,将观测数据同化到自定义模型中。为此,请使用 PhysicsNeMo 中的扩散工具。我们从 x0_predictor 开始,这是一个预训练的去噪扩散模型,它接收带噪样本及其噪声水平作为输入,并预测无噪样本。在没有 SDA 的情况下,该模型的扩散采样实现如下所示:
from physicsnemo.diffusion.noise_schedulers import EDMNoiseScheduler from physicsnemo.diffusion.samplers import sample # Construct diffusion scheduler sigma_min, sigma_max = 0.01, 100 scheduler = EDMNoiseScheduler(sigma_min=sigma_min, sigma_max=sigma_max) # Get denoiser from scheduler denoiser = scheduler.get_denoiser(x0_predictor=x0_predictor) # Generate sample latents = sigma_max * torch.randn(shape) sample(denoiser, latents, noise_scheduler=scheduler, num_steps=num_steps)
使用 SDA 时,我们将 x0_predictor 转换为带有 SDA 引导的分数预测模型。这里采用 DataConsistencyDPSGuidance,它将每个被掩码的像素与对应的观测值关联起来。你可以用它来同化气象站、专有传感器或其他类似的点状数据源观测值。
from physicsnemo.diffusion.guidance import (
DataConsistencyDPSGuidance,
DPSScorePredictor,
)
# Setup SDA guidance
guidance = DataConsistencyDPSGuidance(
mask=mask, # binary mask that identifies pixels with observations
y=y_obs, # gridded observations
std_y=sda_std_obs, # the remaining parameters are SDA settings
norm=sda_dps_norm,
gamma=sda_gamma,
sigma_fn=scheduler.sigma,
alpha_fn=scheduler.alpha,
)
# Convert x0_predictor to score predictor
score_predictor = DPSScorePredictor(
x0_predictor=x0_predictor,
x0_to_score_fn=scheduler.x0_to_score,
guidances=guidance,
)
denoiser = scheduler.get_denoiser(score_predictor=score_predictor)
# Generate sample (identical to non-SDA example)
latents = sigma_max * torch.randn(shape)
sample(denoiser, latents, noise_scheduler=scheduler, num_steps=num_steps)
对于更高级的 SDA 流程,可以使用 ModelConsistencyDPSGuidance 从多个网格点推导模拟观测值。这种方法要求提供一个 PyTorch 模型,将每个样本映射到对应的模拟观测值。通过自定义 PyTorch 模型,你还可以同化观测影响。例如,利用风力发电模型同化风机发电量测量值。
如需查看完整实现,请参见 Earth2Studio 中的 StormCast CONUS wrapper,上述示例即基于此代码。
基于观测值计算全球天气
大多数全球天气预报流程的启动,都依赖于通过数值同化得到的当前天气状态估计。数值同化计算开销很大,不仅拖慢了预报的时效性和刷新频率,也让接入自定义观测数据变得更加困难。
借助一种名为 HealDA 的 AI 技术,你只需几秒钟就能估算出全球大气状态,从而发布更贴近当前实况的预报,或计算自定义的再分析数据。
HealDA 将某个时间窗口内的遥感和现场观测数据映射到全球格点大气状态。它由两个核心组件构成:观测编码器和 Vision Transformer(ViT)骨干网络。编码器把异构观测数据当作点云处理,将每个标量值连同地理位置、时间等元数据一起编码为一个 token,随后这些 token 被聚合到目标网格上,交由 ViT 骨干网络处理。
你可以直接使用预训练的全球数据同化模型作为起点。如果有自定义的常规观测数据,通常无需修改模型即可直接接入。
针对私有卫星数据,你可以适配编码器以支持不同的数据源。这种灵活性使数据同化系统能够针对特定区域或应用需求进行定制。同样的方法也可用于训练区域系统,而非全球系统。如需入门,请参见开源 Python 库 PhysicsNeMo 中的 HealDA 训练流水线。
如何在 Earth2Studio 中运行 HealDA
Earth2Studio 提供了一个预训练的全球数据同化模型,供研究人员使用。它将来自微波高度计、无线电掩星、地面气象站、飞机、浮标及其他来源的数据集成到 1° HEALPix 网格(HPX64)上。
首先,加载模型。
from datetime import timedelta
import numpy as np
from earth2studio.data import UFSObsConv, UFSObsSat, fetch_dataframe
from earth2studio.models.da import HealDA
model = HealDA.load_model(
HealDA.load_default_package(),
lat_lon=True, # regrid from HEALPix to regular lat/lon
).to("cuda")
接下来,从 NOAA UFS 重放仓库获取输入观测数据。这里使用常规和卫星观测数据。
# HealDA was trained on the UFS replay window: 21h before to 3h after analysis time
time_tolerance = (timedelta(hours=-21), timedelta(hours=3))
analysis_time = np.array([np.datetime64("2024-01-01T00:00")])
# input_coords() returns the schemas the two observation DataFrames must satisfy
conv_schema, sat_schema = model.input_coords()
# fetch_dataframe attaches the request_time metadata the model needs
conv_df = fetch_dataframe(
UFSObsConv(time_tolerance=time_tolerance),
time=analysis_time,
variable=np.array(conv_schema["variable"]),
fields=np.array(list(conv_schema.keys())),
)
sat_df = fetch_dataframe(
UFSObsSat(time_tolerance=time_tolerance),
time=analysis_time,
variable=np.array(sat_schema["variable"]),
fields=np.array(list(sat_schema.keys())),
)
然后,使用观测数据帧调用模型。
# stateless model - call it directly for a one-shot analysis, or use # create_generator for cycled assimilation analysis = model(conv_obs=conv_df, sat_obs=sat_df)
你可以在 Earth2Studio 示例库中找到运行 HealDA 的扩展示例。
使用 Earth2Studio 访问观测数据
Earth2Studio 提供广泛的数据源,支持天气模型的开发、初始化与验证,涵盖来自不同平台和传感器类型的观测数据。
这些数据包括来自静止轨道卫星(GOES、Himawari、Meteosat)的格点数据和雷达网络(MRMS、OPERA)数据,可直接用于训练并快速更新区域高分辨率预报模型,如 StormScope。在预报依赖日照或降水量的指标时(如太阳能发电、冷却过程、水库入库量),这些数据源尤为实用。
在开发与基准测试数据同化系统时,Earth2Studio 还允许访问常规观测数据归档(如 GHCN/ISD、NNJA、UFS)以及 GDAS 和 ASOS 的常规业务观测数据。这些数据源以数据帧形式提供气温、风速等变量。极轨卫星系统(如 MetOp 和 JPSS)的观测数据也可获取。
Earth2Studio 为所有数据源提供统一接口。你只需实例化一个数据源对象,并传入时间戳和变量名称列表即可调用。预报类数据源还接受预报时距列表。这种一致的接口设计便于在同一工作流中组合多个数据源,或将自有观测数据接入管道。
era5 = NCAR_ERA5() da_era5 = era5(datetime(2025, 7, 15), ["t2m", "z500"]) print(da_era5.shape) # (1, 2, 721, 1440) ifs = IFS_FX() da_ifs = ifs(datetime(2026, 7, 15), timedelta(hours=48), ["t2m"]) print(da_ifs.shape) # (1, 1, 1, 721, 1440) goes = GOES(satellite="goes19", scan_mode="C") da_goes = goes(datetime(2026, 7, 15), ["abi01c", "abi02c", "abi03c"]) print(da_goes.shape) # (1, 3, 1500, 2500) ghcn = GHCNHourly(stations=["USW00013301"]) df_ghcn = ghcn(datetime(2026, 6, 15), ["t2m", "ws10m"]) print(df_ghcn.shape) # (10, 7)
要查看受支持数据源的完整列表,请参阅 用户指南中的 API 参考。
开始使用 Earth2Studio
欢迎在 Earth2Studio 示例库中探索端到端 AI 数据同化示例。如果想将自己的观测数据接入流程,可以参考自定义数据源示例。
借助 AI 数据同化,你可以纳入对所在地区或机构真正重要的观测数据,从而发布更准确、更及时的预报。
访问 Earth2Studio 用户指南,开始使用 AI 数据同化,并探索 AI 天气模型的更多能力。