为啥说:训练用BF16,推理用FP16

FP16、BF16 是张量里每一个数字的存储格式(数据类型)

张量可以理解成一大堆数字组成的矩阵/向量,里面最小单元就是单个数字,FP16/BF16规定:这个数字在内存、权重文件里占多少字节、怎么存小数。

1. 先搞懂基础参照物:FP32(普通32位浮点数)

电脑平时存小数默认用FP32,占4个字节,分三段:

  1. 正负符号位
  2. 指数(控制数字能多大/多小)
  3. 尾数(控制数字精准程度)

大模型原始训练时,所有权重数字本来都是FP32,但4字节一个数,权重文件会巨大,显存扛不住,于是搞出两种压缩到2字节(16位)的方案:FP16、BF16。

两者都只占2字节,区别只是指数和尾数的位数分配不一样

2. FP16(Float16,标准16位浮点)

分配规则:1位符号 + 5位指数 + 10位尾数

  • 优点:尾数10位,精度更高,算乘法、推理速度更快,老显卡加速友好;
  • 缺点:只有5位指数,能表示的数字范围很小。
    遇到模型里差距很大的权重数值、训练时的梯度,很容易超出范围直接变成0(下溢),训练容易崩。

举个生活化例子:

好比一把尺子,刻度分得特别细(尾数多=精度高),但尺子总长很短(指数少=范围小)。小数能算得很准,但数字稍微一大一小就超出去读不出来。

3. BF16 = BFP16(Brain Float16,谷歌搞出来的)

分配规则:1位符号 + 8位指数 + 7位尾数

  • 优点:8位指数,和FP32的指数长度一模一样,能承载的数字范围和完整版FP32完全一致。训练时梯度、权重大小波动再大,也不会溢出失效;
  • 缺点:尾数只剩7位,精度比FP16低一点点,微小数值会丢失一点细节,但大模型训练完全感知不到损失。

生活化例子:

尺子总长和完整4字节尺子一样长(指数8位),但刻度稍微粗一点(尾数少),范围足够用,牺牲一点点精细度换稳定。

4. 它们是不是张量的基本单元数据类型?

是的,完全正确。

  1. 张量 = 一堆数字的集合(权重矩阵、输入向量、中间计算结果全是张量)
  2. 张量的最小组成单位:单个数值
  3. FP16/BF16 就是规定「张量里每一个数字用哪种16位格式保存」

举个直观对比:

  • 同样100万个权重数字:
    FP32:每个4字节,总占用400MB
    FP16/BF16:每个2字节,总占用200MB,直接减半显存/硬盘占用

5. 使用场景

  1. 训练、微调模型(QLoRA/全量微调)一律用 BF16
    训练时会产生梯度(极大、极小数),BF16表示数值范围广,不怕数值溢出,训练稳定,现在所有大模型预训练标配。
  2. 单纯本地推理、显卡老旧(比如老10系NVIDIA卡)优先 FP16
    FP16表示的数据范围小,计算速度更快,更省算力。

6、手动转换 两种格式

一、先分清 概念:「训练计算精度」「权重文件存储精度」「推理运行精度」

1. QLoRA/全量微调阶段:为什么强制用BF16做计算?

训练时会产生梯度(极小/极大的数值):

  • BF16指数位8位,和FP32范围一模一样,梯度不会溢出、训练稳定;
  • FP16只有5位指数,梯度极易变成0/无穷,训练直接崩掉。
    这里说的「用BF16」,指整个训练过程的运算统一走BF16浮点计算
2. 训练完保存的权重文件默认是什么格式?

两种情况:

  1. 普通LoRA(非QLoRA) :全程基座BF16训练,保存出来的基座权重、LoRA适配器都是 BF16文件
  2. QLoRA 4bit训练 :显存里基座是4bit NF4压缩存储,计算时临时反量化BF16;保存只会存两件东西:4bit基座模型 + BF16格式LoRA小权重,不会直接存完整BF16基座
3. 关键:BF16权重文件 ≠ 推理必须跑BF16

权重文件只是静态存储数字 ,BF16和FP16都是16位浮点数,底层框架(PyTorch/Transformers/vLLM)自带类型强制转换算子,一行代码手动转,不是自动变。

二、两条落地路线:微调完怎么得到FP16推理模型

路线1:LoRA微调(原生BF16权重)转FP16推理
步骤
  1. 用BF16跑完微调,保存.safetensors权重(文件里数值是BF16编码);
  2. 推理加载时,手动执行类型转换:
python 复制代码
# 加载BF16模型
model = AutoModelForCausalLM.from_pretrained("./your_bf16_model")
# 全局强制转FP16,所有权重数值重新编码为FP16格式
model = model.to(torch.float16)
# 此时显存里运行是FP16加速,你也可以重新保存一份FP16权重文件
model.save_pretrained("./fp16_infer_model")
原理大白话

BF16、FP16本质都是记录同一个小数,只是二进制拆分「指数/尾数」规则不同。

框架会把BF16数字先翻译成标准FP32中间值,再重新编码成FP16二进制,存在显存里用于推理;

  • 优点:老10系显卡跑FP16算子速度更快;
  • 代价:极个别超大/极小权重数值会丢失一点精度(推理无梯度,轻微损失肉眼看不出)。
路线2:QLoRA 4bit微调 → 合并LoRA → 导出FP16完整模型(最常用部署流程)

QLoRA训练完不会有完整BF16基座,必须先合并权重才能导出FP16:

  1. 加载4bit量化基座 + BF16 LoRA适配器;
  2. 执行model.merge_and_unload():框架自动把4bit权重反量化还原成BF16完整基座,再叠加LoRA参数;
  3. 此时内存里是完整BF16大模型,手动转FP16后保存,得到纯FP16权重文件用于部署;
  4. 以后推理直接加载这份FP16文件,全程FP16运算加速。

三、必须手动操作

  1. 训练保存的文件固定是BF16/4bit,不会自动变成FP16
  2. 「推理优先FP16」不是让原BF16文件自己变形,是两种操作二选一:
    • 加载BF16权重,运行时实时转FP16计算(不改动原文件);
    • 转换后另存一份独立FP16权重文件,专门给老显卡推理用;
  3. 反过来也成立:FP16权重推理,加载时转BF16运行,完全可逆。
相关推荐
meilindehuzi_a3 小时前
从跑分到生产力:重新理解大模型基准测试与分层协作
人工智能
蜜桃味女焊匠人4 小时前
焊接生产线优化思路:解决手工焊、机器人焊气体浪费问题
人工智能·经验分享·其他·机器人
Georgeviewer8 小时前
商业落地评测|实体门店GEO优化性价比与服务体系深度复盘
大数据·人工智能
GuWenyue9 小时前
分不清AI Workflow与Agent?3个实战案例彻底讲透,做AI应用不再踩选型坑
人工智能
彩讯股份30063410 小时前
彩讯股份与心洲科技签署战略合作协议,共建企业级模型后训练能力
人工智能·科技
To_OC10 小时前
LC 51 N 皇后:我以为难的是回溯,结果栽在了对角线下标
javascript·算法·leetcode
迅易科技10 小时前
从场景验证到Agent上线:迅易 × WorkBuddy如何帮助企业建设AI能力?
人工智能·ai·腾讯云
PNP Robotics10 小时前
多伦多大学机器人峰会|物理AI与具身智能落地新趋势
人工智能·深度学习·机器学习·机器人
GIR12310 小时前
官方出品 | 多通道土壤呼吸测量系统市场现状与十五五规划深度报告:行业分析+趋势预测全收录
大数据·人工智能·机器学习