-
Notifications
You must be signed in to change notification settings - Fork 565
Support quantized Qwen3-VL / Qwen3.5-VL (dense + MoE) export from Megatron-Bridge and verify exported checkpoints #2276
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
c5a03a5
d1f077c
ef4761d
12e4fcb
4c0082c
18db85a
2baab5e
a2f0fe0
7f745d9
c262cc6
5e1a141
215d4aa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -59,14 +59,17 @@ | |
|
|
||
| import torch | ||
| from megatron.bridge import AutoBridge | ||
| from megatron.bridge.training.post_training.checkpointing import has_modelopt_state | ||
| from transformers import AutoConfig | ||
|
|
||
| import modelopt.torch.utils.distributed as dist | ||
| from modelopt.torch.export import copy_hf_ckpt_remote_code | ||
| from modelopt.torch.utils import print_args, print_rank_0 | ||
| from modelopt.torch.utils.plugins.mbridge import ( | ||
| is_vlm_config, | ||
| load_mbridge_model_from_hf, | ||
| load_modelopt_megatron_checkpoint, | ||
| use_moe_grouped_gemm, | ||
| ) | ||
|
|
||
| # Megatron-Bridge checkpoint iteration directories use names like ``iter_0000100``. | ||
|
|
@@ -213,6 +216,16 @@ def get_args() -> argparse.Namespace: | |
| "correct for homogeneous students; unused for VLMs.", | ||
| ) | ||
| parser.add_argument("--trust_remote_code", action="store_true", help="Trust remote code") | ||
| parser.add_argument( | ||
| "--no_moe_grouped_gemm", | ||
| action="store_true", | ||
| help=( | ||
| "Force SequentialMLP for MoE experts instead of the fused TEGroupedMLP (grouped GEMM). " | ||
| "By default grouped GEMM is used unless the architecture cannot export it to " | ||
| "HuggingFace, in which case SequentialMLP is selected automatically. VLMs only: the " | ||
| "LLM path reads the expert layout from the checkpoint and ignores this flag." | ||
| ), | ||
| ) | ||
| parser.add_argument("--tp_size", type=int, default=1, help="Tensor parallel size") | ||
|
kevalmorabia97 marked this conversation as resolved.
|
||
| parser.add_argument("--pp_size", type=int, default=1, help="Pipeline parallel size") | ||
| parser.add_argument("--ep_size", type=int, default=1, help="Expert parallel size") | ||
|
|
@@ -226,10 +239,15 @@ def get_args() -> argparse.Namespace: | |
|
|
||
| def main(args: argparse.Namespace): | ||
| checkpoint_export_paths: list[tuple[Path, Path]] = _get_checkpoint_export_paths(args) | ||
| is_vlm = hasattr( | ||
| AutoConfig.from_pretrained(args.student_hf_path, trust_remote_code=args.trust_remote_code), | ||
| "vision_config", | ||
| ) | ||
| # This path drops quantization, so a QAD checkpoint would export silently unquantized. | ||
| # ``has_modelopt_state`` ignores ``kd_loss``, so plain distillation still passes. | ||
| quantized = [str(p) for p, _ in checkpoint_export_paths if has_modelopt_state(str(p))] | ||
| if quantized: | ||
| raise ValueError( | ||
| f"{quantized[0]} is quantized; this script exports full precision only and would drop " | ||
| "the quantizers. Use export_quantized_megatron_to_hf.py instead." | ||
| ) | ||
| is_vlm = is_vlm_config(args.student_hf_path, trust_remote_code=args.trust_remote_code) | ||
|
|
||
| if is_vlm: | ||
| # Build the full VLM (vision tower / projector + original LM from HF), then overwrite the LM | ||
|
|
@@ -238,6 +256,11 @@ def main(args: argparse.Namespace): | |
| _bridge, _provider, _model, full_model, _tokenizer = load_mbridge_model_from_hf( | ||
| hf_model_name_or_path=args.student_hf_path, | ||
| trust_remote_code=args.trust_remote_code, | ||
| moe_grouped_gemm=use_moe_grouped_gemm( | ||
| args.student_hf_path, | ||
| trust_remote_code=args.trust_remote_code, | ||
| force_sequential=args.no_moe_grouped_gemm, | ||
| ), | ||
|
Comment on lines
+259
to
+263
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [IMPORTANT Compatibility] This picks a different MoE expert layout than
moe_grouped_gemm = (
use_moe_grouped_gemm(..., force_sequential=args.no_moe_grouped_gemm)
if student_has_modelopt_state
else not args.no_moe_grouped_gemm
)This script now rejects checkpoints with ModelOpt state (lines 244-249), so every checkpoint it handles is one Impact: for a MoE VLM whose grouped experts aren't HF-exportable, Suggested fix: mirror moe_grouped_gemm=not args.no_moe_grouped_gemm,and drop the now-unused |
||
| provider_overrides={ | ||
| "tensor_model_parallel_size": args.tp_size, | ||
| "pipeline_model_parallel_size": args.pp_size, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.