在讨论AI芯片性能时,人们经常会看到FP32、FP16、BF16、FP8这些看起来有些像工程师暗号的名词。很多人第一反应是:数字越小,精度是不是越差,速度是不是就越快?
答案没有这么简单。
这些格式真正改变的,是一个数字在计算机里如何表示,以及GPU需要用多少存储空间、多少内存带宽和多少计算资源来处理这些数字。精度降低以后,AI系统得到的并不只是“更快”两个字,而是一整套计算、存储、通信和数值稳定性之间的重新平衡。
理解这一点,才能看懂为什么今天的大模型训练越来越多地从FP32转向BF16和FP16,又为什么FP8开始进入训练和推理系统。
FP32是传统意义上的32位单精度浮点数。它由1位符号位、8位指数位和23位小数位组成,总共32位。它拥有很大的动态范围,同时能够保留相对较多的有效数字,因此长期以来一直是科学计算和深度学习训练的重要基础格式。
这里需要区分两个概念:动态范围和精度。
动态范围解决的是“一个数字能够有多大或者多小”的问题,而精度解决的是“两个非常接近的数字能不能被区分”的问题。FP32的指数位比较多,因此能够表示从非常小到非常大的数;23位尾数则提供了较高的相对精度。
FP16只有16位,由1位符号位、5位指数位和10位尾数位组成。它占用的存储空间只有FP32的一半,因此同样容量的显存理论上可以装下两倍的FP16数据。
但FP16最大的特点并不是简单的“精度减半”,而是指数位也减少了。标准FP16能够表示的最大有限数大约是65504,远远不像FP32那样拥有巨大的动态范围。对于深度学习中的某些中间计算和梯度,这可能造成溢出或者下溢。
这也是为什么现代AI训练很少简单地把所有计算全部改成FP16然后就结束。混合精度训练通常会让适合低精度的计算使用FP16,同时在关键环节保留更高精度的数据或者计算,并通过损失缩放等方法减少数值问题。
BF16则采取了另一种思路。
BF16同样是16位,但它保留了与FP32相同数量的8位指数位,只留下7位尾数。换句话说,BF16牺牲了更多有效数字的精度,却保留了接近FP32的动态范围。
这对于神经网络训练非常有价值。
深度学习模型中的某些激活值、梯度或者中间结果可能跨度很大。BF16虽然没有FP32那么高的精度,但它不容易因为数值太大而溢出,也不容易因为数值太小而直接变成零。因此在很多大模型训练场景中,BF16成为非常实用的选择。
可以把FP16和BF16理解成两个不同的取舍。
FP16把更多位数用于尾数,因此在可表示范围之内拥有更高的精度,但动态范围比较有限。BF16则把位数更多地留给指数,因此动态范围接近FP32,但每次表示数字时能够区分的细节更少。
到了FP8,压缩程度进一步提高。
FP8并不是只有一种格式,目前工程实践中常见的两种形式是E4M3和E5M2。它们分别在指数和尾数之间进行不同分配,因此适合的计算环节也不完全一样。
这说明“FP8”并不是一个单独、固定的精度等级。即使都是8位浮点数,不同格式的动态范围和精度也可能不同。
为什么AI行业愿意把数字压缩到8位?
原因很现实:数据太多了。
一个大型模型包含数十亿甚至数千亿个参数。训练过程中除了模型权重,还有激活值、梯度以及优化器状态等大量数据。这些数据不仅需要存放在显存中,还需要不断在显存、计算单元以及多块GPU之间移动。
FP32每个数需要4字节,FP16和BF16只需要2字节,而FP8只需要1字节。
因此,在其他条件相同的情况下,数据格式越小,同样数量的数据占用的存储空间越少,内存传输的数据量也越少。对于受到显存容量和内存带宽限制的工作负载,这一点非常重要。
但这里有一个经常被宣传材料简化的问题:FP8并不意味着GPU的实际速度一定是FP16的两倍,更不意味着FP16一定是FP32的两倍。
真正的计算速度取决于GPU架构。
现代GPU内部拥有专门用于矩阵计算的Tensor Core等计算单元。不同一代GPU对FP32、FP16、BF16、FP8等格式拥有不同的硬件吞吐能力。因此,“位数减少一半”只能说明数据存储需求下降,并不能直接推出“性能提高一倍”。
有些工作负载受到计算能力限制,低精度确实可以带来非常明显的加速;有些工作负载则受到显存带宽、数据读取、通信或者其他环节限制,换成更低精度以后收益可能没有想象中那么大。
这就是AI系统中经常出现的一个现象:GPU理论算力很高,但实际运行速度却远远达不到规格表上的数字。
原因可能根本不在计算单元。
如果一个模型需要频繁从显存读取大量数据,那么计算单元可能在等待数据。如果多块GPU需要频繁交换参数和梯度,那么瓶颈可能转移到了GPU之间的互联网络。如果CPU负责的数据准备速度跟不上,GPU也可能处于等待状态。
因此,低精度不仅仅是一个“算力优化”问题,它同时也是一个内存和通信优化问题。
这一点在大规模分布式训练中尤其明显。
假设多个GPU需要进行梯度同步,通信数据如果从FP32变成FP16或者BF16,数据量理论上可以减少一半。如果进一步采用FP8,则数据量还可以继续下降。对于网络通信成为瓶颈的系统,这可能带来实际收益。
但通信效率仍然取决于GPU之间使用什么互联技术、网络拓扑、通信库以及具体的并行方式。NVLink、高速网络和PCIe并不是简单的“快”和“慢”三个字可以概括。低精度减少了需要传输的数据量,但并不能消除网络延迟,也不能让通信硬件无限提速。
那么,精度降低以后,AI模型会不会变笨?
有可能,但也没有想象中那么直接。
神经网络本身具有一定的误差容忍能力。模型中的大量计算并不需要每一个数字都保持FP32级别的精确度。只要误差分布处于可接受范围,模型最终的预测结果可能几乎没有明显变化。
问题在于,不同计算环节对精度的敏感程度并不一样。
权重、激活值、梯度、累加结果以及优化器状态可能拥有完全不同的数值特征。某些层对低精度非常宽容,另一些层却可能非常敏感。因此现代AI系统越来越倾向于采用混合精度,而不是把整个模型粗暴地统一成一种格式。
FP8就是这个趋势的一部分。
过去人们更多把FP8理解成推理优化工具,因为推理过程通常不需要像训练那样不断计算反向传播和更新权重。但随着GPU硬件和训练算法的发展,FP8也已经进入越来越多的训练流程。
与此同时,也不能简单地说“使用FP8就必须进行量化感知训练”。
FP8属于低精度浮点表示,而量化并不只有一种实现方式。实际系统可以通过不同的缩放策略、动态或静态scale、张量级或者更细粒度的缩放,以及不同计算环节的精度组合来控制误差。是否需要QAT,要看模型、硬件、量化方案和精度目标,而不是FP8这个格式本身决定一切。
这也是FP8工程实现比较复杂的地方。
当数字范围太大时,如果直接塞进FP8,可能出现溢出;如果范围太小,又可能损失大量有效信息。因此系统通常需要配合缩放和数值管理,让不同张量的数据落在适合FP8表示的范围之内。
换句话说,低精度计算并不是简单地把32位数字“砍掉一半或者四分之三”。
真正发生的是整个计算系统重新安排数字表示方式。
FP32强调精度和数值范围,FP16在存储效率和有效精度之间寻找平衡,BF16用较低的尾数精度换取接近FP32的动态范围,而FP8进一步压缩数据表示,把更多性能空间交给专门的硬件和数值管理算法。
对于训练大型语言模型,BF16之所以受到重视,很大程度上就是因为它在数值范围和存储效率之间取得了非常实用的平衡。FP16仍然具有很高的工程价值,而FP8则代表了进一步降低数据表示成本的方向。
但低精度并不是免费的午餐。
数据越小,能够表达的数值细节通常越少;计算越激进,对缩放、舍入和累加策略的要求越高。硬件也必须提供相应的低精度计算能力,否则仅仅把数据转换成FP8,并不能自动获得高性能。
因此,判断一种AI计算格式是否更好,不能只看它是32位、16位还是8位。
真正需要看的,是整个系统的瓶颈在哪里。
如果问题是显存容量,降低精度可以让更多模型进入GPU;如果问题是显存带宽,更小的数据格式可以减少数据搬运;如果问题是Tensor Core计算吞吐,硬件支持的低精度格式可能带来巨大的加速;如果问题是多GPU通信,降低通信数据量可能改善扩展效率;但如果瓶颈来自CPU、数据加载、网络延迟或者算法本身,单纯降低精度就未必能解决问题。
所以,FP32、FP16、BF16和FP8并不是一条简单的“从高到低、从慢到快”的排行榜。
它们更像是AI工程师手里的四把不同尺寸的扳手。工具越轻,并不意味着什么螺丝都能拧得更好。大型AI系统真正追求的,也不是尽可能低的精度,而是在模型效果可以接受的前提下,把计算、显存、带宽和通信资源压缩到一个更高效的组合。
这也是今天AI硬件竞争越来越激烈的一个原因。芯片厂商真正比拼的已经不只是“有多少TFLOPS”,而是能不能让低精度计算、显存系统、高速互联和软件栈共同工作。对于一台AI服务器来说,最昂贵的往往不是某一个数字,而是让整个系统因为等待数据、等待通信或者等待计算而闲在那里。降低精度的意义,最终就是尽可能减少这种等待,同时又不让模型因为数字表示能力下降而失去应有的能力。
FP32、FP16、BF16 和 FP8 在 AI 计算中的区别,降低精度究竟改变了什么
喜欢这篇报道?
使用下面的功能,方便以后继续阅读和分享 MNewsTV
关于文章收藏
收藏不需要注册帐号,收藏信息仅保存在当前浏览器中。
删除收藏请进入「我的收藏」进行管理。
分享 Facebook | X | WhatsApp | LinkedIn
捐助(Paypal): https://www.paypal.me/observeccp 订阅中国观察电报 Telegram : https://t.me/s/ObserveCCP