一、FP8 为什么成为 2026 年推理的事实标准?
2026 年是 FP8(8-bit 浮点数)推理的转折之年。从 NVIDIA 的路线图到各大大模型的部署策略,FP8 已经从「可选优化」变成了「默认配置」。
FP8 的数学本质
FP8 不是一个新的概念——IEEE 754 标准早在 2008 年就定义了 8-bit 浮点格式。但直到 2022 年 NVIDIA Hopper 架构(H100)引入 FP8 Tensor Core,FP8 才真正具备了实用价值。
FP8 有两种主流格式:
| 格式 | 符号位 | 指数位 | 尾数位 | 动态范围 | 精度 |
|---|---|---|---|---|---|
| E4M3 | 1 | 4 | 3 | ±448 | ~2 位有效数字 |
| E5M2 | 1 | 5 | 2 | ±57344 | ~1.5 位有效数字 |
E4M3 适合权重和激活值——它有更大的尾数位,精度更高,适合需要数值稳定性的场景。
E5M2 适合梯度——它有更大的动态范围,可以容纳更大范围的数值,适合反向传播。
为什么是 FP8 而不是 FP16/INT8?
对比 FP16: FP8 将显存占用和计算量减半,精度损失在 LLM 推理中通常 <1%(perplexity 差异 <0.1)。对于 70B 模型,FP16 需要 140GB 显存,FP8 只需 70GB——从需要 8×H100 降到 4×H100,成本直接减半。
对比 INT8: INT8 是定点数,没有指数位,动态范围有限。对于 LLM 中的激活值(可能跨越多个数量级),INT8 需要复杂的缩放策略(per-token + per-channel 缩放),实现复杂且容易出错。FP8 自带指数位,天然支持大动态范围,实现更简洁。
对比 INT4: INT4 的精度损失在推理中已经比较显著(perplexity 增加 0.5-2.0),而且需要复杂的量化校准流程。FP8 在精度和效率之间取得了更好的平衡。
二、DeepGEMM 源码级解析:FP8 GEMM 的核心技术
GEMM(General Matrix Multiplication)是深度学习中最核心的计算操作。LLM 的每一层 Transformer 都在大量执行矩阵乘法:Q·K^T、注意力输出投影、FFN 层的两个线性变换。可以说,优化了 GEMM 就优化了 LLM 推理的 80%。
DeepSeek 的 DeepGEMM 正是瞄准了这个核心痛点——提供一个专为 FP8 优化的高性能 GEMM 内核库。
DeepGEMM 的核心设计
DeepGEMM 的关键创新在于细粒度缩放(Fine-grained Scaling)。传统 FP8 量化使用 per-tensor 或 per-channel 缩放——整个张量或每个通道共享一个缩放因子。但 LLM 的激活值在不同 token、不同位置上的分布差异巨大,粗粒度缩放会导致精度损失。
DeepGEMM 支持 per-token + per-channel 双维度缩放:
FP8 GEMM: C = (A_fp8 × S_A) × (B_fp8 × S_B) 其中 S_A 是 per-token 缩放因子,S_B 是 per-channel 缩放因子
这种设计让每个 token 和每个输出通道都有独立的缩放因子,最大限度保留精度,同时保持了 FP8 的显存和计算优势。
与 cuBLAS/cuBLASLt 的对比
NVIDIA 的 cuBLAS 库也支持 FP8 GEMM,但 DeepGEMM 在以下方面做了针对性优化:
- 缩放因子融合:将 per-token/per-channel 缩放操作融合到 GEMM 内核中,避免额外的 CUDA kernel 启动开销
- Tile 策略优化:针对 LLM 推理中常见的矩阵形状(如 batch×seq×hidden)优化了 block tiling 策略
- Clean API:提供了比 cuBLAS 更简洁的 Python 接口,易于集成到现有推理框架
import torch
import deep_gemm
# 创建 FP8 矩阵(模拟 LLM 推理中的 Q·K^T 操作)
# batch_size=2, seq_len=1024, hidden_dim=4096
batch, seq, dim = 2, 1024, 4096
# 输入矩阵 A (query): [batch, seq, dim]
A_fp32 = torch.randn(batch, seq, dim, device="cuda", dtype=torch.float32)
# 输入矩阵 B (key): [batch, dim, seq]
B_fp32 = torch.randn(batch, dim, seq, device="cuda", dtype=torch.float32)
# 转换为 FP8 (E4M3 格式)
A_fp8 = A_fp32.to(torch.float8_e4m3fn)
B_fp8 = B_fp32.to(torch.float8_e4m3fn)
# DeepGEMM FP8 GEMM 调用
# m=batch*seq (总 token 数), n=seq (输出序列长度), k=dim (hidden 维度)
m, n, k = batch * seq, seq, dim
C_fp8 = deep_gemm.fp8_gemm(
A=A_fp8,
B=B_fp8,
m=m, n=n, k=k,
# per-token 缩放因子(对 A)
scale_a=torch.ones(m, device="cuda", dtype=torch.float32),
# per-channel 缩放因子(对 B)
scale_b=torch.ones(n, device="cuda", dtype=torch.float32),
)
# 输出转回 FP32 进行后续计算
C_fp32 = C_fp8.to(torch.float32)
print(f"输出形状: {C_fp32.shape}") # [2048, 1024]import torch
import time
import deep_gemm
def benchmark_gemm(m, n, k, iterations=100):
"""对比 DeepGEMM FP8 与 cuBLAS FP16 的性能"""
# 准备 FP8 数据
A_fp8 = torch.randn(m, k, device="cuda", dtype=torch.float8_e4m3fn)
B_fp8 = torch.randn(k, n, device="cuda", dtype=torch.float8_e4m3fn)
# 准备 FP16 数据(cuBLAS 基准)
A_fp16 = torch.randn(m, k, device="cuda", dtype=torch.float16)
B_fp16 = torch.randn(k, n, device="cuda", dtype=torch.float16)
# DeepGEMM FP8 GEMM
torch.cuda.synchronize()
start = time.perf_counter()
for _ in range(iterations):
_ = deep_gemm.fp8_gemm(A_fp8, B_fp8, m, n, k,
torch.ones(m, device="cuda"),
torch.ones(n, device="cuda"))
torch.cuda.synchronize()
fp8_time = (time.perf_counter() - start) / iterations
# cuBLAS FP16 GEMM
torch.cuda.synchronize()
start = time.perf_counter()
for _ in range(iterations):
_ = torch.mm(A_fp16, B_fp16)
torch.cuda.synchronize()
fp16_time = (time.per*counter() - start) / iterations
print(f"矩阵形状: {m}×{k} × {k}×{n}")
print(f"DeepGEMM FP8: {fp8_time*1000:.2f}ms")
print(f"cuBLAS FP16: {fp16_time*1000:.2f}ms")
print(f"加速比: {fp16_time/fp8_time:.2f}x")
print(f"显存节省: 50%")
# 模拟 GPT-5.5 推理场景
# Attention: Q·K^T, batch=4, seq=2048, dim=8192
benchmark_gemm(8192, 2048, 8192)
# FFN: 第一个线性层, batch*seq=8192, dim=8192, ff_dim=22016
benchmark_gemm(8192, 22016, 8192)三、FP8 推理的硬件支持全景
FP8 推理的普及离不开硬件层面的支持。以下是 2026 年主流 GPU 的 FP8 支持情况:
NVIDIA 阵营
| GPU | 架构 | FP8 Tensor Core | FP8 GEMM 吞吐量 | 备注 |
|---|---|---|---|---|
| H100 | Hopper | ✅ | 1,979 TFLOPS | 首次引入 FP8 |
| H200 | Hopper | ✅ | 1,979 TFLOPS | H100 + HBM3e |
| B200 | Blackwell | ✅ | ~3,000 TFLOPS | FP8 性能翻倍 |
| GB200 | Blackwell | ✅ | ~3,000 TFLOPS | 双芯片封装 |
| RTX 5090 | Blackwell | ✅ | ~1,200 TFLOPS | 消费级支持 FP8 |
| A100 | Ampere | ❌ | N/A | 仅支持 FP16/INT8 |
其他厂商
| 厂商 | 产品 | FP8 支持 | 备注 |
|---|---|---|---|
| AMD | MI300X | ✅ | CDNA 3 架构 |
| AMD | MI350X | ✅ | CDNA 4 架构 |
| Intel | Gaudi 3 | ⚠️ | 部分支持 |
| 华为 | 昇腾 910C | ⚠️ | 实验性支持 |
关键结论: H100 及以上(或 B200/GB200)是使用 FP8 推理的最低硬件要求。如果你的部署环境是 A100 或更老的 GPU,FP8 只能退化为软件模拟,反而会变慢。
FP8 推理的显存收益实战
以一个 70B 参数的 LLM 为例:
| 精度 | 权重显存 | KV Cache (8K seq, batch=32) | 总显存需求 | H100 数量 |
|---|---|---|---|---|
| FP16 | 140 GB | 64 GB | 204 GB | 8 |
| FP8 | 70 GB | 32 GB | 102 GB | 4 |
| INT4 | 35 GB | 32 GB | 67 GB | 2 |
FP8 相比 FP16,显存需求减半,所需 GPU 数量减半——这直接转化为 50% 的推理成本节省。
四、主流推理框架的 FP8 支持对比
2026 年,主流 LLM 推理框架都已支持或正在积极支持 FP8。以下是各框架的 FP8 支持状态:
vLLM
vLLM 是最受欢迎的开源 LLM 推理框架,FP8 支持成熟度最高:
- FP8 量化:支持 E4M3 格式的 per-tensor FP8 量化
- FP8 Attention:FlashAttention 的 FP8 变体
- 动态缩放:支持运行时 per-token 缩放
- 与 DeepGEMM 集成:vLLM 正在推进 DeepGEMM 作为 FP8 GEMM 后端
启用方式:
from vllm import LLM
llm = LLM(
model="meta-llama/Llama-3-70B",
quantization="fp8", # 一行代码启用 FP8
tensor_parallel_size=4,
)TensorRT-LLM
NVIDIA 官方推理框架,FP8 支持最底层、最优化:
- 硬件级 FP8:直接调用 FP8 Tensor Core
- Auto FP8:自动为每层选择最优精度(FP8/FP16/INT8 混合)
- 与 DeepGEMM 兼容:可以作为 DeepGEMM 的宿主框架
SGLang
新兴推理框架,以高吞吐量和低延迟著称:
- FP8 KV Cache:支持 FP8 格式的 KV Cache 压缩
- FP8 推理:实验性支持,性能接近 vLLM
TGI (Text Generation Inference)
HuggingFace 官方推理框架:
- bitsandbytes FP8:通过 bitsandbytes 库间接支持
- 性能:不如 vLLM/TensorRT-LLM 的 FP8 实现高效
| 框架 | FP8 权重 | FP8 激活 | FP8 KV Cache | DeepGEMM 集成 | 成熟度 |
|---|---|---|---|---|---|
vLLM | ✅ 成熟 | ✅ 成熟 | ✅ 实验性 | 🔄 推进中 | ⭐⭐⭐⭐⭐ |
TensorRT-LLM | ✅ 成熟 | ✅ 成熟 | ✅ 成熟 | ✅ 兼容 | ⭐⭐⭐⭐⭐ |
SGLang | ✅ 实验性 | ⚠️ 部分 | ✅ 成熟 | ❌ 无 | ⭐⭐⭐⭐ |
TGI | ✅ bitsandbytes | ❌ 无 | ❌ 无 | ❌ 无 | ⭐⭐⭐ |
llama.cpp | ❌ 无 | ❌ 无 | ❌ 无 | ❌ 无 | ⭐⭐ |
五、FP8 推理的精度-性能权衡实战
FP8 推理不是「开了就行」——你需要根据具体场景做精度和性能的权衡。以下是实战中总结的最佳实践:
1. 混合精度策略
最聪明的做法不是全模型 FP8,而是分层选择精度:
- Attention 层:FP8(数值稳定,精度损失 <0.5%)
- FFN 第一层(上投影):FP8(输入范围可控)
- FFN 第二层(下投影):FP16(输出精度敏感)
- 输出层(LM Head):FP16(logits 需要高精度)
- 嵌入层:FP16(低频 token 的嵌入向量对精度敏感)
这种混合策略在几乎不损失精度的前提下,能实现约 40% 的显存节省和 30% 的加速。
2. 校准数据的选择
FP8 量化的精度高度依赖于校准数据的质量:
- 最少样本数:512 个校准样本通常足够
- 数据多样性:覆盖不同领域、不同长度、不同语言
- 避免偏差:校准数据应该与目标推理场景的分布一致
3. 精度监控
在生产环境中持续监控 FP8 推理的精度:
- Perplexity 监控:定期在验证集上计算 FP8 vs FP16 的 perplexity 差异
- 输出一致性:抽样对比 FP8 和 FP16 的输出相似度
- 回退机制:当精度下降超过阈值时,自动切换回 FP16
import torch
import torch.nn as nn
from typing import Dict, Optional
class FP8HybridInference:
"""FP8 混合精度推理引擎
策略:
- Attention 层: FP8 (E4M3)
- FFN 上投影: FP8
- FFN 下投影: FP16
- LM Head: FP16
- Embedding: FP16
"""
def __init__(self, model: nn.Module, calibration_data: torch.Tensor):
self.model = model
self.fp8_layers = self._identify_fp8_layers(model)
self.scales = self._calibrate_scales(calibration_data)
def _identify_fp8_layers(self, model: nn.Module) -> Dict[str, bool]:
"""识别哪些层可以用 FP8"""
fp8_config = {}
for name, module in model.named_modules():
if isinstance(module, nn.Linear):
# LM Head 和 Embedding 用 FP16
if "lm_head" in name or "embed" in name:
fp8_config[name] = False
# FFN 下投影用 FP16
elif "down_proj" in name:
fp8_config[name] = False
# 其他用 FP8
else:
fp8_config[name] = True
return fp8_config
def _calibrate_scales(self, data: torch.Tensor) -> Dict[str, float]:
"""基于校准数据计算每层的 FP8 缩放因子"""
scales = {}
for name, module in self.model.named_modules():
if name in self.fp8_layers and self.fp8_layers[name]:
# 用校准数据的前向传播统计激活值范围
with torch.no_grad():
# 简化版:用输入数据的 max 绝对值作为缩放因子
abs_max = data.abs().max().item()
scales[name] = abs_max / 448.0 # E4M3 最大值为 448
return scales
def forward(self, input_ids: torch.Tensor) -> torch.Tensor:
"""混合精度前向传播"""
x = self.model.embed_tokens(input_ids) # FP16
for layer in self.model.layers:
# Attention (FP8)
attn_out = self._fp8_attention(layer.self_attn, x)
x = x + attn_out
# FFN 上投影 (FP8) + 下投影 (FP16)
ff_out = self._hybrid_ffn(layer.mlp, x)
x = x + ff_out
# LM Head (FP16)
logits = self.model.lm_head(x)
return logits
def _fp8_attention(self, attn_module, x: torch.Tensor) -> torch.Tensor:
"""FP8 注意力计算"""
q = attn_module.q_proj(x).to(torch.float8_e4m3fn)
k = attn_module.k_proj(x).to(torch.float8_e4m3fn)
v = attn_module.v_proj(x).to(torch.float8_e4m3fn)
# FP8 GEMM (用 DeepGEMM 或 cuBLASLt)
# 简化版:torch.mm 自动降级到 FP16
attn_scores = (q.to(torch.float16) @ k.transpose(-1, -2).to(torch.float16)) / (q.shape[-1] ** 0.5)
attn_weights = torch.softmax(attn_scores, dim=-1)
return attn_weights @ v.to(torch.float16)
def _hybrid_ffn(self, mlp_module, x: torch.Tensor) -> torch.Tensor:
"""混合精度 FFN:上投影 FP8 + 下投影 FP16"""
# 上投影:FP8
hidden = mlp_module.up_proj(x).to(torch.float8_e4m3fn)
hidden = mlp_module.act_fn(hidden.to(torch.float16))
# 下投影:FP16
return mlp_module.down_proj(hidden.to(torch.float16))
# 使用示例
# 1. 校准
calibration_data = torch.randn(512, 4096, device="cuda")
engine = FP8HybridInference(model, calibration_data)
# 2. 推理
output = engine.forward(input_ids)
print(f"输出形状: {output.shape}") # [batch, seq, vocab]六、生产部署指南:从开发到上线
将 FP8 推理部署到生产环境,需要关注以下几个关键环节:
1. 模型准备
# 使用 **vLLM** 一键导出 FP8 量化模型
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-3-70B \
--quantization fp8 \
--export-model ./llama3-70b-fp82. 服务配置
# docker-compose.yml
services:
vllm-fp8:
image: vllm/vllm-openai:latest
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 4
capabilities: [gpu]
command: >
--model ./llama3-70b-fp8
--tensor-parallel-size 4
--max-num-seqs 256
--gpu-memory-utilization 0.9
ports:
- "8000:8000"3. 监控与告警
- GPU 利用率:FP8 推理应该达到 60%+ 的 GPU 利用率
- 显存使用:确认 FP8 量化后显存占用减半
- 延迟分布:P50 < 100ms/token, P99 < 300ms/token
- 精度监控:每小时抽样 100 个请求,对比 FP8 vs FP16 输出相似度
4. 常见问题排查
| 问题 | 原因 | 解决方案 |
|---|---|---|
| FP8 推理反而更慢 | GPU 不支持 FP8 Tensor Core | 降级到 FP16 |
| 输出质量显著下降 | 校准数据不具代表性 | 增加校准样本多样性 |
| OOM | 批处理过大 | 减小 max_num_seqs |
| NaN 输出 | 缩放因子计算错误 | 检查 per-token/per-channel 缩放 |
5. 成本收益分析
以月均 1000 万次推理请求为例(每次 2K input + 1K output tokens):
| 方案 | GPU 配置 | 月成本 | 单次延迟 P50 | 备注 |
|---|---|---|---|---|
| FP16 | 8×H100 | $56,000 | 120ms | 基准方案 |
| FP8 | 4×H100 | $28,000 | 95ms | 推荐 |
| INT4 | 2×H100 | $14,000 | 85ms | 精度略低 |
FP8 方案在成本(节省 50%)和精度(损失 <1%)之间取得了最佳平衡。
七、总结:FP8 推理的 2026 年路线图
2026 年 4 月 DeepSeek 开源 DeepGEMM,标志着 FP8 推理基础设施进入了成熟期。以下是我们对 FP8 推理未来发展的预测:
短期(2026 Q2-Q3):
- vLLM 完成 DeepGEMM 集成,FP8 成为 vLLM 默认量化选项
- TensorRT-LLM 推出 Auto-FP8,自动为每层选择最优精度
- 更多开源模型提供 FP8 量化版本
中期(2026 Q4-2027 Q1):
- FP4 推理开始实用化(NVIDIA Rubin 架构支持)
- 端侧 FP8 推理(手机、IoT)成为主流
- FP8 训练(不仅仅是推理)开始探索
长期(2027+):
- FP8 成为 LLM 推理的事实标准,FP16 退居次要地位
- 混合精度推理引擎成熟,自动为每层、每 token 选择最优精度
- FP8 硬件普及到消费级 GPU(RTX 50 系列已支持)
行动建议:
- 如果你有 H100/B200 集群,立即开始 FP8 推理迁移——显存成本减半的收益太大了
- 如果你只有 A100,关注 INT8/INT4 量化,FP8 暂时不可用
- 如果你是推理服务提供商,FP8 是你的成本竞争力核心
- 如果你是模型开发者,在模型发布时同时提供 FP8 量化版本
DeepGEMM 的开源降低了 FP8 推理的技术门槛——现在你只需要几行 Python 代码就能享受 FP8 带来的性能提升。2026 年,不会用 FP8 推理的 LLM 工程师,就像 2020 年不会用 CUDA 的深度学习工程师一样——不是不能用,而是效率差了整整一个时代。