(The Pain of Learning: Gradient Descent & Backpropagation)

“所谓经验,不过是人们给自己的错误取的名字。” —— 奥斯卡·王尔德

“智能是压缩的副产品。” —— 本书核心论点

“学习不是天赋,是痛苦计算的产物。” —— 本章主旨


引言:从静态架构到动态进化

如果说前三章是在搭建静态的架构(骨骼与肌肉),那么这一章我们要注入灵魂——学习(Learning)

我们将探讨模型是如何从一堆随机初始化的参数,变成一个通晓人类语言的智者的。

这个过程充满了数学上的暴力美学。

在第一章中,我们看到了语言如何变成向量。

在第二章中,我们看到了注意力如何建立联系。

在第三章中,我们看到了多头如何解耦特征。

但这些都是静态的

一个随机初始化的 Transformer,和一个训练好的 Transformer,架构完全相同。

参数都是矩阵,计算都是矩阵乘法。

区别在哪里?

区别在于:训练好的模型,其参数经过了数万亿次的梯度下降优化。

每一个参数,都被梯度"雕刻"过无数次。

每一个权重,都凝固了人类语言的统计规律。

这一章,我们将不再把模型看作一个静止的物体,而是一个正在进化的生命体。

它的进化动力,源于一个简单而残酷的目标:预测下一个词(Next Token Prediction)。

为了实现这个目标,模型必须经历一场漫长的、痛苦的、涉及数万亿次计算的"试错"之旅。

这是一场没有意识的进化。

这是一场由数学驱动的进化。

这是一场由梯度下降导演的进化。

让我们开始这场旅程。


4.1 盲人与群山:损失函数的地形图

What:损失函数的物理图像

想象一下,你是一个盲人,被随机扔到了喜马拉雅山脉的某个位置。

你的任务是:找到全世界最低的那个点(马里亚纳海沟)。

这就是模型训练的本质。

4.1.1 参数空间(Parameter Space)

What:什么是参数空间

在这个比喻中:

比喻元素对应概念数学表达
你的位置模型当前的参数状态$\theta \in \mathbb{R}^{350亿}$
你的高度模型当前的损失(Loss)$L(\theta)$
地形由训练数据决定的 Loss 曲面$L: \mathbb{R}^{350亿} \rightarrow \mathbb{R}$
最低点最优参数(Loss 最小)$\theta^* = \arg\min L(\theta)$

关键洞察

  • 对于一个 35B 的模型,你的坐标是350 亿维的。
  • 这不是我们熟悉的 3 维空间,这是超空间
  • 每一句话、每一篇文章,都在这个高维空间里雕刻出了山峰和谷底。

Why:为什么是 350 亿维

组件参数量说明
Embedding~2 亿词表×维度
每层 Attention~6 亿4×d_model²
每层 FFN~12 亿8×d_model²
32 层 Transformer~576 亿32×(6 亿 +12 亿)
总计~350 亿含其他组件

技术细节:Loss 曲面的性质

性质说明影响
非凸性有多个局部最低点可能陷入局部最优
高维鞍点鞍点比局部最优更常见梯度下降可逃离
平坦谷底最优解附近较平坦泛化能力好
尖锐谷底某些局部最优较尖锐泛化能力差

2025-2026 研究发现

  • 高维空间中,鞍点比局部最优更常见(Dauphin et al.)
  • 平坦谷底的解泛化能力更好(Keskar et al.)
  • 大模型更容易找到平坦谷底(Li et al. 2025)

4.1.2 随机初始化(Random Initialization)

What:训练起点

一开始,我们把模型的参数随机设为一些很小的数。

这意味着,盲人被随机扔到了群山中的某个半山腰。

技术细节:初始化策略演进

方法年份公式优点缺点
随机初始化早期$\mathcal{N}(0, 0.02)$简单可能梯度消失/爆炸
Xavier 初始化2010$\mathcal{N}(0, \sqrt{2/(n_{in}+n_{out})})$梯度稳定不适合 ReLU
He 初始化2015$\mathcal{N}(0, \sqrt{2/n_{in}})$适合 ReLU/GELU标准做法
正交初始化2020+正交矩阵深层网络稳定计算稍复杂

此时的模型状态

  • 参数:随机小数值
  • 输出:随机噪声
  • Loss:非常高(如 10.5)
  • 能力:几乎为零

示例

输入:"1+1=?"
随机模型输出:"苹果"(概率 0.001)、"香蕉"(概率 0.001)、"2"(概率 0.0001)...
Loss = -log(0.0001) ≈ 9.2

我们的目标

让这个盲人一步步走下山,直到 Loss 降到 0.1 以下。

这需要数万亿步

4.1.3 损失函数的选择

Why:为什么用交叉熵

在分类任务(如 Token 预测)中,我们使用交叉熵损失(Cross-Entropy Loss)

数学公式

$$ L = -\sum_{i=1}^{V} y_i \log(\hat{y}_i) $$

其中:

  • $V$ 是词表大小(如 50000)
  • $y_i$ 是真实标签(One-Hot,只有一个是 1,其余是 0)
  • $\hat{y}_i$ 是模型预测的概率分布

简化形式(因为 $y$ 是 One-Hot):

$$ L = -\log(\hat{y}_{target}) $$

物理含义

  • 如果模型预测正确($\hat{y}_{target} \approx 1$),Loss ≈ 0
  • 如果模型预测错误($\hat{y}_{target} \approx 0$),Loss → ∞

技术细节:交叉熵 vs 均方误差

损失函数公式适用场景梯度特性
交叉熵$-\log(\hat{y}_{target})$分类任务(Token 预测)梯度稳定,不易饱和
均方误差$(y - \hat{y})^2$回归任务分类任务中梯度易消失

为什么不用均方误差?

  • 交叉熵对"错误预测"惩罚更大
  • 交叉熵的梯度更稳定,不易饱和
  • 交叉熵有信息论解释(编码长度期望)

工程启示:Loss 监控的最佳实践

指标正常范围异常信号解决方案
训练 Loss持续下降不下降/上升检查学习率、数据质量
验证 Loss跟随训练 Loss先降后升过拟合,需早停或正则化
Loss 梯度稳定爆炸/消失梯度裁剪、调整初始化
Loss 波动小幅波动剧烈震荡降低学习率、增大 Batch

4.2 梯度的指引:微积分的魔法

What:梯度的物理意义

盲人看不见路,他怎么知道往哪走?

他只能用脚去感受脚下的坡度。

在数学上,坡度就是梯度(Gradient),记作 $\nabla L$。

4.2.1 梯度下降的核心公式

How:参数更新公式

$$ \theta_{new} = \theta_{old} - \eta \cdot \nabla L(\theta) $$

符号含义类比典型值
$\theta$模型参数盲人的位置350 亿维向量
$\eta$学习率(Learning Rate)步长1e-4 ~ 1e-5
$\nabla L$梯度坡度与$\theta$同维度

关键洞察

  • 梯度指向函数值增长最快的方向(最陡峭的上坡方向)
  • 我们沿着梯度的反方向走(下坡)
  • 学习率控制步长:太大可能跨过谷底,太小下山太慢

技术细节:学习率调度策略

策略公式适用阶段优点
常数学习率$\eta = constant$简单实验实现简单
线性衰减$\eta = \eta_0 \cdot (1 - t/T)$后期微调稳定收敛
余弦退火$\eta = \eta_0 \cdot \frac{1+\cos(\pi t/T)}{2}$标准训练平滑过渡
Warmup+ 衰减先增后减大模型训练避免早期不稳定

2025-2026 最佳实践

Warmup 阶段(前 1000 步):
  学习率从 0 线性增加到 1e-4

主训练阶段(10 万步):
  学习率按余弦退火从 1e-4 降到 1e-6

微调阶段(可选):
  学习率固定为 1e-5 或更低

4.2.2 反向传播:误差的责任分摊

What:反向传播的本质

但是,模型有 350 亿个参数。

当模型预测错了(比如把"1+1=2"预测成了"1+1=苹果"),我们怎么知道是哪一个参数出了问题?

是第 3 层第 5 个神经元的权重太大了?还是第 32 层第 2000 个 Attention Head 的偏置太小了?

这就需要用到 链式法则(Chain Rule)

数学公式

$$ \frac{\partial L}{\partial w} = \frac{\partial L}{\partial y} \cdot \frac{\partial y}{\partial h} \cdot \frac{\partial h}{\partial w} $$

物理含义

反向传播的本质,是误差的责任分摊

传播过程

┌─────────────────────────────────────────────────────────────────┐
│                    反向传播流程                                  │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  1. 前向传播(计算预测):                                       │
│  ─────────────────                                              │
│  输入 → Embedding → Attention → FFN → ... → Logits → Softmax   │
│                                              ↓                  │
│                                          预测"苹果"              │
│                                                                 │
│  2. 计算 Loss(与真实值比较):                                   │
│  ─────────────────────                                          │
│  Loss = -log(P("2")) = -log(0.0001) ≈ 9.2                      │
│                                                                 │
│  3. 反向传播(计算梯度):                                       │
│  ─────────────────                                              │
│  ∂Loss/∂Logits → ∂Loss/∂FFN → ∂Loss/∂Attention → ∂Loss/∂Embedding│
│      ↑            ↑              ↑                  ↑           │
│   输出层      倒数第二层      倒数第三层          输入层         │
│                                                                 │
│  4. 参数更新:                                                   │
│  ─────────                                                      │
│  W_new = W_old - η × ∂Loss/∂W                                  │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

关键洞察

  1. 输出层:首先计算预测值"苹果"和真实值"2"之间的差距(Loss)。
  2. 倒数第二层:输出层把误差传给上一层:“嘿,我算错了是因为你给我的输入不对。你应该变大一点。”
  3. 倒数第三层:再把误差传给上一层…
  4. 输入层:直到传回最初的 Embedding 层。

通过这种方式,每一个参数都知道了自己对最终的错误负有多大的责任(梯度),以及自己该怎么改(变大还是变小)。

技术细节:自动微分(AutoDiff)

现代深度学习框架(PyTorch、TensorFlow)使用自动微分技术:

# PyTorch 示例
import torch
import torch.nn as nn

# 定义模型
model = Transformer()

# 前向传播
logits = model(input_ids)
loss = cross_entropy(logits, target_ids)

# 反向传播(一行代码)
loss.backward()  # 自动计算所有参数的梯度

# 参数更新
optimizer.step()  # 使用梯度更新参数

关键机制

  • PyTorch 构建计算图(Computational Graph)
  • 前向传播时记录所有操作
  • 反向传播时自动应用链式法则
  • 工程师无需手动计算梯度

工程启示:梯度调试技巧

问题症状诊断方法解决方案
梯度消失浅层参数不更新检查梯度范数残差连接、LayerNorm
梯度爆炸梯度范数极大检查梯度范数梯度裁剪
梯度噪声大训练不稳定检查 Batch 内梯度方差增大 Batch、梯度累积
梯度为零参数完全不更新检查计算图检查 requires_grad

4.2.3 优化器的演进:从 SGD 到 AdamW

How:优化器的发展

基础的梯度下降(SGD)有一个问题:所有参数用同一个学习率。

但不同参数可能需要不同的学习率。

优化器演进

优化器年份核心创新优点缺点
SGD1950s基础梯度下降简单收敛慢,需手动调学习率
Momentum1964加入动量加速收敛仍需手动调学习率
Adam2014自适应学习率收敛快,默认参数好可能泛化稍差
AdamW2017Adam+ 权重衰减泛化更好LLM 标准选择

AdamW 的核心思想

$$ \theta_{new} = \theta_{old} - \eta \cdot (\frac{\hat{m}}{\sqrt{\hat{v}} + \epsilon} + \lambda \cdot \theta) $$

其中:

  • $\hat{m}$:梯度的一阶矩估计(动量)
  • $\hat{v}$:梯度的二阶矩估计(自适应)
  • $\lambda$:权重衰减系数

2025-2026 最佳实践

# LLM 训练标准配置
optimizer = torch.optim.AdamW(
    model.parameters(),
    lr=1e-4,           # 学习率
    betas=(0.9, 0.999), # 动量参数
    eps=1e-8,          # 数值稳定性
    weight_decay=0.1    # 权重衰减
)

工程启示:优化器选择策略

场景推荐优化器理由
大模型预训练AdamW泛化好,收敛稳定
小模型微调AdamW与预训练一致
资源受限场景SGD+Momentum显存占用少
实验快速迭代Adam默认参数好,调参少

4.3 压缩即智能 (Compression is Intelligence)

What:本章的核心洞见

这是本章最深刻的洞见,也是 OpenAI 的核心信仰。

为什么简单的"下山"过程,会涌现出智能?

为什么模型不仅仅是记住了训练数据,而是学会了举一反三(泛化)?

4.3.1 资源的匮乏

Why:参数量 < 数据量

关键在于:参数量 < 数据量。

指标数值说明
训练数据量3-10 万亿 Token互联网文本
模型参数量350 亿Qwen3.5-35B
比例约 100:1每个参数需"覆盖"100 个 Token

关键洞察

  • 数据量:互联网上的文本是无限的(几万亿 token)。
  • 参数量:模型的脑容量是有限的(几百亿参数)。
  • 如果模型想要通过"死记硬背"来降低 Loss,它做不到。
  • 因为它没有足够的"硬盘空间"去存储每一句话。

示例

模型记不住:
• "张三昨天吃了苹果"
• "李四前天吃了梨"
• "王五大前天吃了香蕉"
• ...(万亿级句子)

但模型可以学会:
• "人 + 时间 + 吃 + 食物"这个句式
• 用一个通用公式替代千千万万个具体句子

4.3.2 寻找规律(Pattern Recognition)

Why:压缩的必然性

为了在有限的参数空间里,尽可能多地拟合数据,模型被迫寻找数据背后的压缩规律

模型发现的规律

规律类型示例压缩效果
语法规律“主谓宾"结构一个规则覆盖无限句子
语义规律“苹果"是水果一个概念覆盖多个实例
逻辑规律“如果 A 则 B”一个推理模式覆盖多种场景
因果规律“因为…所以…”一个因果链覆盖多种解释

信息论视角

从信息论角度看,训练过程是有损压缩

$$ \text{原始数据} \xrightarrow{\text{压缩}} \text{模型参数} \xrightarrow{\text{解压}} \text{生成内容} $$

  • 原始数据:3-10 万亿 Token
  • 模型参数:350 亿参数(约 70GB)
  • 压缩比:约 100:1

关键洞察

最高级的压缩,不是存储数据,而是存储生成数据的规律。

  • 存储"1+1=2, 1+2=3, 2+2=4…” → 低效压缩
  • 存储"加法运算规则” → 高效压缩

智能,本质上就是对信息的高效压缩。

当你能用最少的定律(比如 $E=mc^2$)解释整个宇宙(海量数据)时,你就拥有了最高的智能。

4.3.3 泛化(Generalization):举一反三

What:泛化的定义

正因为模型学会的是规律而不是样本,所以当我们给它一个从未见过的句子时:

“马斯克明天要吃火星土豆。”

虽然它没见过这句话,但它掌握了"主谓宾"和"吃"的规律。

它能算出:这句话的概率很高,是合理的。

而"土豆吃马斯克"的概率很低,是不合理的。

这就是泛化。这就是智能的涌现。

技术细节:泛化的数学定义

概念定义数学表达
训练误差训练数据上的 Loss$L_{train}(\theta)$
测试误差未见数据上的 Loss$L_{test}(\theta)$
泛化误差测试误差 - 训练误差$L_{test} - L_{train}$
过拟合训练误差低,测试误差高$L_{train} \ll L_{test}$
欠拟合训练误差高,测试误差高$L_{train} \approx L_{test} \approx 高$
良好泛化训练误差低,测试误差低$L_{train} \approx L_{test} \approx 低$

防止过拟合的技术

技术原理效果
Dropout随机丢弃神经元减少依赖,增强鲁棒性
权重衰减L2 正则化限制参数大小
早停(Early Stopping)验证 Loss 上升时停止防止过度拟合训练数据
数据增强增加训练数据多样性提高泛化能力
标签平滑软化 One-Hot 标签减少过度自信

哲学思考:压缩的边界

这里有一个深刻的哲学问题:

压缩是否有极限?

香农信息论告诉我们:

  • 任何无损压缩都有下限(信息熵)
  • 有损压缩可以更低,但有失真

LLM 的训练是有损压缩

  • 它丢失了具体实例(记不住"张三吃了苹果")
  • 它保留了统计规律(记住了"人吃食物")

关键问题

  • 丢失的信息,是"噪音"还是"信号"?
  • 保留的规律,是"本质"还是"偏见"?

本书的立场

  • 大部分丢失的是"噪音"(具体实例的细节)
  • 大部分保留的是"信号"(语言的统计规律)
  • 但也保留了一些"偏见"(训练数据中的社会偏见)

这是 LLM 的局限,也是人类认知的局限。

4.3.4 记忆 vs 泛化的实验证据

What:研究发现的证据

2024-2026 年的研究提供了记忆 vs 泛化的实验证据:

研究方法发现
记忆探测询问训练数据中的事实大模型记忆能力随规模增长
泛化测试询问训练数据中没有的新组合大模型泛化能力更强
对比实验参数量 vs 数据量比例变化参数量/数据量越小,泛化越好

关键发现

  • 小模型:更依赖记忆(训练数据中的模式)
  • 大模型:泛化能力更强(抽象出通用规律)
  • 但仍有记忆成分(尤其是事实性知识)

工程启示:如何评估模型的泛化能力

评估方法说明适用场景
保留验证集训练时不使用的数据标准做法
对抗测试构造困难样本测试鲁棒性
分布外测试与训练数据分布不同的数据测试泛化边界
少样本学习给少量示例看能否学会新任务测试元学习能力

4.4 局部最优 vs 全局最优:高维空间的特殊性

What:优化理论的核心问题

梯度下降会陷入局部最优吗?

这是优化理论的经典问题。

4.4.1 低维空间的直觉

Why:为什么我们担心局部最优

在低维空间中,Loss 曲面可能有多个"谷底":

低维 Loss 曲面(2 维):
┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│       ╱╲        ╱╲                                              │
│      ╱  ╲      ╱  ╲                                             │
│     ╱    ╲    ╱    ╲                                            │
│    ╱ 局部 ╲  ╱ 全局 ╲                                           │
│   ╱  最优  ╲╱  最优  ╲                                          │
│  ╱          ●          ╲                                        │
│ ╱                       ╲                                       │
│●─────────────────────────●                                      │
│                                                                 │
│  问题:梯度下降可能陷入局部最优,找不到全局最优                  │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

4.4.2 高维空间的现实

Why:高维空间的不同

但在 350 亿维空间中,情况完全不同:

研究发现

发现说明引用
鞍点比局部最优更常见高维空间中,鞍点数量指数级增长Dauphin et al. 2014
局部最优和全局最优 Loss 接近即使陷入局部最优,Loss 也接近全局最优Goodfellow et al. 2015
平坦谷底泛化更好尖锐谷底的解容易过拟合Keskar et al. 2017
大模型更容易找到平坦谷底参数越多,优化越容易Li et al. 2025

关键洞察

  • 在 350 亿维空间中,“局部最优"很少见
  • 更常见的是"鞍点”(某些方向上坡,某些方向下坡)
  • 梯度下降可以逃离鞍点
  • 即使"陷入"局部最优,Loss 也接近全局最优

哲学思考:“足够好"vs"完美”

这引出一个工程哲学问题:

我们需要全局最优吗?

答案:不需要。

  • 全局最优和局部最优的 Loss 差异很小
  • 追求全局最优的计算成本极高
  • “足够好"的解已经能产生智能行为

这是工程智慧:追求"足够好”,不是"完美"。


4.5 Batch 与 Epoch:数据利用的艺术

What:批量与轮次的概念

Batch(批量):每次迭代使用的样本数量。

Epoch(轮次):所有训练数据都用过一次。

4.5.1 为什么用 Batch

Why:单个样本 vs 全部样本 vs Batch

策略优点缺点适用场景
单样本 (SGD)更新频繁梯度噪声大,不稳定在线学习
全批量 (Batch GD)梯度准确计算慢,显存不够小数据集
小批量 (Mini-batch)折中方案需要调 Batch 大小LLM 训练标准

LLM 训练中的 Batch 策略

典型配置:
• Micro Batch: 1-4(单卡每次处理的样本数)
• Gradient Accumulation: 64-256(梯度累积步数)
• Effective Batch: 100 万 + Token(有效 Batch 大小)

示例:
• 8 张卡 × 2 Micro Batch × 128 步累积 = 2048 样本/更新
• 每样本 512 Token → 约 100 万 Token/更新

4.5.2 Epoch 的选择

Why:为什么 LLM 通常只训练 1-3 个 Epoch

数据类型推荐 Epoch理由
小数据集 (<1GB)10-100 Epoch数据少,需要多轮学习
中等数据集 (1-100GB)3-10 Epoch平衡过拟合与欠拟合
大数据集 (>100GB)1-3 Epoch数据足够,多轮会过拟合
LLM 预训练 (TB 级)1-2 Epoch数据太多,一轮就够

关键洞察

  • LLM 训练数据是 TB 级(万亿 Token)
  • 一遍数据已经足够模型学习规律
  • 多轮训练会导致过拟合(记住训练数据)
  • 所以 LLM 通常只训练 1-2 个 Epoch

工程启示:训练规模估算

模型规模训练数据训练时间成本估算
1B100B Token1 周(百卡)约 1 万美元
10B500B Token1 月(千卡)约 10 万美元
100B3T Token3 月(千卡)约 100 万美元
350B+10T+ Token6 月 +(万卡)约 500 万 + 美元

4.6 思想实验:学习的本质

思想实验 1:如果参数量 > 数据量?

假设我们有一个 1 万亿参数的模型,但只训练 10 亿 Token。

会发生什么?

  1. 模型可以"死记硬背"所有训练数据
  2. 训练 Loss 可以降到接近 0
  3. 但测试 Loss 会很高(过拟合)
  4. 泛化能力差

结论:参数量 > 数据量 → 过拟合风险高。

工程启示:参数量与数据量需要匹配。

思想实验 2:如果训练数据是随机的?

假设我们用随机生成的 Token 训练模型(没有语言规律)。

会发生什么?

  1. 模型会学习"随机分布"
  2. 训练 Loss 会下降(模型学会了预测随机)
  3. 但没有泛化能力(随机数据没有规律)
  4. 模型变成"随机生成器"

结论:没有规律的数据,无法产生智能。

哲学思考:智能的前提是数据中有规律

思想实验 3:如果梯度下降是"有意识"的?

假设梯度下降有"意识",它能"理解"自己在做什么。

会发生什么?

  1. 它仍然会沿着梯度方向走
  2. 它仍然会最小化 Loss
  3. “意识"不会改变数学过程

结论:学习过程是数学必然,不是"意识"的产物。

哲学思考:这挑战了"意识是智能必要条件"的观点。


4.7 本章总结

核心概念关键洞察工程启示
损失函数交叉熵适合分类任务监控训练/验证 Loss
梯度下降沿负梯度方向更新参数学习率调度是关键
反向传播误差的责任分摊自动微分简化实现
优化器AdamW 是 LLM 标准默认参数通常够用
压缩即智能参数量<数据量迫使模型学习规律防止过拟合是关键
泛化学会规律而非样本用保留集评估泛化能力
局部最优高维空间中不是大问题追求"足够好"而非"完美”
Batch/Epoch数据利用的艺术LLM 通常 1-2 Epoch

4.8 下一章预告

在第四章中,我们完成了训练过程的解构。

我们看到了:

  • 损失函数的地形图:350 亿维空间中的群山与谷底
  • 梯度的指引:机器如何知道"错在哪"
  • 反向传播的链式法则:误差如何精确分摊到每个参数
  • 压缩即智能:过拟合 vs 泛化的本质区别
  • 智能的代价:数万亿次计算的"试错"与"修正"

现在的模型,已经具备了"学习"的能力。

它从随机参数开始,经过梯度下降的"雕刻",变成了通晓人类语言的智者。

但是,还有一个问题没有解决:

为什么现在的 LLM 几乎清一色都是 Decoder-Only?

为什么 BERT 这种强大的双向模型被淘汰了?

为什么"上帝视角"(双向注意力)反而限制了能力的上限?

这涉及到了因果律时间箭头的深刻问题。

下一章,我们将揭开架构之争的秘密:《时间的箭头 —— Decoder-Only 的统治》

我们将看到:

  • Encoder vs Decoder 的本质区别
  • 因果遮蔽(Causal Masking)的数学必然
  • 预测未来比解释过去更难
  • 上下文学习(In-Context Learning)的涌现
  • KV Cache 与工程化优势

让我们继续这场旅程。

从痛苦的学习,走向时间的箭头。


(第四章完)