Một báo cáo ghi pass@1 và pass@10 cho cùng một model. Điểm thứ hai cao hơn không có nghĩa mỗi lần gọi model đã đáng tin cậy hơn. Hai con số cho phép ngân sách thử khác nhau và phải được đọc cùng cách đánh giá.
Bài dành cho developer đang đọc kết quả sinh code hoặc xây bộ đánh giá nội bộ. Đối chiếu ngày 01/11/2026 với paper HumanEval năm 2021 và mã đánh giá đi kèm. Ví dụ chỉ tính toán trên số đếm tự đặt, không chạy model hoặc thực thi chương trình do model sinh.
Repository hiện được đánh dấu ngừng bảo trì; bài dùng nó như tài liệu lịch sử cho công thức.
1. Một bài toán có nhiều mẫu code
Trong cách đánh giá đang tham chiếu, một task được xem là đạt trong k mẫu nếu ít nhất một mẫu vượt bộ kiểm thử. Để ước lượng, ta sinh n mẫu cho task đó, đếm c mẫu vượt kiểm thử, với n lớn hơn hoặc bằng k.
Điểm pass@k không tự chọn giúp bạn mẫu đúng khi triển khai. Nếu sản phẩm chỉ hiển thị một câu trả lời mà không có bộ kiểm thử hay cơ chế chọn ứng viên, không nên lấy pass@10 làm tỷ lệ thành công của một câu trả lời được hiển thị.
“Đạt” cũng phụ thuộc bộ kiểm thử. Test còn thiếu tình huống biên có thể cho mẫu sai đi qua. Khi so sánh hai hệ thống, giữ rõ tập task, test, timeout, cấu hình sinh và số mẫu, thay vì chỉ chụp một điểm số cuối.
2. Công thức dùng số đếm
Với một task, công thức trong HumanEval là 1 - C(n-c, k) / C(n, k). Phần bị trừ là tỷ lệ các tập k mẫu chỉ gồm mẫu không đạt, khi xét chọn không hoàn lại từ n mẫu đã có.
Đây là cách hiểu tổ hợp của estimator, không phải yêu cầu sản phẩm phải chọn mẫu theo cách đó. Paper trình bày tính không chệch dưới giả định lấy mẫu của đánh giá. Những mẫu bị sao chép nhiều lần hoặc bộ chọn tùy biến cần được mô tả riêng, không tự có cùng ý nghĩa thống kê.
from math import comb, isclose
def estimate_pass_at_k(n, c, k):
if not all(type(value) is int for value in (n, c, k)):
raise ValueError("n, c, k phải là số nguyên")
if n < 1 or not 0 <= c <= n or not 1 <= k <= n:
raise ValueError("cần 0 <= c <= n và 1 <= k <= n")
if n - c < k:
return 1.0
return 1.0 - comb(n - c, k) / comb(n, k)
assert isclose(estimate_pass_at_k(10, 2, 1), 0.2)
assert isclose(estimate_pass_at_k(10, 2, 3), 8 / 15)
assert estimate_pass_at_k(10, 0, 3) == 0.0
assert estimate_pass_at_k(10, 10, 3) == 1.0
print(round(estimate_pass_at_k(10, 2, 3), 6))
Đoạn này đã chạy bằng Python 3.9.6, in 0.533333. Các số 10 và 2 là fixture, không phải kết quả đo một model. Với số lượng lớn, mã gốc dùng cách tính tích để tránh thao tác tổ hợp trực tiếp; ví dụ ngắn ở đây ưu tiên đọc được công thức.
3. Không thay bằng một phép lũy thừa tùy tiện
Nếu lấy tỷ lệ c/n bằng 0,2 rồi tính 1 - (1 - 0.2) ** 3, bạn được 0,488. Con số này khác 0,533333 của estimator trên cùng số đếm. Paper giải thích vì sao thay xác suất thật bằng tỷ lệ quan sát trong biểu thức đó tạo ra một estimator khác có độ chệch.
Không cần suy từ sự khác nhau này rằng mẫu code “tốt hơn 4,5%”. Đó là hai phép tính khác trên cùng fixture. Trước khi diễn giải sự thay đổi điểm, cần biết công thức nào đã được dùng và dữ liệu đánh giá được thu thế nào.
4. Tính theo từng task rồi tổng hợp
Mã HumanEval tính estimator cho từng task rồi lấy trung bình. Đừng gộp mọi mẫu đúng và sai của các task thành một c và n duy nhất: một task được lấy nhiều mẫu hơn có thể làm cách gộp thay đổi trọng số.
Chỉ báo k khi mọi task trong phạm vi báo cáo có đủ n ≥ k. Nếu một task mới có hai mẫu, không tự gán pass@10 bằng 1 hoặc loại task đó mà không ghi rõ. Có thể giảm k cho báo cáo hiện tại hoặc bổ sung mẫu theo kế hoạch đánh giá.
Kiểm tra và giới hạn
Hãy thử c bằng 0, c bằng n, k bằng 1 và k lớn hơn n. Code minh họa từ chối đầu vào ngoài phạm vi; nó chưa cung cấp khoảng tin cậy hay đánh giá model. Lưu số đếm từng task để có thể tính lại khi phát hiện lỗi test.
Khi đọc pass@k, hãy hỏi đồng thời “k bằng bao nhiêu” và “mẫu được xác nhận đúng bằng cách nào”. Hai thông tin đó quyết định điểm số có liên quan tới trải nghiệm một lần dùng trong sản phẩm của bạn hay không.

