5Tính lặp lại của thí nghiệm#
Giả sử mô hình đang chạy trong sản xuất bắt đầu cho kết quả lạ, và ta muốn biết nguyên nhân. Việc đầu tiên là dựng lại đúng mô hình đó từ cùng mã, cùng dữ liệu và cùng cấu hình, rồi so sánh với các phiên bản khác. Nếu chạy lại huấn luyện mà ra một mô hình khác, việc điều tra gần như không thể bắt đầu. Chương này bàn về những gì cần làm để kết quả huấn luyện lặp lại được, và hai công cụ để ghi lại quá trình đó: theo dõi thí nghiệm và sổ đăng ký mô hình.
5.1Tái lập, tái tạo và tính bền#
Cụm từ "lặp lại được" thường được dùng cho ba yêu cầu khác nhau, nên cần tách chúng ra.
Yêu cầu chặt nhất là tái lập (reproducibility): chạy lại với cùng mã, cùng dữ liệu, cùng môi trường thì được cùng kết quả. Đây là yêu cầu bắt buộc để điều tra sự cố. Yêu cầu thứ hai là tái tạo (replicability): một người khác, trong một môi trường khác, làm lại được một kết quả tương tự; điều này cần cho hợp tác và kiểm toán. Yêu cầu thứ ba là tính bền (robustness) của kết luận: đổi hạt giống ngẫu nhiên hoặc đổi cách chia dữ liệu mà kết luận vẫn giữ nguyên. Các tài liệu dùng hai từ reproducibility và replicability không thống nhất, có nơi dùng theo nghĩa ngược lại; giáo trình dùng theo nghĩa vừa nêu.
Sculley và cộng sự (2015) gọi việc không đạt được yêu cầu thứ nhất là một dạng nợ (reproducibility debt) và chỉ ra bốn nguyên nhân: thuật toán có yếu tố ngẫu nhiên, tính bất định vốn có của huấn luyện song song, sự phụ thuộc vào điều kiện khởi tạo, và tương tác với thế giới bên ngoài.
Yêu cầu thứ ba hay bị bỏ qua nhất, dù nó ảnh hưởng trực tiếp tới các quyết định. Giả sử một thay đổi làm độ chính xác tăng 0,3 điểm phần trăm. Nếu hai lần chạy chỉ khác hạt giống ngẫu nhiên đã chênh nhau 0,5 điểm, mức cải thiện 0,3 điểm không nói lên điều gì. Trước khi kết luận mô hình mới tốt hơn, cần chạy vài hạt giống cho cả hai mô hình và so sánh mức chênh lệch với độ dao động đó. Khi hai mô hình được chấm trên cùng một tập kiểm tra, nên dùng so sánh ghép cặp, như kiểm định McNemar trình bày ở Mục 12.4 của Ứng dụng LLM.
5.2Cố định nguồn ngẫu nhiên và môi trường#
Để đạt được tái lập, phải cố định đủ sáu nhóm yếu tố; chỉ cần thiếu một nhóm là hai lần chạy có thể cho kết quả khác nhau. Với PyTorch, phần cố định trong mã trông như sau:
import os, random
import numpy as np
import torch
S = 1207
# 1. Hạt giống cho mọi nguồn ngẫu nhiên, không chỉ một
random.seed(S); np.random.seed(S); torch.manual_seed(S)
torch.cuda.manual_seed_all(S)
# 2. Phép toán tất định (chậm hơn)
os.environ["CUBLAS_WORKSPACE_CONFIG"] = ":4096:8" # cần cho một số phép cuBLAS
torch.use_deterministic_algorithms(True) # báo lỗi nếu phép toán không có bản tất định
torch.backends.cudnn.benchmark = False # không chọn thuật toán theo đo thời gian
# 3. Thứ tự dữ liệu và các tiến trình con của DataLoader
def seed_worker(worker_id):
s = torch.initial_seed() % 2**32
np.random.seed(s); random.seed(s)
g = torch.Generator(); g.manual_seed(S)
loader = torch.utils.data.DataLoader(ds, shuffle=True, num_workers=4,
worker_init_fn=seed_worker, generator=g)
# 4. Phiên bản: mã (commit), dữ liệu (hash), thư viện (lockfile), ảnh container (digest)
# 5. Cấu hình: một tệp duy nhất, lưu cùng kết quả
# 6. Phần cứng: loại GPU và số GPU
Ba chi tiết trong đoạn mã này thường bị bỏ sót. Chi tiết đầu tiên là các tiến trình con của DataLoader. Khi num_workers > 0, mỗi worker là một tiến trình riêng. PyTorch tự đặt hạt giống cho bộ sinh số ngẫu nhiên của torch trong mỗi worker, nhưng các thư viện khác mà hàm tăng cường dữ liệu dùng tới, như NumPy hay random, thì không chắc được đặt đúng. Tài liệu của PyTorch khuyến nghị đặt hạt giống cho chúng trong worker_init_fn, như hàm seed_worker ở trên.
Chi tiết thứ hai là số GPU. Đổi từ 4 sang 8 GPU mà giữ nguyên kích thước lô trên mỗi GPU thì kích thước lô hiệu dụng tăng gấp đôi, tức là đã thay đổi bài toán tối ưu. Ngay cả khi điều chỉnh để giữ nguyên kích thước lô hiệu dụng, thứ tự cộng gradient giữa các GPU thay đổi, và vì phép cộng số thực dấu phẩy động không có tính kết hợp, kết quả khác đi ở những chữ số cuối. Vì vậy số GPU nên được coi như một siêu tham số và được ghi lại.
Chi tiết thứ ba là cudnn.benchmark. Khi bật, cuDNN chọn thuật toán tích chập nhanh nhất bằng cách đo thời gian chạy thử, và kết quả đo phụ thuộc vào tải của máy lúc đó, nên hai lần chạy có thể dùng hai thuật toán khác nhau.
Tính tất định hoàn toàn trên GPU không miễn phí: nhiều phép toán có phiên bản tất định chậm hơn đáng kể. Cách làm phổ biến là bật chế độ tất định khi điều tra sự cố hoặc khi chạy kiểm thử hồi quy, còn khi huấn luyện thường ngày thì chấp nhận dao động nhỏ và kiểm tra tính bền bằng cách chạy nhiều hạt giống (Mục 5.1).
5.3Theo dõi thí nghiệm#
Theo dõi thí nghiệm (experiment tracking) là việc ghi lại mỗi lần huấn luyện cùng mọi thông tin liên quan. Nguyên tắc là ghi đủ để dựng lại được thí nghiệm, chứ không chỉ đủ để so sánh các thí nghiệm với nhau. Tối thiểu cần ghi bốn nhóm thông tin: đầu vào (commit của mã, hash của dữ liệu, tệp cấu hình đầy đủ, ảnh container); quá trình (đường cong hàm mất mát, learning rate theo từng bước, tài nguyên sử dụng, thời gian chạy); đầu ra (các chỉ số tính theo lát cắt như ở Mục 6.3, ma trận nhầm lẫn, tệp mô hình kèm hash); và ngữ cảnh (ai chạy, khi nào, để kiểm tra giả thuyết gì).
Các công cụ như MLflow hay Weights & Biases tự động ghi được ba nhóm đầu. Nhóm thứ tư thường bị bỏ trống vì không công cụ nào điền thay con người được, nhưng nó lại có giá trị riêng: nếu giả thuyết được viết ra trước khi chạy, không thể dựng lên một lời giải thích sau khi đã thấy kết quả, thói quen mà Mục 2.5 đã nhắc tới.
5.4Sổ đăng ký mô hình#
Theo dõi thí nghiệm ghi lại mọi lần huấn luyện, kể cả những lần thất bại. Sổ đăng ký mô hình (model registry) chỉ ghi những mô hình có khả năng được đưa vào sử dụng, và quản lý vòng đời của chúng. Mỗi mô hình trong sổ có một định danh, và sổ phải trả lời được các câu hỏi: mô hình này được huấn luyện từ commit nào, dữ liệu nào, cấu hình nào; nó đã qua những bước kiểm định nào, với kết quả ra sao; nó đang ở trạng thái nào (ví dụ staging, production hay archived) và ai đã duyệt; phiên bản nào đang thực sự chạy trong sản xuất, và nếu cần quay lui thì quay về phiên bản nào.
Câu hỏi cuối cùng là lý do chính để có sổ đăng ký, vì yếu tố phiên bản ở Mục 2.2 tồn tại để quay lui được. Shankar và cộng sự ghi nhận hai thực hành đi kèm: giữ các phiên bản cũ làm mô hình dự phòng, và duy trì một lớp quy tắc đơn giản (heuristic) phía sau mô hình, để khi mô hình hỏng thì hệ thống chuyển sang một hành vi tuy đơn giản nhưng đoán trước được.
Mỗi mô hình trong sổ đăng ký nên kèm một thẻ mô hình (model card), theo đề xuất của Mitchell và cộng sự (2019). Thẻ mô hình ghi mục đích sử dụng, những trường hợp không nên dùng, dữ liệu huấn luyện, và kết quả đánh giá tách theo các nhóm liên quan. Nó biến những hiểu biết vốn chỉ nằm trong đầu người huấn luyện thành tài liệu đi cùng mô hình.
5.5Tóm tắt#
Để điều tra sự cố, phải dựng lại được đúng mô hình đã huấn luyện. Điều đó đòi hỏi cố định hạt giống của mọi nguồn ngẫu nhiên, dùng phép toán tất định khi cần, và ghi lại phiên bản của mã, dữ liệu, thư viện, cấu hình và phần cứng. Theo dõi thí nghiệm ghi lại mọi lần chạy kèm giả thuyết của nó, còn sổ đăng ký mô hình quản lý các mô hình được đưa vào sử dụng và cho phép quay lui. Ngoài ra, trước khi tin vào một cải thiện nhỏ, cần kiểm tra nó có bền với hạt giống và cách chia dữ liệu không.
Có một mô hình tái lập được vẫn chưa có nghĩa là nó đủ tốt để triển khai. Chương 6 bàn về cách đánh giá một mô hình trước khi đưa nó tới người dùng.
Tự kiểm tra
4 câu. Chọn đáp án để xem ngay lời giải thích.
1Vì sao
cudnn.benchmark = Truelàm mất tính tất định?Vì sao: Cùng với các tiến trình con của DataLoader và số GPU, đây là những điểm hay bị bỏ sót khi cố định các yếu tố để tái lập kết quả.2Đổi từ 4 sang 8 GPU mà giữ nguyên kích thước lô trên mỗi GPU thì điều gì thay đổi?
Vì sao: Vì vậy số GPU là một siêu tham số. Ngay cả khi giữ kích thước lô hiệu dụng, thứ tự cộng gradient thay đổi, và vì phép cộng số thực dấu phẩy động không có tính kết hợp, kết quả khác đi ở những chữ số cuối.3Ghi lại giả thuyết cần kiểm tra trước khi chạy thí nghiệm giúp tránh thói quen xấu nào?
Vì sao: Nếu giả thuyết được ghi lại trước khi chạy, không thể gắn một lời giải thích vào sau khi đã thấy kết quả.4Thẻ mô hình (model card) chứa những thông tin gì?
Vì sao: Mitchell và cộng sự (2019) đề xuất thẻ mô hình để những hiểu biết về mô hình không chỉ nằm trong đầu người huấn luyện mà đi cùng mô hình trong sổ đăng ký.
Đã trả lời 0/4