FP16与bfloat16位模式可视化工具
可视化半精度浮点数(FP16、IEEE 754 binary16)和bfloat16的位模式。支持十进制与位模式互相转换,符号位、指数部、尾数部分色显示。适合学习机器学习中的量化与推理加速。
FP16与bfloat16的结构比较
两者合计都是16位,但指数部与尾数部的位数分配不同,导致可表示的数值范围和精度完全不同。
| 项目 | FP16(IEEE 754 半精度) | bfloat16 |
|---|---|---|
| 总位数 | 16 | 16 |
| 指数部位数 | 5 | 8 |
| 尾数部位数 | 10 | 7 |
| 可表示的数值范围 | 约±6.1×10⁻⁵ 至 ±65504(范围较窄但尾数位多、精度较高) | 约±1.2×10⁻³⁸ 至 ±3.4×10³⁸(与float32相同的宽范围,但精度较低) |
| 主要用途 | 图像处理、图形学、推理时的省内存化(半精度训练) | 深度学习训练(TPU、最新GPU)。从float32转换时无需担心指数溢出 |
bfloat16的指数部位数(8位)和偏移量(127)与float32(单精度)完全相同,因此只需截断float32的尾数部即可转换,这是实现上的一个优势。
看清 FP16 与 bfloat16 的位是怎样排布的
虽同占十六位,FP16(即 IEEE 754 binary16)与 bfloat16 分配这些位的方式却大不相同。本工具在十进制数与位模式之间双向转换,并把符号、指数、尾数分别着色,让这份差别看得见,而不只是读得到。
**关键正在于分配之别。FP16 给指数五位、给尾数十位,bfloat16 则给指数八位、给尾数七位。** 八位指数恰与单精度相同,由此生出两条性质:其一,**bfloat16 所能表示的取值范围与 FP32 相同**;其二,**由 FP32 转换过来,不过是截取高十六位而已。** 机器学习偏爱 bfloat16 正是为此——训练途中数值飞出范围而把整轮毁掉的风险小得多。代价则是尾数只有七位,**精度比 FP16 来得粗。** 要精度便取 FP16,要范围便取 bfloat16。
使用方法
- 选择转换的方向 十进制到位,或位到十进制,两者皆可。
- 输入数值 十进制数或一串 0 与 1 皆可。
- 阅读着色的位 **符号、指数、尾数各以自己的颜色标出。**
- 把 FP16 与 bfloat16 并置 **同一个数用两种格式表示,便知它们在何处分道扬镳。**
用好本工具的小技巧
- 即使是同一个值0.1,FP16和bfloat16的舍入误差表现也完全不同。切换格式比较尾数部的位模式吧。
- bfloat16的指数部位数和偏移量与float32相同,因此即使是超过65504的大数值也不易溢出。相反FP16一旦超过65504就会立即变为无穷大。
- 将"70000"转换为FP16会溢出变为无穷大,而bfloat16则能正常表示(精度有所下降)。
- 在PyTorch、TensorFlow等机器学习框架中进行模型量化时,bfloat16容易从float32转换,而FP16由于范围较窄有时需要预先缩放。
- 从位模式逆向转换为十进制时,需输入带`0x`前缀的4位十六进制值,或16位二进制值(`0b`前缀可省略)。
这些场景会用到
理解量化的代价
**可以具体弄清:模型降到十六位时,数值会被舍入到什么地步。**
在两种格式间取舍
它为「您这件事要的是范围还是精度」提供了判断的材料。
找出溢出的起点
**可以拿真实数值试一试:一旦超过 FP16 所能表示的最大数会怎样。**
学习浮点数的机理
可以一位一位地追下去,看指数与尾数如何合力表出一个数。
浮点数的术语
- 符号位
- 最高的那一位,给出正负:0 为正,1 为负。
- 指数
- 表示数值量级的部分。**FP16 拨给它五位,bfloat16 拨给它八位。**
- 尾数
- 相当于有效数字的部分。**FP16 有十位,bfloat16 有七位,这道差距正是精度之别。**
- bfloat16
- **一种把指数保持在 FP32 的八位的十六位格式。** 它把存储减半,而不牺牲范围。
- 次正规数
- 指数取到最小时所用的表示,可表出极其贴近零的数值。
- 量化
- 以更少的位数表示模型权重的做法。**存储与计算随之减少,精度也随之下降。**
常见问题
闲话 ― 为何机器学习需要"降低精度"的数值表示
2018年前后,Google为其TPU(Tensor Processing Unit)设计了一种新的16位浮点格式bfloat16。此前已存在的FP16(IEEE 754半精度)已在图像处理和图形学领域实用化,但由于指数部仅5位,可表示的数值范围较窄,难以应对深度学习训练中梯度时而极小、时而极大的现象(梯度消失、梯度爆炸)。
bfloat16的设计思路很明确:牺牲尾数部的精度,换取与float32(单精度)完全相同的8位指数部宽度,从而能安全处理训练过程中频繁出现的极大极小值。"Brain Floating Point"这个名字来源于Google的机器学习研究部门"Google Brain"。
在传统计算机科学中,降低浮点数精度一直被视为"漏洞的温床"而被避免。但深度学习模型有一种特殊性质:即使存在一定的数值误差,对最终预测精度的影响也微乎其微。利用这种"稍有不精确但整体仍能工作"的特性,将内存占用和计算成本减半的16位表示得以广泛普及,这可以说是有别于传统计算机科学常识的、机器学习领域独有的优化。