[GOLD] VLM support for GOLDTrainer - #5969
Conversation
5fd183a to
a3a6a3f
Compare
|
New training runs from examples/scripts/gold_vlm.py:
2. Qwen 8B -> Qwen 2B, ULD loss, vLLM:
3. Qwen 8B -> LFM 1.6B, ULD loss, no-vllm:
Results are consistent with #5461 (comment) and kashif#6 (comment) |
|
nice! the scripts for experimental belong in the experimental trainer's folder for now |
|
To avoid opening a separate discussion or issue, I think I can address this idea here (but if you'd prefer otherwise, I'll create one):
Since GKD functionality is fundamentally a case of GOLD, when I think we could later combine everything under a single GOLDTrainer (basically dropping a separate GKDTrainer) to keep the whole distillation logic in one place and avoid having to change the JSD path in two separate places. This way, I wouldn't need to add separate VLM support to GKDTrainer and then update liger_kernel -- I'd only need to implement the second part. 10.06.2026 UpdateImplementation of the liger kernel support for VLMs was easier than I anticipated, so I added it to the GOLDTrainer in e9d9836 and also added tests regarding it.
|
# Conflicts: # tests/experimental/test_gold_trainer.py # trl/experimental/gold/gold_trainer.py
…support # Conflicts: # trl/experimental/gold/gold_trainer.py
There was a problem hiding this comment.
Pull request overview
This PR extends the experimental GOLDTrainer to support vision-language model (VLM) distillation, including both same-family distillation (JSD) and cross-family distillation (ULD), with identity-collator-based raw image preservation and VLM-aware on-policy generation paths (local + vLLM), plus regression tests and an example script.
Changes:
- Introduces a VLM-specific ChatML collator that tokenizes prompts/completions and processes images on-the-fly while preserving raw prompt/completion text for ULD alignment.
- Updates GOLDTrainer’s buffering, generation, and loss paths to handle VLM batches lazily and to build teacher-compatible VLM inputs for ULD (including teacher-side prompt rendering).
- Adds a VLM distillation example script and expands the GOLDTrainer test suite to cover multimodal collation/alignment and VLM training/generation paths.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
trl/experimental/utils.py |
Adds DataCollatorForVisionLanguageChatML for VLM prompt+completion collation (incl. byte offsets + prompt tensors). |
trl/experimental/gold/gold_trainer.py |
Adds VLM detection, identity-collator buffering/materialization, VLM on-policy generation, and teacher-side VLM input building for ULD. |
tests/experimental/test_gold_trainer.py |
Adds extensive regression coverage for VLM collation, alignment, buffering/lazy materialization, vLLM behavior, and smoke tests. |
examples/scripts/gold_vlm.py |
Provides runnable same-family (JSD + vLLM) and cross-family (ULD) VLM distillation examples on GEOQA_R1V. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Results are consistent with before, but ahead of sharing them I ran into a bug, fully described in #6156 (the PR description is fully AI-generated -- I was too lazy to write it up myself 😄). Since it touches the general Chunked NLL loss in SFTTrainer, I've split it out into its own PR. My suggestion is to merge the PR above first, and then this one, since without it ULD distillation for different families models with no vLLM, and chunked NLL Loss fails.
2. Qwen 8B -> Qwen 2B, ULD, vLLM:
3. Qwen 8B -> LFM 1.6B, ULD, no vLLM:
|
# Conflicts: # trl/experimental/gold/gold_trainer.py
# Conflicts: # trl/experimental/gold/gold_trainer.py
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 2a3e1c8. Configure here.
|
@kashif since the results in #5969 (comment), the branch picked up a few more commits. None of them touch the training path exercised by those runs -- they're either cosmetic or guard against edge cases that don't occur in a normal run:
So the core used to produce those results is unchanged, and the results reported there still stand |
GOLDConfig documents seq_kd but the flag was never read. Off-policy slices always reused the dataset completion. Now, when seq_kd=True, _fill_buffer routes off-policy slices to _generate_seq_kd_for_slices, which batches all prompts into a single teacher.generate call and buffers the completions for training, matching GKDTrainer semantics. Two completion mappings: with ULD and a separate teacher tokenizer the teacher output round-trips through text into the student vocab. With a shared tokenizer the raw teacher ids pass through, which preserves EOS and avoids drift at BPE boundaries. Reconciled with the VLM support added in huggingface#5969. The VLM path buffers raw examples lazily and has no prompt tensors when _fill_buffer runs, while seq_kd feeds prompt ids to teacher_model.generate, so combining the two would need teacher-side image preprocessing and a synthetic example rebuild. GKDTrainer has no VLM support, so parity does not require it. seq_kd=True with a vision dataset now raises a ValueError in __init__ next to the existing VLM guards. A VLM student trained on a text-only dataset still works with seq_kd. Also fix a latent dtype bug in _process_completions_to_buffer: an empty completion produced torch.tensor([]) as float32, corrupting the dtype of input_ids and labels. Force dtype=torch.long.








Clear PR, based on #5461 with changes introduced in 2ac060e
Adds VLM support to GOLDTrainer:
examples/scripts/gold_vlm.pywith documented same-family JSD and cross-family ULD examples.Motivation
The GOLD algorithm has no theoretical constraints against VLM-to-VLM distillation -- the barriers were purely engineering (incompatible image token formats, different tokenizers, raw image handling through the dataloader).
Key changes
_teacher_processoris stored and used incompute_lossto build teacher-compatible vision tensors from raw imagesteacher_tokenizer_name_or_pathexamples/scripts/gold_vlm.pywith two documented usage examples (same-family JSD + vLLM, cross-family ULD)Note
docs/source/gold_trainer.md-- will add if that's desirable, just let me know.Before submitting
AI writing disclosure
We welcome the use of AI tools to help with contributions. For transparency and to help us improve our review process, please indicate the level of AI involvement in this PR.
Who can review?
Anyone in the community is free to review the PR once the tests have passed. Feel free to tag members/contributors who may be interested in your PR.
@qgallouedec @kashif
Note
Medium Risk
Large changes to the experimental GOLD training loop (buffering, generation, eval, loss paths) with multimodal and cross-architecture edge cases; mitigated by extensive tests but still affects core distillation behavior.
Overview
GOLDTrainer now supports vision-language model distillation end-to-end: same-family pairs use standard JSD (and optional Liger) with shared
pixel_values; differentmodel_typepairs requireuse_uld_loss=Trueand route images through separate student/teacher processors.Vision batches keep raw PIL images in the dataloader via an identity collator, then
DataCollatorForVisionLanguageChatMLmaterializes tensors per gradient-accumulation slice (off-policy, local on-policy, and vLLM on-policy). Cross-tokenizer ULD gets_build_teacher_vlm_inputs(teacher chat template +pixel_values) and_raw_images/_raw_promptson the batch. Init-time guards reject LLM+vision data, non-VLM teachers,keep_endtruncation for VLMs, custom collators, and Liger+ULD together.Adds
trl/experimental/gold/gold_vlm.py(GEOQA example), a VLM section ingold_trainer.md, and a largetest_gold_trainer.pysuite including slow smoke steps for JSD/ULD/Liger on tiny VLMs.Reviewed by Cursor Bugbot for commit 2a3e1c8. Bugbot is set up for automated code reviews on this repo. Configure here.