跳到主要内容

预训练范式

本节定位

这一章的主线其实只有一句话:

先在大语料上学通用能力,再把这些能力迁移到具体任务。

这就是现代 NLP 的预训练范式。

如果前面只把它看成“先训一下再微调”,后面会很容易只剩术语。
所以这一节要把它为什么重要、为什么改变整个 NLP 讲清楚。

学习目标

  • 理解预训练范式和“每个任务从零训练”的差别
  • 理解预训练 -> 迁移 -> 微调的主线
  • 通过可运行示例建立“共享底座”的直觉
  • 理解为什么现代 NLP 主线几乎都围绕它展开

一、为什么预训练会改变整个 NLP?

1.1 因为很多任务共享底层语言能力

无论是:

  • 分类
  • NER
  • 问答
  • 翻译

它们都需要一些共同底层能力,例如:

  • 词义理解
  • 语法结构
  • 上下文建模

1.2 如果每个任务都从零学,会很浪费

这就像:

  • 每次做新题,都从头学语言本身

显然成本很高。

1.3 预训练范式的核心

于是更合理的做法就变成:

  1. 先在海量通用文本上学基础能力
  2. 再把这份能力迁移到具体任务

这就是现代 NLP 的主线。


二、预训练、迁移、微调三者关系是什么?

2.1 预训练

目标是:

  • 学通用语言表示和模式

2.2 迁移

目标是:

  • 把已有能力带到新任务上

2.3 微调

目标是:

  • 在具体任务上做进一步适配

2.4 一个类比

预训练像先读通识教材。
迁移像把这套基础搬去新科目。
微调像针对考试题型做专项训练。


三、先跑一个“共享底座”示例

shared_representation = {
"退款": [1.0, 0.2, 0.1],
"发票": [0.3, 1.0, 0.1],
"密码": [0.1, 0.2, 1.0],
}


def sentence_vector(tokens):
vectors = [shared_representation[token] for token in tokens if token in shared_representation]
dim = len(vectors[0])
return [sum(vec[i] for vec in vectors) / len(vectors) for i in range(dim)]


def classify_intent(tokens):
vec = sentence_vector(tokens)
scores = {
"refund": vec[0],
"invoice": vec[1],
"password": vec[2],
}
return max(scores, key=scores.get), scores


for tokens in [["退款"], ["发票"], ["密码"]]:
print(tokens, "->", classify_intent(tokens))

3.1 这个例子在说明什么?

它想表达的不是一个真实强模型,
而是最核心的范式感觉:

  • 先有共享表示底座
  • 再在其上完成具体任务

3.2 为什么这很像预训练时代的思路?

因为你不再是:

  • 每个任务单独从零学所有表示

而是:

  • 复用一套已有语言表示

四、为什么这条路后面会走向 BERT / GPT / T5?

4.1 因为它能规模化

一旦预训练成立,
更大的数据、更多的计算通常会继续提升底座能力。

4.2 因为它更通用

同一底座可以迁移到很多任务。

4.3 因为它降低了下游门槛

很多任务不再需要从零训练一个大模型,
而是:

  • 直接拿预训练模型适配

五、最容易踩的坑

5.1 误区一:预训练范式只是“先训练一下”

不对。
它改变的是整个任务组织方式。

5.2 误区二:所有任务都一定要微调

有些任务只要:

  • 特征抽取
  • Prompt
  • 检索

就够了。

5.3 误区三:只记模型名字,不理解范式

真正重要的是:

  • 为什么先学通用能力再迁移有效

小结

这节最重要的是建立一个时代判断:

现代 NLP 的核心变化,不只是模型变大了,而是训练范式从“每个任务单独做”转向了“先学通用底座,再迁移适配”。

只要这层判断立住,后面学 BERT、GPT、T5 就不会只剩流行词。


练习

  1. 用自己的话解释:为什么预训练范式会显著降低很多 NLP 任务的门槛?
  2. 想一想:哪些任务可能只需要预训练特征,不一定要全量微调?
  3. 这个“共享底座”例子在真实系统里分别对应什么?
  4. 为什么说预训练范式改变的不只是模型,而是整个任务组织方式?