Skip to content

code to patch for qwen3.5 grpo training - #10957

Draft
leah1985 wants to merge 1 commit into
hiyouga:mainfrom
leah1985:leah/qwen35-grpo-exp
Draft

code to patch for qwen3.5 grpo training#10957
leah1985 wants to merge 1 commit into
hiyouga:mainfrom
leah1985:leah/qwen35-grpo-exp

Conversation

@leah1985

@leah1985 leah1985 commented Apr 6, 2026

Copy link
Copy Markdown

No description provided.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for Qwen3.5-VL models, featuring standalone position ID computation and updated dataset processing. It also includes extensive compatibility fixes for newer versions of vLLM (0.17+) and transformers. A key feature added is the manual merging of LoRA weights into the base model on the CPU to support hybrid architectures. Review feedback highlights critical memory efficiency concerns when gathering weights for large models, potential non-determinism in distributed ID generation, and a possible crash in the vision position ID logic.

Comment on lines +202 to +208
for key in list(actor_weights.keys()):
v = actor_weights[key]
if isinstance(v, DTensor):
actor_weights[key] = v.full_tensor().detach().cpu()
else:
actor_weights[key] = v.detach().cpu()
actor_weights = self._merge_lora_into_weights(actor_weights, lora_weights)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This block gathers all model weights into CPU memory simultaneously by calling full_tensor() on every parameter. For large models (e.g., 70B+), this will likely lead to CPU OOM, especially since this happens on every rank. The existing _make_weight_iterator (line 99) avoids this by gathering and yielding tensors one by one. You should refactor the LoRA merging logic to perform the merge lazily during iteration, or at least gather-merge-release each tensor individually to maintain memory efficiency.

if not self.is_lora or self.merge_lora_for_rollout:
model.load_weights(self._make_weight_iterator(actor_weights))
else:
lora_int_id = int(time.time_ns() % 0x7FFFFFFF)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Generating lora_int_id using time.time_ns() is non-deterministic across distributed processes. In a multi-GPU setup where multiple ranks share a vLLM engine (e.g., when tensor_parallel_size > 1), different ranks might generate different IDs, causing vLLM to fail or behave inconsistently. This ID should be synchronized across ranks (e.g., using dist.broadcast) or derived from a deterministic source.

)
current_pos += text_len
else: # image (1) or video (2)
grid_thw = next(grid_iters[modality_type])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The code assumes that grid_iters[modality_type] is an iterator. However, if image_grid_thw or video_grid_thw is None, the corresponding entry in grid_iters is initialized to None (see lines 110-111). Calling next(None) will raise a TypeError. You should check if the iterator exists before calling next or ensure that the input tensors are provided if the modality is present in mm_token_type_ids.

weight_key = f"{model_key}.weight"
if weight_key in actor_weights:
delta = (pair["b"] @ pair["a"]) * scaling
actor_weights[weight_key] = actor_weights[weight_key] + delta.to(actor_weights[weight_key].dtype)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using actor_weights[weight_key] + delta creates a new tensor copy. For large models, this can significantly increase CPU memory usage during the merge process. Consider using the in-place add_ method instead.

Suggested change
actor_weights[weight_key] = actor_weights[weight_key] + delta.to(actor_weights[weight_key].dtype)
actor_weights[weight_key].add_(delta.to(actor_weights[weight_key].dtype))

@2877992943

Copy link
Copy Markdown

good job for supporting qwen3.5, however when use this patch, error still occure saying transformers need to upgrade to support qwen3.5. Then more problem happen after update transformer, seems that patched qwen3.5 model not work.Please help detail how to use the patch.

@leah1985

Copy link
Copy Markdown
Author

good job for supporting qwen3.5, however when use this patch, error still occure saying transformers need to upgrade to support qwen3.5. Then more problem happen after update transformer, seems that patched qwen3.5 model not work.Please help detail how to use the patch.

Hi, this is just for my experiment, I have a script to build an image, I also have another 2 local patch script to patch vllm.
I can probably share the code with you but I need to check with my manager first.

@chuoibo

chuoibo commented Jun 26, 2026

Copy link
Copy Markdown

good job for supporting qwen3.5, however when use this patch, error still occure saying transformers need to upgrade to support qwen3.5. Then more problem happen after update transformer, seems that patched qwen3.5 model not work.Please help detail how to use the patch.

Hi, this is just for my experiment, I have a script to build an image, I also have another 2 local patch script to patch vllm. I can probably share the code with you but I need to check with my manager first.

Hey thanks for sharing the amazing work, but are there any new progress toward this one then

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants