想象你经营着一家大型食堂,每天要为一万名顾客配餐。普通厨师(CUDA Core)会一份一份地炒菜:放油、下料、翻炒、出锅,虽然灵活,但效率有限。而食堂采购了一台“配餐流水线”(Tensor Core)——它不擅长单份小炒,却能在同一时间批量完成几十份标准套餐的装配。你的任务,就是学会如何把食材(矩阵)切好、按固定模具(wmma API)摆放、再交给流水线批量生产。这篇文章,就是你的“后厨操作手册”。我们将从硬件原理讲到编程实战,再到性能调优,带你把 GPU 的每一分算力都榨干。
学完本文,你将掌握 Tensor Core 的硬件原理与 wmma 编程范式,能独立编写高性能矩阵乘加算子,为 LLM 推理加速、GEMM 库优化等一线 AI 工程任务打下扎实基础。
可视化演示
本节配有交互动效(进入视口后自动加载,约 3KB)。
硬件架构原理
食堂后厨里,最忙的永远是那位“配餐大师”。普通厨师炒一份菜要起锅烧油、颠勺调味,一套动作十几步;而配餐大师面前有十台标准模具,只要把食材按格子摆好,一压一推,十份套餐同时出炉。Tensor Core 就是 GPU 里的这位配餐大师——它不处理灵活的单条指令,而是在一个周期内完成一次完整的矩阵乘加运算,把 $D = A \times B + C$ 这个深度学习中最常见的公式变成了“肌肉记忆”。
在 Volta 架构出现之前,GPU 只能靠成百上千个 CUDA Core 逐个计算乘法和加法,就像让十位厨师一人炒一道菜再拼盘,速度慢且耗能。Tensor Core 的出现改变了局面:每个 Tensor Core 内部有专门的高速乘法器和加法树,输入两个小矩阵,直接输出乘加结果。以 A100 为例,每个 SM 中有四个 Tensor Core,FP16 峰值算力可达 312 TFLOPS,是同卡 FP32 CUDA Core 算力的数倍。
这种“以空间换时间”的设计,本质上是把硬件单元从“通用”推向“专用”。通用 CUDA Core 负责灵活的控制流和标量运算,Tensor Core 则专注于矩阵乘加这条主干道。两者各司其职,共同支撑起深度学习训练与推理的巨大算力需求。
1. 符号说明:$D$ 是输出矩阵,$A$ 和 $B$ 是两个输入矩阵,$C$ 是累加矩阵(通常初始为 0 或上一次的偏置结果)。
2. 乘法优先:先计算 $A$ 与 $B$ 的矩阵乘法,这要求 $A$ 的列数等于 $B$ 的行数,结果矩阵的尺寸由 $A$ 的行数和 $B$ 的列数决定。
3. 累加融合:将乘法结果 $R$ 与矩阵 $C$ 逐元素相加,这一步在 Tensor Core 内部的加法树中与乘法同步完成,没有额外的访存开销。
食堂里配餐大师的模具尺寸是固定的,Tensor Core 也有固定形状偏好(如 16×16×16)。接下来我们看看如何通过 wmma API 与这位大师沟通。
wmma编程模型
配餐大师不会说普通话,他只听“套餐模板”——一种印好格子的标准订单。你不需要告诉他每一份菜怎么炒,只需要把食材按格子放好,在订单上打勾。CUDA 提供的 wmma API(Warp Matrix Multiply-Accumulate)正是这张标准订单:它把矩阵运算包装成三个固定步骤,让程序员无需触碰底层硬件细节。
wmma 的核心是 fragment 这个“分片托盘”。矩阵太大搬不动,fragment 负责把一块 16×16 的小矩阵从全局内存或共享内存“端”到每个线程的寄存器里。load_matrix_sync 函数同步加载数据到 fragment,mma_sync 执行乘加,store_matrix_sync 把结果写回内存。这三个函数调用,就对应了配餐流程中的“备菜 → 压模 → 出餐”。
之所以叫 sync(同步),是因为一个 warp(32 个线程)需要集体协作完成这些操作。每个线程只持有 fragment 中的一部分元素,用“大家同时伸手拿自己那份”来理解最贴切。所有线程步调一致,缺一不可——这正是 wmma 与普通 CUDA 编程最大的思维差异:你不是在写“我的线程做什么”,而是在写“整个 warp 共同完成什么”。
1. fragment 初始化:声明 fragment 时指定矩阵类型(matrix_a / matrix_b / accumulator)、精度(half / float)和形状(如 16×16×16),相当于告诉食堂“我要三人份标准套餐”。
2. 同步加载:load_matrix_sync 把共享内存或全局内存中的一块数据按固定布局填入 fragment,每个线程拿到属于自己的那几份“食材”。
3. 乘加执行:mma_sync 让整个 warp 的 fragment 进行一次矩阵乘加,硬件内部完成所有乘法和加法,结果累积到累加器 fragment 中。
现在你有了“标准订单”,但整张菜单可能有几千个菜。下一节我们看看如何把大矩阵“切碎”,分批喂给这位配餐大师。
矩阵分块策略
食材太大,模具放不下怎么办?答案很简单:切。一整头牛不能直接塞进模具,但切成 16×16 的小肉块就刚刚好。矩阵分块(Tiling)就是干这个的——传统的矩阵乘法需要 $M \times N \times K$ 次乘加,如果直接把整个矩阵交给 Tensor Core,硬件模具根本装不下。聪明的做法是把大矩阵切成若干个 16×16(或 16×8×8)的小 tile,逐个送入 Tensor Core 计算。
在 CUDA 程序的视角里,分块策略是一场“三层嵌套的配餐循环”:外层循环遍历输出分块的行和列,内层循环遍历 K 维度上的累加步数。每一轮内层循环,我们都从全局内存取一块 A 的 tile 和一块 B 的 tile,放进共享内存这个“备菜台”,再让 warp 们从备菜台取食材送入 Tensor Core。
共享内存在这里扮演了“冰箱”的角色——全局内存太慢,直接把每个 tile 送到 Tensor Core 会饿着它。先把当前循环需要的 A 和 B 分块搬进共享内存,warp 再从共享内存快速取用,访存速度能提升一个数量级。而 tile 尺寸的选择也很有讲究:16×16 能完美贴合 Tensor Core 的模具,但更大的 tile(如 32×32)能减少循环次数、提高数据复用率,代价是共享内存占用更大,可能降低 SM 上同时驻留的线程块数量。
1. 外层行块循环:遍历输出矩阵的行方向,每次取 $M_{\text{tile}}$ 行,对应 $\text{C}_{\text{tile}}$ 的第一维。
2. 外层列块循环:遍历输出矩阵的列方向,与行块组合确定一个输出分块。
3. 内层 K 循环:沿 K 维逐步累加,每次取 A 的 $16 \times 16$ 块和 B 的 $16 \times 16$ 块做乘加。
分块是空间上的切配艺术,而混合精度则是“食材用量”上的巧妙计算。接下来我们看看如何用“半份食材”做出同样美味的菜。
混合精度实战
食堂要控制成本,食材贵怎么办?聪明的做法是:排骨切成薄片(FP16)来配菜,但记账时仍然用精确到分的计算器(FP32)。混合精度训练的哲学与此如出一辙——用 FP16 存储和搬运矩阵数据,节省一半内存带宽,但在 Tensor Core 内部用 FP32 做累加,保证计算精度不“缩水”。
为什么要这样做?FP16 只用 16 位存储,数值范围小、精度低,但它的存储体积是 FP32 的一半,搬运速度翻倍。Tensor Core 的硬件设计恰好迎合了这种“不对称”:输入两个 FP16 矩阵,内部用高精度乘法器和 FP32 累加器,最终输出 FP32 结果。就像配餐时食材是半份,但每份菜的分量都由电子秤精确称量。
实际使用中还有一个经典坑:FP16 的动态范围只有约 5.96e-8 到 65504,梯度稍微小一点就会“下溢”变成零,导致训练不收敛。损失缩放(Loss Scaling)技术应运而生——训练时把损失值放大若干倍(如 1024),等梯度计算完毕再缩小回来,相当于把整道菜先放大再摆盘,确保微小食材也能被看见。
1. 存储格式:$A$ 和 $B$ 以 FP16 格式存放在内存中,内存占用减半、带宽需求减半。
2. 内部提升:进入 Tensor Core 后,FP16 值被转换为 FP32 参与乘法,避免精度损失。
3. 高精度累加:乘法结果与 FP32 累加矩阵 $C$ 相加,全程保持单精度累积,只在最终写回时选择是否转换为低精度。
食材备好了,模板也有了,但如何让流水线持续高速运转不空转?这就进入了性能优化的深水区。
性能优化途径
食堂开业后你发现:配餐大师经常“等菜”。食材没送到,模具空转;模具压完了,下一个分块还没切好。性能优化的本质,就是消除这些“等待”——让食材供应链、切配台和压模机三者之间永远没有空闲。
第一大优化是内存对齐。Tensor Core 要求矩阵的行主序步长(ldm)是 16 字节的倍数,相当于托盘上的每道菜必须按固定间距摆放,否则取餐机器人会拿错。如果你用行主序存储一个 17 列的矩阵,每行末尾要补上 padding 字节,确保每行首地址对齐。
第二大优化是规避共享内存的 bank 冲突。共享内存被划分成 32 个 bank,同一时钟周期内多个线程访问同一个 bank 就会排队。当多个线程同时读取同一行相邻地址时,如果地址恰好映射到同一个 bank,性能骤降。解决办法是在共享内存数组的每行末尾加一个元素的 padding,让访问“错开”。
第三大优化是双缓冲流水线。原理和食堂的“双灶台”一样:一个灶台在做菜,另一个灶台已经在预热。用两个共享内存缓冲区交替加载和计算,cp.async 异步拷贝让数据搬运与矩阵乘加重叠执行,把访存延迟完全隐藏在计算背后。这样流水线的吞吐公式就变成了两个阶段中较慢者的速度,而不是两者之和。
1. 加载阶段:共享内存缓冲区 $B_0$ 正在从全局内存装载下一块数据。
2. 计算阶段:共享内存缓冲区 $B_1$ 中的数据正被 Tensor Core 消耗计算。
3. 重叠效果:双缓冲让两个阶段并行,总时间由慢者决定。
优化之后,如何确认食堂真的变快了?这就轮到质检员登场了。
调试性能分析
食堂老板想知道“出餐速度到底卡在哪个环节”,光靠感觉不行,得用数据说话。GPU 性能分析工具 Nsight Compute(ncu)就是这位质检员:它会详细记录你的 kernel 在每个硬件单元上的耗时、占用率和吞吐量,告诉你 Tensor Core 的利用率是 90% 还是只有 30%。
使用 ncu 的基本流程是“三问”:第一问,计算吞吐够不够?看 tensor 指令的占用率,如果 Tensor Core 只有 20% 活跃,说明数据供给跟不上,要优化访存或分块策略。第二问,访存效率高不高?看 Memory Throughput 和 L2 Cache Hit Rate,如果全局内存访问频繁且命中率低,说明共享内存复用不够。第三问,SM 占用率合理吗?看 Achieved Occupancy,如果线程块太大或寄存器用太多,SM 上驻留的 warp 数量会减少,延迟隐藏能力变弱。
瓶颈定位有一个经典的“剥洋葱”思路:先用 ncu 的全量报告看大方向(计算密集还是访存密集?),再逐项深入——如果是访存瓶颈,检查是否有未合并访问、bank 冲突和低缓存命中;如果是计算瓶颈,检查 Tensor Core 是否有空转周期。每一步都用数据佐证,而不是凭直觉改代码。
1. 实际活跃周期:ncu 统计出的 Tensor Core 真正执行乘加指令的时钟数。
2. 理论最大周期:kernel 运行总时长内 Tensor Core 能执行指令的最大时钟数。
3. 利用率计算:两者相除得百分数,低于 50% 说明流水线存在明显“饿肚子”。
质检合格后,终于到了出正式菜单的时候。最后我们把所有技巧打包,看看真实工程中如何应用。
工程应用实践
从单道菜的烹饪技巧到一家餐厅的完整菜单,中间还差一步:标准化。CUTLASS 是 NVIDIA 开源的 GEMM 算子库,它把分块、流水线、混合精度这些技巧固化成模板代码,你只需要声明“我要 FP16 输入、FP32 累加、16×16 tile”,就能自动生成一个高性能矩阵乘算子。就像食堂把配餐流程写成标准作业手册,新员工照着做就能出菜。
在 Transformer 架构中,Tensor Core 的身影无处不在:QKV 投影矩阵乘、注意力分数计算、FFN 两层线性变换,每一步都是 GEMM。以 GPT-3 为例,一次前向推理要执行上千次矩阵乘法,这些运算约占整体计算量的 90% 以上。用 Tensor Core 加速这些 GEMM,推理速度能提升数倍,这也是为什么大模型推理框架(如 TensorRT-LLM、vLLM)深度依赖 Tensor Core。
工程中还有两个实战心得:第一,算子融合——把“矩阵乘 + 偏置 + 激活函数”打包成一个 kernel,减少中间结果的显存读写,相当于在食堂里把“配餐+热菜+装盘”合并成一个工位;第二,版本兼容——不同 GPU 架构(Volta/Turing/Ampere/Hopper)的 Tensor Core 指令集和 wmma API 有差异,编写算子时要用 __CUDA_ARCH__ 宏做分支,确保老卡也能运行。
1. 输出矩阵:$C$ 的每个元素是 $A$ 的第 $i$ 行与 $B$ 的第 $j$ 列的内积。
2. 计算规模:总乘加次数为 $M \times N \times K$,当 $M=N=K=4096$ 时超 680 亿次运算。
3. 并行分解:所有 $C_{ij}$ 互不依赖,天然可并行——这正是分块交给不同 SM 执行的硬件基础。
从硬件原理到工程实践,Tensor Core 编程的完整链路已经打通。就像一家食堂从采购、切配、压模、出餐到质检的全流程管理,每一步都有章可循。
AI 应用场景
LLM推理引擎中的GEMM加速
阶段:模型部署与推理优化
解决的问题:大模型推理时,QKV 投影和 FFN 层的大量矩阵乘法在普通 CUDA Core 上耗时巨大,导致 token 生成延迟高、吞吐量低,传统优化手写 kernel 难以兼顾效率与通用性。
具体案例:vLLM 和 TensorRT-LLM 在服务 Llama-3-70B 时,利用 Tensor Core 的 FP16/BF16 wmma 算子加速 GEMM。通过将 batch 内多个请求的 KV 计算合并为一个大矩阵乘,配合 Tensor Core 的分块执行,推理吞吐量提升约 3.5 倍,单 token 延迟从 45ms 降至 13ms。
推荐系统Embedding层的矩阵化改造
阶段:特征工程与训练加速
解决的问题:大规模推荐模型的 Embedding 查表后需要与权重矩阵相乘,在 CPU 或普通 GPU 算子下吞吐不足,成为训练与上线服务的性能瓶颈。
具体案例:某广告推荐系统的 M×K 交互矩阵(M=用户数,K=特征维度)通过自定义 CUDA kernel 调用 wmma API,将向量与矩阵乘法组织为 16×16 tile 的批量乘加,配合混合精度(FP16 存储、FP32 累加),整体训练吞吐提升 2.8 倍,GPU 显存占用降低 40%。
科学计算中的GEMM算子库开发
阶段:算子研发与基础库建设
解决的问题:金融风险模拟和流体力学仿真中的稠密线性代数运算在 AI 芯片上的性能表现依赖高效的 GEMM 算子,而通用库(如 cuBLAS)无法覆盖所有定制化的矩阵尺寸和精度需求。
具体案例:某量化团队基于 CUTLASS 和 wmma API 自研了一批支持混合精度(FP16/BF16 输入、FP32 累加)的 GEMM 算子,针对 128×128 到 4096×4096 的矩阵尺寸做模板特化,实测比 cuBLAS 同配置快 12%–18%。
Python 演示
import numpy as np def wmma_simulate(A, B, C, tile=16): """用分块三重循环模拟 Tensor Core 的 wmma 乘加流程.""" M, K = A.shape K2, N = B.shape assert K == K2, "A 的列数必须等于 B 的行数" for i in range(0, M, tile): for j in range(0, N, tile): acc = C[i:i+tile, j:j+tile].astype(np.float32) for k in range(0, K, tile): a_tile = A[i:i+tile, k:k+tile].astype(np.float16) b_tile = B[k:k+tile, j:j+tile].astype(np.float16) acc += a_tile.astype(np.float32) @ b_tile.astype(np.float32) C[i:i+tile, j:j+tile] = acc return C def main(): M, N, K = 64, 64, 64 rng = np.random.default_rng(42) A = rng.standard_normal((M, K)).astype(np.float32) B = rng.standard_normal((K, N)).astype(np.float32) C = np.zeros((M, N), dtype=np.float32) C_out = wmma_simulate(A, B, C, tile=16) C_ref = A.astype(np.float32) @ B.astype(np.float32) err = np.max(np.abs(C_out.astype(np.float32) - C_ref)) print("最大绝对误差:", err) print("分块结果与参考一致:", err < 0.5) if __name__ == "__main__": main()
for i in range(0, M, tile):外层循环按 tile 步长遍历输出矩阵行方向,对应 CUDA 中线程块在网格中的行划分。acc = C[i:i+tile, j:j+tile].astype(np.float32)取出输出分块并转为 FP32,模拟 Tensor Core 中累加器 fragment 的精度。a_tile = A[i:i+tile, k:k+tile].astype(np.float16)将 A 的分块转为 FP16,模拟 wmma 中以半精度加载输入矩阵。acc += a_tile.astype(np.float32) @ b_tile.astype(np.float32)核心乘加语句:FP16 转 FP32 后相乘累加,模拟 mma_sync 的行为。C[i:i+tile, j:j+tile] = acc将累加结果写回输出矩阵,对应 store_matrix_sync 函数。
常见误区
误区我之前一直以为 Tensor Core 是更新一代的 CUDA Core,程序里随便写个矩阵乘法它就会自动用上,速度肯定快很多。
正解两者是分工不同的硬件单元:CUDA Core 是通用标量计算核心,擅长控制流和逐元素操作;Tensor Core 是专用矩阵乘加单元,只做 $D=A\times B+C$ 这类稠密矩阵运算。想让 Tensor Core 工作,必须显式调用 wmma API 或依赖 cuBLAS 等库,普通 CUDA 代码默认走的是 CUDA Core。
为何常见:GPU 架构不断迭代,Tensor Core 是较新的特性,容易让人误以为它是 CUDA Core 的替代品,实际上它们是并存的异构单元。
误区我以为只要把矩阵乘法改成 load_matrix_sync 加 mma_sync,性能就能翻倍,结果跑出来反而比普通 CUDA 核函数还慢。
正解wmma 只是提供了使用 Tensor Core 的接口,性能收益取决于分块策略、共享内存复用、访存对齐和流水线隐藏等综合优化。如果数据布局不对齐、分块太小、没有双缓冲,Tensor Core 会大量空转,甚至因为额外的数据搬移开销导致性能回退。
为何常见:看到官方文档的峰值算力数字很震撼,容易忽略“峰值需要特定数据流模式才能达到”这一前提。
误区我一直担心用 FP16 训练模型会把梯度算歪,所以宁可用 FP32,速度慢也认了。
正解Tensor Core 的混合精度方案是“FP16 存储 + FP32 累加”,乘法和累加都在 FP32 下完成,精度损失远小于“全程 FP16”。配合损失缩放(Loss Scaling)技术,可以把梯度下溢问题也解决掉。实际上,大部分现代大模型(GPT、Llama、BERT)都使用混合精度训练,效果与 FP32 基本一致。
为何常见:人们看到“半精度”就联想到“半吊子”,忽略了硬件内部其实做了高精度累加的事实。
误区我写好的 wmma kernel 在 NVIDIA 的卡上都能跑,同学用老显卡跑我的代码应该也没问题。
正解Tensor Core 从 Volta 架构(V100,2017 年)才开始引入,Turing、Ampere、Hopper 等后续架构才有。更早的 Pascal 及之前的 GPU 完全不支持 wmma API。此外,不同架构的 Tensor Core 在形状和精度上也有差异(如 Ampere 支持 TF32、Hopper 支持 FP8),代码中需要用 __CUDA_ARCH__ 做版本判断。
为何常见:多数开发者的本地环境已经是较新的 RTX 系列,容易把“我的卡有”当成“所有卡都有”。
面试题
Q1. Tensor Core 最核心的硬件加速计算是什么?
- A.融合乘加:D=A×B+C← 正确答案
- B.逐点加法:D=A+B
- C.纯矩阵乘:D=A×B
- D.逐点减法:D=A-B
答案:A。Tensor Core 的核心是融合乘加(FMA),在一个时钟周期内完成矩阵乘法和累加。选 B 只做了加法、选 C 只有乘法,都没体现“融合”优势;选 D 与硬件功能完全无关。正如配餐流水线同时完成“配菜+装盘”,融合才能省时间。
Q2. wmma API 中用于描述矩阵分片数据存储的类是什么?
- A.fragment 分片管理类← 正确答案
- B.matrix 矩阵容器类
- C.tensor 张量对象类
- D.thread_block 线程块类
答案:A。wmma 用 fragment 类管理矩阵分片,它负责把一块 tile 的数据分布到 warp 各线程的寄存器中。matrix 和 tensor 是其他库(如 Eigen、ATen)中的概念;thread_block 是线程协作 API,与数据分片无关。fragment 像是配餐时每人托盘里分到的那几份菜。
Q3. Tensor Core 使用 FP16 输入时,累加器默认采用什么精度?
- A.FP32 单精度累加器← 正确答案
- B.FP16 半精度累加器
- C.INT8 整型累加器
- D.BF16 宽半精度累加器
答案:A。Tensor Core 的设计是“FP16 输入、FP32 累加”,保证大矩阵乘加的高精度累积。如果累加也用 FP16,误差会随 K 维度累积而快速放大。INT8 累加用于量化推理场景,BF16 则是另一类低精度格式,但 wmma 默认针对 FP16×FP16+FP32。
Q4. GPU 中矩阵分块(Tiling)的主要目的是什么?
- A.适配固定计算形状← 正确答案
- B.减少程序代码行数
- C.让循环嵌套层次更多
- D.让线程数自动变少
答案:A。分块的核心目的是把大矩阵切成 Tensor Core 硬件模具能处理的固定形状(如 16×16×16),同时提高数据在共享内存中的复用率,减少全局内存访问。减少代码行数和增加循环嵌套是附属结果而非目的;线程数由线程块配置决定,不受分块影响。
Q5. 以下哪些是 wmma API 提供的核心函数?
- A.load_matrix_sync 加载← 正确答案
- B.mma_sync 乘加同步← 正确答案
- C.store_matrix_sync 写回← 正确答案
- D.printf_matrix 打印矩阵
答案:ABC。wmma 三件套包括 load_matrix_sync(加载数据到 fragment)、mma_sync(执行矩阵乘加)、store_matrix_sync(写回结果)。这三个函数对应配餐的“备菜、压模、出餐”流程。printf_matrix 是虚构的,wmma 中不存在此函数。
Q6. wmma 中 “fragment 形状为 16×16×16” 描述的是什么?
- A.每线程片段尺寸形状← 正确答案
- B.全局内存总容量
- C.共享内存总大小
- D.线程束中线程数
答案:A。16×16×16 表示一次 mma_sync 中 A 分片为 16×16、B 分片为 16×16、累加器为 16×16,K 维步长为 16。它描述的是 fragment 的矩阵形状,与全局内存容量和共享内存大小无关;线程束固定 32 线程,不由 fragment 决定。
Q7. 规避共享内存 bank 冲突最常用的办法是什么?
- A.补零填充避免冲突← 正确答案
- B.增大线程束规模
- C.改用全局内存存储
- D.降低 GPU 核心频率
答案:A。在共享内存数组的每行末尾加一个元素的 padding(补零),可以让相邻线程访问的地址错开映射到不同 bank,从而消除冲突。增大线程束规模无法改变 bank 映射关系;改用全局内存只会更慢;降低频率是开倒车。
Q8. 下列哪些属于 Tensor Core 算子的有效性能优化手段?
- A.双缓冲重叠隐藏延迟← 正确答案
- B.共享内存按行长对齐← 正确答案
- C.增加不必要的循环层数
- D.降低累加器计算精度
答案:AB。双缓冲让数据加载与计算重叠,隐藏访存延迟;按行长对齐(16B 对齐)保证 wmma 访存指令不越界、不拆分。增加循环层数只会增加开销;降低累加器精度会引入误差,且 Tensor Core 不提供“低精度累加”选项。
Q9. 相比 CUDA Core,Tensor Core 最显著的优势是什么?
- A.矩阵乘加吞吐更高← 正确答案
- B.标量加法速度更快
- C.分支预测能力更强
- D.寄存器文件容量更大
答案:A。Tensor Core 的硬件设计目标就是让矩阵乘加吞吐量达到 CUDA Core 的数倍乃至一个数量级,代价是失去通用性。标量加法和分支预测是 CUDA Core 的强项;寄存器文件容量由架构统一设计,与 Tensor Core 无关。
Q10. 混合精度训练中,下列哪些做法是正确的?
- A.损失缩放保尾数精度← 正确答案
- B.主权重保持FP32格式← 正确答案
- C.全流程都只使用FP16
- D.梯度累积用FP16变量
答案:AB。损失缩放(Loss Scaling)把小的梯度值放大到 FP16 可表示范围,避免下溢;主权重保持 FP32 是为了在参数更新时保留高精度累积。“全流程 FP16”和“梯度累积用 FP16”都会导致精度崩溃,是混合精度训练中最常见的错误做法。