第1章:TensorCore硬件架构 — Volta/Turing/Ampere中的设计

大家好,我是你们这门课的老朋友。今天咱们聊聊TensorCore的硬件架构。

说实话,我第一次接触TensorCore是在Volta架构的发布会上。当时NVIDIA说这东西能让矩阵运算快一个数量级,我心里还犯嘀咕:真有这么神?后来亲手调过几个模型之后,嗯,真香。

1.1 为什么要有TensorCore?

深度学习的核心是什么?说白了就是矩阵乘法。全连接层是矩阵乘,卷积层也能转化成矩阵乘。传统的CUDA Core做矩阵乘,是一个元素一个元素地算,效率其实不高。

你想想看,一个4x4的矩阵乘,如果用CUDA Core,得拆成16个乘法和12个加法。但TensorCore不一样,它一个时钟周期就能搞定一个4x4矩阵乘。这就是硬件级别的加速。

核心思想:TensorCore不是替代CUDA Core,而是专门为矩阵乘法设计的专用电路。它把乘法和加法打包成一个原子操作,一次搞定。

1.2 Volta架构:TensorCore的诞生

Volta(V100)是第一代搭载TensorCore的架构。我记得当时看白皮书,第一反应是:这玩意儿怎么用?

Volta的TensorCore支持的是4x4矩阵乘法,精度是FP16输入,FP32累加。具体来说:

  • 输入:两个4x4的FP16矩阵(A和B)
  • 累加:一个4x4的FP32矩阵(C)
  • 输出:一个4x4的FP32矩阵(D = A*B + C)

每个SM(Streaming Multiprocessor)里有8个TensorCore。V100总共80个SM,所以有640个TensorCore。这个数量听起来不多,但每个TensorCore一个时钟周期能完成64个浮点运算(4x4x4=64),所以吞吐量相当可观。

个人经验:我在做BERT训练时发现,用TensorCore比纯FP32快了将近4倍。但有个坑——数据必须对齐到4的倍数。如果你的矩阵维度不是4的倍数,性能会大打折扣。

1.3 Turing架构:引入INT8和INT4

Turing(T4/RTX 20系列)在Volta的基础上做了两件事:

  1. 增加了INT8和INT4支持——推理场景下,低精度完全够用
  2. 改进了稀疏性支持——虽然这章不展开讲

Turing的TensorCore依然做4x4矩阵乘,但多了INT8和INT4模式。INT8模式下,吞吐量是FP16的两倍;INT4模式下,是四倍。

为什么会这样?因为数据位宽减半,同样的硬件电路可以塞进更多运算。说白了,就是拿精度换速度。

避坑指南:我曾经在一个图像分类项目里直接用INT4,结果精度掉了3个点。后来发现是激活值分布太广,INT4根本装不下。所以,用低精度之前,一定要做量化校准。

1.4 Ampere架构:第三代TensorCore

Ampere(A100)是目前的旗舰。它把TensorCore升级到了第三代,主要改进有:

特性 Volta Turing Ampere
矩阵大小 4x4 4x4 4x4 / 8x8 / 16x16
支持精度 FP16 FP16/INT8/INT4 FP64/FP32/FP16/BF16/INT8/INT4
稀疏支持 无 有限 2:4结构化稀疏
每个SM的TensorCore数 8 8 4(但更强)

Ampere最大的变化是支持了BF16(Brain Floating Point)。BF16和FP16都是16位,但BF16的指数位更多,动态范围更大。我个人的经验是:训练大模型时,BF16比FP16稳定得多,很少出现梯度溢出。

另外,Ampere的TensorCore可以处理更大的矩阵块——16x16。这意味着什么?意味着你可以在一次操作中完成更多计算,减少数据搬运的开销。

1.5 矩阵乘法累加运算原理

咱们来拆解一下TensorCore到底怎么算矩阵乘的。

假设我们要算 D = A * B + C,其中A和B是4x4的FP16矩阵,C是4x4的FP32矩阵。

传统做法:

for i in range(4):
    for j in range(4):
        for k in range(4):
            D[i][j] += A[i][k] * B[k][j]

TensorCore的做法:

// 伪代码,实际是硬件指令
D = warp_matrix_multiply_add(A, B, C);

看到了吗?一个指令搞定。硬件内部有专门的乘法器和加法器阵列,并行完成所有运算。

具体来说,TensorCore内部是一个4x4的乘法器阵列,每个乘法器同时做FP16乘法,结果送到加法树里累加。整个过程是流水线化的,一个时钟周期就能出结果。

关键点:TensorCore的运算是在Warp级别完成的。一个Warp(32个线程)协作完成一个矩阵乘。每个线程负责一部分数据搬运和结果写回。

1.6 混合精度计算基础

混合精度,说白了就是:该用高精度的地方用高精度,该用低精度的地方用低精度。

TensorCore的混合精度策略是:

  • 输入:FP16或BF16(低精度,省带宽)
  • 累加:FP32(高精度,防止溢出)
  • 输出:FP32(保持精度)

为什么累加要用FP32?因为矩阵乘里有很多加法,如果累加也用FP16,很容易溢出。我见过一个案例,有人用纯FP16训练Transformer,结果loss直接变成NaN。换成混合精度就好了。

实际使用中,我们通常用PyTorch的AMP(Automatic Mixed Precision)或TensorFlow的混合精度API。它们会自动判断哪些操作用FP16,哪些用FP32。

我的建议:刚开始用混合精度时,一定要打开梯度缩放(Gradient Scaling)。这是AMP的核心机制——把梯度放大,防止下溢,更新权重时再缩小回去。我曾经因为没开梯度缩放,模型训练了三天才发现根本没收敛。

1.7 知识体系总览

下面这张图总结了本章的核心内容:

TensorCore硬件架构知识体系 Volta (V100) Turing (T4/RTX20) Ampere (A100) 特性 • 4x4矩阵乘 • FP16输入/FP32累加 • 每SM 8个TensorCore • 640个总核心数 特性 • 新增INT8/INT4 • 推理优化 • 稀疏性支持 • 每SM 8个TensorCore 特性 • 4x4/8x8/16x16 • BF16/FP64支持 • 2:4结构化稀疏 • 每SM 4个(更强) 核心原理:矩阵乘法累加 D = A × B + C 混合精度:FP16/BF16输入 → FP32累加 → FP32输出 从Volta到Ampere,TensorCore不断进化,但核心思想始终如一:硬件加速矩阵乘法

1.8 本章小结

这一章我们聊了TensorCore的硬件架构。从Volta的初代设计,到Turing的低精度扩展,再到Ampere的全面升级。核心就一句话:TensorCore是专门为矩阵乘法设计的硬件加速器,通过混合精度计算实现极致性能。

下一章,我们会深入CUDA编程层面,看看怎么在代码里真正用上TensorCore。到时候我会带大家手写一个矩阵乘法的示例,感受一下硬件加速的魅力。

记住:理解硬件架构是写出高性能代码的前提。你只有知道TensorCore怎么工作的,才能写出让TensorCore满负荷运转的代码。

想要更多资料,联系可可