Nếu mô hình thẩm định GPT-4 Turbo của AlpacaEval sử dụng một kết quả đánh giá mẫu cho mỗi câu trả lời, biên độ sai số của GPT-4o sẽ là ±3,45 điểm. Việc sử dụng năm kết quả đánh giá sẽ giúp sai số này giảm còn ±3,00 điểm, tương đương hiệu quả khi bổ sung thêm 32% số lượng câu hỏi.
Việc chấm điểm mỗi câu trả lời năm lần bằng mô hình thẩm định LLM sẽ làm tăng chi phí thẩm định lên năm lần. Tuy nhiên, trên 805 câu hỏi công khai của AlpacaEval, các dữ liệu xác suất từ chính mô hình cho thấy giải pháp này chỉ thu hẹp biên độ sai số 13%.
Ý tưởng này xuất phát từ Cameron Wolfe, nhà khoa học nghiên cứu tại Netflix. Dựa trên nội dung bài viết, người dùng có thể thực thi một đoạn mã (script) đối với các thang điểm chấm của mô hình để cân nhắc nên chi trả thêm cho các lượt thẩm định hay đầu tư bổ sung các trường hợp kiểm thử (test case).
01 — Nội dung bài thuyết trình
Cameron Wolfe, người đồng thời là tác giả của
Nếu mô hình đánh giá (judge) GPT-4 Turbo của AlpacaEval chỉ lấy mẫu một kết quả đánh giá cho mỗi câu trả lời, biên độ sai số của GPT-4o sẽ là ±3,45 điểm. Khi tăng lên 5 kết quả đánh giá, con số này giảm xuống còn ±3,00 điểm. Việc bổ sung 32% số lượng câu hỏi cũng mang lại kết quả tương tự.
Việc chấm điểm mỗi câu trả lời 5 lần bằng mô hình LLM đánh giá sẽ làm tăng chi phí vận hành lên gấp 5 lần. Dựa trên 805 câu hỏi công khai của AlpacaEval, xác suất do chính mô hình đánh giá đưa ra cho thấy phương pháp này chỉ thu hẹp biên độ sai số được 13%.
Ý tưởng này xuất phát từ Cameron Wolfe, nhà khoa học nghiên cứu kỳ cựu tại Netflix. Dựa trên phương pháp này, người dùng có thể chạy một đoạn mã xử lý trên kết quả chấm điểm của mô hình đánh giá để cân nhắc giữa việc chi trả thêm chi phí cho các lượt đánh giá lặp lại hay bổ sung thêm các trường hợp kiểm thử (test case).
01 — Nội dung bài tham luận
Ông Cameron Wolfe, tác giả của bản tin Deep (Learning) Focus, đã trình bày bài tham luận mang tên “Cách thức Netflix đánh giá AI khi không có đáp án chuẩn” (How Netflix Evaluates AI When There’s No Right Answer), được kênh AI Engineer đăng tải vào ngày 5/11. Nội dung đề cập đến các tác vụ như sáng tạo nội dung văn bản, nơi việc xác định đạt hay không đạt phụ thuộc vào nhận định mang tính chủ quan.
Khung phương pháp luận này gồm ba thành phần:
Đánh giá từ con người đóng vai trò định hướng cốt lõi (North Star). Các chuyên gia soạn thảo hướng dẫn, nhiều chuyên viên cùng chấm điểm trên một tập mẫu, và các tiêu chí sẽ được điều chỉnh tại những điểm chưa đạt được sự đồng thuận.
Mô hình LLM đánh giá và bộ tiêu chí giúp mở rộng quy mô ngoại tuyến (offline). Kết quả của mô hình được đối chiếu với tập điểm chuẩn do con người chấm; mục tiêu đặt ra là mức độ tương đồng giữa mô hình và con người phải tiệm cận mức độ tương đồng giữa người với người.
Thử nghiệm A/B và giám sát trên hệ thống vận hành thực tế giúp kiểm chứng hiệu quả thông qua người dùng cuối. Trong một dự án của Netflix, điểm số từ mô hình LLM đánh giá có mối liên hệ nhân quả với tỷ lệ người xem từ bỏ chương trình.
Luận điểm trọng tâm được tác giả đưa ra là hiện tượng nhiễu: cả mô hình tạo sinh lẫn mô hình LLM đánh giá đều mang tính ngẫu nhiên. Các giải pháp xử lý bao gồm phân tích độ mạnh thống kê (power analysis) để xác định quy mô đánh giá, thiết lập biên độ sai số cho mọi chỉ số, và tái lấy mẫu (resampling) - tức thực hiện nhiều lượt suy luận độc lập từ mô hình hoặc từ hệ thống đánh giá. Dưới đây là phân tích chi tiết về hiệu quả thực tế của kỹ thuật tái lấy mẫu đối với một mô hình đánh giá đã công khai các giá trị xác suất.
02 — Nguồn xác định độ nhiễu thực tế của mô hình đánh giá
Quá trình phân tích đòi hỏi một mô hình đánh giá đã chấm điểm lượng lớn câu hỏi và công bố mức độ chắc chắn của kết quả. Bộ dữ liệu AlpacaEval 2.0 cung cấp đầy đủ thông tin này. Mô hình đánh giá GPT-4 Turbo của hệ thống so sánh câu trả lời của từng mô hình với câu trả lời của chính GPT-4 Turbo trên 805 câu hỏi, đồng thời kho lưu trữ lưu lại xác suất chiến thắng cho từng câu hỏi, được trích xuất từ tỷ lệ xác suất của các token.
Xác suất này là yếu tố cốt lõi giúp tiến hành phép kiểm thử. Cấu hình của mô hình đánh giá yêu cầu xuất một token với mức nhiệt độ (temperature) bằng 1; do đó, nếu mô hình đưa ra giá trị 0,7 cho một câu hỏi, một kết quả đánh giá lấy mẫu tương đương với việc tung một đồng xu có xác suất xuất hiện kết quả "thắng" là 70%. Phương sai tương ứng, 0,7 × 0,3, chính là độ nhiễu nội tại của mô hình đánh giá đối với câu hỏi đó. Trong khi đó, phương sai của các xác suất giữa các câu hỏi phản ánh độ nhiễu bắt nguồn từ tập câu hỏi được lựa chọn ngẫu nhiên.
03 — Hai dạng nhiễu trong đánh giá
Điểm đánh giá là giá trị trung bình trên tập câu hỏi, do đó biên độ sai số bắt nguồn từ hai yếu tố:
+----------+---------------------------------+-----------------------------+
| Nguồn | Bản chất | Biện pháp khắc phục |
+==========+=================================+=============================+
| Tác vụ | Tập câu hỏi được chọn | Tăng số lượng câu hỏi |
| Đánh giá | Tính ngẫu nhiên mỗi lần phán quyét| Tăng số lượt chạy đánh giá |
+----------+---------------------------------+-----------------------------+
Việc chấm điểm mỗi câu trả lời K lần chỉ giúp giảm phương sai phần đánh giá đi K lần, trong khi phương sai phần tác vụ hoàn toàn không thay đổi.
04 — Kịch bản xử lý
judgenoise.py sử dụng thư viện chuẩn của Python 3.8 trở lên. Tệp tin có khả năng đọc tệp annotations.json của AlpacaEval hoặc tệp CSV chứa dữ liệu chấm điểm riêng, phân tách phương sai thành hai thành phần nêu trên, và in ra biên độ sai số tương ứng với từng số lượt chạy đánh giá:
#!/usr/bin/env python3
"""judgenoise.py - tỷ lệ đóng góp của mô hình đánh giá vào biên độ sai số là bao nhiêu?
Cách dùng: judgenoise.py TỆP_TIN [K ...]
TỆP_TIN là tệp annotations.json của AlpacaEval (mức ưu tiên 1..2) hoặc tệp CSV gồm các
dòng tác vụ,điểm số (điểm số 0..1; lặp lại tác vụ theo từng lượt chạy đánh giá).
Giá trị K: số lượt chạy đánh giá trên mỗi câu trả lời cần tính toán chi phí (mặc định 1 2 3 5 10).
Chỉ sử dụng thư viện chuẩn, Python 3.8+."""
import csv, json, math, sys
def load(path):
# trả về [(trung bình tác vụ, phương sai đánh giá
e, runs behind the mean)], basis
if path.endswith(".json"):
rows = json.load(open(path))
# AlpacaEval: mức độ ưu tiên 1 = mô hình cơ sở thắng, 2 = mô hình thử nghiệm thắng
ps = [float(r["preference"]) - 1 for r in rows
if r.get("preference") not in (None, "")]
# Tỷ lệ xác suất nội tại của giám khảo: một phán quyết lấy mẫu có phương sai p(1-p)
return [(p, p * (1 - p), math.inf) for p in ps], "tỷ lệ token của giám khảo"
by = {}
with open(path, newline="") as f:
for i, row in enumerate(csv.reader(f)):
if not row or row[0].startswith("#"):
continue
try:
g = float(row[1])
except (IndexError, ValueError):
if i == 0:
continue # dòng tiêu đề
sys.exit("dòng không hợp lệ %d: %r" % (i + 1, row))
if not 0 <= g <= 1:
sys.exit("điểm số nằm ngoài khoảng 0..1 ở dòng %d" % (i + 1))
by.setdefault(row[0].strip(), []).append(g)
if any(len(v) < 2 for v in by.values()):
sys.exit("mỗi tác vụ cần từ 2 lượt đánh giá trở lên để đo độ nhiễu của giám khảo")
out = []
for v in by.values():
m = sum(v) / len(v)
w = sum((x - m) ** 2 for x in v) / (len(v) - 1)
out.append((m, w, len(v)))
return out, "lượt đánh giá lặp lại"
def main():
if len(sys.argv) < 2:
sys.exit(__doc__.splitlines()[1])
try:
items, basis = load(sys.argv[1])
except OSError as e:
sys.exit("không thể đọc %s: %s" % (sys.argv[1], e.strerror))
if not all(k.isdigit() and int(k) > 0 for k in sys.argv[2:]):
sys.exit("K phải là một số nguyên dương")
ks = [int(k) for k in sys.argv[2:]] or [1, 2, 3, 5, 10]
n = len(items)
if n < 2:
sys.exit("cần ít nhất 2 tác vụ")
mean = sum(m for m, _, _ in items) / n
vj = sum(w for _, w, _ in items) / n # giám khảo: độ phân tán trong cùng một tác vụ
vm = sum((m - mean) ** 2 for m, _, _ in items) / (n - 1)
# giá trị trung bình của tác vụ vẫn chịu độ nhiễu giám khảo qua các lượt chạy; cần loại bỏ
vt = max(vm - sum(w / r for _, w, r in items) / n, 0.0)
tot = vt + vj
if tot == 0:
sys.exit("tất cả điểm số đều giống nhau: không có độ nhiễu để phân tách")
print("số tác vụ %d, điểm số %.1f%%, độ nhiễu giám khảo từ: %s"
% (n, 100 * mean, basis))
print("phương sai từ các tác vụ %.4f, từ giám khảo %.4f (tỷ trọng giám khảo %.0f%%)"
% (vt, vj, 100 * vj / tot))
print(" lượt giám khảo | thanh sai số 95% | 1 lượt chạy tương ứng với")
for k in ks:
part = vt + vj / k
need = math.ceil(n * tot / part)
print(" %10d | +/- %5.2f điểm | %d tác vụ (%+.0f%%)"
% (k, 196 * math.sqrt(part / n), need, 100 * (need / n - 1)))
print(" %10s | +/- %5.2f điểm | mức sàn: độ nhiễu tác vụ được giữ nguyên"
% ("không giới hạn", 196 * math.sqrt(vt / n)))
print("giảm một nửa biên sai số của 1 lượt chạy cần gấp 4 lần số tác vụ (%d); không giá trị K nào đạt được"
% (4 * n) if vt > tot / 4 else
"có thể giảm một nửa biên sai số của 1 lượt chạy khi có thêm")
Nguồn tin: Medium Towards AI — Tác giả: Chew Loong Nian - AI ENGINEER. Bản dịch tiếng Việt do AI thực hiện, có thể có sai sót.