Skip to content

Level 4 单任务桥接层

Abstract

入口:

python
strategy.execute(series_name, model_factory)

这一层解释:

Level 3 里被 schedule(...) 提交出去的单任务体,怎样先经过 ForecastingStrategy.execute(...) 这个通用外壳,再进入 RollingForecast._execute(...),最后把控制权交给 _eval_batch(...)

1. 上一层与当前层位置

上一层是:

当前层对应上一层中的这两个节点:

  • 3B 被调度任务体
  • 3C RollingForecast 任务主体

更具体地说,Level 4 从上一层承接的是这条已经在 23 中解释清楚的顺序链:

text
schedule(strategy.execute, (series_name, model_factory))
-> strategy.execute(series_name, model_factory)
-> ForecastingStrategy.execute(...)
-> self._execute(...)
-> RollingForecast._execute(...)

更准确地说:

  1. Level 3 负责说明:
    • eval_model(...) 怎样把任务提交出去
  2. Level 4 负责说明:
    • 被提交出去的这个任务体,内部先后怎样推进

所以这一层不是凭空跳出来的。
它就是上一层这条边的展开:

text
3A-2 schedule(...)
-> 3B ForecastingStrategy.execute(...)
-> 3C RollingForecast._execute(...)

1.5 这一层的关系类型说明

这一层要同时看两个函数,但它们不是并列顶层对象,而是:

  1. ForecastingStrategy.execute(...)
    • 通用外壳
  2. RollingForecast._execute(...)
    • 具体策略实现入口

所以这一层的结构是:

text
单任务桥接层
├─ 4A ForecastingStrategy.execute 通用外壳
└─ 4B RollingForecast._execute 策略实现入口

其中:

  • 4A 负责设 seed、取 data/meta_info、调用 self._execute(...)
  • 4B 负责实例化模型、判断路由、进入 _eval_batch(...)

2. 当前层第一性

这一层的第一性是:

把 Level 3 里“已提交的单序列任务”,推进成“真正进入 rolling batch 主体 _eval_batch(...) 的具体执行链”。

所以这层的功能不是:

  • 训练模型
  • 做预测
  • 算指标

而是:

  1. 衔接 schedule(...) 和真正业务主体
  2. 把通用策略外壳和 rolling 策略入口串起来

3. 当前命令的最小例子

当前例子里:

  • series_name = "ETTh1.csv"
  • model_factory = DLinear 对应的 ModelFactory
  • strategy = RollingForecast(...)

所以 Level 3 里真正提交出去的任务是:

python
strategy.execute("ETTh1.csv", model_factory)

而 Level 4 解释的就是这句内部会发生什么:

python
ForecastingStrategy.execute(...)
-> self._execute(...)
-> RollingForecast._execute(...)
-> self._eval_batch(...)

4. 先看顺序图

这张图回答的是:

Level 3 里那个被调度任务体,在时间顺序上到底怎样推进到 _eval_batch(...)

5. 再看抽象索引树

这棵树回答的是:

为了理解被调度任务体,人脑应该先把它分成哪两个桥接节点。

6. 职责树

6.1 4A ForecastingStrategy.execute(...)

职责:

  • 读取 deterministicseed
  • 固定随机性
  • DataPool 中取:
    • data
    • meta_info
  • 把控制权交给 self._execute(...)

6.2 4B RollingForecast._execute(...)

职责:

  • model_factory() 实例化本次任务使用的模型
  • 判断走:
    • _eval_sample(...)
    • 还是 _eval_batch(...)
  • 在当前例子里进入 _eval_batch(...)

7. 输入输出接口

7.1 本层总入口接口

python
strategy.execute(series_name, model_factory)

输入:

  • series_name
  • model_factory

7.2 4A 的出口

python
self._execute(data, meta_info, model_factory, series_name)

7.3 4B 的出口

当前例子里出口是:

python
self._eval_batch(series, meta_info, model, series_name)

8. 函数 / 文件关系图

9. 当前例子的具体落地

9.1 Level 3 到 Level 4 的真实连接点

eval_model(...) 里真正提交的是:

python
eval_backend.schedule(strategy.execute, (series_name, model_factory))

所以进入 Level 4 的真实入口不是“凭空出现的 RollingForecast”,而是:

python
strategy.execute("ETTh1.csv", model_factory)

这句会先进入 ForecastingStrategy.execute(...),对应代码骨架是:

python
def execute(self, series_name, model_factory):
    deterministic_mode = ...
    seed = ...
    data_pool = DataPool().get_pool()
    data = data_pool.get_series(series_name)
    meta_info = data_pool.get_series_meta_info(series_name)
    single_series_results = self._execute(
        data, meta_info, model_factory, series_name
    )
    return single_series_results

9.2 为什么后面会到 RollingForecast._execute(...)

因为:

  • strategy 当前实际类型是 RollingForecast
  • execute(...) 定义在 ForecastingStrategy 基类里
  • execute(...) 内部会调:
python
self._execute(data, meta_info, model_factory, series_name)

而当前 selfRollingForecast
所以这句最终会动态分派到:

python
RollingForecast._execute(...)

这就是 Level 3 和 Level 4 真正接上的地方。

9.3 当前例子的完整桥接代码

对当前 RollingForecast 例子,可以直接压成:

python
strategy.execute("ETTh1.csv", model_factory)
-> ForecastingStrategy.execute("ETTh1.csv", model_factory)
-> self._execute(data, meta_info, model_factory, "ETTh1.csv")
-> RollingForecast._execute(data, meta_info, model_factory, "ETTh1.csv")

然后 RollingForecast._execute(...) 里再继续:

python
model = model_factory()
return self._eval_batch(series, meta_info, model, series_name)

10. 下一层入口

下一层只继续展开:

python
RollingForecast._eval_batch(...)

也就是当前层索引树里的:

  • 4B-3 进入 _eval_batch(...)

对应:

11. 只留一句

Level 4 不是“突然从 eval_model 跳到 RollingForecast”,而是把 schedule(strategy.execute, ...) 这条被提交任务体,继续展开成 ForecastingStrategy.execute(...) -> RollingForecast._execute(...) -> _eval_batch(...)

*记录并在线阅读我的笔记*