FP8
FP8 là định dạng số dấu phẩy động 8 bit với các biến thể E4M3 và E5M2, giảm một nửa bộ nhớ so với 16 bit và tăng gấp đôi thông lượng ma trận trên GPU được hỗ trợ.
FP8 là định dạng số dấu phẩy động 8 bit dùng để huấn luyện và chạy mạng nơ-ron với một nửa bộ nhớ và lượng truyền dữ liệu so với định dạng 16 bit. Giống mọi kiểu dấu phẩy động, mỗi giá trị có một bit dấu, các bit số mũ xác định phạm vi và các bit phần định trị xác định độ chính xác; nhưng với tổng cộng chỉ tám bit, định dạng này phải đánh đổi đáng kể cả hai yếu tố. Các kỹ sư của NVIDIA, Arm và Intel xác định hai biến thể chuẩn là E4M3 và E5M2 trong bài báo tháng 9 năm 2022 Định dạng FP8 cho học sâu, đồng thời xác thực việc huấn luyện mô hình ngôn ngữ lên đến 175 tỷ tham số bằng các định dạng này. Trên GPU có Tensor Core FP8, chẳng hạn NVIDIA Hopper H100 ra mắt năm 2022, phép nhân ma trận FP8 đạt thông lượng gấp đôi FP16 hoặc BF16.
E4M3 và E5M2#
Hai biến thể phân bổ bảy bit không phải bit dấu theo cách khác nhau:
- E4M3: Bốn bit số mũ và ba bit phần định trị. Định dạng này bỏ giá trị vô cực và chỉ giữ một mẫu NaN để đạt giá trị tối đa 448; phù hợp với trọng số và activation trong lượt chạy xuôi.
- E5M2: Năm bit số mũ và hai bit phần định trị, tuân theo quy ước IEEE 754 cho các giá trị đặc biệt. Định dạng này đạt 57.344 với các bước lượng tử thô hơn, phù hợp với gradient có độ lớn biến thiên trên phạm vi rộng hơn.
Cả hai định dạng đều đưa các giá trị nhỏ về 0 và cắt ngưỡng các giá trị lớn, vì vậy tensor FP8 thường đi kèm hệ số tỷ lệ để dịch chuyển giá trị vào phạm vi biểu diễn được. Chuyển các giá trị cỡ gradient có và không có hệ số này cho thấy lý do:
import torch
torch.manual_seed(0)
grads = torch.randn(10_000) * 1e-4 # gradient-sized values, far below 1
e4m3, e5m2 = torch.float8_e4m3fn, torch.float8_e5m2
print(f"E4M3 max {torch.finfo(e4m3).max:g}, E5M2 max {torch.finfo(e5m2).max:g}")
# Per-tensor scaling maps the largest magnitude onto the E4M3 maximum before casting
scale = torch.finfo(e4m3).max / grads.abs().max()
results = {
"E4M3 direct": grads.to(e4m3).float(),
"E5M2 direct": grads.to(e5m2).float(),
"E4M3 scaled": (grads * scale).to(e4m3).float() / scale,
}
for name, restored in results.items():
zeros = (restored == 0).float().mean()
error = ((restored - grads).abs() / grads.abs()).median()
print(f"{name}: {zeros:.0%} rounded to zero, median relative error {error:.1%}")Ép kiểu trực tiếp sang E4M3 làm tròn 100% số giá trị về 0; phạm vi rộng hơn của E5M2 giữ lại hầu hết giá trị với sai số tương đối trung vị 6.4% và mất 7%, còn việc scale trước giúp E4M3 giữ lại mọi giá trị với sai số trung vị 2.2%. PyTorch cũng cung cấp float8_e4m3fnuz và float8_e5m2fnuz, là các biến thể được bộ tăng tốc MI300 của AMD sử dụng; chúng loại bỏ số âm 0 và dịch độ lệch số mũ, giới hạn E4M3 ở mức 240. Do đó, model FP8 không tự động có thể chuyển đổi giữa các nhà cung cấp.
Chiến lược scaling#
Dùng một hệ số tỷ lệ cho toàn bộ tensor sẽ thất bại khi một vài giá trị ngoại lệ xác định giá trị cực đại và đẩy mọi giá trị khác về gần 0 — điều thường gặp trong activation của transformer. Các phương pháp khác nhau ở mức độ chi tiết khi scale:
- Scaling trì hoãn theo tensor: Transformer Engine của NVIDIA chọn hệ số tỷ lệ cho từng tensor dựa trên các giá trị cực đại quan sát được trong những bước huấn luyện gần nhất, do đó không cần thêm một lượt duyệt dữ liệu.
- Scaling theo khối: DeepSeek-V3 scale activation theo từng tile 1 × 128 giá trị và trọng số theo từng khối 128 × 128; nhóm phát triển báo cáo đây là lần đầu tiên xác thực việc huấn luyện FP8 trên một model cực lớn gồm 671 tỷ tham số.
- MXFP8: Định dạng microscaling của Open Compute Project dùng chung một hệ số tỷ lệ lũy thừa của hai cho mỗi 32 giá trị; GPU Blackwell của NVIDIA hỗ trợ chạy định dạng này bằng phần cứng.
Phép nhân ma trận tích lũy kết quả ở độ chính xác cao hơn; các layer nhạy hoặc ít tốn kém như chuẩn hóa, softmax và trọng số master của optimizer vẫn dùng BF16 hoặc FP32. Vì vậy, FP8 chỉ là một phần trong quy trình độ chính xác hỗn hợp.
FP8 trong huấn luyện và suy luận#
Trong huấn luyện, Transformer Engine của NVIDIA và TorchAO thay các linear layer bằng phiên bản FP8, đồng thời giữ trọng số master ở độ chính xác cao hơn. Trong suy luận, engine phục vụ model lưu trọng số model và KV cache của mô hình ngôn ngữ lớn ở định dạng FP8, giảm một nửa bộ nhớ so với định dạng 16 bit và dành chỗ cho nhiều yêu cầu đồng thời hơn. TensorRT cũng xây dựng engine FP8 cho GPU có Tensor Core FP8. Định dạng này cần được phần cứng hỗ trợ mới phát huy hiệu quả: A100 của NVIDIA chạy FP16, BF16 và INT8 trên Tensor Core nhưng không có đơn vị FP8, trong khi GPU Ada Lovelace, Hopper và Blackwell cùng dòng MI300 của AMD đều hỗ trợ.
FP8 nằm giữa các định dạng lân cận:
- FP16 hay độ chính xác bán phần: Số bit gấp đôi, có 10 bit phần định trị và phạm vi đủ rộng cho hầu hết tác vụ suy luận mà không cần hệ số tỷ lệ theo từng tensor.
- FP4: Số bit giảm một nửa lần nữa, dựa vào hệ số tỷ lệ theo khối chi tiết để duy trì độ chính xác.
- INT8: Định dạng 8 bit còn lại, có 256 mức cách đều nhau thay vì khoảng cách dựa trên số mũ như FP8; vì vậy cần hệ số tỷ lệ được hiệu chỉnh nhưng chạy được trên nhiều phần cứng hơn, bao gồm hầu hết CPU và NPU.
Ultralytics YOLO26 sử dụng INT8 để suy luận 8 bit: xuất model bằng quantize=8 trong chế độ export sang các định dạng như TensorRT và OpenVINO sẽ chạy quy trình lượng tử hóa model sau huấn luyện để hiệu chỉnh hệ số tỷ lệ trên hình ảnh từ bộ dữ liệu data; trong khi đó, model được tinh chỉnh bằng quantize=8 thông qua huấn luyện nhận biết lượng tử hóa sẽ được xuất sang TensorRT với các phạm vi đã học và không cần hiệu chỉnh.










