# Hướng Dẫn Về Huấn Luyện Hậu Kỳ Bằng Học Tăng Cường Cho LLM: PPO, DPO, GRPO Và Hơn Thế Nữa
# Dịch thuật ngữ và nội dung kỹ thuật
**Trạng thái** $s_t$: Ngữ cảnh hiện tại, bao gồm prompt gốc của người dùng và tất cả các token đã được sinh ra cho đến thời điểm đó.
Ví dụ: Prompt: "The sky is..." → Trạng thái: ["The", "sky", "is"] trong không gian token.
**Hành động** $a_t$: Token tiếp theo được sinh ra.
**Chính sách** $\pi_\theta$: Bản thân LLM. Về bản chất, đây là một phân phối xác suất trên toàn bộ từ vựng cho trước một trạng thái $s_t$.
Ví dụ: $\pi_\theta(\text{"blue"} | [\text{"The", "sky", "is"}]) = 0.87$
**Quỹ đạo** $\tau$: Toàn bộ cuộc hội thoại. Chuỗi đầy đủ các trạng thái (ngữ cảnh) và hành động (token được chọn) từ prompt đến token kết thúc chuỗi.
**Phần thưởng** $R$: Điểm số. Thường được gán cho toàn bộ quỹ đạo, cho biết mức độ tốt của toàn bộ phản hồi.
**Mạng Critic** $V(s)$: Một mô hình riêng biệt (hoặc một đầu ra riêng) dùng để ước tính giá trị của một trạng thái. Nó dự đoán lượng phần thưởng tương lai kỳ vọng nhận được từ trạng thái hiện tại. Còn được gọi là Hàm Giá trị.
**Mô hình Phần thưởng**: Một mô hình riêng biệt được huấn luyện để học sở thích của con người hoặc các phần thưởng khác. Thông thường, nó nhận toàn bộ phản hồi và cho ra phần thưởng vô hướng $R$.
**Mô hình tham chiếu** $\pi_{ref}$: LLM gốc đã được pre-train sau bước SFT, trước khi áp dụng bất kỳ RL nào.
---
Trong học **on-policy**, mô hình chủ động tự sinh dữ liệu trong quá trình huấn luyện. Mô hình sinh ra các phản hồi, các phản hồi đó được chấm điểm và tham số của mô hình được cập nhật.
Mục tiêu cốt lõi là tối đa hóa **Kỳ vọng Lợi nhuận** $J(\pi_\theta)$:
$$J(\pi_\theta) = \mathbb{E}_{\tau \sim \pi_\theta}[R(\tau)]$$
Điều này có nghĩa là chúng ta đang tính giá trị kỳ vọng của phần thưởng trên tất cả các cuộc hội thoại được lấy mẫu từ mô hình $\pi_\theta$.
> Lưu ý rằng, nói một cách chặt chẽ, chính sách $\pi_\theta$ cho ra xác suất cho từng token một tại mỗi thời điểm. Khi viết rằng chúng ta đang lấy mẫu toàn bộ quỹ đạo (chuỗi) từ $\pi_\theta$, thực ra chúng ta cần một chiến lược giải mã (như ancestral sampling hoặc top-p sampling). Vì vậy, đây chỉ là cách viết tắt để nói rằng chúng ta đang sinh chuỗi một cách tự hồi quy từng bước dựa trên chính sách.
Chúng ta muốn tìm các trọng số $\theta$ của mô hình sao cho tối đa hóa lợi nhuận kỳ vọng $J$. Để làm điều này, chúng ta cần tính gradient của nó $\nabla_\theta J(\pi_\theta)$:
$$\nabla_\theta J(\pi_\theta) = \nabla_\theta \int P(\tau|\theta) R(\tau) \, d\tau$$
Vấn đề ở đây là chúng ta **không thể vi phân qua một quá trình sinh rời rạc**, chẳng hạn như việc lấy mẫu token trong trường hợp này. Trong một mạng nơ-ron thông thường, chúng ta có thể tính gradient cho mọi bước. Nhưng khi một LLM sinh văn bản (hay tổng quát hơn, khi một hành động được chọn), nó thực hiện một bước lấy mẫu **không khả vi**. Hơn nữa, phần thưởng thường cũng không khả vi (trừ khi chúng ta sử dụng một mô hình phần thưởng khả vi). Để giải quyết vấn đề này, chúng ta sử dụng **ước lượng hàm score**, còn được gọi là **thủ thuật log-đạo hàm**.
Đầu tiên, chúng ta đưa gradient vào bên trong (giả sử các điều kiện chính quy được thỏa mãn):
$$= \int \nabla_\theta P(\tau|\theta) R(\tau) \, d\tau$$
enerally produces good responses, but occasionally makes a mistake. With REINFORCE, even the good tokens in a bad response get penalized, and even the bad tokens in a good response get reinforced. This is because the reward is applied uniformly to all tokens in the trajectory.
## Dịch
eta) R(\tau) \, d\tau=∫∇θP(τ∣θ)R(τ)dτ
và áp dụng thủ thuật log-đạo hàm (log-derivative trick).
=∫P(τ∣θ)∇θlogP(τ∣θ)⏟Thay thế∇θPR(τ)dτ= \int \underbrace{P(\tau|\theta) \nabla_\theta \log P(\tau|\theta)}_{\text{Thay thế } \nabla_\theta P} R(\tau) \, d\tau
Điều này cho phép chúng ta viết lại gradient dưới dạng kỳ vọng và có thể dùng phương pháp lấy mẫu để ước lượng nó.
=Eτ∼πθ[∇θlogP(τ∣θ)⋅R(τ)]= \mathbb{E}_{\tau \sim \pi_\theta} \left[ \nabla_\theta \log P(\tau|\theta) \cdot R(\tau) \right]
Đây là điều tuyệt vời vì chúng ta không còn cần đạo hàm của hàm phần thưởng nữa, và có thể ước lượng gradient bằng cách lấy mẫu các trajectory.
Với LLM, xác suất của toàn bộ văn bản là tích xác suất của từng token:
P(τ∣θ)=∏t=0Tπθ(at∣st)P(\tau|\theta) = \prod_{t=0}^T \pi_\theta(a_t | s_t)
Chúng ta có thể lấy log của tích, kết quả trở thành một tổng:
logP(τ∣θ)=∑t=0Tlogπθ(at∣st)\log P(\tau|\theta) = \sum_{t=0}^T \log \pi_\theta(a_t | s_t)
và thay thế ngược lại vào phương trình trên. Chúng ta cũng có thể tổng quát hóa số hạng phần thưởng R(τ) thành một trọng số Φt:
∇θJ(πθ)=Eτ∼πθ[∑t=0T∇θlogπθ(at∣st)⏟Hướng⋅Φt⏟Trọng số]\nabla_\theta J(\pi_\theta) = \mathbb{E}_{\tau \sim \pi_\theta} \left[ \sum_{t=0}^T \underbrace{\nabla_\theta \log \pi_\theta(a_t|s_t)}_{\text{Hướng}} \cdot \underbrace{\Phi_t}_{\text{Trọng số}} \right]
Bạn có thể hiểu các thuật toán policy gradient khác nhau như những cách triển khai khác nhau của trọng số này. Ở mức độ tổng quát, có thể hiểu như sau:
- Nếu Φt = R(τ), tức là tổng phần thưởng của trajectory, ta thu được REINFORCE (hoặc phổ biến hơn, ta tính phần thưởng từ thời điểm hiện tại trở đi: Φt = ∑k=tT rk)
- Nếu Φt = Q(st, at) − V(st), tức là Advantage, ta thu được Vanilla Policy Gradient hoặc các phương pháp Actor-Critic.
REINFORCE về bản chất là cách triển khai trực tiếp của phương trình trên. Trong trường hợp đơn giản nhất, trọng số cập nhật được đặt bằng tổng phần thưởng của trajectory R(τ). Điều này rất trực quan: nếu mô hình tạo ra một phản hồi và nhận được điểm cao, chúng ta củng cố mọi token mà nó đã sử dụng. Nếu nhận được điểm thấp, chúng ta hạn chế các token đó.
Quy tắc cập nhật trông như sau, được tính trung bình trên một batch các trajectory:
∇θJ(πθ)≈1N∑i=1N∑t=0T∇θlogπθ(at∣st)⋅R(τ)\nabla_\theta J(\pi_\theta) \approx \frac{1}{N} \sum_{i=1}^N \sum_{t=0}^T \nabla_\theta \log \pi_\theta(a_t|s_t) \cdot R(\tau)
- ∇θ log πθ(at|st) là gradient của log-xác suất như trên - R(τ) là điểm số của toàn bộ phản hồi. Nó đóng vai trò là trọng số cho việc cập nhật. Nếu phần thưởng dương, chúng ta dịch chuyển các trọng số theo hướng gradient và tăng xác suất của token. Nếu phần thưởng âm, chúng ta giảm xác suất của các token đó.
REINFORCE có thể rất kém hiệu quả. Hãy tưởng tượng một mô hình thường xuyên tạo ra các phản hồi tốt, nhưng đôi khi mắc lỗi. Với REINFORCE, ngay cả những token tốt trong một phản hồi kém cũng bị phạt, và ngay cả những token kém trong một phản hồi tốt cũng được củng cố. Điều này xảy ra vì phần thưởng được áp dụng đồng đều cho tất cả các token trong trajectory.
Tạo ra một phản hồi dài rất tốt nhưng lại ảo giác ở cuối, và Reward Model gán cho nó điểm số là −100. REINFORCE sẽ phạt toàn bộ văn bản được tạo ra vì nó không thể xác định token nào gây ra điểm số thấp. Khó khăn lớn nhất của thuật toán này là phương sai cao và tính không ổn định.
**Proximal Policy Optimization (PPO)** là một họ các phương pháp policy gradient được OpenAI giới thiệu vào năm 2017 (Schulman et al. 2017), và khắc phục nhiều vấn đề bất ổn định này. PPO là một trong những thuật toán được sử dụng rộng rãi nhất trong các ứng dụng RL. Nó giải quyết các vấn đề của Vanilla Policy Gradients và REINFORCE bằng cách sử dụng ba cải tiến chính:
**Generalized Advantage Estimation (GAE):** PPO sử dụng GAE để tính toán các giá trị advantage, giúp giảm phương sai trong các ước tính policy gradient trong khi vẫn duy trì độ lệch thấp.
**Tương tác Actor-Critic:** PPO giới thiệu một mô hình critic (còn được gọi là hàm giá trị).
**Cập nhật có giới hạn (Clipped Updates):** PPO giới hạn các cập nhật policy bằng cách sử dụng mục tiêu thay thế có cắt xén (clipped surrogate objective) hoặc bằng cách sử dụng hình phạt KL divergence thích ứng.
Thay vì sử dụng phần thưởng thô R, PPO sử dụng **Advantage** $\hat{A}_t$. Advantage cho chúng ta biết hành động cụ thể này tốt hơn bao nhiêu so với kết quả cơ sở kỳ vọng.
Advantage cũng chỉ xem xét các phần thưởng thu được từ bước $t$ trở đi. Chúng ta bỏ qua những gì đã xảy ra trước hành động $a_t$ vì token mới không thể ảnh hưởng đến quá khứ.
$$\hat{A}_t = Q(s_t, a_t) - V(s_t)$$
$Q(s_t, a_t)$ là phần thưởng-đến-đích (rewards-to-go). Đây là tổng phần thưởng thực tế chúng ta nhận được sau khi thực hiện hành động $a_t$.
$V(s_t)$ là phần thưởng trung bình chúng ta thường nhận được từ trạng thái này. Nó được dự đoán bởi một mạng riêng biệt gọi là **Critic**.
Điều này làm giảm đáng kể nhiễu vì chúng ta đang chuẩn hóa tín hiệu so với một đường cơ sở và chỉ xem xét các phần thưởng trong tương lai.
Cụ thể hơn, PPO sử dụng công thức **Generalized Advantage Estimation (GAE)** từ Schulman et al. (2015), sử dụng các ước tính advantage có trọng số mũ mượt mà từ nhiều bước. Điều này giúp giảm...


