手撕 Transformer 和手撕 bert区别
“手撕 Transformer” 和 “手撕 BERT” 虽然都涉及手动实现深度学习模型,但二者在目标、复杂度、应用场景和技术细节上存在显著差异。以下从多个维度对比分析:
一、核心目标与应用场景
| 对比项 | 手撕 Transformer | 手撕 BERT |
|---|---|---|
| 本质 | 实现 Transformer 的基础架构(编码器 + 解码器) | 实现基于 Transformer 的预训练语言模型 |
| 核心任务 | 构建通用序列处理框架,适用于翻译、生成等任务 | 构建大规模预训练 + 微调的 NLP 范式 |
| 应用场景 | 需自定义模型结构(如语音、图像领域) | 需基于预训练权重做下游任务(如文本分类) |
二、技术复杂度与实现重点
1. Transformer(基础架构)
- 关键模块:
- 多头注意力机制:手动实现 Q/K/V 矩阵生成、维度变换、Softmax 计算(需处理数值稳定性)。
- 位置编码:实现正弦 / 余弦函数编码或学习型编码。
- 残差连接与 LayerNorm:处理张量形状匹配(如
x + sublayer(x))。
- 难点:
- 多头并行计算的张量操作(如
(batch, seq_len, d_model)→(batch, heads, seq_len, d_k))。 - 编码器 - 解码器交互(Seq2Seq 任务中的 Cross-Attention)。
- 多头并行计算的张量操作(如
2. BERT(预训练模型)
- 关键模块:
- 仅编码器架构:丢弃 Transformer 的解码器,堆叠多层编码器(如 12 层或 24 层)。
- 预训练任务:
- MLM(掩码语言模型):随机掩码 15% 的 token,预测被掩码的词。
- NSP(下一句预测):判断两句话是否连续。
- 特殊 token 设计:
[CLS]分类 token、[SEP]分隔符、[MASK]掩码符。
- 难点:
- 预训练数据处理(如掩码策略、句子对构建)。
- 大规模训练优化(如混合精度、梯度累积)。
三、代码实现的核心差异
1. Transformer 核心代码示例
python
运行
class Transformer(nn.Module):
def __init__(self, src_vocab_size, tgt_vocab_size, d_model, nhead, num_layers):
super().__init__()
# 编码器和解码器
self.encoder = TransformerEncoder(src_vocab_size, d_model, nhead, num_layers)
self.decoder = TransformerDecoder(tgt_vocab_size, d_model, nhead, num_layers)
self.generator = nn.Linear(d_model, tgt_vocab_size)
def forward(self, src, tgt, src_mask, tgt_mask):
# 编码源语言
memory = self.encoder(src, src_mask)
# 解码目标语言(结合源语言编码)
output = self.decoder(tgt, memory, tgt_mask, src_mask)
return self.generator(output)
2. BERT 核心代码示例
python
运行
class BERT(nn.Module):
def __init__(self, vocab_size, d_model, nhead, num_layers):
super().__init__()
# 仅需编码器(无解码器)
self.encoder = TransformerEncoder(vocab_size, d_model, nhead, num_layers)
# MLM预测头
self.mlm_head = nn.Sequential(
nn.Linear(d_model, d_model),
nn.GELU(),
nn.LayerNorm(d_model),
nn.Linear(d_model, vocab_size)
)
# NSP预测头
self.nsp_head = nn.Linear(d_model, 2)
def forward(self, input_ids, attention_mask, token_type_ids):
# 获取编码表示
outputs = self.encoder(input_ids, attention_mask)
# [CLS] token用于分类
cls_output = outputs[:, 0, :]
# 预测掩码token
mlm_output = self.mlm_head(outputs)
# 预测下一句关系
nsp_output = self.nsp_head(cls_output)
return mlm_output, nsp_output
四、数据处理与训练流程
| 对比项 | Transformer | BERT |
|---|---|---|
| 数据格式 | 源语言 - 目标语言对(如中英句子对) | 单文本或文本对(如段落、问题 - 答案) |
| 训练目标 | 最大化目标序列的生成概率 | 最小化 MLM 和 NSP 任务的损失 |
| 训练数据量 | 特定领域的平行语料(通常数百万句对) | 大规模无标注文本(如 Wikipedia、BooksCorpus) |
| 训练技巧 | 标签平滑、学习率预热 | 掩码策略(如 80% 替换为 [MASK]、10% 随机替换) |
五、应用场景与扩展方向
1. Transformer 的应用
- 神经机器翻译(如 Google Translate)。
- 文本生成(如 GPT 系列的基础架构)。
- 跨模态任务(如 Vision Transformer 处理图像)。
2. BERT 的应用
- 文本分类(如情感分析)。
- 问答系统(如 SQuAD 任务)。
- 命名实体识别(NER)。
六、面试中的高频问题差异
| Transformer 相关问题 | BERT 相关问题 |
|---|---|
| 1. 为什么需要多头注意力? | 1. BERT 为什么使用 MLM 而非传统语言模型? |
| 2. 如何处理长序列输入(如超过 512 tokens)? | 2. BERT 的输入表示有哪些部分组成? |
| 3. LayerNorm 应该放在残差连接前还是后? | 3. 为什么 BERT 在微调时比从头训练效果好? |
总结:选择 “手撕” 哪个更有价值?
- 选 Transformer:适合想深入理解深度学习基础架构、需要自定义模型(如处理音频、图像)的场景。
- 选 BERT:适合专注 NLP 任务、希望快速应用预训练模型解决实际问题的场景。
二者的关系类似于 “造汽车引擎”(Transformer)与 “改装汽车”(BERT):前者是基础能力,后者是应用创新。实际中,建议先掌握 Transformer 的核心实现,再扩展到 BERT 等变种,形成完整的技术栈。

浙公网安备 33010602011771号