Direct Preference Optimization
Tối ưu hóa sở thích trực tiếp (DPO) căn chỉnh model ngôn ngữ với các cặp phản hồi được ưu tiên và bị từ chối bằng một hàm loss, không cần model phần thưởng hay RL.
Tối ưu hóa ưu tiên trực tiếp (DPO) là phương pháp căn chỉnh model ngôn ngữ lớn (LLM) với sở thích của con người bằng cách huấn luyện trực tiếp trên các cặp câu trả lời, một câu được ưu tiên và một câu bị từ chối, sử dụng một hàm mất mát dạng phân loại duy nhất. Phương pháp này đạt mục tiêu của học tăng cường từ phản hồi của con người (RLHF) mà không cần model phần thưởng riêng biệt hoặc vòng lặp học tăng cường lấy mẫu từ model trong quá trình huấn luyện. Rafael Rafailov, Archit Sharma, Eric Mitchell, Stefano Ermon, Christopher Manning và Chelsea Finn tại Stanford giới thiệu phương pháp này vào năm 2023 trong bài báo Tối ưu hóa ưu tiên trực tiếp: Model ngôn ngữ của bạn thực chất là một model phần thưởng, được trình bày tại NeurIPS 2023. Ý tưởng cốt lõi là model ngôn ngữ đang được huấn luyện tự xác định phần thưởng ẩn của chính nó, do đó model phần thưởng và policy được khớp trong một bước.
Cách DPO hoạt động#
Mỗi ví dụ huấn luyện gồm một prompt, một câu trả lời được chọn và một câu trả lời bị từ chối, do con người hoặc model khác gán nhãn. Quá trình huấn luyện bắt đầu từ một model đã trải qua tinh chỉnh có giám sát, thường là tinh chỉnh theo chỉ dẫn, và giữ một bản sao cố định làm model tham chiếu. Với mỗi câu trả lời, DPO so sánh log-probability theo model đang huấn luyện với log-probability theo model tham chiếu. Phần thưởng ẩn của câu trả lời bằng β nhân với log-ratio đó; hàm mất mát là log-sigmoid âm của phần thưởng cho câu trả lời được chọn trừ đi phần thưởng cho câu bị từ chối. Tối thiểu hóa hàm này làm tăng xác suất của câu trả lời được chọn so với câu bị từ chối, với các cập nhật lớn hơn cho những cặp mà model vẫn xếp hạng sai.
Hệ số β đóng vai trò như mức phạt KL trong RLHF. Rafailov và cộng sự chứng minh rằng bài toán tối đa hóa phần thưởng có ràng buộc KL được dùng trong RLHF có policy tối ưu dạng đóng: xác suất tham chiếu được tái trọng số theo hàm mũ của phần thưởng chia cho β; sau đó họ biến đổi công thức để biểu diễn phần thưởng thông qua chính policy. β càng nhỏ thì quá trình huấn luyện có thể đưa model đi càng xa model tham chiếu.
Ví dụ PyTorch này chạy mười bước DPO trên GPT-2 từ Transformers của Hugging Face, sử dụng hai cặp ưu tiên trong dịch vụ khách hàng, sau đó kiểm tra cặp thứ ba mà model chưa từng được huấn luyện:
import copy
import torch
import torch.nn.functional as F
from transformers import AutoModelForCausalLM, AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("gpt2")
policy = AutoModelForCausalLM.from_pretrained("gpt2")
reference = copy.deepcopy(policy).requires_grad_(False) # frozen copy of the starting model
optimizer = torch.optim.Adam(policy.parameters(), lr=1e-5)
# Preference pairs: (prompt, chosen reply, rejected reply)
train = [
("My order arrived broken.", " Sorry about that, we will send a replacement today.", " That is not our problem."),
("I was charged twice.", " Sorry for the trouble, we have refunded the extra charge.", " Check your bank again."),
]
held_out = ("My package is a week late.", " Sorry for the delay, we will track it down for you.", " Be more patient.")
def log_prob(model, prompt, reply):
"""Sum of the log-probabilities the model gives the reply tokens after the prompt."""
ids = tokenizer(f"Customer: {prompt}\nAgent:{reply}", return_tensors="pt").input_ids
token_logps = model(ids).logits[0, :-1].log_softmax(-1).gather(1, ids[0, 1:, None])
return token_logps[-len(tokenizer(reply).input_ids) :].sum()
def margin(prompt, chosen, rejected):
"""Policy-to-reference log-ratio of the chosen reply minus that of the rejected reply."""
chosen_ratio = log_prob(policy, prompt, chosen) - log_prob(reference, prompt, chosen)
return chosen_ratio - (log_prob(policy, prompt, rejected) - log_prob(reference, prompt, rejected))
for step in range(10):
loss = sum(-F.logsigmoid(0.1 * margin(*pair)) for pair in train) / len(train) # DPO loss, beta = 0.1
if step in {0, 9}:
print(f"Step {step}: training loss {loss.item():.3f}")
optimizer.zero_grad()
loss.backward()
optimizer.step()
with torch.no_grad():
print(f"Held-out margin: {margin(*held_out).item():+.1f}")Ở bước 0, hàm in ra loss huấn luyện là 0.693, tức ln 2, vì policy vẫn giống model tham chiếu và cả hai câu trả lời đều có phần thưởng ẩn bằng không. Đến bước 9, loss là 0.047, còn margin trên cặp giữ lại để đánh giá là +7.8: với một khiếu nại chưa từng gặp, model tăng log-probability của lời hồi đáp xin lỗi so với model tham chiếu nhiều hơn 7.8 so với lời hồi đáp thờ ơ.
DPO so với RLHF#
RLHF cổ điển huấn luyện một model phần thưởng trên các cặp ưu tiên rồi tối ưu model ngôn ngữ dựa trên model đó bằng Tối ưu hóa Chính sách Gần (PPO), phương pháp cần lấy mẫu mới từ model ở mỗi bước và giữ policy, model giá trị, model phần thưởng cùng model tham chiếu trong bộ nhớ. DPO chỉ cần policy và model tham chiếu, đồng thời huấn luyện trên tập dữ liệu cố định như học có giám sát thông thường, nên dễ tinh chỉnh hơn và chi phí vận hành thấp hơn nhiều. Trong các thử nghiệm ban đầu, DPO vượt trội hơn PPO trong việc kiểm soát sắc thái cảm xúc của các bài đánh giá phim được tạo ra với cùng ngân sách KL. Trên tác vụ tóm tắt Reddit TL;DR, GPT-4 đánh giá bản tóm tắt DPO tốt hơn tài liệu tham chiếu do con người viết trong 61% trường hợp ở nhiệt độ lấy mẫu 0, so với 57% của PPO tại nhiệt độ tốt nhất. Trên dữ liệu hội thoại hữu ích và vô hại của Anthropic, DPO là phương pháp duy nhất được thử nghiệm có hiệu quả tính toán và cải thiện được các câu trả lời ưu tiên trong tập dữ liệu.
Đánh đổi là DPO chỉ học từ các cặp được cung cấp. Các phương pháp RL trực tuyến như Tối ưu hóa chính sách tương đối theo nhóm (GRPO) chấm điểm các mẫu mới từ model hiện tại trong quá trình huấn luyện, nhờ vậy chúng chiếm ưu thế trong học tăng cường với phần thưởng có thể kiểm chứng (RLVR) cho toán học và mã nguồn, nơi bộ kiểm tra có thể chấm điểm mọi câu trả lời mới. Nhãn ưu tiên cũng có thể do một model AI tạo ra dựa trên các nguyên tắc được viết sẵn, như trong AI Hiến pháp; DPO huấn luyện trên những nhãn đó theo cùng cách.
Ứng dụng của DPO#
DPO đã trở thành một bước hậu huấn luyện tiêu chuẩn cho chatbot có trọng số mở. Zephyr-7B-β của Hugging Face đã áp dụng DPO cho dữ liệu UltraFeedback được AI xếp hạng, còn các model Llama 3 của Meta được căn chỉnh qua nhiều vòng fine-tuning có giám sát, sau đó là DPO. Thư viện TRL cung cấp sẵn một trainer DPO. Giao diện LLM của Ultralytics gọi các model thông qua mọi endpoint tương thích với OpenAI, bao gồm cả server cục bộ, nhờ đó một model mở được căn chỉnh bằng DPO có thể tạo phần văn bản trong pipeline thị giác Ultralytics YOLO26.
Phương pháp này cũng áp dụng được cho hình ảnh. Diffusion-DPO viết lại hàm mất mát cho model diffusion và tinh chỉnh model nền Stable Diffusion XL trên 851.000 cặp ưu tiên do cộng đồng đóng góp từ tập dữ liệu Pick-a-Pic, cải thiện độ bám sát prompt và tính hấp dẫn thị giác trong quá trình tạo văn bản thành hình ảnh. Với model thị giác-ngôn ngữ (VLM), RLHF-V thu thập các chỉnh sửa của con người ở cấp độ phân đoạn đối với mô tả hình ảnh bị ảo giác và huấn luyện bằng biến thể DPO dày đặc, giảm tỷ lệ ảo giác của model nền 34.8% chỉ với 1.400 mẫu được gán nhãn.
Các biến thể DPO#
- IPO (Tối ưu hóa ưu tiên đồng nhất): Thay log-sigmoid bằng hàm mất mát bình phương hướng đến một margin cố định, ngăn phần thưởng ẩn tăng vô hạn và tránh overfit khi cùng một câu trả lời luôn thắng.
- KTO (Tối ưu hóa Kahneman-Tversky): Học từ từng câu trả lời riêng lẻ được gán nhãn là mong muốn hoặc không mong muốn, do đó không cần so sánh theo cặp.
- ORPO (Tối ưu hóa ưu tiên tỷ số odds): Loại bỏ model tham chiếu và thêm mức phạt tỷ số odds vào loss tinh chỉnh có giám sát, gộp tinh chỉnh theo chỉ dẫn và căn chỉnh ưu tiên thành một giai đoạn.
- SimPO (Tối ưu hóa ưu tiên đơn giản): Dùng log-probability trung bình đã chuẩn hóa theo độ dài của câu trả lời làm phần thưởng, loại bỏ model tham chiếu và yêu cầu margin mục tiêu giữa phần thưởng của câu được chọn và câu bị từ chối.










