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

简介: 手撕 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。

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

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

目录
相关文章
|
13天前
|
人工智能 JavaScript Ubuntu
5分钟上手龙虾AI!OpenClaw部署(阿里云+本地)+ 免费多模型配置保姆级教程(MiniMax、Claude、阿里云百炼)
OpenClaw(昵称“龙虾AI”)作为2026年热门的开源个人AI助手,由PSPDFKit创始人Peter Steinberger开发,核心优势在于“真正执行任务”——不仅能聊天互动,还能自动处理邮件、管理日程、订机票、写代码等,且所有数据本地处理,隐私完全可控。它支持接入MiniMax、Claude、GPT等多类大模型,兼容微信、Telegram、飞书等主流聊天工具,搭配100+可扩展技能,成为兼顾实用性与隐私性的AI工具首选。
20123 111
|
6天前
|
人工智能 安全 Linux
【OpenClaw保姆级图文教程】阿里云/本地部署集成模型Ollama/Qwen3.5/百炼 API 步骤流程及避坑指南
2026年,AI代理工具的部署逻辑已从“单一云端依赖”转向“云端+本地双轨模式”。OpenClaw(曾用名Clawdbot)作为开源AI代理框架,既支持对接阿里云百炼等云端免费API,也能通过Ollama部署本地大模型,完美解决两类核心需求:一是担心云端API泄露核心数据的隐私安全诉求;二是频繁调用导致token消耗过高的成本控制需求。
4414 7
|
8天前
|
人工智能 安全 API
OpenClaw“小龙虾”进阶保姆级攻略!阿里云/本地部署+百炼API配置+4种Skills安装方法
很多用户成功部署OpenClaw(昵称“小龙虾”)后,都会陷入“看似能用却不好用”的困境——默认状态下的OpenClaw更像一个聊天机器人,缺乏连接外部工具、执行实际任务的能力。而Skills(技能插件)作为OpenClaw的“动手能力核心”,正是打破这一局限的关键:装对Skills,它能帮你自动化处理流程、检索全网资源、管理平台账号,真正变身“能做事的AI管家”。
5137 7
|
9天前
|
人工智能 API 网络安全
Mac mini × OpenClaw 保姆级配置教程(附阿里云/本地部署OpenClaw配置百炼API图文指南)
Mac mini凭借小巧机身、低功耗和稳定性能,成为OpenClaw(原Clawdbot)本地部署的首选设备——既能作为家用AI节点实现7×24小时运行,又能通过本地存储保障数据隐私,搭配阿里云部署方案,可灵活满足“长期值守”与“隐私优先”的双重需求。对新手而言,无需复杂命令行操作,无需专业技术储备,按本文步骤复制粘贴代码,即可完成OpenClaw的全流程配置,同时接入阿里云百炼API,解锁更强的AI任务执行能力。
6420 2
|
10天前
|
人工智能 安全 前端开发
Team 版 OpenClaw:HiClaw 开源,5 分钟完成本地安装
HiClaw 基于 OpenClaw、Higress AI Gateway、Element IM 客户端+Tuwunel IM 服务器(均基于 Matrix 实时通信协议)、MinIO 共享文件系统打造。
7780 6
|
12天前
|
人工智能 JSON API
保姆级教程:OpenClaw阿里云及本地部署+模型切换流程+GLM5.0/Seedance2.0/MiniMax M2.5接入指南
2026年,GLM5.0、Seedance2.0、MiniMax M2.5等旗舰大模型相继发布,凭借出色的性能与极具竞争力的成本优势,成为AI工具的热门选择。OpenClaw作为灵活的AI Agent平台,支持无缝接入这些主流模型,通过简单配置即可实现“永久切换、快速切换、主备切换”三种模式,让不同场景下的任务执行更高效、更稳定。
7224 4
|
12天前
|
人工智能 JavaScript API
保姆级教程:OpenClaw阿里云/本地部署配置Tavily Search skill 实时联网,让OpenClaw“睁眼看世界”
默认状态下的OpenClaw如同“闭门造车”的隐士,仅能依赖模型训练数据回答问题,无法获取实时新闻、最新数据或训练截止日期后的新信息。2026年,激活其联网能力的最优方案是配置Tavily Search技能——无需科学上网、无需信用卡验证,每月1000次免费搜索额度完全满足个人需求,搭配ClawHub技能市场,还能一键拓展天气查询、邮件管理等实用功能。
7250 5
|
18天前
|
人工智能 自然语言处理 JavaScript
2026年Windows+Ollama本地部署OpenClaw保姆级教程:本地AI Agent+阿里云上快速搭建
2026年OpenClaw凭借本地部署、私有化运行的特性,成为打造个人智能体的核心工具,而Ollama作为轻量级本地大模型管理工具,能让OpenClaw摆脱对云端大模型的依赖,实现**本地推理、数据不泄露、全流程私有化**的智能体验。本文基于Windows 11系统,从硬件环境准备、Ollama安装与模型定制、OpenClaw部署配置、技能扩展到常见问题排查,打造保姆级本地部署教程,同时补充阿里云OpenClaw(Clawdbot)快速部署步骤,兼顾本地私有化需求与云端7×24小时运行需求,文中所有代码命令均可直接复制执行,确保零基础用户也能快速搭建属于自己的本地智能体。
19277 116