Bắt đầu bằng một đường cơ sở đáp ứng nhu cầu
Hãy chọn một tập ngắn gồm các đầu vào thông thường, các trường hợp biên và các ranh giới quyết định. Cố định mô hình, trọng số, tiền xử lý và chế độ train hay eval. So sánh giữa hai mô hình hay hai batch không cho phép quy sự khác biệt của chúng cho độ chính xác.
Hãy lưu lại đầu ra hữu ích cho ứng dụng của bạn, không chỉ hàm mất mát. Với bộ phân loại, điều đó có thể gồm điểm số và quyết định; với bài toán hồi quy, gồm sai số và các giá trị cực trị. Trước tiên hãy kiểm tra sự hiện diện của NaN hoặc inf trong đường cơ sở. Một lần chạy FP32 sai không trở thành cơ sở đáng tin chỉ vì nó có nhiều bit hơn.
Hãy đặt ngưỡng dung sai, chất lượng tối thiểu và yêu cầu không có giá trị không hữu hạn trước khi thử nghiệm. PyTorch nhắc rằng tính toán dấu phẩy động không đảm bảo kết quả giống hệt nhau giữa các thiết bị hay đường thực thi.
Phân biệt autocast, định dạng số và GradScaler
autocast chọn kiểu của một số phép toán tùy theo chính sách tính toán của chúng. Nó không chuyển toàn bộ chương trình sang một định dạng duy nhất. Với cách dùng này, hãy tránh chuyển đổi thủ công toàn bộ mô hình bằng half(). Tài liệu hiện hành khuyến nghị torch.autocast hoặc torch.amp.autocast; các giao diện cũ torch.cuda.amp đã bị ngừng hỗ trợ.
GradScaler tác động lên thang của loss và gradient trong quá trình huấn luyện. Nó không được dùng như một công cụ tăng tốc suy luận, vì suy luận không thực hiện backward. FP16 có dải số hạn chế hơn BF16; một mô hình được thiết kế cho BF16 có thể tràn khi dùng FP16. Do đó, việc thang giảm liên tục không chứng minh rằng vấn đề đã được giải quyết.
Hãy chọn định dạng dựa trên các ràng buộc của mô hình và những phép toán thực sự được dùng, rồi kiểm tra khả năng hỗ trợ của mục tiêu. Tên thương mại của một card hay sở thích chuẩn bị PyTorch không chứng minh rằng toán tử tùy chỉnh của bạn có nhân mong muốn.
Cuộn bảng để xem tất cả các cột.| Lựa chọn | Vai trò | Kiểm tra cần thiết |
|---|---|---|
| Tham chiếu FP32 | Điểm so sánh của dự án | Đầu ra hữu hạn và chất lượng mong đợi |
| Autocast FP16 | Một số phép toán ở độ chính xác rút gọn | Dải số và gradient |
| Autocast BF16 | Cân nhắc khác giữa dải và độ chính xác | Các toán tử khả dụng và chất lượng |
| GradScaler | Quản lý thang gradient | Các cập nhật thực sự được thực hiện |
Đặt các bước huấn luyện đúng thứ tự
Đoạn mã đề xuất giả định mô hình và optimizer đã được dựng sẵn, đầu vào và mục tiêu nằm trên cùng một GPU, và loss là scalar. Nó chưa được chạy và không phải là sự xác nhận cho một dịch vụ nào. Ngữ cảnh autocast bao quanh forward và loss; backward diễn ra sau khi ngữ cảnh đóng lại. Scaler được tạo một lần cho phiên huấn luyện, không phải cho từng batch.
Để kiểm tra hoặc cắt gradient, trước tiên hãy gỡ hệ số thang của chúng bằng unscale_. Các ví dụ AMP chính thức nêu rõ chỉ làm việc này một lần cho mỗi optimizer và sau khi đã tích lũy các gradient dành cho việc cập nhật của nó. Ngưỡng cắt 1.0 dưới đây là giá trị minh họa cần chọn cho dự án của bạn, không phải khuyến nghị phổ quát.
Các guard ở đây dừng việc chẩn đoán nếu loss, gradient hay norm tổng không hữu hạn. Những lần đọc trên CPU này gây ảnh hưởng: đừng đo thời gian đoạn mã này. Việc tích lũy, nhiều optimizer và scheduler đòi hỏi định nghĩa riêng cho bước cập nhật.
import torch
# Điều kiện tiên quyết: model, optimizer, loss_fn, inputs và targets đã tồn tại.
# Mô hình và đầu vào nằm trên cùng thiết bị CUDA/HIP.
dtype = torch.float16 # Lựa chọn cần xác nhận; BF16 là một thử nghiệm khác.
scaler = torch.amp.GradScaler("cuda", enabled=(dtype == torch.float16))
# Đặt trong vòng lặp của bạn, giữ scaler qua các batch.
optimizer.zero_grad(set_to_none=True)
with torch.autocast(device_type="cuda", dtype=dtype):
prediction = model(inputs)
loss = loss_fn(prediction, targets)
if not bool(torch.isfinite(loss).item()):
raise FloatingPointError("Loss không hữu hạn: dừng chẩn đoán")
scaler.scale(loss).backward()
scaler.unscale_(optimizer)
if any(p.grad is not None and
not bool(torch.isfinite(p.grad).all().item())
for p in model.parameters()):
raise FloatingPointError("Gradient không hữu hạn: dừng chẩn đoán")
torch.nn.utils.clip_grad_norm_(
model.parameters(), max_norm=1.0, error_if_nonfinite=True,
)
scaler.step(optimizer)
scaler.update()Ví dụ minh họa: hai quyết định gần nhau không thể thay thế cho nhau
Giả sử một dịch vụ chọn lớp có điểm cao nhất. Trên một đầu vào minh họa, tham chiếu tạo ra hai điểm rất gần nhau: 1,0000 và 1,0003. Một đường tính toán số khác có thể thay đổi thứ tự của chúng hoặc tạo ra thế hòa. Những con số này minh họa một ranh giới quyết định; chúng không phải là đầu ra đo được của FP16 hay BF16.
Việc kiểm tra đúng đắn gồm hai mức. Hãy so sánh các điểm với dung sai rõ ràng, rồi so sánh quyết định và quy tắc áp dụng cho các trường hợp hòa. Một khác biệt nhỏ về giá trị tuyệt đối có thể thay đổi hành động được chọn. Ngược lại, một khác biệt số nhìn thấy được có thể không gây hậu quả cho một tác vụ có ngưỡng nằm xa các điểm quan sát được.
Ghi lại số liệu nhận dạng, kết quả tham chiếu, thử nghiệm AMP và tác động lên quyết định. Đặt quy tắc chấp nhận trước khi đọc kết quả. Đừng nới rộng dung sai để làm biến mất một trường hợp khó chịu; các kết quả ở thang đo khác nhau có thể cần tiêu chí riêng.
Cuộn bảng để xem tất cả các cột.| Tiêu chí | Mã tham chiếu | Thử nghiệm AMP | Quyết định |
|---|---|---|---|
| Kết quả hoàn chỉnh | Cần kiểm tra | Cần kiểm tra | Từ chối các kết quả chưa hoàn chỉnh không rõ nguyên nhân |
| Sai lệch số học | Giá trị được giữ lại | Sai lệch cần tính | Dung sai định trước khi thử |
| Quyết định ứng dụng | Lớp hoặc hành động | Lớp hoặc hành động | Xem xét các thay đổi |
| Chất lượng trên bộ dữ liệu cố định | Cần đo | Cần đo | Tuân thủ ngưỡng của dự án |
Diễn giải NaN và các cập nhật bị bỏ qua
Khi xuất hiện các giá trị không hữu hạn, hãy tìm bước đầu tiên tạo ra chúng: đầu vào, đầu ra trung gian, loss hay gradient. Chạy lại cùng trường hợp ở chế độ tham chiếu, rồi tạm tắt autocast cục bộ quanh phép toán nghi ngờ, đồng thời kiểm tra cả kiểu dữ liệu của đầu vào. Chuyển toàn bộ quá trình huấn luyện về FP32 có thể dùng để so sánh, nhưng không tự động khoanh vùng được vấn đề.
Scaler có thể bỏ qua một cập nhật khi gradient chứa inf hoặc NaN. Vì vậy, một vòng lặp tiếp tục chạy không nhất thiết đã thực hiện số cập nhật bằng số vòng lặp. Hãy ghi lại hành vi này trong quá trình chẩn đoán. Đừng mù quáng cho rằng một chính sách học tập tiến triển theo số cập nhật thực tế.
Loss hữu hạn không đảm bảo gradient hữu hạn. Ngược lại, một sự cố đơn lẻ không đủ để kết luận quá trình huấn luyện không dùng được: hãy xem xét tần suất, tiến độ và chất lượng. Công thức AMP cung cấp phương pháp để tách riêng autocast và scaling khi một trong hai bị nghi ngờ.
Chuẩn bị khả năng quay lui có thể tái lập
Trước khi thử, hãy giữ lại cấu hình tham chiếu, trọng số, trạng thái optimizer và một checkpoint nhất quán. Nếu quá trình huấn luyện của bạn dùng scaler, trạng thái của nó cũng là một phần của việc khôi phục. Ghi lại dtype và các vùng có thể vẫn ở FP32. Khôi phục với một chính sách khác là một thay đổi thử nghiệm cần được nhận diện, chứ không phải là sự tiếp nối tương đương ngầm định.
Hãy quay lại cấu hình trước đó nếu kết quả trở nên không hữu hạn, nếu chất lượng vượt ra ngoài tiêu chí đã đặt hoặc nếu các cập nhật ngừng tiến triển ở mức có thể khai thác. Giữ lại trường hợp đã dẫn đến việc quay lui này. Sau một thay đổi, hãy bắt đầu lại so sánh trên cùng bộ dữ liệu trước khi kéo dài thời gian.
Bài tập Kernodeck về checkpoint kiểm tra việc khôi phục trên CPU không có AMP. Hãy tái sử dụng phương pháp so sánh của bài đó, bổ sung các trạng thái mà vòng lặp của bạn thực sự tiêu thụ.
Chỉ đo lợi ích sau khi đã kiểm chứng số học
Sau khi kiểm chứng, hãy đo bộ nhớ và thời gian mà không bật chẩn đoán chi tiết. Giữ nguyên hình dạng, batch, mô hình và chất lượng. Việc đọc scalar, đồng bộ và profiler có thể làm thay đổi thời lượng; hãy loại bỏ các kiểm tra xâm nhập khỏi phép đo cuối cùng.
Trên ROCm, tên thiết bị của PyTorch vẫn là cuda và các giao diện tương ứng được tái sử dụng. Điều này không đảm bảo cùng kernel hay kết quả giống hệt NVIDIA. Hãy kiểm tra backend và các toán tử của dự án trên mục tiêu. Hướng dẫn này không công bố bất kỳ mức giảm bộ nhớ cố định, hệ số tăng tốc hay khả năng tương thích chuẩn bị Kernodeck nào.