Appearance
Level 8 _process 到 DLinear.forward
Abstract
入口:
pythonout_loss = self._process(input, target, input_mark, target_mark)当前例子里,它会进入:
pythonTransformerAdapter._process(...) -> self.model(input, input_mark, dec_input, target_mark) -> DLinear.forward(...)这一层解释:
训练循环里的统一前向入口,怎样先经过 adapter 做接口翻译,再进入 DLinear 的真实计算。
1. 上一层与当前层位置
上一层是:
当前层是:
- Level 8:训练线里最底部的前向路径。
这一层是你当前 debug_tfb_framework.py 和 run_benchmark.py 两条学习线重新汇合的地方。
1.5 这一层的关系类型说明
这一层是在继续下钻:
- Level 7 训练循环里的
7B 模型前向
所以这里的 8A / 8B / 8C:
- 是 一次前向路径内部的角色分层
- 不是新的同级业务流程
2. 当前层第一性
这一层要分清两个角色:
2.1 TransformerAdapter._process(...)
第一性:
把 TFB 训练循环提供的统一四元组接口,翻译成底层模型能接收的 forward 输入。
2.2 DLinear.forward(...)
第一性:
接收已经准备好的模型输入,并完成真正的数值计算,输出预测张量。
所以这层的核心不是一条线,而是两段不同职责的接力:
- adapter 负责接口翻译
- model 负责实际计算
3. 当前命令的最小例子
当前训练 batch 的真实 shape:
input.shape = (4, 96, 7)target.shape = (4, 72, 7)input_mark.shape = (4, 96, 4)target_mark.shape = (4, 72, 4)
当前 config 的关键值:
seq_len = 96label_len = 48horizon = 24pred_len = 24enc_in = 7
这一层的关键任务就是把上面这些变量变成:
dec_input.shape = (4, 72, 7)output.shape = (4, 24, 7)
4. 先看顺序图
5. 抽象索引树
6. 职责树
6.1 8A 统一接口层
职责:
- 给训练循环一个统一前向入口:
self._process(...)
6.2 8B adapter 翻译层
职责:
- 从
target中构造 decoder 输入dec_input - 把训练循环的四元组翻译成底层模型的 forward 接口
6.3 8C DLinear 真实计算层
职责:
- 基于
x_enc做分解和线性预测 - 输出未来
pred_len段预测值
7. 输入输出接口
7.1 本层入口接口
训练循环调用的是:
python
self._process(input, target, input_mark, target_mark)输入:
inputtargetinput_marktarget_mark
7.2 adapter 层关键中间变量
dec_inputoutput
7.3 DLinear.forward(...) 的接口
python
forward(x_enc, x_mark_enc, x_dec, x_mark_dec, mask=None)当前例子里实际映射是:
x_enc = inputx_mark_enc = input_markx_dec = dec_inputx_mark_dec = target_mark
7.4 本层输出
python
{"output": output}其中:
output.shape = (4, 24, 7)
8. 函数 / 文件关系图
9. 关键代码对应关系
9.1 统一前向入口
训练循环里:
python
out_loss = self._process(input, target, input_mark, target_mark)这一层并不知道当前模型是不是 DLinear。
它只知道:
_process(...)会给我一个out_loss["output"]
9.2 adapter 翻译
在 TransformerAdapter._process(...) 里:
python
dec_input = torch.zeros_like(target[:, -self.config.horizon :, :]).float()
dec_input = torch.cat([target[:, : self.config.label_len, :], dec_input], dim=1)
output = self.model(input, input_mark, dec_input, target_mark)这里最关键的是:
target[:, -horizon:, :]先提供未来部分的零占位target[:, :label_len, :]提供 decoder 已知历史尾部
所以:
text
dec_input = 历史尾部(label_len) + 未来零填充(horizon)在当前例子里:
label_len = 48horizon = 24
所以:
dec_input.shape = (4, 72, 7)
9.3 DLinear.forward(...)
在 DLinear.forward(...) 里:
python
dec_out = self.forecast(x_enc)
return dec_out[:, -self.pred_len :, :]当前任务是 short_term_forecast,所以:
- 它走
forecast(x_enc) - 并且只返回最后
pred_len=24步
这也说明:
虽然接口上 DLinear 接收了 4 个输入,但真正用来计算 forecast 的核心输入是
x_enc。
9.4 DLinear.encoder(...)
真正计算在这里:
python
seasonal_init, trend_init = self.decompsition(x)
seasonal_output = self.Linear_Seasonal(...)
trend_output = self.Linear_Trend(...)
x = seasonal_output + trend_output也就是:
- 先把输入分成 trend / seasonal
- 分别做线性映射
- 再相加得到预测结果
10. 当前例子的具体落地
10.1 训练循环输入
input = (4, 96, 7)target = (4, 72, 7)
10.2 adapter 构造的 dec_input
- 前 48 步来自
target[:, :48, :] - 后 24 步是零
所以:
dec_input = (4, 72, 7)
10.3 DLinear.forward 输出
DLinear 实际只围绕:
x_enc = (4, 96, 7)
进行计算,最后返回:
output = (4, 24, 7)
10.4 回到训练循环
然后训练循环再做:
python
target = target[:, -24:, :]
loss = criterion(output, target)所以这层和上一层正好闭环。
11. 当前层最重要的认知
这一层最重要的认知是:
self._process(...)不是多余中间层,它是 TFB 统一训练循环和具体模型之间的接口翻译层。
以及:
在当前 DLinear 例子里,adapter 仍然按 transformer family 的统一接口传 4 个输入,但 DLinear 的核心计算几乎只依赖
x_enc。
12. 下一层入口
如果后面还继续 DFS,下一个自然入口有两个方向:
- 继续拆
TransformerAdapter._process(...)- 专门看
dec_input语义
- 专门看
- 继续拆
DLinear.encoder(...)- 专门看
series_decomp + Linear_Seasonal / Linear_Trend
- 专门看
如果按当前主线,我更建议先停在这里,因为:
对 benchmark 主链理解来说,Level 8 已经打通了“训练循环 -> adapter -> 模型 forward”。
13. 只留一句
Level 8 只看一件事:统一训练循环怎样先经过 adapter 翻译,再进入 DLinear 的真实前向计算。