大模型常见张量类型入门:FP32、FP16、BF16、TF32 与 FP8

用一篇文章梳理大模型里最常见的张量类型:FP32、FP16、BF16、TF32 和 FP8,各自的位宽结构、优缺点,以及它们为什么会影响训练与部署体验。

只要你开始接触大模型训练、推理或者部署,很快就会遇到一组高频缩写:FP32FP16BF16TF32FP8。它们看起来像是参数页上的几个附加标签,但实际影响远不止“写法不同”。

这些类型决定了数字在显存里怎么存、在计算中怎么表示,也直接影响模型训练是否稳定、推理速度如何,以及一张显卡到底能装下多大的模型。

所以如果你想真正理解大模型里的精度取舍,最值得先补的一课,不是某个具体模型的跑分,而是先把这些常见张量类型各自是什么、为什么会这样设计搞清楚。

张量类型到底在决定什么

大模型本质上是海量参数参与的矩阵运算,而张量类型就是这些数字在显存里如何存、在计算中如何表示。

它的核心取舍通常围绕三个维度展开:

  • 精度
  • 显存占用
  • 计算速度

这和图片格式其实很像。无损格式保留细节更多,但体积大、加载慢;压缩格式会丢掉一部分肉眼不敏感的信息,换来更小的体积和更快的处理速度。大模型之所以能接受这种取舍,是因为在极大量参数里,很多微小数值变化并不会明显影响最终输出。

也正因为如此,模型世界里才会出现一整套不同精度的张量格式。

一个数字是怎么被表示的

理解这些格式之前,可以先记住一个非常基础的结构。一个浮点数通常由三部分组成:

  • 符号位:决定正负
  • 指数位:决定数值范围
  • 尾数位:决定数值精细程度

在大模型里,尾数精度当然重要,但很多时候模型更怕的是数值范围不够,也就是指数位太小,导致溢出或者训练不稳定。很多张量格式的设计,本质上就是在“范围”和“细节”之间重新分配有限的 bit 数。

下面这张图可以先帮你建立一个整体印象:

FP32、FP16、BF16、TF32 与 FP8 的位宽结构总览

FP32:最稳,但太贵

FP32 是最传统的单精度浮点格式,总共 32 bit,也就是 4 个字节。

FP32 位宽结构示意图

它的优点很直接:

  • 数值范围大
  • 精度高
  • 训练最稳

但问题也同样明显:太占显存。

一个非常粗略的估算方式是:

1
显存占用 ≈ 参数量 × 每个参数的字节数

如果一个 27B 模型完全用 FP32 存权重,那么光权重本身就大约需要:

1
27B × 4 bytes ≈ 108GB

这还没算激活值、KV Cache、优化器状态和其他运行开销。也就是说,FP32 在今天的大模型推理和训练里,已经不是“默认选择”,而更像是“最稳的基线格式”。

FP16:体积减半,但稳定性一般

FP16 把每个参数压缩到 2 个字节,显存占用相比 FP32 直接减半。

FP16 位宽结构示意图

对于同一个 27B 模型,如果只看权重体积:

1
27B × 2 bytes ≈ 54GB

这就已经能解释为什么很多部署说明里,27B 模型的显存需求会落在 50GB 左右。

FP16 的优势很明显:

  • 显存压力大幅下降
  • 吞吐更高
  • 早期混合精度训练大量使用

但它的问题在于指数位偏小,动态范围不够大。对于大模型训练来说,这会让溢出更容易发生,需要额外依赖 loss scaling 一类技巧来补救,工程上比较麻烦。

所以现在 FP16 仍然常见,但在很多场景里,它已经不再是最舒服的选择。

BF16:大模型时代更实用的半精度

BF16 同样只占 2 个字节,但和 FP16 的设计重点不一样。

BF16 位宽结构示意图

它保留了更大的指数范围,让它在动态范围上更接近 FP32,只是牺牲了一部分尾数精度。这种取舍对大模型尤其友好,因为很多时候模型对“范围”更敏感,对尾数少几位反而没那么敏感。

这也是为什么现在很多训练框架、很多大模型论文和大量实际部署方案,都更偏向 BF16

你可以把它理解成:

  • 显存成本接近 FP16
  • 稳定性体验更接近 FP32

如果一套 27B 部署方案写的是 50GB 左右显存,而另一套经过进一步优化后接近 30GB,前者往往还停留在 FP16/BF16 这一层,后者则通常已经继续向更低精度或量化方向走了。

TF32:不是省显存,而是加速 FP32 工作流

TF32 很容易被误会成“又一种更省的格式”,但它的定位其实不太一样。

从常见理解上看,它可以近似看成一种保留了较大指数范围、但缩短了尾数精度的计算格式。

TF32 计算格式示意图

不过要注意,TF32 更像是一条 Tensor Core 计算路径里的内部计算格式,而不是像 FP16/BF16 那样主要拿来做权重存储。

它主要是 NVIDIA 在较新的 GPU 上提供的一种计算模式,目标不是减少显存占用,而是让原本基于 FP32 的训练流程,在尽量不大改代码的前提下跑得更快。

它的特点可以概括成一句话:

  • 对外看起来还是 FP32 工作流
  • 底层在矩阵乘法时做了更快的近似计算

所以 TF32 主要解决的是“FP32 太慢”的问题,而不是“FP32 太占显存”的问题。如果你关心的是为什么同一个模型部署时显存需求不一样,TF32 不是最主要的答案。

FP8:进一步压缩,但更考验工程能力

再往下走就是 FP8。它把单个数值继续压缩到更少 bit 数,进一步降低显存带宽和存储成本。

它常见的不是单一一种格式,而是两类变体:E4M3E5M2

FP8 两种常见变体示意图

FP8 的代价也很明显:位数太少以后,你很难同时兼顾范围和精度,因此实际工程里通常会针对不同阶段采用不同变体,分别照顾前向、反向和梯度的稳定性。

这类格式代表的是一种更激进的思路:

  • 愿意牺牲更多精度
  • 换取更低的存储和更高的吞吐
  • 需要更成熟的硬件和训练框架配合

它很有前景,但对普通使用者来说,日常最常碰到的核心分界点,通常还是 FP32FP16BF16

为什么理解这些类型很重要

很多人第一次看到这些缩写,会把它们理解成“模型下载页上的一些实现细节”。但实际上,它们会直接改变你对模型训练和部署的理解方式。

比如同样一张显卡:

  • 为什么有些模型训练必须强调数值稳定性
  • 为什么有些推理方案会优先谈量化和低精度
  • 为什么看起来参数量相近的模型,部署门槛却差很多
  • 为什么有些格式适合存权重,有些格式更适合做计算路径

这些问题往下拆,最后几乎都会回到同一个核心:你到底怎么在“精度、范围、显存和速度”之间做取舍。

也正因为这样,理解 FP32FP16BF16TF32FP8,不只是为了看懂术语表,而是为了在面对训练配置、推理引擎和部署门槛时,知道这些数字背后到底在交换什么。

一个实用的理解框架

如果你不想一上来就记一堆格式细节,可以先用下面这个顺序理解:

  • FP32:最稳、最贵
  • FP16:更省显存,但范围偏小
  • BF16:显存接近 FP16,稳定性更适合大模型
  • TF32:主要解决 FP32 太慢,不主要解决显存
  • FP8:更激进的压缩和加速路线

常见张量类型总结图

当你以后再看到模型下载页里写着 fp16bf16fp8,或者看到不同部署教程给出完全不一样的显存门槛时,就不会再觉得那只是“写法不同”。它们背后其实对应的是完全不同的精度预算和工程取舍。

结语

大模型里的张量类型,表面上是在讨论 bit 数,实际上讨论的是一整套工程取舍。

FP32FP16BF16TF32FP8 没有绝对的好坏,它们只是分别站在不同的位置上,帮你在稳定性、范围、精度、显存和速度之间做平衡。

如果把这一层看懂,后面无论你是在读训练论文、调推理参数,还是比较不同部署方案,都会更容易抓住重点。

记录并分享
使用 Hugo 构建
主题 StackJimmy 设计