# 7.6 混合精度训练：精度与速度的权衡

**混合精度训练**（Mixed Precision Training）使用半精度浮点数（FP16 或 BF16）代替全精度 FP32 进行大部分计算，是现代大语言模型训练的标配技术。

## 7.6.1 为什么使用半精度

FP32 使用 32 位存储一个浮点数，FP16 只需 16 位。半精度带来两个直接好处：

**显存减半**：同样大小的模型参数和激活值只需一半的显存，允许训练更大的模型或使用更大的批次。

**计算加倍**：现代 GPU（如 NVIDIA A100、H100）的 FP16/BF16 吞吐量是 FP32 的 2 倍以上。Tensor Core 针对半精度矩阵运算进行了专门优化。

## 7.6.2 精度问题与解决方案

直接使用 FP16 训练会遇到精度不足的问题：

**梯度下溢**：FP16 能表示的最小正数约为 $$6 \times 10^{-8}$$，小于此值的梯度会变为零（下溢），导致无法学习。**损失缩放**（Loss Scaling）是标准的解决方案：在计算反向传播之前将损失值乘以一个大常数（如 1024 或自动调整），放大梯度以避免下溢，然后在参数更新前将梯度除以同样的常数恢复原始尺度。

**参数更新精度**：微小的权重更新可能在 FP16 下被舍入为零。因此，混合精度训练维护一份**FP32 的主权重副本**，参数更新在 FP32 下进行，然后将更新后的参数截断为 FP16 用于下一轮前向传播。

## 7.6.3 BF16 的优势

**BF16**（Brain Floating Point 16）与 FP16 使用相同的 16 位，但分配了更多的位给指数部分（8 位指数 vs FP16 的 5 位），从而拥有与 FP32 相同的**数值范围**。代价是精度略低（7 位尾数 vs FP16 的 10 位）。

BF16 的关键优势是：**不容易出现梯度下溢问题**，因此通常不需要损失缩放。这简化了训练流程，减少了调试难度。如今，支持 BF16 的硬件（A100 及以后）上的大模型训练几乎都使用 BF16。

## 7.6.4 FP8 的前沿探索

NVIDIA H100 和 H200 GPU 引入了 FP8 精度支持（8 位浮点数），可进一步提升吞吐量。FP8 常见 E4M3 和 E5M2 两种编码：前者保留 3 位尾数、精度更高，后者保留 2 位尾数、动态范围更大，因此需要更精细的量化策略：

* **Per-tensor 动态缩放**：与 FP16 的单一损失缩放不同，FP8 通常需要为每个张量（激活值、梯度、权重）单独维护缩放因子，根据其数值范围动态调整。
* **数值范围处理**：由于精度极限，过小的梯度可能下溢为零，过大的值可能溢出为 inf/NaN 或饱和，需要更激进的缩放策略、amax 跟踪和异常检测。
* **动态缩放与 amax 跟踪**：FP8 训练通常维护每个张量或块的缩放元数据，根据当前或历史 amax 动态调整；分布式张量还需要在 rank 间同步 amax。某些推理或离线量化流程会做校准，但这不是 Transformer Engine 式 FP8 训练的唯一机制。

DeepSeek-V3 等前沿模型已开始探索 FP8 训练，通过**分组 FP8**（将权重矩阵按行或块分组，每组使用独立的缩放因子）在保持数值稳定性的同时实现了显著的效率提升。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://yeasy.gitbook.io/llm_internals/di-er-bu-fen-xun-lian-pian/07_distributed_training/7.6_mixed_precision.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
