CD-OPD: CFG-Distilled On-Policy Distillation for Video Hallucination Suppression
Status: design (Phase 1 motivation pending). Mirrors what we agreed on in conversation; falsifiable kill criteria live in §6.
1. Problem
Vanilla OPD (Qwen-3 / Thinking-Machines style, reverse-KL, k-estimator, optional PG wrap) is a strong post-training paradigm: dense per-token supervision from a frontier teacher, on-policy distribution matching at the student. We are running it via verl 0.8 from Qwen2.5-VL-72B → Qwen2.5-VL-7B on 5K video samples (1K TemporalBench + 4K LLaVA-Video-178K) to suppress video MLLM hallucination, mirroring the PaMi-VDPO setup but swapping VDPO → OPD.
The thing we want to attack: Vanilla OPD assumes the teacher's per-token distribution is uniformly reliable. For video MLLM hallucination this is false. The 72B teacher itself hallucinates -- it produces tokens that come from a language prior rather than from the visual evidence -- and Vanilla OPD's token-uniform KL distills those exact tokens into the student. The "dense token-level supervision" claim of OPD therefore collapses into "dense language-prior pass-through" on the very phenomenon (hallucination) we want to suppress.
We name this failure mode Hallucinated-Token Pass-through.
2. What evidence would prove (or kill) the problem
Three Phase 1 questions, all computable from teacher inference alone (no trained student needed):
- F2a -- is the teacher's per-token grounding score
g_t := log π_T(a_t | video, prefix) − log π_T(a_t | video⁻, prefix)bimodal across a realistic corpus? Single-peak around zero → the grounded vs. free-rider split we are building the method on does not exist. - F2b⁻ -- on the bottom-20% g_t tokens, does an external judge (GPT-4o) label
≥40% as hallucinated? If not,
g_tis too noisy to be the supervision filter. - F2b⁺ -- on the top-20% g_t tokens, does the judge label ≤25% as hallucinated? If not, type-(e) visually-anchored-but-wrong hallucinations dominate and our CFG-style intervention will not catch them.
If any of these fails, stop, and re-open the challenge selection. Do not push the method.
3. Method: CD-OPD
We treat the teacher distribution as a sum of "what the model says because of the video" and "what the model says because of the language prior". To isolate the first, we use a classifier-free-guidance style construction at the distillation target:
target_logit_t(a) = (1 + α) · log π_T(a | v, prefix)
− α · log π_T(a | v⁻, prefix)
where v⁻ is a frame-count-preserving perturbation of the video that strips
visual content (default: all-black frames). The student is then distilled
toward this CFG-amplified target via the same k-estimator reverse-KL machinery
as Vanilla OPD; for the PG-OPD path the per-token negative-loss becomes the
reward as before.
Properties:
- α = 0 ⇒ vanilla OPD exactly. Single hyperparameter, monotone ablation.
- Token-level, no POS tagging, no external classifier, no detection threshold.
- Connects to prior work: classifier-free guidance (Ho & Salimans 2022) and
contrastive decoding (Li et al. 2023) both use the same
(1+α)·p − α·qcombination -- we are simply applying it at training time so the student inherits the language-prior-debiased behaviour at inference for free (amortisation: no extra forward at inference). - Cost: one extra teacher forward per training step (perturbed video, same sequence). Wall-time hit ≈ 50–70% of teacher time, which already dominates the step. Acceptable.
3.1 What v⁻ to use
Constraint: same frame count as v (otherwise the number of vision tokens in
the prompt changes, and prompt_logprobs no longer aligns with prompt_ids).
Three perturbations supported in code:
| name | semantics | recommended use |
|---|---|---|
black_frames |
replace every frame with all-zero RGB | default (Phase 2 main) |
shuffle |
random permutation of frame order | ablation: time-only break |
mean_frame |
every frame = temporal mean of video | ablation: motion-only break |
black_frames is closest to "language-prior baseline" while keeping the teacher
in distribution (still a video with the right number of frames).
4. Implementation in verl
All changes live in this fork; no upstream PR planned.
verl/workers/config/distillation.py— addcfg_enabled,cfg_alpha,cfg_perturbationtoDistillationLossConfig.verl/trainer/config/distillation/distillation.yaml— surface those knobs.verl/experimental/teacher_loop/teacher_manager.py— addperturb_multi_modal_data()(operates on the videos list insidemulti_modal_data) and_pad_teacher_logprobs()helper.verl/experimental/agent_loop/agent_loop.py— whencfg_enabled, do a 2nd teacher forward onperturb_multi_modal_data(mmd, cfg_perturbation)and stashteacher_logprobs_perturbedthrough the same flow asteacher_logprobs(typed field on_InternalAgentLoopOutput, extra-field promotion inAgentLoopOutput.as_dict, batch concatenation in_postprocess).verl/trainer/distillation/losses.py— incompute_distillation_loss_reverse_kl_estimator, when bothteacher_logprobsandteacher_logprobs_perturbedare present, build(1+α) · log p − α · log p_perturbedas theref_logprobforkl_penaltyand log new metrics (distillation/cfg_grounding_mean,distillation/cfg_grounding_abs_mean,distillation/cfg_target_shift_mean).
Only the k-estimator loss path supports CD-OPD; the topk path is untouched and
will raise nothing -- it just runs vanilla OPD even with cfg_enabled=True.
That is acceptable because our running config uses loss_mode=k1.
5. Phase 1 → Phase 4 plan
| phase | what | who | gate |
|---|---|---|---|
| 0 | Vanilla OPD continues (in-progress, finishes today ~18-19:30) | - | - |
| 1 | scripts/compute_grounding.py then scripts/run_motivation_f2.py→ F2a/F2a2/F2b/F2c figures + GPT-4o judge round |
local | F2a bimodal AND F2b⁻ ≥40% AND F2b⁺ ≤25% |
| 2 | Pilot CD-OPD run, α=1.0, 50 step subset, sanity check loss curves and cfg_grounding_* metrics |
GPU | loss not NaN, grounding mean > 0 |
| 3 | Full CD-OPD runs (α ∈ {0.5, 1.0, 1.5, 2.0}, perturbation ∈ {black_frames, shuffle}) + ablations | GPU | at least α=1.0 ≥ Vanilla OPD on VideoHallucer |
| 4 | Eval: VideoHallucer + EventHallusion (main); NextQA + VideoMME + TempCompass (regression) | GPU | hallucination ↑, general ≈ |
Ablation matrix (each row is one training run):
| run | cfg_enabled | α | perturbation | purpose |
|---|---|---|---|---|
| A0 | False | - | - | Vanilla OPD baseline (already running) |
| A1 | True | 1.0 | black_frames | CD-OPD main |
| A2 | True | 0.5 | black_frames | α-sweep low |
| A3 | True | 1.5 | black_frames | α-sweep high |
| A4 | True | 2.0 | black_frames | α-sweep over-correction check |
| A5 | True | 1.0 | shuffle | perturbation: time-only ablation |
| A6 | True | 1.0 | mean_frame | perturbation: motion-only ablation |
6. What would change my mind
- Phase 1 kill criteria fire → CD-OPD as designed cannot work. Pivot back to choosing a different challenge (most likely candidates: detection via teacher self-consistency, or attention-distillation based grounding).
- F2a bimodal but α-sweep shows monotone decreasing eval at any α > 0 → CFG target is producing valid-shape distributions but the wrong direction of effect. Consider sign flip or contrastive triplet form (Variant B from the chat) instead of CFG-additive.
- Vanilla OPD beats CD-OPD on general benchmarks by >2 pt → the CFG amplification is collateral-damaging the parts of teacher behaviour that are correct boilerplate. Mitigations: lower α; combine with a content-token mask so CFG only fires on noun/verb/number tokens.
7. Related work positioning
- PaMi-VDPO (Wang et al., arXiv 2504.05810). Same dataset / hallucination niche, uses frame perturbation but for DPO negatives. We share the perturbation primitive; we use it as a CFG branch on top of OPD instead.
- Video-OPD / TVDF (Li et al., arXiv 2602.02994). Same OPD-for-video niche, but their teacher reliability check uses ground-truth IoU annotations for sample-level filtering on closed-form TVG. We address open-ended captioning / QA where no per-sample GT exists, and our reliability signal is intrinsic (visual counterfactual) and token-level.
- TCOD (Wang et al., arXiv 2604.24005). Different OPD failure mode (trajectory-level KL instability in multi-turn agents). They use a trajectory-depth curriculum; we use a per-token CFG target. We borrow the narrative structure (name a failure, propose a small fix) but not the method.
- Classifier-free guidance (Ho & Salimans 2022) and contrastive
decoding (Li et al., 2023). Same
(1+α)·p − α·qconstruction, but they apply it at inference to a single model with two conditionings. We apply it at distillation so a student amortises it -- inference is one forward, no overhead.