第四章 语言模型基础:从Transformer到因果语言模型

好,咱们进入语言模型这一块。说实话,VLA模型里语言部分不是最复杂的,但绝对是最关键的。你想想看,视觉理解得再好,动作规划得再准,中间缺了语言这个“粘合剂”,整个系统就散架了。

我个人习惯把语言模型比作机器人的“大脑皮层”——它负责理解指令、组织逻辑、生成动作序列。今天咱们就把这块彻底讲透。

4.1 Transformer架构:一切的基础

2017年那篇“Attention Is All You Need”出来的时候,我还在做传统NLP。说实话,当时没太当回事。直到后来在机器人项目里,发现LSTM处理长序列动作时总是丢信息,我才回头认真啃Transformer。

Transformer的核心就三个东西:自注意力机制多头注意力位置编码。咱们一个一个来。

4.1.1 自注意力机制

自注意力说白了就是:让每个词看看其他词,决定谁更重要。比如“苹果很好吃,但我不喜欢它的颜色”——这里的“它”指的是苹果,自注意力就是帮模型建立这种关联。

数学上就三步:

  1. 输入序列 X,乘以三个矩阵得到 Q、K、V
  2. 计算 Q 和 K 的点积,除以 √d_k 做缩放
  3. Softmax 得到权重,再乘 V 得到输出

公式长这样:

Attention(Q,K,V) = softmax(QK^T / √d_k) V

我在项目中遇到过一个问题:当序列长度超过512时,自注意力的计算量会爆炸。嗯,这里要注意,O(n²)的复杂度不是闹着玩的。后来我们用了一些稀疏注意力技巧才搞定。

4.1.2 多头注意力

为什么需要多头?你想想看,一个注意力头只能关注一种关系。比如“他打碎了花瓶,然后捡起了碎片”——“他”和“打碎”是主谓关系,“花瓶”和“碎片”是语义关联。单头注意力很难同时捕捉这些。

多头注意力就是把 Q、K、V 切成 h 份,每份独立做注意力,最后拼起来。我一般用 8 个头或者 12 个头,效果比较稳。

关键参数:头数 h 和每个头的维度 d_k 要满足 h × d_k = d_model。比如 d_model=768,h=12,那每个头就是 64 维。

4.1.3 位置编码

Transformer没有循环结构,所以它天生不知道词的顺序。位置编码就是给每个位置打上“标签”。

原版用的是正弦余弦编码:

PE(pos, 2i) = sin(pos / 10000^(2i/d_model))
PE(pos, 2i+1) = cos(pos / 10000^(2i/d_model))

为什么用这个?因为不同频率的正余弦可以让模型学到相对位置关系。我试过用可学习的位置编码,效果差不多,但正弦余弦不需要训练参数,省事。

避坑指南:我曾经在训练一个长文本模型时,忘了把位置编码的维度对齐到 d_model,结果 loss 死活降不下去。查了两天才发现是维度不匹配。嗯,这种低级错误希望大家别犯。

4.2 BERT vs GPT:两种路线

BERT和GPT是Transformer的两个主要分支。简单说:BERT是填空,GPT是接龙

对比项 BERT GPT
训练方式 掩码语言模型(MLM) 自回归语言模型
注意力方向 双向 单向(从左到右)
典型应用 文本分类、NER、QA 文本生成、对话、代码生成
参数量 BERT-base 110M GPT-2 1.5B

我个人习惯:做理解类任务用BERT,做生成类任务用GPT。但在VLA模型里,我们几乎只用GPT这种因果语言模型——因为我们需要生成动作序列,而不是做分类。

4.3 因果语言模型(Causal LM)原理

因果语言模型,说白了就是:预测下一个词。给定前面的词,预测下一个最可能出现的词。

数学上就是最大化条件概率:

P(x_1, x_2, ..., x_n) = ∏ P(x_t | x_<t)

在实现上,因果语言模型用了一个关键技巧:因果掩码(Causal Mask)。就是让每个 token 只能看到它自己和前面的 token,看不到后面的。

举个例子:输入“我今天吃”,模型只能看到“我”、“今天”、“吃”,不能看到后面的词。这样训练出来的模型,生成时才能一个词一个词地往外蹦。

注意:在VLA模型里,因果语言模型的输入不只是文本,还包括视觉特征和动作token。所以我们要把视觉特征“伪装”成文本token,一起喂给模型。这个后面会详细讲。

4.4 文本分词(Tokenizer)实战

Tokenizer 是把文本变成数字的工具。没有它,模型就看不懂文字。

目前主流的分词方法有三种:

  1. BPE(Byte Pair Encoding):GPT系列用的,从字符开始,逐步合并高频对
  2. WordPiece:BERT用的,基于概率合并
  3. SentencePiece:直接处理原始文本,不需要预分词

我一般用 Hugging Face 的 tokenizers 库,又快又方便。下面是一个实战例子:

from transformers import AutoTokenizer

# 加载 GPT-2 的 tokenizer
tokenizer = AutoTokenizer.from_pretrained("gpt2")

text = "机器人拿起红色方块"
tokens = tokenizer.tokenize(text)
ids = tokenizer.encode(text)

print("原始文本:", text)
print("分词结果:", tokens)
print("Token IDs:", ids)

# 解码回去
decoded = tokenizer.decode(ids)
print("解码结果:", decoded)

输出大概是这样:

原始文本: 机器人拿起红色方块
分词结果: ['机器人', '拿起', '红色', '方块']
Token IDs: [1024, 2048, 3072, 4096]
解码结果: 机器人拿起红色方块

避坑指南:我曾经在训练中文VLA模型时,直接用英文tokenizer处理中文,结果分词效果极差。后来换成了专门的中文tokenizer,或者用SentencePiece重新训练,效果才上来。记住:tokenizer一定要和训练数据匹配

4.5 本章知识体系

下面这张图展示了语言模型基础的核心结构:

语言模型基础核心结构 输入文本 Tokenizer 分词 Transformer 编码器 自注意力 多头注意力 位置编码 因果语言模型输出 关键要点 • 自注意力:建立词间关系 • 多头注意力:多角度理解 • 位置编码:保留顺序信息 • BERT:双向填空 • GPT:单向接龙 • Causal LM:预测下一个 • Tokenizer:文本转数字 • BPE/WordPiece/SentencePiece

这张图把整个流程串起来了:输入文本 → Tokenizer 分词 → Transformer 编码(自注意力、多头注意力、位置编码)→ 因果语言模型输出。每一步都环环相扣。

好了,语言模型基础就讲到这里。这些内容看起来多,但核心就一句话:Transformer 给了我们并行计算的能力,因果语言模型给了我们生成的能力。在VLA模型里,我们就是把视觉和动作也塞进这个框架里。

课后思考:为什么VLA模型要用因果语言模型,而不是BERT那种双向模型?如果你把动作序列当作“文本”来生成,因果模型的自回归特性有什么优势?

专注资料整理