# 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_t` is 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 − α·q` combination -- 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` — add `cfg_enabled`, `cfg_alpha`, `cfg_perturbation` to `DistillationLossConfig`. - `verl/trainer/config/distillation/distillation.yaml` — surface those knobs. - `verl/experimental/teacher_loop/teacher_manager.py` — add `perturb_multi_modal_data()` (operates on the videos list inside `multi_modal_data`) and `_pad_teacher_logprobs()` helper. - `verl/experimental/agent_loop/agent_loop.py` — when `cfg_enabled`, do a 2nd teacher forward on `perturb_multi_modal_data(mmd, cfg_perturbation)` and stash `teacher_logprobs_perturbed` through the same flow as `teacher_logprobs` (typed field on `_InternalAgentLoopOutput`, extra-field promotion in `AgentLoopOutput.as_dict`, batch concatenation in `_postprocess`). - `verl/trainer/distillation/losses.py` — in `compute_distillation_loss_reverse_kl_estimator`, when both `teacher_logprobs` and `teacher_logprobs_perturbed` are present, build `(1+α) · log p − α · log p_perturbed` as the `ref_logprob` for `kl_penalty` and 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 − α·q` construction, 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.