首页
/ Transformers 中 Informer 模型详解:ProbSparse 稀疏自注意力与长序列时间序列预测实战

Transformers 中 Informer 模型详解:ProbSparse 稀疏自注意力与长序列时间序列预测实战

2026-09-07 12:00:59作者:吴年前Myrtle

Informer 是面向长序列时间序列预测(LSTF,Long Sequence Time-Series Forecasting)的稀疏 Transformer 架构。本文以 模型文档 为主线,结合当前仓库中 配置实现模型实现测试代码,逐层拆解其三大核心机制(ProbSparse 自注意力、自注意力蒸馏、生成式解码器),完整讲解 InformerConfig 全部参数,并给出基于 InformerModel / InformerForPrediction 的加载、训练与采样预测实战代码。

读完本文,你将掌握:Informer 相对标准 Transformer 解决了什么本质问题、稀疏注意力在源码层面如何实现与采样、如何配置预测长度/上下文长度/滞后序列/静态特征等参数,以及如何用开源预训练 checkpoint 完成一次端到端的概率时间序列预测。

Informer 的动机:标准 Transformer 为何难以直接用于 LSTF

Informer 模型由 Haoyi Zhou、Shanghang Zhang、Jieqi Peng、Shuai Zhang、Jianxin Li、Hui Xiong、Wancai Zhang 在论文 Informer: Beyond Efficient Transformer for Long Sequence Time-Series Forecasting 中提出。按 模型文档 的记录,该论文于 2020-12-14 发布在 HF Papers,模型于 2023-03-08 由贡献者 elisimkashif 合入 Transformers。

许多真实应用(如电力消费规划)需要预测很长的时序。这类 LSTF 任务要求模型具备高"预测容量",即高效捕获输出与输入之间精确的长程依赖耦合。论文指出,直接套用标准 Transformer 会遇到三类严重障碍:

  1. 二次方时间复杂度:vanilla self-attention 的复杂度随序列长度平方增长,长上下文下不可负担;
  2. 高内存占用:完整的注意力分数矩阵在长序列下会耗尽显存;
  3. 编码器-解码器架构的固有限制:传统的 step-by-step 自回归解码推断速度慢,不适合超长输出的场景。

Informer 围绕这些问题给出三个标志性设计,模型文档对它们的概括是:

  • ProbSparse self-attention:选"活跃(active)"query 而非"懒惰(lazy)"query,实现 O(L logL) 的时间与内存复杂度,同时保持序列依赖对齐的相当性能;
  • self-attention distilling(自注意力蒸馏):通过逐层减半层输入来突出占主导的注意力,从而高效处理超长输入序列;
  • 生成式风格解码器(generative style decoder):概念上简单,却能在一次前向中预测整段长序列,而非逐时间步滚动,大幅提升长序列预测的推理速度。

仓库中的模型文档明确说明该模型为"稀疏 Transformer",用来缓解标准注意力在计算与内存上的二次开销;这也是理解其全部设计细节的总纲。

源码脉络:modular 文件驱动的一体化实现

在继续深入原理前,先梳理当前仓库中 Informer 的代码布局(位于 src/transformers/models/informer/):

文件 职责
configuration_informer.py InformerConfig,全部超参定义、默认值推导与架构校验
modeling_informer.py InformerModelInformerForPrediction 以及注意力度量、标定器、嵌入与编码器/解码器全栈实现(约 1773 行)
modular_informer.py Informer 的 modular 源文件modeling_informer.py 由其自动生成,文件头标注"Do NOT edit this file manually",任何改动都应落在 modular 文件上
init.py 模块导出入口

模型顶层类与标准 Transformer 时序家族(Time Series Transformer 等)的输入输出约定保持一致。对应的集成测试位于 tests/models/informer/test_modeling_informer.py,其中 InformerModelTester 定义了统一的测试超参(如 batch_size=13prediction_length=7context_length=14),InformerModelTest 继承 ModelTesterMixin 校验前向、隐藏状态形状、注意力张量形状与缓存行为。

推理链路顶层结构

modeling_informer.py 的顶层类定义可以看出完整推理管线被拆成了清晰的模块:

  • InformerModel(第 994 行起):时序专用 encoder-decoder,承担输入特征构建、标定与变换;
  • InformerForPrediction(第 1357 行起):在 InformerModel 之上叠加概率分布输出头与 NLL 损失,并提供 generate 采样预测入口;
  • InformerEncoder / InformerDecoder:标准的 Transformer encoder/decoder 栈,但 encoder 内嵌 distilling 卷积层;
  • 分布式工具类:StudentTOutputNormalOutputNegativeBinomialOutput 等分布头定义在 src/transformers/time_series_utils.pyInformerForPrediction__init__config.distribution_output 从这里选取分布)。

InformerConfig:核心配置参数全解读

InformerConfig(见 configuration_informer.py)继承 PreTrainedConfig,声明 model_type = "informer"。它把上游标准名称映射到 Informer 命名:

attribute_map = {
    "hidden_size": "d_model",
    "num_attention_heads": "encoder_attention_heads",
    "num_hidden_layers": "encoder_layers",
    "initializer_range": "init_std",
}

这意味着当你从其它 Transformer checkpoint 转换配置、或使用通用工具时,Transformers 会自动完成字段映射。下面按配置文件的 docstring 与源码逐一解释全部参数。

时序任务核心参数

参数 类型 / 默认值 含义与建议
prediction_length int,必填 解码器的预测长度,即模型的预测时域(horizon)。通常由数据集决定,建议按任务设置合适值
context_length int,默认等于 prediction_length 编码器看到的上下文长度。若为 None,在 __post_init__ 中被自动赋为 prediction_length
input_size int,默认 1 目标变量尺寸。单变量目标为 1,多变量目标 > 1
lags_sequence list[int],默认 [1, 2, 3, 4, 5, 6, 7] 输入序列的滞后阶数,常由数据频率决定(默认覆盖一周的日滞后)。建议按数据集特性调整
scaling str / bool,默认 "mean" 输入目标的标定方式:"mean"(均值标定)、"std"(标准差标定)、None/False(不标定);若传 True 等价于 "mean"

协变量 / 特征维度参数

参数 类型 / 默认值 含义
num_dynamic_real_features int,默认 0 动态实数特征数量(随时间变化且在预测期必须已知)
num_static_real_features int,默认 0 静态实数特征数量(随时间保持不变)
num_static_categorical_features int,默认 0 静态类别特征数量(模型会为它学习 embedding)
num_time_features int,默认 0 时间特征数量(如"月""日"等编码向量)
cardinality list[int] 每个静态类别特征的取值个数,长度须等于 num_static_categorical_features;若后者为 0 则可省略
embedding_dimension list[int] 每个静态类别特征对应的 embedding 维度,长度同样须匹配类别数

__post_init__ 中的默认值推导逻辑值得注意(configuration_informer.py):

  • context_length 缺省时取 prediction_length
  • lags_sequence 缺省时为 [1, 2, 3, 4, 5, 6, 7]
  • num_static_categorical_features == 0cardinality 被设为 [0]
  • num_static_categorical_features > 0 但未提供 embedding_dimension,则按 min(50, (cat + 1) // 2) 自动生成;
  • 关键的 feature_sizeinput_size * len(lags_sequence) + _number_of_features 计算得出。

其中 _number_of_features 属性(configuration_informer.py)汇总了 sum(embedding_dimension)、动态/时间/静态实数特征数,外加 input_size * 2——这两个来自标定器产生的 log1p(abs(loc))log(scale) 特征。它决定了 InformerValueEmbedding 的输入通道数,也解释了为何输入构建阶段会自动把 loc/scale 作为静态特征喂入网络。

模型容量与训练参数

参数 默认值 含义
d_model 64 模型隐层维度(原版 "hidden_size")
encoder_ffn_dim / decoder_ffn_dim 32 / 32 编码器/解码器前馈网络维度
encoder_attention_heads / decoder_attention_heads 2 / 2 注意力头数
encoder_layers / decoder_layers 2 / 2 层数
is_encoder_decoder True 固定为 encoder-decoder 架构
activation_function "gelu" FFN 激活函数
dropout / attention_dropout / activation_dropout 0.05 / 0.1 / 0.1 整体 / 注意力 / FFN 两层之间的 dropout
encoder_layerdrop / decoder_layerdrop 0.1 / 0.1 训练期随机跳过层的概率(LayerDrop)
init_std 0.02 权重初始化标准差
use_cache True 是否使用自回归缓存(Cache

Informer 特有机制参数

参数 默认值 含义
attention_type "prob" 编码器使用的注意力类型:"prob" 为 Informer 的 ProbSparse 注意力,"full" 为普通自注意力
sampling_factor 5 ProbSparse 采样因子,仅在 attention_type="prob" 时生效,控制缩减后的 query 矩阵 Q_reduce 长度
distil True 编码器是否启用蒸馏(distilling)
num_parallel_samples 100 推理时每个时间步并行生成的样本数(用于概率预测)

loss 参数默认 "nll"(负对数似然),目前是参数化分布唯一支持的损失;distribution_output 默认 "student_t",可选 "normal""negative_binomial"

从配置初始化一个模型

配置 docstring 给出了最小可运行示例:

>>> from transformers import InformerConfig, InformerModel

>>> # 用 12 个时间步作为预测长度初始化配置
>>> configuration = InformerConfig(prediction_length=12)

>>> # 用随机权重初始化模型
>>> model = InformerModel(configuration)

>>> # 访问模型配置
>>> configuration = model.config

若想直接使用社区预训练 checkpoint,也可以跳过 InformerConfig,用 from_pretrained 加载(参考本文后面示例中的 "huggingface/informer-tourism-monthly")。

ProbSparse 自注意力的源码实现

ProbSparse 注意力是 Informer 最具辨识度的创新,其核心类为 InformerProbSparseAttentionmodeling_informer.py),docstring 与论文保持一致:"选择活跃 query 而非懒惰 query,提供稀疏 Transformer,缓解 vanilla attention 的二次计算与内存需求"。

关键计算步骤

forward 中(modeling_informer.py),Q/K/V 投影完成并 reshape 到多头后,算法依次执行:

  1. 有放回地采样一部分 key:设 key 时间长度为 L_K,query 时间长度为 L_Q,先计算 u_part = min(sampling_factor * L_Q * log1p(L_K), L_K),然后 torch.randintL_K 内采样 u_part 个 index,得到缩减的 k_sample。代码使用 math.ceil(math.log1p(L)) 近似 log L,这是论文中 O(L log L) 复杂度的直接体现。

  2. 用缩减 key 估计稀疏度并选 top-k query:对所有 query 计算与采样 key 的点积 Q_K_sampled,得到每个 query 的稀疏度量 M = max(Q_K_sampled) - mean(Q_K_sampled)modeling_informer.py),再对 Mtopk(u)u = min(sampling_factor * log1p(L_Q), L_Q),得到"最活跃"的 query 索引 q_reduce

  3. 仅对活跃 query 做完整注意力:用 q_reduce 与全部 key 计算 attn_weights 与 softmax,dropout 后与 value 做 bmm

  4. 上下文补齐(context filling):非活跃位置的输出并不是丢弃,而是由 value 的统计量填充——解码器(is_decoder=True)用 value 沿时间维的 cumsum 作为上下文(modeling_informer.py),编码器则用 value 沿时间维的均值广播(modeling_informer.py),随后把稀疏注意力的真实输出写回到 top-k 位置(modeling_informer.py)。这样既保持了输出张量的形状,又让梯度能沿着挑选出的活跃路径传播。

采样因子对稀疏度的控制

sampling_factor 直接决定上面 u_partu 的规模:因子越大,参与稀疏度量与最终注意力的 query/key 越多,接近 full attention,开销上升;因子越小越稀疏、越省显存与算力。若 sampling_factor 或长度取极端值使 u == 0,代码会退化为使用全部 query(modeling_informer.py)。

full attention 的可切换性

编码器的注意力在 InformerEncoderLayer 中会根据 config.attention_type 选择 InformerAttention(普通实现)还是 InformerProbSparseAttention。这一点让 Informer 也可以作为普通 Transformer 时序模型运行,便于做稀疏/非稀疏的消融对比——正如配置 docstring 所说明的 attention_type="full" 表示"vanilla transformer 的标准自注意力"。

自注意力蒸馏(Distilling)与编码器结构

InformerEncodermodeling_informer.py)负责把原始输入转成可计算的特征序列:

  1. InformerValueEmbeddingmodeling_informer.py)将 feature_size 维输入映射到 d_model(内部使用 Conv1d + GELU,随后投影);
  2. 叠加 InformerSinusoidalPositionalEmbeddingmodeling_informer.py)生成的正弦位置向量,经过 layernorm_embedding 与 dropout;
  3. 逐层执行编码器层,并在相邻层之间根据 config.distil 插入 InformerConvLayer

蒸馏的关键在于 InformerConvLayermodeling_informer.py):它用 kernel_size=3、stride 为 2 的 Conv1d + ELU + MaxPool1d 把序列的时间维减半。编码器构建 conv_layers 的代码显示(modeling_informer.py):当 distil=True 时,encoder_layers - 1 个层后各接一个卷积层、最后一层不接;当 distil=False 时则完全不使用卷积。这种"逐层减半"正是论文所说"突出主导注意力、高效处理超长输入"的实现——深层编码器的序列长度指数级收缩,显著降低后续层与交叉注意力的计算量。测试中的 @slow 用例 expected_shape = torch.Size((64, model.config.context_length // 8, model.config.d_model))test_modeling_informer.py)恰好验证了 distilling 后长度除以 8 的效果。

输入特征体系:past、future 与协变量约定

时序 Transformer 与 BERT 这类模型的关键区别之一在于位置信息由外部时间特征提供而非内部学习。从 InformerModel.forwardInformerForPrediction.forward 的 docstring(modeling_informer.py)可以整理出完整输入契约:

  • past_values:形状 (batch_size, sequence_length) 或加 input_size 维。序列长度必须大于 context_length,因为模型需要更长的历史来构造滞后特征;_past_length = context_length + max(lags_sequence)modeling_informer.py),在默认 lags_sequence 下即 context_length + 7
  • past_time_features:形状 (batch_size, sequence_length, num_features)num_features = num_time_features + num_dynamic_real_features。它们是输入的时间特征(月份、日期、节假日,乃至随时间单调增长的 age 特征),承担"位置编码"的角色。动态实数协变量也可以拼接进来,前提是预测期可知。
  • past_observed_mask:布尔张量,1 表示观测到、0 表示缺失(缺失值须先用 0 填充)。它同时参与标定器(scaler)的均值/方差统计。
  • static_categorical_features / static_real_features:全时间步恒定。类别特征会经 InformerFeatureEmbedder 逐特征查 embedding 后拼接(modeling_informer.py),典型例子是时间序列 ID、促销信息等。注意 Informer 只对静态类别特征学习 embedding
  • future_values:形状 (batch_size, prediction_length),训练时的标签,配合 future_time_features 一起送入解码器。
  • future_time_features:预测窗口的时间特征,推理阶段由调用方提供,模型据此生成未来输入。

标定流程在 create_network_inputs 中体现(modeling_informer.py):取最近 context_length 的观测上下文喂给 scaler,得到 locscale,再对 past 与 future 拼接后的整段序列做 (x - loc) / scale 归一化。InformerModel.__init__modeling_informer.py)根据 config.scaling 选择 InformerMeanScaler / InformerStdScaler / InformerNOPScaler 三种标定器(定义于 modeling_informer.py),标准差标定还带 minimum_scale=1e-5 的数值保护。locscale 与静态特征会作为模型的额外输入(log1p(abs(loc))log(scale))参与特征拼装,并在输出中一并返回以便反归一化。

InformerModel:编码器-解码器组合使用

InformerModel 内部维护 self.encoderself.decoder 与 scaler/embedder。它的 forward 流程(modeling_informer.py)是:

  1. 调用 create_network_inputs 生成规整后的 transformer_inputs
  2. 把前 context_length 段送入 encoder;
  3. context_length 之后(含 future)的段送入 decoder,做 encoder-decoder 交叉注意力;
  4. 返回 Seq2SeqTSModelOutput(含 decoder 输出、encoder 隐状态、locscalestatic_features)。

当只给 past 不给 future 时,它也能运行——解码器输入会回退到零张量占位,为生成式预测预留接口。

模型 docstring 的官方示例展示了训练形态的调用(下载一个批量数据文件后直接前向):

>>> from huggingface_hub import hf_hub_download
>>> import torch
>>> from transformers import InformerModel

>>> file = hf_hub_download(
...     repo_id="hf-internal-testing/tourism-monthly-batch", filename="train-batch.pt", repo_type="dataset"
... )
>>> batch = torch.load(file)

>>> model = InformerModel.from_pretrained("huggingface/informer-tourism-monthly")

>>> # 训练时同时提供 past 与 future 值及可能的附加特征
>>> outputs = model(
...     past_values=batch["past_values"],
...     past_time_features=batch["past_time_features"],
...     past_observed_mask=batch["past_observed_mask"],
...     static_categorical_features=batch["static_categorical_features"],
...     static_real_features=batch["static_real_features"],
...     future_values=batch["future_values"],
...     future_time_features=batch["future_time_features"],
... )

>>> last_hidden_state = outputs.last_hidden_state

InformerForPrediction:概率输出头、训练损失与采样预测

InformerForPredictionmodeling_informer.py)在 InformerModel 之上做了三件事:

  • 依据 config.distribution_output 实例化 StudentTOutput / NormalOutput / NegativeBinomialOutput(定义于 src/transformers/time_series_utils.py),并用 get_parameter_projection(d_model) 把 decoder 输出投影为分布参数;
  • 依据 config.loss 选择 nll 作为损失;
  • 对缺失标签用 weighted_average 掩码平均(modeling_informer.py),避免 nan * 0 污染梯度。

官方 docstring 的训练 + 推理示例是"复制即用"的模板:

>>> from huggingface_hub import hf_hub_download
>>> import torch
>>> from transformers import InformerForPrediction

>>> file = hf_hub_download(
...     repo_id="hf-internal-testing/tourism-monthly-batch", filename="train-batch.pt", repo_type="dataset"
... )
>>> batch = torch.load(file)

>>> model = InformerForPrediction.from_pretrained("huggingface/informer-tourism-monthly")

>>> # 训练:同时提供 past 与 future 值
>>> outputs = model(
...     past_values=batch["past_values"],
...     past_time_features=batch["past_time_features"],
...     past_observed_mask=batch["past_observed_mask"],
...     static_categorical_features=batch["static_categorical_features"],
...     static_real_features=batch["static_real_features"],
...     future_values=batch["future_values"],
...     future_time_features=batch["future_time_features"],
... )

>>> loss = outputs.loss
>>> loss.backward()

>>> # 推理:只提供 past 值,模型自动生成未来样本
>>> outputs = model.generate(
...     past_values=batch["past_values"],
...     past_time_features=batch["past_time_features"],
...     past_observed_mask=batch["past_observed_mask"],
...     static_categorical_features=batch["static_categorical_features"],
...     static_real_features=batch["static_real_features"],
...     future_time_features=batch["future_time_features"],
... )

>>> mean_prediction = outputs.sequences.mean(dim=1)

generate 的并行采样语义

InformerForPrediction.generatemodeling_informer.py)是"生成式解码器"的落地:在 forward 中传入 future_values=None,编码器处理历史、交叉注意力缓存被复用(use_cache=True);随后按 num_parallel_samples(默认 100)把 loc/scalerepeat_interleave,对分布进行并行采样来获得多个轨迹。返回的 SampleTSPredictionOutput.sequences 形状为 (batch_size, num_parallel_samples, prediction_length)(多变量时为 (batch_size, num_parallel_samples, prediction_length, input_size)),因此上面的 mean_prediction = outputs.sequences.mean(dim=1) 就是对 100 条样本取平均得到的点预测。

值得注意的源码细节:forward 中只要提供了 future_values 就会强制 use_cache=Falsemodeling_informer.py),因为训练形态下 decoder 一次性看到整段 future,不需要自回归缓存。

测试与可验证的行为约定

测试文件 一方面作为 CI 保护,另一方面也精确记录了模型的行为规格:

  • InformerModelTester 的默认超参组合(test_modeling_informer.py)给出了一个可直接照抄的小配置:batch_size=13prediction_length=7context_length=14,并显式传递 lags_sequencescalingnum_time_features 等字段——从中可以看到静态类别特征被编码成长度为 cardinality[0] 的 id、静态实数特征为单列、past_time_features 的第三维等于 config.num_time_features 等张量约定;
  • InformerModelTest 断言 encoder/decoder 的注意力形状分别为 (heads, context_length, context_length)(heads, prediction_length, context_length) 量级(test_modeling_informer.py),并覆盖 cache、padding、generate 输出形状((batch, num_parallel_samples, prediction_length))等(test_modeling_informer.py)。

也就是说,本文前面提到的所有关键约定(_past_length、encoder 输入长度为 context_length、decoder 输出长度为 prediction_lengthgenerate 采样维度)都能在测试断言中找到对应证据。

小结

Informer 在 Transformers 中的实现可以归纳为三个"机制—代码"对照:

论文机制 源码落点 关键配置
ProbSparse 自注意力 InformerProbSparseAttention attention_type="prob"sampling_factor
自注意力蒸馏 InformerConvLayer + InformerEncoder.conv_layers distil=Trueencoder_layers
生成式解码器 InformerForPrediction.generate(并行采样) prediction_lengthnum_parallel_samples

同时它继承了 Transformers 时序家族统一的输入协议(past/future 值、时间特征、观测掩码、静态类别/实数特征、标定器),并通过 distribution_output 支持 Student-T / Normal / Negative-Binomial 概率输出,从而既能做点预测,也能输出带不确定性的样本轨迹。

进一步探索可以从三个入口继续:完整的端到端训练/微调流程见 examples 与官方模型卡片配套脚本;想对比 ProbSparse 与普通注意力的行为差异,可阅读 InformerAttentionInformerProbSparseAttention 两段实现并切换 attention_type;若要给 InformerConfig 增加字段或调整默认逻辑,请遵循 modular 工作流修改 modular_informer.py,再由其重新生成 modeling_informer.py。模型文档原文见 docs/source/en/model_doc/informer.md

登录后查看全文
热门项目推荐
相关项目推荐