T
traeai
登录
返回首页
Towards Data Science

微调Chronos-2时间序列基础模型的五种方法

8.2Score
微调Chronos-2时间序列基础模型的五种方法

TL;DR · AI 摘要

Chronos-2时间序列基础模型可通过LoRA微调解决零样本预测偏差,文章详解了单建筑适配、组合池化、协变量注入等五种实战场景及数据划分规范。

核心要点

  • 使用LoRA冻结120M参数主模型,仅训练低秩适配器以高效适配私有数据。
  • 定义Train/Val/Context/Test四段式数据切分,确保微调与推理无数据泄露。
  • 提供5种微调模板:单体适配、组合池化、协变量感知、混合模式及留出迁移。

结构提纲

按章节快速跳转。

  1. 当数据分布偏离预训练集或存在系统性误差时,零样本预测不足,需通过微调对齐下游目标。

  2. 涵盖单资产适配、多资产池化、协变量注入、混合策略及未见资产迁移五类工程化模板。

  3. 采用Train/Validation/Inference Context/Test四窗口划分,严格隔离微调训练与测试推理数据。

  4. ·LoRA技术原理

    通过低秩适配冻结原始权重矩阵,仅学习少量附加参数以修改模型行为,降低计算存储成本。

思维导图

用一张图看清主题之间的关系。

查看大纲文本(无障碍 / 无 JS 友好)
  • Chronos-2 Fine-Tuning
    • 5 Scenarios
      • Single-building
      • Portfolio + Covariates
    • Technical Basis
      • LoRA Adaptation
      • Data Split Strategy

金句 / Highlights

值得收藏与分享的关键句。

  • 当数据分布不同于预训练集或下游目标不一致时,零样本预测往往不够用。

    引言

    ⬇︎ 下载 PNG𝕏 分享到 X
  • LoRA冻结原始预训练模型,仅学习少量附加参数来高效修改模型行为。

    第2.2节

    ⬇︎ 下载 PNG𝕏 分享到 X
  • 时间线被划分为训练(12周)、验证(1周)、推理上下文(45天)和测试(1周)以防止泄露。

    第1节

    ⬇︎ 下载 PNG𝕏 分享到 X
#Chronos-2#时间序列基础模型#LoRA#微调#预测
打开原文

标题:微调时间序列基础模型 Chronos-2 的五种方法

URL 来源:https://towardsdatascience.com/five-ways-to-fine-tune-chronos-2-the-time-series-foundation-model/

发布时间:2026-06-04T16:30:00+00:00

Markdown 内容: 在本系列的第一部分中,我们介绍了 Chronos-2 这一时间序列基础模型。我们通过一个实际案例进行了实操演练,了解了 Chronos-2 在无需训练的情况下开箱即用的能力。

但正如我们在第一部分结尾所指出的,零样本(zero-shot)预测并不总是足够的

在以下情况下:

  • 你的数据可能与预训练混合数据集中的任何数据都截然不同。
  • 模型持续出现系统性错误。
  • 你确实拥有可以利用的丰富历史数据。
  • 你的下游目标可能与 Chronos-2 训练时所优化的目标不一致。

微调(Fine-tuning)是顺理成章的下一步。

在本文中,我们将延续第一部分中的建筑电力需求案例研究,并详细介绍 Chronos-2 的五种微调场景:

  1. 单栋建筑适配:如何针对单一资产进行微调。
  2. 资产组合微调:如何汇总整个资产集群的历史数据以训练共享适配器。
  3. 协变量感知微调:如何利用已知未来信号进行微调。
  4. 资产组合 + 协变量:如何同时利用协变量和资产集群信息。
  5. 留出集迁移:如何进行一次性适配,然后部署到微调期间模型从未见过的资产上。

读完本文后,你将获得一套可直接用于自身数据的 TSFM 微调实用模板。

本系列第一部分介绍了如何使用 Chronos-2 进行单变量、多变量、协变量感知及跨学习场景的预测。如果你想直接使用开箱即用的 Chronos-2,请查阅这篇文章

  • * *

1. 案例回顾

让我们快速回顾一下第一部分的实验设置。

我们拥有一个包含八栋商业建筑的合成数据集,记录了每小时的电力需求。我们要解决的任务是预测未来一周(即 168 小时)的总电力负荷。我们使用物理模拟器生成该数据集,其中总负荷被分解为基础负荷、插座负荷、照明负荷和暖通空调(HVAC)负荷。从物理机制上看,插座和照明负荷由工作日的占用模式决定,而 HVAC 负荷则由室外温度决定。

第二部分的新变化在于,我们模拟了更长的时间跨度,以便拥有用于微调的数据。同时,我们在微调数据和推理数据之间保持了严格的隔离。具体而言,我们将时间线划分为四个连续的窗口:

  • 训练集(12 周):2025-03-01 至 2025-05-22,这是微调过程唯一可见的窗口。
  • 验证集(1 周):2025-05-23 至 2025-05-29,用于检查点选择和早停(early stopping)。
  • 推理上下文(45 天):2025-05-30 至 2025-07-13,预测时用作上下文的窗口。第一部分中的零样本流程同样使用了 45 天的上下文。
  • 测试集(1 周):2025-07-14 至 2025-07-20,用于测试微调模型的预测范围。

请注意,微调过程仅能访问训练集和验证集中的数据,因此分析中不存在数据泄露问题。

图片 1

图 1. 训练集/验证集/上下文/测试集划分。(作者供图)

  • * *

2. 微调与 LoRA 简介

在开始实战演练之前,我们先简要讨论一下微调的概念及其一项具体技术——LoRA。

2.1 什么是微调?

微调是指在我们自己的数据上继续训练预训练模型。实际上,我们是在调整预训练模型的权重,使其能够理解并遵循特定于我们问题的模式。

具体到 Chronos-2,它是一个拥有 1.2 亿参数的 Transformer 模型,已经学习了大量通用的时间序列结构。微调使我们能够进一步引导其行为,使其更贴合我们的数据分布。

但是,我们是否需要更新全部 1.2 亿个参数?

可能不需要。

全量更新在计算和存储方面成本高昂。此外,在实际应用中,我们可能没有足够的数据来支撑对所有 1.2 亿个参数的调整。

我们需要一种更高效的微调方法。LoRA 就是其中一种解决方案。

2.2 什么是 LoRA?

LoRA 代表低秩适配(Low-Rank Adaptation)[1]。其核心思想很简单:不更新完整的权重矩阵,而是冻结原始预训练模型,仅学习一小组额外参数来轻微修改其行为。

举个例子,假设预训练模型中的某一层包含一个权重矩阵 _W_,形状为 d_out x d_in,其中 d_out=d_in=1024。

权重矩阵的更新意味着:

图片 2

那么,_ΔW_ 的大小也必须是 1024 x 1024。如果我们想进行全量更新,就意味着要更新超过一百万个可训练参数。

LoRA 采用的技巧是不将 _ΔW_ 作为完整矩阵进行学习。相反,LoRA 将其表示为两个小得多的矩阵的乘积:

图片 3

其中 _A_ 的形状为 _r_ x d_in,B 的形状为 d_out x _r_。这里的 _r_ 是适配器的(rank)。之所以称之为低秩方法,是因为 _r_ 通常非常小,例如 4、8、16 或 32。

这意味着 LoRA 不允许微调对 _W_ 进行任意的全维度更改。更新被限制在一个低维子空间内。而这种限制正是效率的来源。

这在实践中行之有效,因为许多下游适配任务并不需要模型在所有可能的方向上都发生改变。通常,有效的变化仅存在于一个更小的子空间中。LoRA 正是直接利用了这一假设。

在实际应用中,这为我们带来了多重优势。由于可训练参数大幅减少,由梯度和优化器状态占用的 GPU 显存可以显著降低。同时,检查点文件也更小,因为我们无需为每次实验都保存一份包含 1.2 亿参数的完整模型副本,只需保存适配器即可。此外,这也降低了过拟合风险,尤其是在下游数据集规模不大的情况下。

3. 如何对 Chronos-2 应用 LoRA?

要对 Chronos-2 模型应用 LoRA,首先需要确定我们希望适配 Chronos-2 的哪些层。

要回答这个问题,我们应先了解模型的构建方式。

第一部分中,我们解释了 Chronos-2 是一个 Transformer 编码器,由三个基本模块组成:

  1. 输入 Patch Embedding。
  2. 一系列注意力层,在时间注意力和组注意力之间交替。
  3. 输出 Patch Embedding。

我们的 LoRA 配置针对这三个模块中的两个进行适配:

  • 每个注意力层中的 Q、K、V 和 O 投影。通过这部分,我们可以微调模型在每个序列内部的时间维度上以及组内各序列之间的注意力机制。

_在 Chronos-2 中,每个注意力层包含四个线性投影,用于将层的输入映射到输出。查询(Q)、键(K)和值(V)生成输入的三种不同视图,随后注意力机制计算每个查询与每个键之间的相似度分数,并利用这些分数对值进行加权聚合。结果接着通过输出投影(O),该投影整合各个注意力头的信息,并将其重塑回符合层标准输出维度的形状。_

  • 输出 Patch Embedding。这使我们能够微调模型将内部状态投射为最终预测结果的方式。

在代码中,配置如下:

code
LORA_CONFIG = {
    "r": 8,
    "lora_alpha": 16,
    "target_modules": [
        "self_attention.q",
        "self_attention.v",
        "self_attention.k",
        "self_attention.o",
        "output_patch_embedding.output_layer",
    ],
}

其中 lora_alpha 是一个缩放因子。它控制 LoRA 更新的施加力度,α 值越大意味着适配越激进。

在本研究中,我们使用 Hugging Face 的 peft 库来微调 Chronos-2。

现在,我们可以开始动手实践了。

  • * *

4. 五种微调场景

在接下来的实验中,我们同样从相同的基础模型(即 amazon/chronos-2 检查点)出发,并使用相同的 LoRA 配置。不同的是用于微调的数据。

我们将使用的主要评估指标是加权绝对百分比误差:

Image 4

基于上述设置,让我们逐一探讨这五种场景。

_如果您尚未搭建好 Chronos 环境,请参考**第一部分:4.1 设置 Chronos-2 模型**。_

4.1 单栋建筑适配

_能否仅针对单个资产进行微调?_

假设我们只关注一栋建筑,例如 Building 03。我们拥有其历史负荷数据,并希望让 Chronos-2 适应该特定建筑的模式。

这是最简单的微调设置。没有协变量,没有组合信息,仅有一个目标序列。

如前所述,我们从 amazon/chronos-2 检查点开始,保持基础模型冻结,仅在其之上训练一个小型 LoRA 适配器。

Chronos-2 的微调 API 要求训练数据以任务字典列表的形式提供。对于当前这种仅含目标的单变量任务,每个字典只需包含一个键:target

对于 Building 03,我们可以这样准备微调输入数据:

code
story_building = "Building 03"
train_df = full_df[full_df["timestamp"] < "2025-05-23"]

single_building_train = train_df[
    train_df["building"].eq(story_building)
].sort_values("timestamp")

train_inputs = [
    {
        "target": single_building_train[["total_load_kw"]]
        .to_numpy(dtype="float32")
        .T
    }
]

上述代码之所以需要“转置”操作,是因为 Chronos-2 期望目标数组的形状为:

(num_target_series, time_steps) 由于我们只有一个单变量目标,因此形状为:

(1, T) 除了训练数据外,我们还应以相同格式准备验证数据:

code
validation_df = full_df[full_df["timestamp"] < "2025-05-30"]
single_building_validation = validation_df[
    validation_df["building"].eq(story_building)
].sort_values("timestamp")

validation_inputs = [
    {
        "target": single_building_validation[["total_load_kw"]]
        .to_numpy(dtype="float32")
        .T
    }
]

这里有两点值得说明:

首先提醒一下:此处的验证数据并非用于更新 LoRA 适配器,而是用于决定保留哪个适配器检查点。这与训练神经网络模型时通常采用的模式一致。

其次,您可能会注意到 validation_df 不仅包含 5 月 23 日至 29 日的数据,还包含了之前的所有数据。我们需要这些数据是因为 Chronos-2 在进行预测时需要上下文信息。根据设定的 prediction_length,Chronos 会在内部将 validation_df 的最后 prediction_length 个小时作为真实的验证预测目标,而之前的数值则作为上下文。

_在当前案例中,我们在 validation_inputs 中仅配置了一个验证任务。这意味着我们实际上只有一个验证预测窗口,因为 Chronos-2 在内部始终将 DataFrame 的最后 prediction_length 个时间步作为目标窗口,并将其之前的_ _context_length 个时间步作为上下文,无论你在该 DataFrame 中输入了多少额外的时间步。换句话说,仅仅输入更长的验证 DataFrame 并不会自动创建更多的验证窗口。_

_在实践中,如果你需要更多的验证预测窗口(例如进行滚动窗口验证),则需要创建多个验证任务,每个任务在不同的截止日期结束。这样,Chronos-2 就会对每个任务的最后 168 小时进行验证。_

_不过,对于训练而言,我们不需要任何特殊处理,只需向 Chronos-2 传入一个较长的历史序列,让它在内部自行采样生成多个训练窗口即可。_

现在我们可以开始微调了:

code
fine_tuned_model = base_model.fit(
    train_inputs,
    prediction_length=168,
    validation_inputs=validation_inputs,
    finetune_mode="lora",
    lora_config=LORA_CONFIG,
    context_length=1080,         # 45-day context window
    learning_rate=2e-5,
    num_steps=1000,
    batch_size=32,
    output_dir="finetuned_models/fine_tuning_modes/single_target",
    finetuned_ckpt_name="checkpoint",
    callbacks=[EarlyStoppingCallback(early_stopping_patience=6)],
    save_steps=25,
    eval_steps=25,
)

这里,我们将 prediction_length 设置为 168,以确保模型针对测试时关心的任务进行训练,即未来一周的逐小时预测。此外,我们将 context_length 设置为 45 * 24,表示 45 天的上下文窗口。这与我们在第 1 部分中使用的上下文长度一致。最后,由于使用了 validation_inputs,检查点选择机制被激活。每训练 25 步,Chronos-2 会评估一次验证损失;如果验证损失连续 6 次评估均未改善(early_stopping_patience=6),早停机制将触发并终止微调过程。

Image 5

图 2. 训练损失持续下降,但验证损失在第一个检查点之后开始上升。(图片由作者提供)

我在配备 8 GB 显存的 NVIDIA RTX 2000 Ada Laptop GPU 上运行了此次微调任务,整个过程大约耗时 42 秒。

适配器训练完成后,推理过程与零样本预测几乎完全相同:

code
single_context = test_context_df[
    test_context_df["building"].eq(story_building)
][["building", "timestamp", "total_load_kw"]]

pred_single_finetuned = fine_tuned_model.predict_df(
    single_context,
    prediction_length=168,
    quantile_levels=[0.025, 0.5, 0.975],
    id_column="building",
    timestamp_column="timestamp",
    target="total_load_kw",
)

对于 Building 03,仅使用目标变量的零样本基线模型的 WAPE 为 8.3%。而仅针对 Building 03 进行微调后,WAPE 降至 7.6%。可以看出,微调确实带来了一定的性能提升。

4.2 组合级微调

_我们能否整合整个资产组合的历史数据来训练一个共享适配器?_

在实际应用中,我们通常拥有一个包含多个相关资产的组合。

在本例中,即八栋建筑。它们虽不完全相同,但遵循相似的日度和周度需求模式。

因此,下一个自然的问题是:我们能否在整个建筑组合上微调一个适配器,而不是每次只针对一栋建筑?

在此场景中,我们仍然只预测 total_load_kw,因此设置与之前几乎相同:

code
target_column = "total_load_kw"

train_inputs = [
    {
        "target": building_df[[target_column]].to_numpy(dtype="float32").T,
    }
    for _, building_df in train_df.groupby("building", sort=True)
]

validation_inputs = [
    {
        "target": building_df[[target_column]].to_numpy(dtype="float32").T,
    }
    for _, building_df in validation_df.groupby("building", sort=True)
]

实际上,每栋建筑都成为一个独立的训练任务。随后,我们使用与之前相同的 LoRA 配置对 Chronos-2 进行微调:

code
fine_tuned_model = base_model.fit(
    inputs=train_inputs,
    validation_inputs=validation_inputs,
    prediction_length=168,
    context_length=1080,
    lora_config=LORA_CONFIG,
    learning_rate=2e-5,
    max_steps=1000,
)

值得强调的是,这里我们并非训练八个独立的适配器,而是让 Chronos-2 学习一个适用于整个资产组合的共享适配策略。在实践中,如果各建筑之间存在重复出现的模式,适配器将有更多机会学习到这些规律。然而,如果每栋建筑完全独立,这种策略可能收效甚微。

微调结果如下所示,我们对比了零样本预测与微调后 Chronos-2 的预测质量:

code
Building      Zero-shot WAPE    Fine-tuned WAPE
Building 01   8.0%              7.4%
Building 02   12.2%             11.3%
Building 03   8.3%              7.5%
Building 04   8.0%              7.6%
Building 05   7.2%              6.8%
Building 06   10.9%             9.9%
Building 07   7.7%              7.2%
Building 08   6.6%              6.3%

可以看到所有建筑的预测精度均有提升,这是一个积极的信号,表明每栋建筑都从共享适配器中受益。

4.3 基于协变量的微调

_我们能否在微调过程中向 Chronos-2 提供已知协变量?_

到目前为止,Chronos-2 仅能观测到目标序列本身,即历史的 total_load_kw 数据。

但在我们的建筑需求预测场景中,我们确实了解或能够较为准确地预测潜在的驱动因素,包括室外温度、人员占用模式、太阳辐照度以及周末标识等。这些都是驱动 total_load_kw 变化的关键协变量。

因此,在这种微调场景下,我们希望了解是否不仅能在目标历史数据上微调 Chronos-2,还能利用目标序列与已知未来协变量之间的关系进行微调。

这就需要调整微调的输入格式。每个训练任务不再仅传入目标序列,还应包含 past_covariatesfuture_covariates

code
known_future_columns = [
    "outdoor_temp_c",
    "occupancy",
    "solar_irradiance",
    "is_weekend",
]

single_building_train = train_df[
    train_df["building"].eq(story_building)
].sort_values("timestamp")

train_inputs = [
    {
        "target": single_building_train[["total_load_kw"]]
        .to_numpy(dtype="float32")
        .T,
        "past_covariates": {
            column: single_building_train[column].to_numpy(dtype="float32")
            for column in known_future_columns
        },
        "future_covariates": {
            column: None
            for column in known_future_columns
        },
    }
]

past_covariates 部分包含协变量序列的历史值。在微调过程中,Chronos-2 能够学习到温度、人员占用率、太阳辐射以及周末标识等协变量的变化如何影响负荷。

future_covariates 部分则告知 Chronos-2 这些协变量在预测范围内也是可用的。这里我们将它们设为 None,因为 Chronos-2 会基于相同的历史序列在内部构建未来窗口。稍后在推理阶段,我们会像第 1 部分那样,通过 future_df 提供实际的未来协变量值。

微调调用本身几乎保持不变:

code
fine_tuned_model = base_model.fit(
    train_inputs,
    prediction_length=168,
    validation_inputs=validation_inputs,
    finetune_mode="lora",
    lora_config=LORA_CONFIG,
    context_length=1080,
    learning_rate=2e-5,
    num_steps=1000,
    batch_size=32,
    output_dir="finetuned_models/fine_tuning_modes/single_covariate",
    finetuned_ckpt_name="checkpoint",
    callbacks=[EarlyStoppingCallback(early_stopping_patience=6)],
    save_steps=25,
    eval_steps=25,
)

微调完成后,在推理时我们需要同时传入历史上下文和已知的未来协变量:

code
context_with_covariates = test_context_df[
    ["building", "timestamp", "total_load_kw"] + known_future_columns
]

future_covariates_df = test_truth_df[
    ["building", "timestamp"] + known_future_columns
]

pred_single_covariate = fine_tuned_model.predict_df(
    context_with_covariates,
    future_df=future_covariates_df,
    prediction_length=168,
    quantile_levels=[0.025, 0.5, 0.975],
    id_column="building",
    timestamp_column="timestamp",
    target="total_load_kw",
)

对于 Building 03,结合协变量的零样本 WAPE 为 4.0%。在该建筑上对协变量感知适配器进行微调后,WAPE 降至 2.8%,相对降幅达 30.7%。

这一提升幅度远超仅使用目标序列进行微调的效果。

这也带来了一个有趣的实践启示:有时最大的收益并非来自“微调”本身,而是用正确的信息来微调模型。

4.4 资产组合 + 协变量

_我们能否在微调中同时利用协变量和资产组合信息?_

前两个场景分别单独引入了“资产组合”和“协变量”。自然而然地,我们希望将两者结合使用。

我认为这种设置在许多实际应用场景中最具相关性,因为在实践中,我们很少只面对单一资产;而且通常情况下,我们确实拥有已知或可预测的外部信号,可以辅助目标序列的预测。同时利用这两者进行微调不仅合乎逻辑,往往也是更优的选择。

具体到当前案例,我们在全部八栋建筑上进行微调,对于每栋建筑,以 total_load_kw 作为目标,并将 outdoor_temp_coccupancysolar_irradianceis_weekend 作为已知未来协变量:

code
train_inputs = []

for building, building_df in train_df.groupby("building", sort=True):
    building_df = building_df.sort_values("timestamp")

    train_inputs.append(
        {
            "target": building_df[["total_load_kw"]]
            .to_numpy(dtype="float32")
            .T,
            "past_covariates": {
                column: building_df[column].to_numpy(dtype="float32")
                for column in known_future_columns
            },
            "future_covariates": {
                column: None
                for column in known_future_columns
            },
        }
    )

在上述代码片段中,我们为每栋建筑创建了一个训练任务。验证数据也采用相同的思路:每栋建筑对应一个验证任务,Chronos-2 会将每个任务的最后 168 小时作为验证预测窗口。

微调调用本身依然保持不变:

code
fine_tuned_model = base_model.fit(
    train_inputs,
    prediction_length=168,
    validation_inputs=validation_inputs,
    finetune_mode="lora",
    lora_config=LORA_CONFIG,
    context_length=1080,
    learning_rate=2e-5,
    num_steps=1000,
    batch_size=32,
    output_dir="finetuned_models/fine_tuning_modes/portfolio_covariate",
    finetuned_ckpt_name="checkpoint",
    callbacks=[EarlyStoppingCallback(early_stopping_patience=6)],
    save_steps=25,
    eval_steps=25,
)

在推理时,我们传入 45 天的历史上下文,以及预测周对应的已知未来协变量:

code
context_with_covariates = test_context_df[
    ["building", "timestamp", "total_load_kw"] + known_future_columns
]

future_covariates_df = test_truth_df[
    ["building", "timestamp"] + known_future_columns
]

pred_portfolio_covariate = fine_tuned_model.predict_df(
    context_with_covariates,
    future_df=future_covariates_df,
    prediction_length=168,
    quantile_levels=[0.025, 0.5, 0.975],
    id_column="building",
    timestamp_column="timestamp",
    target="total_load_kw",
)

下图展示了 Building 03 的微调结果,我们可以清楚地看到微调带来的提升:

Image 6

图 3. Building 03 的组合+协变量微调与纯零样本预测的对比。(图片由作者提供)

在全部八栋建筑中,纯零样本基线的 WAPE 为 8.4%。经过组合+协变量微调后,WAPE 降至 2.8%,相对降幅达 66.8%。

4.5 留出迁移

_我们能否只进行一次适配,然后将其部署到模型在微调期间从未见过的资产上?_

到目前为止,每个微调场景使用的都是后续推理阶段会出现的相同建筑。

但还有一个重要问题:如果一栋新建筑刚刚投入使用怎么办?

因此,在这最后一个场景中,我们在微调时保留了 Building 06,使 Chronos-2 在学习 LoRA adapter 时从未接触过它的数据。我们在其余七栋建筑上进行微调,同时使用目标历史数据和已知未来协变量。随后,在推理阶段,我们将该 adapter 应用于 Building 06。

代码改动很小:

code
held_out_building = "Building 06"

train_buildings = [
    building
    for building in sorted(train_df["building"].unique())
    if building != held_out_building
]

train_inputs = []

for building in train_buildings:
    building_df = train_df[
        train_df["building"].eq(building)
    ].sort_values("timestamp")

    train_inputs.append(
        {
            "target": building_df[["total_load_kw"]]
            .to_numpy(dtype="float32")
            .T,
            "past_covariates": {
                column: building_df[column].to_numpy(dtype="float32")
                for column in known_future_columns
            },
            "future_covariates": {
                column: None
                for column in known_future_columns
            },
        }
    )

接着,在推理阶段,我们针对 Building 06 进行预测:

code
building_06_context = test_context_df[
    test_context_df["building"].eq(held_out_building)
][["building", "timestamp", "total_load_kw"] + known_future_columns]

building_06_future_covariates = test_truth_df[
    test_truth_df["building"].eq(held_out_building)
][["building", "timestamp"] + known_future_columns]

pred_heldout = fine_tuned_model.predict_df(
    building_06_context,
    future_df=building_06_future_covariates,
    prediction_length=168,
    quantile_levels=[0.025, 0.5, 0.975],
    id_column="building",
    timestamp_column="timestamp",
    target="total_load_kw",
)

对于 Building 06,基于协变量的零样本基线 WAPE 为 4.2%。应用在其余七栋建筑上微调得到的 adapter 后,WAPE 降至 3.1%,相对降幅为 26.8%。

对于实际部署而言,我们当前的 Q5 研究代表了一种更具可扩展性的模式,即在一个具有代表性的资产组合上微调 adapter,然后在相关资产上线时直接部署。对于每个新资产,我们仍需提供其近期上下文和已知未来协变量,但无需立即重新微调——况且我们也没有足够的数据来支持重新微调。

5. 我们学到了什么?

在逐一探讨了五个场景之后,让我们将它们的结果并列对比。

对于每一行,我都将微调模型与对应的零样本基线进行比较。具体来说,仅使用目标的微调与仅使用目标的零样本预测对比,而基于协变量的微调则与基于协变量的零样本预测对比:

Image 7

图 4. 微调在所有五个场景中均带来了提升。基于协变量的设置获得了最大的收益。(图片由作者提供)

规律相当明显。仅使用目标的微调在一定程度上有所帮助,但效果有限。当我们向 Chronos-2 提供已知未来协变量并据此微调 adapter 时,才能获得更大的收益。留出迁移的结果同样令人鼓舞:即使对于未参与微调的建筑,adapter 也能从相关建筑中学习,并且性能依然优于基于协变量的零样本基线。

_完整 notebook 可在此处获取:__https://github.com/ShuaiGuo16/chronos-2-forecasting/blob/main/02\_chronos2\_fine\_tuning\_building\_demand.ipynb_

  • * *

参考文献

[1] LoRA: Low-Rank Adaptation of Large Language Models. arXiv, 2021.

AI 可能会生成不准确的信息,请核实重要内容