Appearance
Level 3 执行评测总顺序
Abstract
入口:
pythoneval_model(model_factory, series_list, evaluation_config)出口:
pythonEvalResult(strategy, result_list, model_factory, series_list)这一层只解释:
eval_model(...)怎样把“一个模型 + 一组序列 + 一套评测配置”变成“已提交的任务句柄集合”,并把它们封装成EvalResult。
1. 这一层在总主线里的位置
上一层是:
当前层对应上一层中的具体位置是:
2C 执行侧- 也就是:
python
eval_model(model_factory, data_name_list, evaluation_config)这一层对应的是 pipeline(...) 里的第 3 块:
- 执行评测
这一层还不继续细拆:
_eval_batch(...)内部四段forecast_fit(...)batch_forecast(...)
2. 当前层第一性
这一层的第一性是:
把
eval_model(...)的输入,转换成“已经提交出去的单序列评测任务集合”,再包装成EvalResult返回。
这一层的关键词只有三个:
strategyschedule(...)EvalResult
3. 输入与输出
3.1 输入
python
eval_model(model_factory, series_list, evaluation_config)输入包括:
model_factoryseries_listevaluation_config
3.2 输出
python
EvalResult(strategy, result_list, model_factory, series_list)输出不是最终指标,而是:
strategyresult_listmodel_factoryseries_list
其中最关键的是:
result_list里装的是TaskResult- 不是最终
DataFrame - 也不是最终 metric 数值
4. 当前例子的最小落地
当前命令下,这一层的输入是:
model_factory = DLinear 对应的 ModelFactoryseries_list = ["ETTh1.csv"]evaluation_config["strategy_args"]["strategy_name"] = "rolling_forecast"
所以这一层的真实业务含义可以压成一句:
为
DLinear在ETTh1.csv上提交一个 rolling forecast 评测任务,并返回一个EvalResult结果句柄对象。
5. 顺序图
这张图只回答:
eval_model(...)内部按什么顺序推进。
这张图只描述 eval_model(...) 自己内部的顺序。
它还没有展开被提交出去的任务体。
6. 包含树
这张树只回答:
eval_model(...)这一层里,外层壳和被提交任务体的结构关系是什么。
这一层最重要的结构结论是:
strategy.execute(...)不是和eval_model(...)并列,
而是挂在schedule(...)下面的任务体。
7. schedule(...) 怎么往下执行
eval_model(...) 里的真实代码是:
python
result_list.append(
eval_backend.schedule(strategy.execute, (series_name, model_factory))
)这里传给 schedule(...) 的是:
fn = strategy.executeargs = (series_name, model_factory)
所以从接口角度,它的语义就是:
python
schedule(
fn=strategy.execute,
args=(series_name, model_factory),
)而 schedule(...) 的下一步业务语义就是:
python
strategy.execute(series_name, model_factory)7.1 在 SequentialBackend 下
sequential_backend.py 的核心代码是:
python
res = SequentialResult()
res.put(fn(*args))
return res代入当前例子就是:
python
res.put(strategy.execute(series_name, model_factory))7.2 在 RayBackend 下
ray_backend.py 不会立刻在主线程执行 fn(*args),
而是先把:
fn = strategy.executeargs = (series_name, model_factory)
提交给 actor pool。
但任务真正开始执行时,业务入口仍然是:
python
strategy.execute(series_name, model_factory)所以无论 backend 是顺序还是 ray,
这一层真正的任务入口都一样:
python
strategy.execute(series_name, model_factory)8. Level 3 到 Level 4 的桥
Level 3 的出口不是直接到 _eval_batch(...)。
它先到:
python
strategy.execute(series_name, model_factory)然后在 forecasting.py 里,这个方法内部会执行:
python
self._execute(data, meta_info, model_factory, series_name)当前 self 的真实类型是:
RollingForecast
所以这句会动态分派到:
python
RollingForecast._execute(data, meta_info, model_factory, series_name)因此 Level 3 到 Level 4 的真实桥接链是:
9. 职责表
9.1 eval_model(...)
职责:
- 解析 strategy
- 解析 metrics
- 创建 evaluator
- 创建 strategy
- 为每个序列提交一个任务
- 返回
EvalResult
9.2 schedule(...)
职责:
- 接收:
- 一个任务函数
fn - 一组参数
args
- 一个任务函数
- 返回任务句柄
TaskResult
9.3 strategy.execute(...)
职责:
- 作为被提交任务体的真正入口
- 后续再进入
ForecastingStrategy.execute(...)
10. 文件 / 函数关系图
11. 下一层入口
下一层开始解释:
python
strategy.execute(series_name, model_factory)也就是:
- 先进入
ForecastingStrategy.execute(...) - 再进入
RollingForecast._execute(...)
对应:
12. 只留一句
Level 3 只做一件事:把
eval_model(...)里的schedule(strategy.execute, ...)这条链讲清楚,并把任务交给 Level 4。