我们来看一个在AI圈子里越来越常见的数据格式——BF16。它又名BFloat16,全称是Brain Float 16,由Google Brain团队开发,最早用在第三代TPU上。如今,Google、英特尔、Arm等多家公司的AI翻跟斗几乎都在用这个格式。

BF16的核心思路其实挺简单:通过降低数字的精度,来减少张量乘法运算所需的计算资源和功耗。张量说白了就是三维矩阵,而张量乘法正是AI计算中最核心的数学操作。
现在大多数AI训练还是用FP32,也就是32位浮点数。精度极高,但代价也大——硬件要够强,功耗更是惊人。而推理阶段常用的INT8(8位整数)情况正好相反:精度低,但传输效率高、省电,只是预测准确度会有所折损。
BF16正是在精度和预测准确性之间找到了一个不错的平衡点,从而在保持模型表现的同时,大幅提升吞吐量。这听起来有点绕,我们来拆开看看浮点数的结构就明白了。
浮点数字解析
计算机中浮点数的基本表示方式是:符号位 × 基数^{指数},基数为2。在FP32里,每个数字占用32位:1位符号,8位指数,23位尾数。
Google Brain团队给BF16出的题很简单:把FP32里的尾数砍掉16位,只留下7位。所以BF16的格式就成了:1位符号,8位指数,7位尾数,总共16位。
关键在这里:指数位数和FP32一样,都是8位。这意味着BF16保留了FP32的动态范围——能表示的数字范围几乎不变。额外的信息来自Google的解释:神经网络对指数的大小远比尾数敏感。所以用BF16做预测,准确率几乎和FP32持平。对大多数AI应用来说,这样的折衷完全可以接受。
为什么不使用FP16?
这里就引出一个自然的问题:FP16也是16位浮点数,在移动端图形处理里用得也很多,为什么不直接用呢?
FP16的位分配是:1位符号,5位指数,10位尾数。问题出在指数上——只有5位,动态范围比FP32小得多。要把FP32转成FP16,操作远比截断尾数要复杂。
还有一个重要的硬件因素:乘法器的芯片面积和尾数宽度的平方成正比。BF16的乘法器比FP32小8倍,只有FP16的一半不到。这正是Google为TPU选择BF16的关键原因之一——省面积、省功耗。
还有哪些DL运算格式?
BF16并不是唯一的选项。2017年,AI软件公司Nervana曾提出一种叫做Flexpoint的格式。它的想法很聪明:结合定点和浮点数字系统的优势,减少运算和内存需求。
定点数用固定位数表示整数和小数,运算比浮点数简单快速。但代价是动态范围远小于浮点数。Flexpoint的做法是:让张量里所有数字共享同一个指数(不光是指数大小相同,连值都完全相同)。这样一来,张量乘法就可以当作定点运算来做,省去了浮点运算的复杂度。

想法很巧妙,管理共享指数却是极其复杂的事,而且所有数字拥有相同指数,也限制了动态范围。更重要的是,Flexpoint从未真正起飞——Nervana自己在被英特尔收购之前,用的也还是BF16。
