Skip to content

Commit 54957df

Browse files
heavyrain-lzytengqm
authored andcommitted
[Model] Update qwen3vl for current Megatron-LM-FL (flagos-ai#1235)
### PR Category <!-- One of [ Train | Inference | Compress | Serve | RL | Core | Hardware | CICD | Tools | Others ] --> Train ### PR Types <!-- One of [ User Experience | New Features | Bug Fixes | Improvements | Performance | Breaking Change| Deprecations | Test Case | Docs | Others ] --> Others ### PR Description <!-- Describe what you’ve done --> Update qwen3vl for the current `Megatron-LM-FL` and add functional tests.
1 parent 5c694d2 commit 54957df

15 files changed

Lines changed: 250 additions & 30 deletions

File tree

flagscale/models/megatron/qwen2_5_vl/language_module.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@ def __init__(
3636
position_embedding_type: Literal['learned_absolute', 'rope', 'none'] = 'learned_absolute',
3737
num_tokentypes: int = 0,
3838
scatter_to_sequence_parallel: bool = False, # chage default to False
39+
tp_group = None,
3940
):
4041
assert scatter_to_sequence_parallel == False, "QwenVLLanguageModelEmbedding does not support scatter_to_sequence_parallel"
41-
super().__init__(config, vocab_size, max_sequence_length, position_embedding_type, num_tokentypes, scatter_to_sequence_parallel)
42+
super().__init__(config, vocab_size, max_sequence_length, position_embedding_type, num_tokentypes, scatter_to_sequence_parallel, tp_group)
4243

4344

4445
def forward(

flagscale/models/megatron/qwen2_5_vl/vit_model.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def enable_linear(self):
6868
# and https://github.com/huggingface/transformers/pull/45041
6969
# By default, we use CUDNN's convolution ops with optimization.
7070
return self.kernel_size == self.stride and \
71-
version.parse(torch.__version__) > version.parse('2.9.0')
71+
version.parse(torch.__version__) > version.parse('2.9.0') and version.parse(torch.__version__) < version.parse('2.11.0')
7272

7373
def _forward_matmul(self, hidden_states):
7474
target_dtype = self.proj.weight.dtype

flagscale/models/megatron/qwen3_vl/language_model.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from megatron.core.utils import WrappedTensor, deprecate_inference_params
2828
from megatron.core.models.gpt.gpt_model import GPTModel
2929
from megatron.core.process_groups_config import ProcessGroupCollection
30+
from megatron.core.transformer.multi_token_prediction import MultiTokenPredictionBlock
3031

3132
from .language_transformer_block import LanguageTransformerBlock
3233

@@ -100,7 +101,7 @@ def apply_interleaved_mrope(self, freqs, mrope_section):
100101
freqs_t[..., idx] = freqs[dim, ..., idx]
101102
return freqs_t
102103

103-
def forward(self, position_ids: torch.Tensor, mrope_section: List[int]) -> Tensor:
104+
def forward(self, position_ids: torch.Tensor, mrope_section: List[int], cp_group: Optional[torch.distributed.ProcessGroup] = None) -> Tensor:
104105
"""Forward pass of multimodal RoPE embedding.
105106
106107
Args:
@@ -137,10 +138,12 @@ def forward(self, position_ids: torch.Tensor, mrope_section: List[int]) -> Tenso
137138

138139
# shape (seq_length, bs, 1, 2 * dim)
139140
emb = emb[..., None, :].transpose(0, 1).contiguous()
140-
if self.cp_group is not None and self.cp_group.size() > 1:
141+
if cp_group is None:
142+
cp_group = self.cp_group
143+
if cp_group is not None and cp_group.size() > 1:
141144
# slice rotary_pos_emb along sequence dimension and select the parition of the current
142145
# CP rank
143-
emb = get_pos_emb_on_this_cp_rank(emb, 0, self.cp_group)
146+
emb = get_pos_emb_on_this_cp_rank(emb, 0, cp_group)
144147
return emb
145148

146149
class Qwen3VLLanguageModule(GPTModel):
@@ -228,6 +231,7 @@ def __init__(
228231
vocab_size=self.vocab_size,
229232
max_sequence_length=self.max_sequence_length,
230233
position_embedding_type=position_embedding_type,
234+
tp_group=self.pg_collection.tp,
231235
)
232236
if self.position_embedding_type == 'mrope' and not self.config.multi_latent_attention:
233237
self.rotary_pos_emb = Qwen3VLLanguageRotaryEmbedding(
@@ -258,7 +262,7 @@ def __init__(
258262

259263
if self.mtp_process:
260264
self.mtp = MultiTokenPredictionBlock(
261-
config=self.config, spec=self.mtp_block_spec, vp_stage=vp_stage
265+
config=self.config, spec=self.mtp_block_spec, vp_stage=vp_stage, pg_collection=self.pg_collection
262266
)
263267

264268
# Output
@@ -314,18 +318,20 @@ def forward(self, input_ids, position_ids, attention_mask,
314318
visual_pos_masks: Optional[torch.Tensor] = None,
315319
deepstack_visual_embeds: Optional[list[torch.Tensor]] = None,
316320
*, inference_params = None,
317-
loss_mask = None):
321+
loss_mask = None,
322+
padding_mask: Optional[torch.Tensor] = None):
318323

319324
inference_context = deprecate_inference_params(inference_context, inference_params)
320325

321-
decoder_input, rotary_pos_emb, rotary_pos_cos, rotary_pos_sin, sequence_len_offset = (
326+
decoder_input, rotary_pos_emb, rotary_pos_cos, rotary_pos_sin, sequence_len_offset, padding_mask = (
322327
self._preprocess(
323328
input_ids=input_ids,
324329
position_ids=position_ids,
325330
decoder_input=decoder_input,
326331
inference_context=inference_context,
327332
packed_seq_params=packed_seq_params,
328-
)
333+
padding_mask=padding_mask,
334+
)[:6]
329335
)
330336

331337
# Run decoder.
@@ -338,6 +344,7 @@ def forward(self, input_ids, position_ids, attention_mask,
338344
rotary_pos_sin=rotary_pos_sin,
339345
packed_seq_params=packed_seq_params,
340346
sequence_len_offset=sequence_len_offset,
347+
padding_mask=padding_mask,
341348
visual_pos_masks = visual_pos_masks,
342349
deepstack_visual_embeds = deepstack_visual_embeds,
343350
**(extra_block_kwargs or {}),

flagscale/models/megatron/qwen3_vl/language_transformer_block.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,21 @@
6262

6363
class LanguageTransformerBlock(TransformerBlock):
6464

65+
def __init__(
66+
self,
67+
config,
68+
spec,
69+
post_layer_norm=True,
70+
pre_process=True,
71+
post_process=True,
72+
pg_collection=None,
73+
vp_stage=None,
74+
dualpipev_stage=None,
75+
):
76+
super().__init__(
77+
config, spec, post_layer_norm, pre_process, post_process, pg_collection, vp_stage, dualpipev_stage
78+
)
79+
6580
def _checkpointed_forward(
6681
self,
6782
hidden_states: Tensor,
@@ -207,6 +222,7 @@ def forward(
207222
inference_context: Optional[BaseInferenceContext] = None,
208223
packed_seq_params: Optional[PackedSeqParams] = None,
209224
sequence_len_offset: Optional[Tensor] = None,
225+
padding_mask: Optional[Tensor] = None,
210226
# args for deepstack
211227
visual_pos_masks: Optional[torch.Tensor] = None,
212228
deepstack_visual_embeds: Optional[list[torch.Tensor]] = None,
@@ -343,6 +359,7 @@ def forward(
343359
inference_context=inference_context,
344360
packed_seq_params=packed_seq_params,
345361
sequence_len_offset=sequence_len_offset,
362+
padding_mask=padding_mask,
346363
)
347364
# Deepstack visual embedding addition
348365
# NOTE: Assume that this is first pipeline stage that has at least three layers.

flagscale/models/megatron/qwen3_vl/model.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ def __init__(
7272
language_rotary_base: int = 10000,
7373
fp16_lm_cross_entropy: bool = False,
7474
language_share_embeddings_and_output_weights: bool=False,
75+
pg_collection = None,
7576
vp_stage: int=None
7677
) -> None:
7778
super().__init__(config=language_transformer_config)
@@ -121,6 +122,7 @@ def __init__(
121122
share_embeddings_and_output_weights=language_share_embeddings_and_output_weights,
122123
rope_scaling=False,
123124
mtp_block_spec=None,
125+
pg_collection=pg_collection,
124126
vp_stage=vp_stage,
125127
)
126128
self.share_embeddings_and_output_weights = (

flagscale/models/megatron/qwen3_vl/vision_transformer_block.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,12 @@ class VisionTransformerBlock(TransformerBlock):
6767
"""
6868
def __init__(self, config, spec,
6969
post_layer_norm = True, pre_process = True, post_process = True,
70-
pg_collection = None, vp_stage = None,
70+
pg_collection = None, vp_stage = None, dualpipev_stage = None,
7171
projection_config = None, # Note: DeepStack
7272
projection_layer_spec = None, # Note: DeepStack
7373
projection_type = 'mlp', # Note: DeepStack):
7474
):
75-
super().__init__(config, spec, post_layer_norm, pre_process, post_process, pg_collection, vp_stage)
75+
super().__init__(config, spec, post_layer_norm, pre_process, post_process, pg_collection, vp_stage, dualpipev_stage)
7676

7777
if self.final_layernorm != None:
7878
# NOTE(lizhiyu): replace final layernorm with TENorm if using TE

flagscale/train/megatron/train_qwen3_vl.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,17 @@
9292
#### especially for qwen2.5-vl ####
9393
IGNORE_IDX=-100
9494
def model_provider(
95-
pre_process=True, post_process=True, add_encoder=True, add_decoder=True
95+
pre_process=True, post_process=True, vp_stage=None, config=None, pg_collection=None
9696
) -> Union[Qwen3VLModel]:
9797
args = get_args()
9898
print_rank_0("start building qwen3-vl model ...")
9999

100100
# Config of vit, llm and projector
101-
config = core_transformer_config_from_args(args, Qwen3VLTransformerConfig)
101+
if config is None:
102+
config = core_transformer_config_from_args(args, Qwen3VLTransformerConfig)
103+
else:
104+
# config passed from backend, use it directly
105+
pass
102106
use_te = args.transformer_impl == "transformer_engine"
103107
if not use_te:
104108
raise NotImplementedError("The Qwen3-VL model is only implemented with TransformerEngine!")
@@ -144,12 +148,12 @@ def model_provider(
144148

145149
pre_process=pre_process,
146150
post_process=post_process,
147-
add_decoder=add_decoder,
148-
add_encoder=add_encoder,
149151

150152
fp16_lm_cross_entropy=args.fp16_lm_cross_entropy,
151153
parallel_output=True,
152154
language_share_embeddings_and_output_weights=not args.untie_embeddings_and_output_weights,
155+
pg_collection=pg_collection,
156+
vp_stage=vp_stage,
153157
)
154158

155159
model.freeze(
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
defaults:
2+
- _self_
3+
- train: tp2
4+
5+
experiment:
6+
exp_name: tp2
7+
exp_dir: tests/functional_tests/train/qwen3_vl/test_results/tp2
8+
task:
9+
type: train
10+
backend: megatron
11+
entrypoint: flagscale/train/megatron/train_qwen3_vl.py
12+
runner:
13+
ssh_port: null
14+
shell_cmds: null
15+
envs:
16+
HYDRA_FULL_ERROR: 1
17+
CUDA_VISIBLE_DEVICES: "0,1,2,3,4,5,6,7"
18+
CUDA_DEVICE_MAX_CONNECTIONS: 1
19+
# CUBLAS_WORKSPACE_CONFIG: ":4096:8"
20+
NCCL_ALGO: "Ring"
21+
NVTE_APPLY_QK_LAYER_SCALING: 0
22+
NVTE_ALLOW_NONDETERMINISTIC_ALGO: 0
23+
NVTE_FLASH_ATTN: 1
24+
NVTE_FUSED_ATTN: 0
25+
CUDNN_BENCHMARK: "false"
26+
CUDNN_DETERMINISTIC: "true"
27+
cmds:
28+
before_start: source /root/miniconda3/bin/activate flagscale-train && pip install git+https://github.com/NVIDIA/Megatron-Energon.git@ab40226100830f41de38d1f1204d7848b54b1f3e && pip install "multi-storage-client==0.42.0" && pip install transformers==4.57
29+
action: run
30+
31+
hydra:
32+
run:
33+
dir: ${experiment.exp_dir}/hydra
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
system:
2+
vision_ration: 0.1
3+
num_workers: 1
4+
calculate_per_token_loss: true
5+
tensor_model_parallel_size: 4
6+
pipeline_model_parallel_size: 1
7+
context_parallel_size: 1
8+
use_flash_attn: True
9+
use_distributed_optimizer: True
10+
sequence_parallel: True
11+
tp_comm_overlap: False
12+
overlap_grad_reduce: False # if has text-only must be false
13+
overlap_param_gather: False # if has text-only must be false
14+
use_mcore_models: True
15+
transformer_impl: transformer_engine
16+
use_te: True
17+
precision:
18+
bf16: True
19+
attention_softmax_in_fp32: True
20+
logging:
21+
log_interval: 1
22+
tensorboard_log_interval: 1
23+
log_throughput: True
24+
wandb_project: ${experiment.exp_name}
25+
wandb_exp_name: ${experiment.exp_name}
26+
log_params_norm: True
27+
log_num_zeros_in_grad: True
28+
checkpoint:
29+
save_interval: 1000
30+
# pretrained_checkpoint: /nfs/lizhiyu/embody/data/Qwen3-VL-8B-Instruct-tp2/
31+
dataloader_save: ${experiment.exp_dir}/checkpoints/dataloader
32+
ckpt_format: torch
33+
async_save: False
34+
35+
model:
36+
kv_channels: 128 # the weight out_size of prepare qkv
37+
qk_layernorm: True
38+
attention_backend: flash # don't use "auto(nvte_flash_attn)"
39+
disable_bias_linear: True
40+
num_layers: 36
41+
hidden_size: 4096
42+
ffn_hidden_size: 12288
43+
num_attention_heads: 32
44+
num_query_groups: 8
45+
seq_length: 2048
46+
max_padding_length: 2048 # (cutoff_len)max 262144, change according the dataset
47+
# especial for qwen3-vl
48+
enable_variable_seq_lengths: True
49+
max_position_embeddings: 262144 # only useful for additional position embedding
50+
swiglu: True
51+
normalization: RMSNorm
52+
norm_epsilon: 1e-6
53+
init_method_std: 0.02
54+
attention_dropout: 0.0
55+
hidden_dropout: 0.0
56+
clip_grad: 1.0
57+
train_iters: 10
58+
eval_iters: 0 # no valid
59+
eval_interval: 1000
60+
micro_batch_size: 1
61+
global_batch_size: 4
62+
allow_missing_vision_projection_checkpoint: False
63+
apply_layernorm_1p: False
64+
group_query_attention: True
65+
no_masked_softmax_fusion: True
66+
untie_embeddings_and_output_weights: True
67+
68+
# position embedding
69+
position_embedding_type: mrope
70+
rotary_percent: 1.0
71+
rotary_base: 5000000
72+
rotary_seq_len_interpolation_factor: 1
73+
no_rope_fusion: False
74+
mrope_section: [24, 20, 20]
75+
eod_mask_loss: False
76+
77+
# vision model
78+
patch_size: 16
79+
freeze_LM: False
80+
freeze_ViT: False
81+
disable_vision_class_token: True
82+
seed: 42
83+
84+
optimizer:
85+
weight_decay: 0.1
86+
adam_beta1: 0.9
87+
adam_beta2: 0.999
88+
lr_scheduler:
89+
lr: 1.0e-5
90+
min_lr: 1.0e-6
91+
lr_warmup_fraction: .03
92+
lr_decay_style: cosine
93+
94+
data:
95+
no_use_system_prompt: True
96+
data_path: /home/gitlab-runner/data/blip_laion_cc_sbu_558k_first_5k/wds-2/
97+
vision_root: /home/gitlab-runner/data/blip_laion_cc_sbu_558k_first_5k/
98+
dataloader_type: external
99+
split: 100,0,0
100+
tokenizer:
101+
tokenizer_type: Qwen2VLTokenizer
102+
tokenizer_path: /home/gitlab-runner/tokenizers/Qwen3-VL-8B-Instruct
103+
# vocab_size: 151936 #
104+
extra_vocab_size: 293 # Qwen3-VL specific. total vocab size = 151643 + extra_vocab_size
105+
make_vocab_size_divisible_by: 64
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"lm loss:": {"values": [12.81162, 12.78231, 10.90357, 13.56564, 13.17456, 13.97026, 11.54165, 10.94413, 11.21150, 9.978001], "rtol": 0.1, "atol": 0.2}}

0 commit comments

Comments
 (0)