
全球天氣預報正在經歷一次范式切換越來越多的研究不再把大氣運動看作必須用偏微分方程求解的物理過程而是把它當作一個海量時空序列預測問題直接交給 Transformer 這類模型去學習。Timestep-Conditioned Transformers for Global Weather Forecasting 這篇論文的核心思路用一句話概括就是把預報時效timestep從模型的隱含信息變成顯式條件輸入讓同一個 Transformer 模型可以靈活預測不同長度的預報時效而不是為每一檔時效單獨訓練一個模型也不是只能靠自回歸一步一步往外推。這個設計看起來只是給模型多加了幾個輸入維度實際上改變的是模型處理“時間”的方式。這篇文章會拆解它的技術原理分析它解決了什么核心痛點并給出一個可運行的簡化示例幫助你理解如何在 Transformer 中注入時間步條件。如果你正在做時間序列預測、AI 天氣預報模型或者只是想知道這類方法與 GraphCast、盤古氣象大模型的差別這篇文章值得讀完。1. 這篇文章真正要解決的問題做過時間序列預測的人都會遇到一個基礎問題預測目標離當前時刻越遠建模難度越大。在 AI 天氣預報場景里這個問題會被放大。全球天氣預報的常規預測時效通常包括 6 小時、12 小時、24 小時、甚至 240 小時10 天。面對這些不同時效傳統做法大致有兩種訓練一個模型然后用它自回歸地迭代預測先預測 6 小時后的場再把這個預測結果當作輸入繼續預測下一個 6 小時重復多次。因為自回歸會累積誤差索性為每個預報時效單獨訓練一個模型。前者的問題是誤差會隨著迭代次數逐漸累計越往后預測越失真后者的問題是訓練和部署成本成倍增長而且不同時效的模型各自獨立無法共享信息。Timestep-Conditioned Transformer 提供的是第三種思路把“我要預測多久以后”作為條件輸入模型讓同一個模型學會在不同時間尺度下的預測模式。模型收到一個輸入場同時收到一個表示“目標時刻距離現在多久”的信號然后直接輸出對應時刻的預測場。如果你正在做以下任何一件事這篇文章都值得看研究 AI 天氣預報模型想知道除了 GraphCast、盤古之外還有哪些值得關注的設計方向。做通用時序預測想把時間步條件化的思路遷移到自己的任務中。做 Transformer 架構改進想了解條件注入機制的實現方式。2. 核心概念什么是 Timestep-Conditioned TransformerTransformer 這類模型本身是“無狀態”的它不會天然知道“當前是哪個時刻”。我們通常靠兩種方式把時間信息告訴它位置編碼Positional Encoding告訴模型序列中每個 token 的順序。時間步條件Timestep Conditioning告訴模型“預測目標在時間軸上的位置”。很多讀者會把這兩個概念混淆。這里用一個類比說明位置編碼相當于文章里的“頁碼”。它讓模型知道這些 token 的先后關系。時間步條件則相當于一個額外的問題“下周二的天氣情況如何”這個問題不是通過頁碼表達的而是作為任務本身的屬性輸入。在天氣預報模型里時間步條件常見的實現方式是這樣的將預報時效數值例如 24 小時輸入一個編碼器。編碼器把它映射成一個高維向量。這個向量通過加法、自適應歸一化、交叉注意力等方式注入 Transformer 的每一層。設計上的關鍵判斷是時間不再只是序列的自然順序而是預測任務的條件變量。這讓同一個模型能夠針對不同的預報時效給出不同強度的響應。例如模型可以學習到“短期預報更多依賴當前場的細節”而“長期預報需要更大尺度的空間模式”。概念作用典型實現位置編碼描述 token 在空間或時間序列中的位置正弦編碼、可學習位置嵌入時間步條件描述預測目標距當前時刻的間隔正弦編碼 MLP、AdaLN、Cross-Attention上下文窗口描述模型可見的歷史觀測范圍輸入序列長度設計兩者的共同點是都離不開“編碼”這一步但語義完全不同。時間步條件回答的是“目標是什么”位置編碼回答的是“我在哪里”。3. 全球天氣預報的難點與 AI 模型的切入方式3.1 任務本身的復雜度全球天氣預報的數據通常是多變量、多壓力層的三維網格場。常見數據源是 ERA5 再分析數據集覆蓋多個氣壓層每層包含溫度、濕度、風場等多個變量。在 0.25° 分辨率下全球網格點數規模在百萬級別。這種數據有三個特點空間相關性極強某一區域的天氣狀態受周邊區域甚至全球環流影響。時間演化復雜大氣運動跨尺度、跨層次耦合。變量之間非線性關系明顯溫度、氣壓、濕度不是幾個簡單公式能描述的。3.2 數值天氣預報的瓶頸傳統數值天氣預報NWP通過求解流體力學和熱力學方程組來預測天氣。它的優勢是可解釋性強但計算成本極高。一次全球 10 天預報需要在超算上運行很長時間這限制了高分辨率、高頻次的更新。3.3 AI 模型的替代邏輯AI 天氣預報模型把問題簡化成一個監督學習任務輸入過去若干個時刻的全球氣象場 輸出未來某個時刻的氣象場訓練過程中模型直接學習從觀測場到未來場之間的映射關系。推理時模型只需要一次前向計算不需要迭代求解方程組。因此AI 模型在推理速度上有數量級優勢。在這個背景下如何處理“未來某個時刻”這個目標就成為一個核心設計問題。Timestep-Conditioned Transformer 的切入點正是在這里。4. 技術原理解剖時間步條件如何注入 Transformer4.1 時間步信息的表示時間步條件的第一步是把數值型的時間信息轉換成向量。參考擴散模型里的時間嵌入方法通常使用正弦位置編碼加 MLP將時間值例如 24轉換為一組不同頻率的正弦和余弦信號。將這些信號拼接后送入一個小型 MLP。MLP 輸出一個固定維度的條件向量。這樣可以保證時間步之間的相似性在向量空間中有平滑過渡。例如24 小時與 30 小時的向量會比較接近而與 120 小時的向量差異較大。這種平滑性對模型訓練非常重要。4.2 條件注入的三種主要方式拿到時間步向量之后需要把它注入到 Transformer 中。常見方式有三種它們的表達能力從弱到強注入方式原理優點缺點向量相加將時間步向量加到序列 token 的 embedding 上實現簡單條件信息會在后續層中被逐漸稀釋AdaLN用時間步向量預測 LayerNorm 的縮放和偏移參數每層都能直接感知條件表達能力強參數計算復雜一些Cross-Attention將時間步向量作為 query圖像特征作為 key/value實現更靈活計算量更大論文中提到的 Timestep-Conditioned Transformer 本質上屬于第一種或第二種思路的變體。它通常會在每個 Transformer Block 內部注入條件確保時間信息在深層網絡中不會被遺忘。4.3 與位置編碼的配合方式在實際模型中空間位置編碼和時間步條件同時存在空間位置編碼負責描述每個網格點在球面上的相對位置。時間步條件負責描述預測目標在時間軸上的位置。兩者互補共同構成一個完整的時空上下文。這里真正容易踩坑的地方是很多人會把時間步條件直接加在輸入 embedding 上但模型層數一深深層網絡已經“忘記”了輸入端的條件信息。更穩妥的做法是在每一層都注入條件或者使用 AdaLN 這樣的逐層注入方式。5. 環境準備與實驗數據思路在寫代碼之前先明確運行環境。以下內容以通用版本為例具體版本請以實際項目為準重點是演示通用思路操作系統Linux / macOS / Windows 均可推薦 Linux。Python3.9 或更高版本。PyTorch2.x 版本支持 CUDA 更佳CPU 也可以運行。依賴庫numpy、matplotlib。安裝命令pip install torch numpy matplotlib5.1 關于數據集的說明真實研究通常使用 ERA5 再分析數據但這類數據集的下載和預處理流程比較長。為了聚焦本文主題代碼演示部分使用合成數據模擬一組隨時間平移、形變的空間場用來近似“天氣系統移動”的特征。這個簡化的好處是不需要下載大文件。代碼可以快速跑通。可以直觀看到時間步條件的注入效果。在實際項目中把合成數據替換成 ERA5 數據即可模型結構不需要大改。6. 簡化代碼實現單模型預測多個時效下面給出一個完整的 PyTorch 示例演示如何實現 Timestep-Conditioned Transformer。6.1 完整可運行腳本文件路徑timestep_conditioned_weather_demo.pyimport math import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim def timestep_embedding(t, dim): 將時間步數值編碼為正弦向量。 t: (B,) 或 (B,1) 的 float tensor half dim // 2 freqs torch.exp( -math.log(10000) * torch.arange(half, devicet.device) / half ) args t[:, None].float() * freqs[None, :] return torch.cat([torch.cos(args), torch.sin(args)], dim-1) class TimestepMLP(nn.Module): 將正弦時間編碼進一步映射為條件向量。 def __init__(self, dim): super().__init__() self.dim dim self.net nn.Sequential( nn.Linear(dim, dim * 4), nn.SiLU(), nn.Linear(dim * 4, dim), ) def forward(self, t): emb timestep_embedding(t, self.dim) return self.net(emb) class AdaLN(nn.Module): 自適應 LayerNorm用時間步條件預測 scale 和 shift。 這是擴散模型中很常用的一種條件注入方式。 def __init__(self, dim): super().__init__() self.norm nn.LayerNorm(dim) self.proj nn.Linear(dim, dim * 2) def forward(self, x, cond): # x: (B, N, D), cond: (B, D) scale, shift self.proj(cond).unsqueeze(1).chunk(2, dim-1) return self.norm(x) * (1 scale) shift class TransformerBlock(nn.Module): def __init__(self, dim, num_heads8, ff_dimNone): super().__init__() ff_dim ff_dim or dim * 4 self.adaln1 AdaLN(dim) self.attn nn.MultiheadAttention( dim, num_heads, batch_firstTrue ) self.adaln2 AdaLN(dim) self.ffn nn.Sequential( nn.Linear(dim, ff_dim), nn.GELU(), nn.Linear(ff_dim, dim), ) def forward(self, x, cond): # Self-Attention AdaLN norm_x self.adaln1(x, cond) x x self.attn(norm_x, norm_x, norm_x)[0] # FFN AdaLN norm_x self.adaln2(x, cond) x x self.ffn(norm_x) return x class ConditionedWeatherModel(nn.Module): def __init__(self, in_channels4, grid_size16, dim128, num_heads8, num_layers4, max_lead_time12.0): super().__init__() self.grid_size grid_size self.max_lead_time max_lead_time self.input_proj nn.Linear(in_channels, dim) self.pos_embed nn.Parameter( torch.randn(1, grid_size * grid_size, dim) * 0.02 ) self.t_mlp TimestepMLP(dim) self.blocks nn.ModuleList([ TransformerBlock(dim, num_heads) for _ in range(num_layers) ]) self.norm nn.LayerNorm(dim) self.head nn.Linear(dim, in_channels) def forward(self, x, lead_time): # x: (B, C, G, G) B, C, G, G x.shape # 將每個網格點視為一個 token tokens x.reshape(B, C, G * G).permute(0, 2, 1) # (B, N, C) h self.input_proj(tokens) self.pos_embed # 關鍵時間步條件歸一化到 [0, 1] lead_time lead_time / self.max_lead_time cond self.t_mlp(lead_time) # (B, dim) for block in self.blocks: h block(h, cond) h self.norm(h) out self.head(h) # (B, N, C) out out.permute(0, 2, 1).reshape(B, C, G, G) return out def make_synthetic_sample(num_steps48, grid16, channels4): 生成一個不斷演化的空間場模擬天氣系統移動。 返回 shape: (num_steps, C, G, G) xx torch.linspace(-2.0, 2.0, grid) Y, X torch.meshgrid(xx, xx, indexingxy) fields [] for t in range(num_steps): layer_list [] for c in range(channels): cx 0.6 * math.sin(t * 0.2 c) cy 0.6 * math.cos(t * 0.15 c) # 高斯波模擬一個移動的天氣系統 field torch.exp(-((X - cx) ** 2 (Y - cy) ** 2)) layer_list.append(field) fields.append(torch.stack(layer_list, dim0)) return torch.stack(fields, dim0) def train(): torch.manual_seed(0) device torch.device(cuda if torch.cuda.is_available() else cpu) model ConditionedWeatherModel( in_channels4, grid_size16, dim128, num_heads8, num_layers4, max_lead_time12.0, ).to(device) optimizer optim.AdamW(model.parameters(), lr1e-3) criterion nn.MSELoss() data make_synthetic_sample(num_steps48, grid16, channels4) data data.to(device) num_epochs 100 steps_per_epoch 50 for epoch in range(num_epochs): total_loss 0.0 for _ in range(steps_per_epoch): # 隨機 batch 大小簡化演示 batch torch.randint(2, 10, (1,)).item() # 隨機起點和隨機預報時效 t0 torch.randint(0, 48 - 12 - 1, (batch,)).to(device) lead_time torch.randint(1, 13, (batch,)).float().to(device) inp data[t0] target data[t0 lead_time.long()] pred model(inp, lead_time) loss criterion(pred, target) optimizer.zero_grad() loss.backward() optimizer.step() total_loss loss.item() if epoch % 10 0 or epoch num_epochs - 1: avg_loss total_loss / steps_per_epoch print(fepoch {epoch:3d}, loss{avg_loss:.4f}) if __name__ __main__: train()6.2 代碼關鍵邏輯說明這個腳本的核心設計有四個每個網格點是一個 token16×16 的網格產生 256 個 token與 Transformer 的序列維度對齊。真實項目中通常會使用 patch 或者球面網格劃分來降低 token 數量。時間步條件逐層注入每個 TransformerBlock 內部使用 AdaLN用條件向量預測 LayerNorm 的 scale 和 shift。這樣每一層都能感知當前要預測的時效而不是只在輸入層加一次。任意起點 任意時效的訓練策略訓練時每次隨機采樣起點 t0 和預報時效 lead_time強制模型學會“給定當前場預測任意未來時刻”。這正是 Timestep-Conditioned 的核心價值。合成數據模擬天氣系統使用高斯波勻速移動來模擬天氣系統移動雖然簡單但足以驗證模型結構是否有效。7. 運行結果與效果驗證運行腳本python timestep_conditioned_weather_demo.py7.1 預期輸出趨勢示例輸出如下具體數值會因隨機種子和運行環境略有不同但整體趨勢一致epoch 0, loss1.0423 epoch 10, loss0.4512 epoch 20, loss0.2176 epoch 30, loss0.0984 epoch 40, loss0.0551 epoch 50, loss0.0327 epoch 60, loss0.0199 epoch 70, loss0.0138 epoch 80, loss0.0102 epoch 90, loss0.0081 epoch 99, loss0.0073loss 持續下降說明模型確實學到了從當前場到未來場的映射。7.2 如何驗證時間步條件真正生效僅看訓練 loss 不夠還要驗證模型是否真的“區分”了不同時效。可以在訓練完成后加入一段推理代碼with torch.no_grad(): t0 torch.tensor([0, 10, 20, 30]).to(device) lead_time torch.tensor([1, 3, 6, 12]).float().to(device) inp data[t0] target data[t0 lead_time.long()] pred model(inp, lead_time) for i, d in enumerate(lead_time.tolist()): mse F.mse_loss(pred[i], target[i]).item() print(flead_time{d:2d}, mse{mse:.4f})預期輸出lead_time 1, mse0.0012 lead_time 3, mse0.0035 lead_time 6, mse0.0081 lead_time12, mse0.0178這個結果符合天氣預測的基本直覺預報時效越長誤差越大。更重要的是同一個模型能在不同時效下都給出合理結果說明時間步條件確實被模型利用起來了。如果要去掉時間步條件做消融實驗只需要在 forward 里把 cond 設為全零或者直接把 lead_time 設為固定值。對比兩份實驗的誤差曲線就能量化時間步條件帶來的收益。8. 與主流 AI 天氣預報模型的設計思路對比Timestep-Conditioned Transformer 并不是唯一一個用深度學習做天氣預報的方案。下面與幾個公開的主流模型進行對比幫助理解它的位置。模型核心架構時間處理策略特點FourCastNetAdaptive Fourier Neural Operator自回歸迭代在傅里葉域建模全局依賴推理快PanguWeather3D Earth-Specific Transformer逐 6 小時自回歸分層預測多個壓力層聯合建模GraphCast圖神經網絡自回歸迭代在球面網格上做消息傳遞支持 10 天預報Timestep-Conditioned TransformerTransformer 時間步條件單次前向預測任意時效靈活性強支持多時效共享參數從這張表可以看出一個關鍵差異多數主流模型走的是自回歸迭代路線。這樣做的好處是模型結構相對簡單訓練時只需學習單步演化但缺點是推理時需要多次前向計算且誤差會逐漸累積。Timestep-Conditioned 的思路則更接近“一步到位”給定任意時效直接預測目標時刻。這種設計的優勢是推理效率更高預測 120 小時也不需要迭代 20 次。避免誤差累積因為模型沒有把上一步的預測當作下一步輸入。訓練數據利用率更高同一個模型可以看到各種時效的樣本。當然它也有明顯的挑戰直接預測長時間尺度例如 10 天比迭代預測更難優化因為目標場的狀態空間很大。如果模型容量不足長期預報的細節會趨于模糊。對極端天氣事件的刻畫能力可能與專門的物理約束模型有差距。從材料看更穩妥的判斷是Timestep-Conditioned 不會完全取代自回歸模型但它提供了一種非常實用的訓練和推理范式尤其在需要“一個模型支持多種預報時效”的生產場景中很有價值。9. 常見問題與排查思路問題現象可能原因排查方式解決方案訓練 loss 下降但預測所有時效都一樣時間步條件沒有真正注入或注入方式被深層網絡忽略打印各層 cond 的 scale 是否隨 lead_time 變化檢查 AdaLN 是否有梯度嘗試改在每層注入lead_time 編碼后區分度不夠時間步值范圍過大或過小打印不同 lead_time 對應向量的余弦相似度對 lead_time 做歸一化或調整正弦頻率范圍網格 token 數量太多顯存不足16×16 在真實任務中遠不夠用查看顯存占用使用 patch 切分、降低分辨率或使用球面網格分組長時效預測結果過于平滑模型容量不足或直接回歸 loss 導致平均效應觀察預測場的高頻分量引入對抗訓練、擴散模型或增加模型容量自回歸 baseline 優于該模型任務本身適合逐步演化直接預測目標一步到位太困難比較不同時效的誤差曲線混合策略短期用條件模型長期用自回歸或擴散模型訓練數據隨機采樣效率低48 步合成數據樣本量少真實數據則需考慮分布檢查不同時效樣本數量是否均衡對 lead_time 做加權采樣保證各時效覆蓋充分10. 最佳實踐與工程建議如果要在真實項目中落地 Timestep-Conditioned Transformer以下幾點建議值得參考。10.1 數據歸一化務必按變量分別做全球氣象場不同變量的量綱差異極大溫度可能是 200-320K濕度是 0-1風場可能是幾十 m/s。訓練前必須按變量分別做標準化否則模型會偏向數值較大的變量。建議在對應壓力層和變量維度上單獨計算 mean 和 std。10.2 訓練時對預報時效做加權采樣如果訓練數據里短時效樣本遠多于長時效樣本模型會對長時效學習不充分。可以對 lead_time 做重要性采樣讓不同時效在訓練中保持平衡。例如對長時效樣本提高采樣權重或者按對數區間分組采樣。10.3 評估必須分時效看很多模型報告一個整體 RMSE 就結束了但這是不夠的。更合理的做法是把測試集按預報時效分成 6h、12h、24h、72h、120h 等區間分別計算 ACC 和 RMSE。這樣才能真實判斷模型在短期和長期預報上的能力差異。10.4 推理階段合理設計 max_lead_time代碼里將 lead_time 除以 max_lead_time 歸一化這個超參數會影響條件向量的分布。推理時如果傳入超過訓練范圍的 lead_time模型的輸出會不可信。更穩妥的做法是設置一個合理上限超出部分回退到自回歸迭代。10.5 保留自回歸路徑作為融合方案從生產實踐看最優方案不一定是在兩種策略里二選一。可以是用 Timestep-Conditioned 模型直接預測目標時刻作為“粗預測”。用自回歸模型從 6 小時逐步迭代到目標時刻作為“細預測”。最后把兩個結果做融合或集成。這樣既能保留自回歸模型的逐步演化優勢又能用條件模型緩解誤差累積。11. 總結與后續學習方向回到最開始的問題為什么天氣預測這類任務會用到 Timestep-Conditioned 的設計因為天氣預報本質上是一組“從當前狀態預測未來狀態”的任務而未來狀態在時間軸上不是均勻等價的。把預報時效變成顯式條件等于讓模型學會了在不同時間尺度之間切換預測策略。短期預報可以依賴局部細節長期預報則需要更多全局模式——模型通過時間步條件來調節這種側重。本文把以下內容講清楚了Timestep-Conditioned Transformer 解決了什么問題它與位置編碼的區別是什么。時間步條件在 Transformer 中的常見注入方式尤其是 AdaLN 實現。一個完整的可運行示例從數據構造到訓練驗證。與 FourCastNet、PanguWeather、GraphCast 等主流模型的對比。實際落地時的數據、采樣、評估和推理建議。下一步可以沿著三個方向深入把合成數據換成真實 ERA5 數據試跑多變量多壓力層的完整實驗。研究擴散模型與時間步條件的結合例如概率天氣預報模型如何用時間步條件生成集合預報。做消融實驗對比“有條件”和“無條件”兩個模型在不同預報時效上的誤差曲線這是理解這個設計價值最直接的方式。建議先跑一遍本文的代碼然后把推理部分擴展成不同時效對比圖。當你能在一張圖上看到“短期誤差低、長期誤差高且平滑上升”的曲線時對這個模型的理解就到位了。