手撕 Transformer:从原理到代码,一步步造一个“小型大模型”

举报
Echo_Wish 发表于 2026/03/15 20:12:02 2026/03/15
【摘要】 手撕 Transformer:从原理到代码,一步步造一个“小型大模型”

手撕 Transformer:从原理到代码,一步步造一个“小型大模型”

作者:Echo_Wish

很多人第一次接触大模型的时候,都会有一种错觉:

Transformer 好像很复杂。

论文几十页、代码几千行、框架一堆组件。

但如果你真的把它拆开来看,其实会发现:

Transformer 的核心只有三样东西:

  1. Attention(注意力)
  2. Feed Forward(前馈网络)
  3. Position Encoding(位置编码)

说白了就是一句话:

Transformer = Attention + MLP + 一点点工程技巧

今天我们就用一种 “手撕源码”的方式,从零写一个最简版 Transformer。

不用任何深度学习框架黑盒。

只用 PyTorch + 基本数学

你会发现:

大模型的底层其实没有那么神秘。


一、Transformer 到底解决了什么问题?

在 Transformer 出现之前,NLP 主要用的是:

  • RNN
  • LSTM
  • GRU

这些模型有个致命问题:

不能并行计算。

因为它们是这样的:

word1 → word2 → word3 → word4

必须一步一步算。

而 Transformer 的思路很简单:

让每个词都能直接看到所有词。

这就是 Attention 的核心思想。


Transformer 的整体结构

从结构上看,Transformer 主要由两部分组成:

Encoder
Decoder

每一层内部包含:

Multi Head Attention
Feed Forward
Add & Norm

整个模型就是不断堆叠这些模块。


二、Attention 的核心思想

Attention 可以用一句非常接地气的话解释:

每个词在阅读句子的时候,会重点关注几个词。

例如:

The animal didn't cross the street because it was tired

这里的 it 指代谁?

模型需要去关注:

animal

Attention 就是一个计算 “谁和谁更相关” 的机制。


三、Self-Attention 的数学原理

Self-Attention 有三个关键向量:

Q  Query
K  Key
V  Value

计算公式是:

[
Attention(Q,K,V) = softmax(\frac{QK^T}{\sqrt{d_k}})V
]

简单理解就是三步:

1 计算相关性
2 softmax 归一化
3 加权求和

四、手写 Self-Attention(核心代码)

我们先写最核心的一段代码。

import torch
import torch.nn as nn
import torch.nn.functional as F

class SelfAttention(nn.Module):

    def __init__(self, embed_size):
        super().__init__()

        self.embed_size = embed_size

        self.Wq = nn.Linear(embed_size, embed_size)
        self.Wk = nn.Linear(embed_size, embed_size)
        self.Wv = nn.Linear(embed_size, embed_size)

    def forward(self, x):

        Q = self.Wq(x)
        K = self.Wk(x)
        V = self.Wv(x)

        scores = torch.matmul(Q, K.transpose(-2, -1))

        scores = scores / (self.embed_size ** 0.5)

        attention = F.softmax(scores, dim=-1)

        out = torch.matmul(attention, V)

        return out

这段代码就是:

最简版 Self-Attention。

逻辑非常清晰:

输入 embedding
↓
生成 Q K V
↓
计算注意力
↓
加权输出

五、为什么需要 Multi-Head Attention

一个 Attention 其实能力有限。

Transformer 的解决方案是:

多头注意力。

意思是:

同时用多个注意力去理解句子。

例如:

Head1 学语法
Head2 学语义
Head3 学上下文关系

Multi Head Attention 代码实现

class MultiHeadAttention(nn.Module):

    def __init__(self, embed_size, heads):
        super().__init__()

        self.heads = heads
        self.embed_size = embed_size
        self.head_dim = embed_size // heads

        self.q_linear = nn.Linear(embed_size, embed_size)
        self.k_linear = nn.Linear(embed_size, embed_size)
        self.v_linear = nn.Linear(embed_size, embed_size)

        self.fc_out = nn.Linear(embed_size, embed_size)

    def forward(self, x):

        batch_size = x.shape[0]

        Q = self.q_linear(x)
        K = self.k_linear(x)
        V = self.v_linear(x)

        Q = Q.reshape(batch_size, -1, self.heads, self.head_dim)
        K = K.reshape(batch_size, -1, self.heads, self.head_dim)
        V = V.reshape(batch_size, -1, self.heads, self.head_dim)

        scores = torch.einsum("nqhd,nkhd->nhqk", Q, K)

        attention = torch.softmax(scores / (self.head_dim ** 0.5), dim=-1)

        out = torch.einsum("nhql,nlhd->nqhd", attention, V)

        out = out.reshape(batch_size, -1, self.embed_size)

        out = self.fc_out(out)

        return out

这就是 Transformer 的核心模块


六、Feed Forward 网络

每个 Transformer Block 还有一个结构:

Feed Forward Network

其实就是一个两层 MLP。

结构非常简单:

Linear
ReLU
Linear

代码如下:

class FeedForward(nn.Module):

    def __init__(self, embed_size, hidden_dim):

        super().__init__()

        self.fc1 = nn.Linear(embed_size, hidden_dim)
        self.fc2 = nn.Linear(hidden_dim, embed_size)

    def forward(self, x):

        x = F.relu(self.fc1(x))

        x = self.fc2(x)

        return x

七、Position Encoding(解决顺序问题)

Transformer 最大的问题是:

它不知道词的顺序。

所以论文设计了:

位置编码。

公式:

[
PE(pos,2i)=sin(pos/10000^{2i/d})
]

[
PE(pos,2i+1)=cos(pos/10000^{2i/d})
]

实现代码:

import math

def positional_encoding(seq_len, embed_size):

    pe = torch.zeros(seq_len, embed_size)

    for pos in range(seq_len):

        for i in range(0, embed_size, 2):

            pe[pos, i] = math.sin(pos / (10000 ** (i / embed_size)))
            pe[pos, i + 1] = math.cos(pos / (10000 ** (i / embed_size)))

    return pe

八、组合成 Transformer Block

现在我们把组件组合起来:

Attention
+
FeedForward
+
LayerNorm

代码如下:

class TransformerBlock(nn.Module):

    def __init__(self, embed_size, heads):

        super().__init__()

        self.attention = MultiHeadAttention(embed_size, heads)

        self.norm1 = nn.LayerNorm(embed_size)

        self.ff = FeedForward(embed_size, embed_size*4)

        self.norm2 = nn.LayerNorm(embed_size)

    def forward(self, x):

        attn = self.attention(x)

        x = self.norm1(x + attn)

        forward = self.ff(x)

        out = self.norm2(x + forward)

        return out

这就是 Transformer 的一层。

真实模型就是:

Stack 12 layers
Stack 24 layers
Stack 96 layers

九、完整 Transformer(简化版)

class Transformer(nn.Module):

    def __init__(self, vocab_size, embed_size, heads, num_layers):

        super().__init__()

        self.embedding = nn.Embedding(vocab_size, embed_size)

        self.layers = nn.ModuleList(
            [TransformerBlock(embed_size, heads) for _ in range(num_layers)]
        )

        self.fc = nn.Linear(embed_size, vocab_size)

    def forward(self, x):

        x = self.embedding(x)

        for layer in self.layers:
            x = layer(x)

        out = self.fc(x)

        return out

一个简化版 Transformer 就完成了。


十、我第一次读 Transformer 的感受

说实话,当年第一次看论文:

完全看不懂。

公式一堆、图一堆。

但后来自己手写了一遍代码之后,突然就明白了:

Transformer 本质其实很简单:

Embedding
↓
Attention
↓
MLP
↓
重复很多层

真正复杂的不是模型结构。

而是:

  • 训练数据
  • 参数规模
  • 工程优化

这也是为什么现在的大模型动不动就是:

70B 参数
100B 参数
1T 参数

结构没变。

只是规模变了。


十一、最后聊点真实感受

很多人把 Transformer 看成一个非常神秘的 AI 技术。

但在我看来,它更像一个:

工程奇迹。

2017 年那篇论文其实只有一句核心思想:

Attention Is All You Need

但这句话却改变了整个 AI 行业。

从:

  • GPT
  • BERT
  • Stable Diffusion
  • ChatGPT

几乎所有大模型,

背后都是 Transformer。

有时候技术革命真的很神奇:

改变世界的,可能只是一条公式。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。