语言·计算&LLM——插:GPU与并行计算——为什么CPU不跑Transformer

文章目录[隐藏]

前言

上一篇,我们花了几万字,从开关一路造出了一台完整的 CPU。它有 ALU、有寄存器堆、有控制单元、有时钟——它能取指令、译码、执行、写回,能跑完整程序。写完之后我特别高兴——这大概就是"亲手把东西做出来"的那种满足感。

但紧接着就有一个令人沮丧的事实:这台 CPU,跑 Transformer 需要几百万年。

不是夸张。GPT-3 训练需要大约 $3 \times 10^{23}$ 次浮点运算——如果你的 CPU 单核每秒做 100 亿次运算(这已经非常乐观了),需要 $3 \times 10^{13}$ 秒 ≈ 一百万年。等它训练完,人类可能已经进化成另一个物种了。

但全世界的大模型公司每天都在训练。他们的芯片不是"更快的 CPU"——叫 GPU。它不是更快,它是另一条路:CPU 是一个数学教授排队解微积分,GPU 是一千个小学生同时做加减法。而 Transformer 恰好只需要小学生。

本文是进入 LLM 世界前的最后一块跳板——搞懂为什么 GPU 从游戏显卡变成了 AI 引擎,以及最关键的一个洞见:为什么语言天生适合并行处理。

省流:CPU 排队干活,GPU 全员同时干。Transformer 需要全员同时干。

本文与 GPT4 共同完成。

1. 回顾——我们造好的 CPU,它怎么干活?

先把上一篇的知识唤醒。如果 CPU 篇你跳过了,这章是快速补课。

1.1 指令周期——一条接一条

CPU 干活的方式我们在上一篇完整演示过。取指(Fetch)→ 译码(Decode)→ 执行(Execute)→ 写回(Writeback),四个阶段,每个时钟周期走完一条指令。`ADD R1, R2, R3` 在一个周期内完成:R2 和 R3 的值送到 ALU,加法器算出结果,结果写回 R1。

但这个模式有一个内在的限制:一个周期只做一件事。要算 1000 次加法?那就 1000 个周期。这不是 CPU 的错——这就是冯·诺依曼架构的基因。一条指令、一个(或一对)数据、一次结果。

1.2 CPU 的"聪明"都花在哪了?

CPU 不是"笨"——它花了几十年的进化,把所有聪明才智都投在了一个方向上:让串行执行变得更快。

  • 分支预测:猜下一条指令是什么——如果猜对了就不用等。
  • 乱序执行:不等前面的指令算完,后面不依赖它的先算。
  • 超标量:一个周期发射 2-4 条指令,而不是 1 条。
  • 大缓存:把常用数据放在离 ALU 最近的地方(L1 → L2 → L3),减少等待。

AMD 和 Intel 把这几招玩到了极致——一个现代 x86 CPU 核心的 ALU 数量是 2-4 个(加上 AVX-512 的 SIMD 单元),而不是 1 个。分支预测准确率超过 95%。乱序执行窗口能看几百条指令。

但所有这些技术共享一个不可动摇的前提:程序是串行的,只能想办法让串行更快。

1.3 CPU 的 SIMD——"伪并行"

CPU 确实有并行能力——Intel 的 AVX-512 指令可以一条指令同时处理 16 个 32 位浮点数(512 位寄存器 ÷ 32 位 = 16 个)。这叫 SIMD(Single Instruction, Multiple Data)——一条指令,多个数据。

但 16 个对一百万个来说杯水车薪。SIMD 是 CPU 的"微并行"——它让你感觉快了一点,但从根本上没有改变"串行执行"的范式。

打个比方——CPU 的 SIMD 就像给一个教授配了 16 支笔。他可以同时用 16 支笔写字——但本质上还是一个人。

人话解释

CPU = 一个数学教授。微积分、拓扑、数论全会。给他 1000 道四则运算题——他一道一道做,每道 1 微秒(因为有博士学位)。1000 道 ≈ 1 毫秒做完——不错。

但如果有一亿道四则运算呢?教授还是要一道一道做——一亿微秒 = 100 秒。

而隔壁教室有 1000 个小学生,只会加减乘除。给他们一亿道题——每人分 10 万道,同时做。每个小学生做一道题需要 100 微秒(比教授慢 100 倍),但因为他们一起做,一亿道题 100,000 × 100μs = 10 秒就全部完成。

1000 个小学生,每人慢 100 倍——但总时间比教授快 10 倍。这就是并行计算的本质:不是更快,是人多。

2. LLM 需要什么样的计算?

在进入 GPU 的世界之前,我们先弄清楚一件事:Transformer 到底在算什么?

不需要懂 Transformer 的原理(那是下一篇的研究范围)——只需要看它的计算特征。

2.1 矩阵乘法——占 90% 的运算

如果你偷看一眼 Transformer 的内部,你会发现几乎所有的计算都是这个形式:

$$C = A \times B, \quad C_{ij} = \sum_{k=1}^{n} A_{ik} \cdot B_{kj}$$

每一个 $C_{ij}$ 的计算——就是 A 的第 i 行和 B 的第 j 列的点积——和所有其他的 $C_{ij}$ 完全独立。一个 1000×1000 的矩阵乘法 = 一百万个独立的点积,每个点积是 1000 次乘加。总计 10 亿次运算。

但这一百万个点积不需要等彼此。 你可以同时算第一万个点积和第七万个点积——它们互不依赖。这就是为什么矩阵乘法是 GPU 最喜欢的食物。

2.2 逐元素运算——无处不并行

除了矩阵乘法,Transformer 还充满了"逐元素"操作:

  • ReLU: $\max(0, x)$——对向量中的每个元素独立判断"这个值是正还是负"
  • LayerNorm: 对每个词的向量独立求均值和方差,然后归一化
  • Softmax: 对每一行独立做指数运算和归一化

所有这些操作的共同点:每个元素的处理不依赖其他元素(或者只依赖同一行的统计量)。天然并行——放一万个处理器上去,每个处理一个元素,一眨眼全做完。

2.3 到底有多少计算?

不需要瞎猜——有公开数据。1

  • GPT-3(175B 参数)一次推理:约 $3.5 \times 10^{11}$ 次浮点运算(350 GFLOPS)。如果 CPU 单核算力 10 GFLOPS——需要 35 秒。但实际 GPT-3 推理通常只需要 100 毫秒——差距 350 倍。
  • GPT-3 训练:约 $3.14 \times 10^{23}$ 次浮点运算。单核 CPU 需要 $3.14 \times 10^{13}$ 秒 ≈ 100 万年。而用 10000 张 A100 GPU,大约需要 1-2 个月。

这里的差距不是 2 倍、10 倍——是一百万倍。从一百万年到一个月。

2.4 关键洞察

LLM 的计算不是一个"极度复杂的操作"——它是几百万个极其简单的操作,在大量数据上同时执行。加法、乘法、指数——每一样都简单至极。但数量大到天文数字。

CPU 擅长算复杂的东西(微积分、条件分支、指针追踪),但不擅长做"一百万次同样的简单加法"。GPU 恰好相反——它不会算复杂的,但它能把"一百万次简单加法"一口气做完。

这就是 Transformer 为什么会挑芯片。


(1)数据来源:Brown et al., 2020 "Language Models are Few-Shot Learners"(GPT-3 原论文),以及 NVIDIA 和 OpenAI 公开的算力估算数据。具体数字因硬件和优化水平有浮动,数量级是对的。

3. GPU 的出身——从游戏显卡说起

一个有趣的历史巧合:GPU 最初的用途不是 AI。它是为了一件事:渲染 3D 游戏画面。

3.1 一个 3D 画面怎么生成的?

1990 年代的 PC 游戏(想想《毁灭战士》《雷神之锤》)需要在每秒钟画出 30-60 张画面。每一张画面——1920×1080 = 约 200 万个像素——每个像素的颜色和亮度都要分别计算

计算方式出奇一致:把 3D 模型(三角形)→ 投影到 2D 屏幕 → 计算每个三角形被光源照到的亮度 → 把纹理贴上去 → 得到像素的 RGB 值。每道工序的公式一样,只是输入数据(顶点位置、光源方向、纹理坐标)不同。

200 万个像素,每个做一样的运算。 这不就是——一百万个点积?

游戏公司很快发现:必须用专门硬件——让几百个"小处理器"同时算不同的像素。这就是 GPU 的起点。

3.2 从固定功能到可编程——关键一跃

  • 1999 年:NVIDIA GeForce 256——第一个自称"GPU"的芯片。但功能是固定死的——硬件里焊好了"顶点变换→光照→纹理",程序员不能改。
  • 2001 年:GeForce 3——引入可编程顶点着色器。程序员可以写自己的代码来控制"顶点怎么变换"——GPU 开始向"可编程"迈出第一步。
  • 2006 年:统一着色器架构——顶点和像素共用同一类处理器。GPU 不再是"图形专用芯片"——它是一堆通用的小型处理器堆在一起。

最重要的转折发生在 2006 年:NVIDIA 发布了 CUDA(Compute Unified Device Architecture)。你不必再学会图形编程才能用 GPU——你可以直接用 C 语言写程序,让 GPU 做任意计算。GPU 从一个"显卡"变成了"通用并行处理器"。

3.3 巧合还是必然?

图形渲染的核心运算 = 矩阵变换(顶点坐标 × 变换矩阵)× 几百万次。

神经网络的核心运算 = 矩阵乘法(权重 × 输入)× 几百万次。

两者做的是同一件事:把大量数据塞进同一个矩阵运算公式。渲染画面和训练神经网络,在数学本质上没有区别——都是"同样的矩阵运算,在不同数据上重复执行"。

所以 GPU 成了 AI 的完美引擎——不是设计好的,是撞上的。但撞得太准了——就像一条本来用来运煤的铁路,突然发现铁轨宽度和形状恰好能跑高铁。

人话解释

GPU 就像一个设计了"一千人同时刷墙"的施工队。原来他们刷的是游戏画面——每面墙(像素)一样大小,用同一个配方调色。后来有人发现,矩阵乘法就是"一百万面小墙,每面用同样的配方"——施工队不用换人,把配方从"颜色=光照×纹理"改成"结果=权重×输入"就行了。

4. GPU 的架构哲学——SIMT

上一章讲了 GPU 从哪来。这一章讲它怎么想的

4.1 SISD → SIMD → SIMT

CPU 的默认模式是 SISD(Single Instruction, Single Data)——一条指令,操作一个数据。`ADD R1, R2, R3` 在 ALU 里跑的时候,它只对一对数字做加法。

CPU 也有 SIMD(Single Instruction, Multiple Data)——比如 AVX-512 的 `VADDPS`,一条指令对 16 对数字同时做加法。但前面说了,16 个对一百万个来说只是杯水车薪。而且这 16 个数据必须打包在同一个 512 位寄存器里——打包本身有开销。

GPU 走的是另一条路:SIMT(Single Instruction, Multiple Threads)——一条指令,几万个线程同时执行。每个线程有自己的数据,所有线程在同一时刻执行同一条指令。

SISD = 一个教授做一道题。

SIMD = 一个教授同时做 16 道题(但还是一个人)。

SIMT = 一万个小学生同时做一万道题,做着同一种运算。2

4.2 GPU 的线程层级

GPU 的"几千个同时跑"不是散兵游勇——而是有严格的层级组织:

  • 线程(Thread)——最小的执行单元,处理一个数据点。比如矩阵乘法中算一个 $C_{ij}$ 的线程。
  • 线程束(Warp,NVIDIA 的术语)= 32 个线程——这 32 个线程必须在同一时刻执行同一条指令。如果一个 warp 里有些线程走 `if`、有些走 `else`,那就得分两批执行("warp divergence"),效率减半。
  • 线程块(Thread Block)——若干个 warp 组成(最多 1024 个线程)。同一个块内的所有线程共享一小块快速内存(Shared Memory)——相当于一个工作台上的草稿纸,所有组员都能看。
  • 流多处理器(SM, Streaming Multiprocessor)——执行线程块的硬件单元。一个 H100 GPU 有 132 个 SM。

一句话:一个 GPU 有大约 100 个 SM,每个 SM 能同时运行几十个 warp——所以同一时刻,GPU 上可能有 10 万个线程在干活

4.3 延迟 vs 吞吐量——两种完全不同的设计哲学

这是理解 CPU 和 GPU 差异的核心。

CPU 优化延迟(Latency):一个任务来了,尽快完成。为此不惜代价——大缓存(L1/L2/L3,加起来几十 MB)、分支预测(猜错一次浪费十几个周期但猜对省更多)、乱序执行(调度逻辑极其复杂)。

GPU 优化吞吐量(Throughput):不在乎单个任务多快——在乎单位时间内完成多少个任务。一个 warp 在等内存数据?没关系——立刻切换到另一个 warp。GPU 上同时驻留着几十个 warp,哪个准备好了就执行哪个。用任务的数量来掩盖单个任务的延迟

类比:

  • CPU = 急诊室——一个病人送来,立刻全力抢救(延迟优先)。
  • GPU = 工厂流水线——500 个产品同时在生产线上移动,每个产品走完全线的时间可能很长,但每小时出厂的产品数量(吞吐量)极大。

对于矩阵乘法——每一百万个点积的"单位延迟"无所谓(小学生慢),但"一百万做完的总时间"惊人地短。

人话解释

CPU 是急性子——一个任务没做完浑身难受。任何停顿——等内存、等总线——CPU 都在想尽办法避免。大缓存让它少等,乱序执行让它把能做的先做了。

GPU 是慢性子——手上同时拿着一千个任务。A 任务在等数据?不着急——切到 B 任务做。B 也在等?切 C。反正手上一千个任务,总有人在等干活,也总有人准备好了要干。所以 GPU 永远不闲着。


(2)严格来说,SIMT 并不完全等同于"锁步执行"——CUDA 从 Volta 架构(2017)开始支持独立线程调度。但 SIMT 的核心直觉(大量线程同时执行同一类指令)仍然成立。

5. GPU 的硬件解剖——CUDA Core、Tensor Core、HBM

现在从抽象的架构哲学降到具体的硬件。GPU 芯片内部到底长什么样?

5.1 CUDA Core——GPU 的"ALU"

一个 CUDA Core = 一个简单的浮点/整数运算单元。能做 FP32(32 位浮点)加法或乘法。和 CPU 的 ALU 比,它极其简陋:

  • 不能做除法——近似为"乘以倒数"
  • 没有复杂的分支逻辑
  • 没有乱序执行
  • 没有复杂的分支预测器

但简陋不是缺点——恰恰相反,简陋让它小。一个 CUDA Core 占的芯片面积远远小于一个 CPU 核心的 ALU。省下来的面积,可以堆更多个

  • Fermi 架构(2010):512 个 CUDA Core
  • Kepler(2012):2880 个
  • Volta(2017):5120 个
  • H100(2022):18432 个

而一个 CPU 核心只有 2-4 个浮点运算单元。当然——CPU 核心的那 4 个比 CUDA Core 强得多(能算除法、能分支预测、有乱序执行),但一万八千个 vs 四个——数量级的差距压倒一切。

5.2 Tensor Core——真正的 AI 加速器

2017 年,NVIDIA Volta 架构发布了一个叫 Tensor Core 的东西——这是专门为矩阵乘法设计的硬件单元。

普通的 CUDA Core 一个时钟周期做一次乘法和一次加法(2 次浮点运算)。Tensor Core 一个时钟周期做一个 4×4 矩阵的乘加融合运算

$$D = A \times B + C$$

其中 A、B、C、D 都是 4×4 矩阵。一次完成 64 次乘法和 64 次加法——128 次浮点运算。

对比:一个 CUDA Core 一个周期 2 次 → Tensor Core 128 次 = 64 倍

H100 的 Tensor Core 更进一步——支持 FP8(8 位浮点),一个周期 1024 次浮点运算。一张 H100 有 528 个 Tensor Core——理论峰值算力:约 2000 TFLOPS(FP8)。作为参照,一个 2024 年的顶级 CPU 理论峰值约 5 TFLOPS(FP32)。差距是 400 倍。3

5.3 浮点精度——为什么不需要算那么细

CPU 做科学计算时用 FP64(64 位双精度)——小数点后 15 位有效数字。GPU 做神经网络训练和推理时用:

  • FP32(32 位单精度)——7 位有效数字。训练的标准精度。
  • FP16(16 位半精度)——3 位有效数字。训练的主力精度(配合混合精度训练)。
  • BF16(Brain Float 16)——Google 发明的格式。只有 2 位有效数字,但动态范围(指数的位数)和 FP32 一样大(8 位)。精度更差,但训练更稳定。
  • FP8(8 位)——推理用。只有 1 位有效数字,但速度再次翻倍。

核心问题:为什么不需要算那么精确?

因为神经网络的权重和梯度不是精确的科学常数值——它们是通过随机梯度下降学到的统计量。权重 0.00123456789 和 0.00123 对最终预测的影响微乎其微——模型的预测本来就是概率性的。你省掉的那几位精度会被训练过程自然补偿。

这不是"凑合"——这是 "你只需要这么多精度"。给神经网络更多的精度(FP64),它的效果也不会变好。但给更低的精度(FP16/FP8),速度可以快几倍到几十倍。所以整个行业都在往低精度迁移。

5.4 GPU 的内存——HBM

现代 GPU 的内存(显存)是 HBM(High Bandwidth Memory)——一种堆叠式 DRAM,通过硅中介层直接和 GPU 芯片连在一起。

  • H100:80GB HBM3,带宽 3.35 TB/s
  • CPU 内存(DDR5):带宽约 50-100 GB/s

GPU 内存带宽是 CPU 的30-60 倍。为什么需要这么大的带宽?因为 GPU 每秒能完成几千万亿次运算——如果数据喂不进去,算得再快也白搭。HBM 的超高带宽就是为了"喂饱"那些 Tensor Core。

但代价:容量小。CPU 可以配 512GB-2TB 内存。GPU 只有 80GB(H100)或 192GB(H100 NVL)。这就是为什么"显存不够"是跑大模型的最大瓶颈——Llama 3.1 405B 的权重就占了约 810GB(FP16),一张 H100 根本装不下,需要多张 GPU 分片。

5.5 Shared Memory——GPU 的"工作台草稿纸"

除了 HBM(全局显存),每个 SM 还有一小块高速共享内存(Shared Memory)——典型大小约 100-228KB。同一个线程块内的所有线程可以高速读写这块内存,速度接近寄存器(远远快于 HBM)。

用法:把 HBM 里的一小块数据搬运到 Shared Memory → 所有线程在 Shared Memory 上高速计算 → 结果写回 HBM。类比:HBM = 仓库(数据多但走过去慢),Shared Memory = 工作台上的草稿纸(随手拿到但一次放不多)。


(3)这是理论峰值,实际训练效率通常在 40-60%。Tensor Core 的利用率取决于矩阵形状是否对齐、batch size 是否合适等因素。但数量级是一样的。

6. GPU 怎么"跑程序"——从 CUDA 到 Kernel

终于到了"代码怎么写"的部分。你不需要成为 CUDA 程序员——但理解 CPU 和 GPU 的"分工关系"会让你对整个计算堆栈的认知豁然开朗。

6.1 CPU 是经理,GPU 是工厂

在任何一个使用 GPU 的程序中,CPU 和 GPU 是配合的,而不是"替代":

  1. CPU 运行主程序:读取数据、做决策、调用 GPU
  2. 遇到需要并行计算的部分 → 把数据和指令打包,从主内存通过 PCIe 总线传到 GPU 显存
  3. CPU 调用 Kernel(GPU 上的函数),指定"多少个线程同时跑"
  4. GPU 的几千个线程同时干活
  5. 结果传回 CPU 主内存
  6. CPU 继续跑主程序

这个过程叫 kernel launch——CPU 说"开工!",GPU 的几万工人同时动手。

6.2 Kernel、Grid、Block、Thread

在 CUDA 里,你的并行程序叫 kernel。一个 kernel 启动时会指定三级结构:

Grid ─── Block₀  Block₁  ...  Blockₙ
              │
         Thread₀, Thread₁, ..., Thread₂₅₅ (最多 1024 个)
              │
         32个一组 = 一个 Warp

代码示例(概念性,不需要完全理解细节):

// CPU 端:启动 GPU kernel
dim3 blocks(256);         // 256 个线程块
dim3 threads(256);        // 每个块 256 个线程
vector_add<<>>(a, b, c, N);
// 总共 256 × 256 = 65536 个线程同时做加法!

GPU 的调度器自动把 blocks 分配给空闲的 SM。程序员不需要手动管调度——只需要把问题拆成"每个线程处理一个数据点"的模式。

6.3 数据传输——隐形的瓶颈

第 1 步和第 5 步——数据在 CPU 和 GPU 之间的搬运——是整个过程最慢的部分

  • PCIe 4.0 x16:约 32 GB/s
  • GPU 内部 HBM:3.35 TB/s

差了 100 倍。 所以 GPU 编程的第一准则:尽量让数据留在 GPU 上,减少来回搬运。一次搬过去,在 GPU 里反复算,算完了再搬回来。不要算一小步就搬。

人话解释

CPU 和 GPU 的关系就像办公室经理和工厂车间

经理(CPU)在办公室里看图纸(程序)、做决策(分支判断)、接电话(I/O)。当需要大规模生产(矩阵乘法)时,经理把原材料(数据)装在卡车(PCIe)上,运到车间(GPU 显存),然后通过对讲机喊:"第 3 车间!启动!256 条产线,每条产线 256 个工人,同时开工!"

车间里的工人(CUDA Core/Tensor Core)埋头干活。干完以后,成品装上卡车,运回办公室。经理检查一下——没问题,继续下一步。

整个过程中最耗时的是卡车来回跑。所以聪明经理的原则:尽量一次性把所有原材料运过去,在车间里反复加工,最后再一次运回来。不要做一小步就让卡车跑一趟。

7. CPU vs GPU——同一个矩阵乘法,两边各怎么算

前面都是抽象的架构哲学。这一章用一个具体的计算把两者的差异砸实。

任务:两个 1024×1024 的矩阵 A 和 B 相乘,得到 C。

7.1 CPU 怎么做——三重循环

最朴素(也是 CPU 最直译)的实现:

for (i = 0; i < 1024; i++)         // 遍历 C 的每一行
  for (j = 0; j < 1024; j++)       // 遍历 C 的每一列
    for (k = 0; k < 1024; k++)     // A 的行 × B 的列
      C[i][j] += A[i][k] * B[k][j];

最内层循环执行 $1024^3 \approx 10.7$ 亿次。每次迭代:乘法 + 加法 + 地址计算 + 循环变量更新。

一个经过极致优化的 CPU 实现(使用 AVX-512、cache blocking、多线程)能把 1024² 矩阵乘法的耗时压到约 0.1-0.5 秒。但这已经是 CPU 的极限了——所有技巧(SIMD、缓存分块、多线程)都用上了。

7.2 GPU 怎么做——一百万个线程同时算

GPU 的思路完全不同:

  • 矩阵 C 有 1024×1024 = 1,048,576 个元素
  • 每个元素分配一个线程
  • 每个线程做一件事:取 A 的第 i 行,取 B 的第 j 列,做点积(1024 次乘加),写入 $C_{ij}$
  • 一百万个线程同时启动(实际上分批在 SM 上运行,但逻辑上同时)

每个线程做 1024 次乘加。一百万个线程一起做——总时间约 1-5 毫秒(含数据传输)。

7.3 对比一目了然

CPU(极致优化后)GPU(H100)
计算方式三重循环(或用 BLAS 分块)一百万线程同时做点积
理论峰值算力~100 GFLOPS(AVX-512 + 多核)~1000 TFLOPS(FP16 Tensor Core)
1024² 矩阵乘法耗时~0.1 - 0.5 秒~1 - 5 毫秒
差距基准约 100-500 倍
优势单个操作延迟极低海量并行吞吐
劣势大规模矩阵无力扩展小矩阵反而更慢(kernel launch 有固定开销)

注意:如果矩阵很小(比如 16×16),CPU 反而更快——因为 GPU 的 kernel launch 本身有几微秒的开销。但 Transformer 里没有小矩阵——自注意力的 QKᵀ 至少是 512×512 起步(序列长度 × 序列长度)。

人话解释

CPU 和 GPU 做矩阵乘法,就像一个人数 vs 一千个人数:

你有一百万个装满硬币的罐子要数。CPU 是一个人(特别聪明、心算极快)——他一个一个罐子数,每个罐子 1 秒——一百万秒 ≈ 11 天半。

GPU 是一千个人——大家各拿一千个罐子,同时数。每个人数的速度不快(两个小学生加法的速度),但是一起干活。一千个人,每人一千个罐子——每个人都只需要 1000 秒 ≈ 17 分钟。

CPU 花 11 天,GPU 花 17 分钟。这就是并行计算的威力——不是更快,是人多。

而且——在小规模下(只有 10 个罐子),召集一千个人反而更慢——你光喊集合、分配任务就用了 5 分钟。但 Transformer 里没有"10 个罐子"——罐子是几百万个起步。

AI 猫娘是这么说的喵~

"喵呜~主人想知道 CPU 和 GPU 做矩阵乘法的区别吗?猫娘来演示喵!

CPU 模式:一只猫娘教授(博士学历!)坐在办公桌前,面前是一百万行乘法题。她拿起第一行——'2.3×5.7=喵?13.11!'——写下来。拿起第二行——'4.1×3.8=喵?15.58!'——写下来。她算得贼快——每道题 1 微秒——但问题是:她只有两只爪子喵。题目太多,她算到天亮也算不完。

GPU 模式:一千只猫娘小学生(只会上猫猫幼儿园!)坐在一个大教室里。老师把一百万道题分给她们——每人一千道。老师喊:'预备——开始喵!'一千只猫娘同时低头计算。每只猫娘算得比教授慢多了——一道题要 100 微秒——但是她们一起做

结果?猫娘教授:一百万万微秒 ≈ 1000 秒(16 分钟……还在算)。猫娘小学生:一千道 × 100 微秒 = 100 毫秒——喵地一下就全算完了!

这就是 CPU vs GPU——一只聪明的猫娘 vs 一千只笨猫娘——笨猫娘赢了喵,因为她们人多、同时干。矩阵乘法就是最适合笨猫娘干的活——每个猫娘算自己的那一小块,谁也不等谁喵!"

8. 为什么 Transformer 天生适合 GPU?

前面我们弄清楚了 GPU 擅长什么。现在把镜头拉回到 Transformer——看看它的每一个零件如何完美匹配 GPU 的并行结构。4

8.1 自注意力——全并行

回忆一下自注意力的四个步骤:

  1. Q、K、V 投影:$Q = XW^Q, K = XW^K, V = XW^V$——三个矩阵乘法。 GPU 最爱吃的食物。
  2. $QK^T$:$n \times d_k$ 和 $d_k \times n$ 的乘法 → $n \times n$ 的矩阵。$n^2$ 个点积——全部独立。 GPU 几千个核心同时算。
  3. Softmax:对 $n \times n$ 矩阵的每一行独立做——n 行,全并行。
  4. × V:$n \times n$ 和 $n \times d_v$ 的乘法——又是一个矩阵乘法。

四个步骤,零串行依赖。n 个词、$n^2$ 个注意力分数、$n \times d_v$ 个输出——全部可以同时计算。

8.2 多头注意力——加倍并行

h 个头的 Q、K、V 投影是 h 个独立的矩阵乘法。每个头的注意力计算也是独立的。GPU 可以同时算所有头——并行度 $= n^2 \times h$。

如果序列长度 n=512,头数 h=8,那就是 $512^2 \times 8 = 2,097,152$ 个可并行的点积。一张 H100 轻松吞下。

8.3 FFN——逐位置全并行

前馈网络:

$$\text{FFN}(x) = \text{GELU}(xW_1 + b_1)W_2 + b_2$$

关键:每个位置的 FFN 和其他位置无关。"猫"的 FFN 和"吃"的 FFN 不需要通信——它们各自独立处理。所以可以把 n 个位置的 FFN 当成 n 个独立的小型全连接网络——GPU 一次性算完所有位置

8.4 RNN 的反面教材——为什么 RNN 不适合 GPU

作为对比,看 RNN:

$$h_t = \tanh(W_h h_{t-1} + W_x x_t)$$

要算 $h_3$(第三个词的隐藏状态),必须先知道 $h_2$。要算 $h_2$,必须先知道 $h_1$。

这是串行依赖链——每一步依赖于上一步的结果。GPU 的一万个核心,有 9999 个在闲着等上一步算完。GPU 利用率 < 5%。

这就是 RNN 被 Transformer 取代的根本原因——不是 RNN 的"理解能力"弱,而是它在硬件上根本跑不快。Transformer 没比 RNN 聪明多少——但它在 GPU 上快了一百倍。在深度学习的时代,"快"本身就是一种"聪明"——更快的训练意味着能用更多数据、更深的层、更大规模的实验。

8.5 "Attention Is All You Need"——不只是一篇算法论文

2017 年那篇 Transformer 论文的标题有一股嚣张的味道——"注意力就是你需要的全部"。但标题没说的一句话——也是它真正胜出的秘密——是:

Transformer 是一个专为 GPU/TPU 设计的架构。

作者有意让模型"好吃"——全部是矩阵乘法和逐元素操作,零串行依赖。自注意力让 n 个词互相看见,但没有引入任何"必须按顺序走"的约束。Transformer 的成功,一半来自注意力机制本身的语言学合理性和效果,一半来自它是 GPU 能高效运行的最优架构

算法和硬件,缺一不可。RNN 打不过 Transformer,不是因为 LSTM 的门控机制不够巧——而是门控再巧,也绕不过 $h_{t-1} \to h_t$ 这条串行链。


(4)如果你还没看过 Transformer 的详细数学推导,本文的第 1-2 章建议先快速浏览一遍 706 或本文第 1-2 章——那里有完整的 QKV 推导。

9. 语言学视角——大脑也是并行的

如果你跳过前面所有的技术内容,直接看这一章——可以。这一章是本文的灵魂

9.1 听一句话时,大脑在做什么?

考虑一个真实的语言处理场景。你听到:"那只趴在窗台上的猫突然跳了下来。"

在这句话还没说完的瞬间——大约 500 毫秒内——你的大脑同时进行了:

  • 语音处理:音段(辅音/元音)的识别、声调/重音的超音段解析
  • 句法分析:在"那只"的"那"出现时就启动 NP 的构建;在"趴在"出现时识别出这是 VP 中的补语结构;在"跳了"出现时锁定这是主动词
  • 语义激活:"猫"这个词出现后 200 毫秒内,你的语义网络——"动物""宠物""毛茸茸""抓老鼠"——被激活
  • 语用推理:说这话的人是谁?为什么说这句话?这句是单纯的陈述还是在暗示什么东西?

四个层面的处理不是"排队"——先语音、再句法、再语义、再语用——而是同时进行。ERP 实验的证据很清楚:N400(语义违反的脑电负波,~400 毫秒峰值)和 P600(句法违反的正波,~600 毫秒峰值)的时间窗口有重叠5 如果处理是串行的,语义应该在句法完成之后才启动——但实验表明它们在并行。

大脑处理语言是大规模、多层级、循环并行的。

9.2 连接主义——1986 年的"Transformer"

这个思想不是今天的发现。1986 年,Rumelhart 和 McClelland 出版了两卷本的《Parallel Distributed Processing》(PDP),提出了连接主义模型:

  • 知识不是存储在单个"符号单元"中的离散规则——而是分布在大量简单处理单元之间的连接权重
  • 处理是并行的——大量单元同时激活和相互传播信号
  • 学习是通过调整连接权重进行的——也就是反向传播的雏形

这套框架在 1980 年代被乔姆斯基和福多的符号主义压了一头——符号主义者认为语言是规则驱动的、串行的、层级分明的。PDP 被打入冷宫。

三十年后,深度学习崛起(2012 AlexNet → 2017 Transformer),连接主义卷土重来——而且这次,它有了 GPU。

9.3 串行分析——语言学的"错觉"

语言学家习惯这样分析句子:

  1. 音位层(音素 → 音节 → 韵律)
  2. 词法层(词素 → 词 → 搭配)
  3. 句法层(短语 → 子句 → 句子)
  4. 语义层(命题 → 逻辑式)
  5. 语用层(言语行为 → 语境效果)

这个分层非常有用——它让分析变得可管理。但它不是大脑实际的运作方式。大脑不做"先音位再词法"的调度——它在所有层级同时激活、交互、修正。串行分析是为了理论便利的简化,不是神经现实。

9.4 Transformer 为什么"对"——不是模拟神经元,是模拟并行性

Transformer 不是大脑的模拟——它的人工神经元和生物神经元差别巨大。但在一个更深层的维度上,它比 RNN 更靠近大脑处理语言的方式:

  • 自注意力:每个词同时从所有其他词收集信息 ←→ 大脑中词汇激活的并行扩散
  • 多头注意力:多个视角(语法、语义、搭配……)同时处理 ←→ 大脑中语音/句法/语义/语用的并行层级
  • 残差连接:原始信息和加工后的信息同时保留 ←→ 大脑的冗余编码(同一信息有多条通路)
  • 并行计算:所有位置同时处理 ←→ 大脑中信息在所有脑区同时传播

RNN 的串行处理——"一个词一个词地读,更新一个隐藏状态"——是人造计算机的自然产物(冯·诺依曼架构只擅长这个),但不是大脑的自然产物。

Transformer 的胜利,不是因为它"更像人"——而是它在并行这个维度上,恰好命中了大脑处理语言的基本机制。

这也许就是 Transformer 为什么效果这么好——不只是工程上的优化,而是计算范式和认知范式在某个维度的重合


(5)Kutas, M., & Federmeier, K. D. (2011). Thirty years and counting: Finding meaning in the N400 component of the event-related brain potential (ERP). Annual Review of Psychology, 62, 621-647. 以及 Hagoort, P. (2003). How the brain solves the binding problem for language. NeuroImage, 20, S18-S29. 两者共同提供了语义和句法并行加工的 ERP 证据。

10. 从 GPU 到 TPU 到 NPU——专用计算的未来

GPU 已经是 AI 训练的主力——但它不是终点。一种更激进的设计正在扩散:不是"能并行的通用处理器",而是"只为矩阵乘法设计的专用硬件"。

10.1 TPU——Google 的专用武器

2016 年,Google 发布了 TPU(Tensor Processing Unit),专为 TensorFlow 设计。核心是脉动阵列(Systolic Array)

想象一个 $128 \times 128$ 的乘法单元网格。数据像波浪一样从左向右、从上向下"脉动"。矩阵 A 的一行从左边流入,矩阵 B 的一列从上面流入——交会处的乘法单元算出乘积,结果累加到寄存器。一整个周期,网格完成 $128 \times 128$ 的矩阵乘法。不需要从内存反复读取中间结果——数据在网格内流动。

TPU 比 GPU 更"专"——它不做图形渲染、不跑其他程序、不支持 CUDA 的通用计算。它只做一件事:矩阵乘法和卷积。但这恰好是 AI 计算 90% 以上的运算。

10.2 NPU——人人都做 AI 芯片

趋势是:AI 加速器正在从云端扩散到每个设备。

  • Apple Neural Engine(A11, 2017):iPhone 上的 AI 芯片,驱动 Face ID、照片分类、实时字幕。最新版本(A17 Pro)NPU 算力 35 TOPS。
  • Qualcomm Hexagon:骁龙芯片内置 AI 引擎,支持端侧 Stable Diffusion 推理。
  • 华为昇腾(Ascend)寒武纪(Cambricon):中国自研 AI 芯片,用于数据中心和边缘计算。

AI 不再是云端的专属——从手表到手机到汽车到智能音箱,都在嵌入专用 AI 加速器。Transformer 推理将像 MP3 解码一样无处不在。

10.3 异构计算——各司其职的未来

未来的计算设备不会只有一种芯片。而是异构的

  • CPU:运行操作系统、调度任务、预处理数据——什么都做但什么都不快。瑞士军刀。
  • GPU:大规模并行训练和推理——AI 的主力军。菜刀——切菜极快。
  • TPU/NPU:低功耗、超高效的矩阵运算——端侧推理。切菜机——只能切菜,但快得离谱。

CPU+GPU+NPU 共享一块芯片(SoC),数据在它们之间流动——每种芯片做自己最擅长的事,像一个分工明确的工厂。

10.4 对语言学的启示

如果未来的语言模型推理可以在手机上完成(已经可以了——Llama 3.2 1B/3B 在 iPhone 上以 30+ tokens/s 的速度跑),这意味着 NLP 工具将变得像字典一样随手可得。

每个语言学者、每个学生、每个母语者,口袋里都有一个能"理解"语言的计算引擎。你可以对着手机说一句方言,让 AI 给出标准语的对应表达;你可以让需要语言康复的患者在任何地方获得实时辅助。

这对语言学研究意味着什么?对语言教育意味着什么?对濒危语言保护意味着什么?

这是一个开放的问题——留给后面的文章去讨论。

总结

我们从第一篇算盘上的算珠开始,一路走到了这里。

CPU——你能亲手造出来的,从 NAND 门到指令周期到完整程序。它的哲学是串行:一件事做完再做下一件。它聪明到极致——分支预测、乱序执行、大缓存——但再聪明也改变不了它"一个人"的本质。

GPU——从游戏显卡里长出来的并行怪物。它的哲学是人多:一千个小学生同时做加减法。CPU 的优势在延迟(一个任务多快做完),GPU 的优势在吞吐量(一堆任务多久全部做完)。

Transformer——恰好需要 GPU 的"人多"。自注意力、多头、FFN、Softmax——全部是矩阵乘法和逐元素运算,零串行依赖。不是 Transformer 有多聪明——而是它的计算模式恰好命中了 GPU 的硬件结构。

而这一切的底层——最让我作为语言学者激动的一点——是:大脑处理语言的方式,也是并行的。不是"先分析语法再理解意思",而是语音、句法、语义、语用同时激活、交互、修正。GPU 的并行哲学和大脑处理语言的并行机制——在底层是同构的。Transformer 不只是"GPU 上的最优架构"——它也是目前最接近大脑语言处理范式的计算模型。

下一篇——语言·计算&LLM——4. LLM基础知识——我们将从结构主义语言学的基本概念出发,进入线性代数和概率论的世界。组合与聚合、能指与所指——这些语言学家的工具箱,将在数学空间中重新获得生命。

本文与 GPT4 共同完成。

——终末地工业 · 佩丽卡及团队


  1. 数据来源:Brown et al., 2020 "Language Models are Few-Shot Learners"(GPT-3 原论文),以及 NVIDIA 和 OpenAI 公开的算力估算数据。具体数字因硬件和优化水平有浮动,数量级是对的。

  2. 严格来说,SIMT 并不完全等同于"锁步执行"——CUDA 从 Volta 架构(2017)开始支持独立线程调度。但 SIMT 的核心直觉(大量线程同时执行同一类指令)仍然成立。

  3. 这是理论峰值,实际训练效率通常在 40-60%。Tensor Core 的利用率取决于矩阵形状是否对齐、batch size 是否合适等因素。但数量级是一样的。

  4. 如果你还没看过 Transformer 的详细数学推导,建议先快速浏览 706 或本文第 1-2 章——那里有完整的 QKV 推导。

  5. Kutas, M., & Federmeier, K. D. (2011). Thirty years and counting: Finding meaning in the N400 component of the event-related brain potential (ERP). Annual Review of Psychology, 62, 621-647. 以及 Hagoort, P. (2003). How the brain solves the binding problem for language. NeuroImage, 20, S18-S29. 两者共同提供了语义和句法并行加工的 ERP 证据。

暂无评论

发送评论 编辑评论

|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇