Download ThinkStream/thinkstream/model/patch.py from JohnCage/stream-tbstars: direct link, hf CLI and curl.
- Browser
- Download file 14.2 kB
-
https://huggingface.co/JohnCage/stream-tbstars/resolve/main/ThinkStream/thinkstream/model/patch.py
- Command line
-
hf download hf://JohnCage/stream-tbstars/ThinkStream/thinkstream/model/patch.py
-
curl -L -o patch.py https://huggingface.co/JohnCage/stream-tbstars/resolve/main/ThinkStream/thinkstream/model/patch.py
14.2 kB
| from liger_kernel.transformers.model import loss_utils | |
| # The original loss_utils | |
| LigerForCausalLMLoss = loss_utils.LigerForCausalLMLoss | |
| def _LigerForCausalLMLoss(*args, **kwargs): | |
| # Remove related kwargs to avoid error | |
| # NOTE: video_block_mask is for flex attention | |
| kwargs.pop("video_block_mask") | |
| return LigerForCausalLMLoss(*args, **kwargs) | |
| loss_utils.LigerForCausalLMLoss = _LigerForCausalLMLoss | |
| # NOTE: We should patch LigerForCausalLMLoss first, and then patch the following models | |
| from transformers.utils import can_return_tuple | |
| from liger_kernel.transformers.model import qwen2_5_vl | |
| from liger_kernel.transformers.model import qwen3_vl | |
| lce_forward_qwen2_5_vl = qwen2_5_vl.lce_forward | |
| lce_forward_qwen3_vl = qwen3_vl.lce_forward | |
| from thinkstream.model.streaming_attention import ( | |
| create_mask, | |
| generate_video_sliding_window_mask_mod, | |
| ) | |
| from thinkstream.model import DEFAULT_VIDEO_FLEX_WINDOW_SIZE | |
| def build_video_block_mask(model, video_mask, attention_mask): | |
| """Create ``video_block_mask`` from ``video_mask`` and ``attention_mask``. | |
| This is the shared helper used by all patched forwards (SFT / GRPO) so | |
| that the sliding-window flex-attention mask is built in exactly one place. | |
| Returns ``None`` when ``video_mask`` is ``None``. | |
| """ | |
| if video_mask is None: | |
| return None | |
| assert attention_mask is not None | |
| window_size_n = getattr( | |
| model.config, "video_flex_window_size", DEFAULT_VIDEO_FLEX_WINDOW_SIZE | |
| ) | |
| B, L = video_mask.shape | |
| assert video_mask.shape == attention_mask.shape | |
| mask_mod = generate_video_sliding_window_mask_mod( | |
| video_mask.contiguous(), attention_mask.contiguous(), window_size_n | |
| ) | |
| return create_mask( | |
| mask_mod, | |
| model.training, | |
| B=B, | |
| H=None, | |
| Q_LEN=L, | |
| KV_LEN=L, | |
| device=model.device, | |
| ) | |
| def _lce_forward_qwen2_5_vl( | |
| self, | |
| *args, | |
| attention_mask=None, | |
| video_mask=None, | |
| **kwargs, | |
| ): | |
| video_block_mask = build_video_block_mask(self, video_mask, attention_mask) | |
| return lce_forward_qwen2_5_vl( | |
| self, | |
| *args, | |
| attention_mask=attention_mask, | |
| video_block_mask=video_block_mask, | |
| **kwargs, | |
| ) | |
| def _lce_forward_qwen3_vl( | |
| self, | |
| *args, | |
| attention_mask=None, | |
| video_mask=None, | |
| **kwargs, | |
| ): | |
| video_block_mask = build_video_block_mask(self, video_mask, attention_mask) | |
| return lce_forward_qwen3_vl( | |
| self, | |
| *args, | |
| attention_mask=attention_mask, | |
| video_block_mask=video_block_mask, | |
| **kwargs, | |
| ) | |
| qwen2_5_vl.lce_forward = _lce_forward_qwen2_5_vl | |
| qwen3_vl.lce_forward = _lce_forward_qwen3_vl | |
| print("Successfully Patched!") | |
| # --------------------------------------------------------------------------- | |
| # Liger fused-linear GRPO forward (replaces lce_forward for GRPO training) | |
| # --------------------------------------------------------------------------- | |
| import torch | |
| from liger_kernel.chunked_loss.grpo_loss import LigerFusedLinearGRPOLoss | |
| from transformers.models.qwen2_5_vl.modeling_qwen2_5_vl import ( | |
| Qwen2_5_VLCausalLMOutputWithPast, | |
| ) | |
| from transformers.models.qwen3_vl.modeling_qwen3_vl import ( | |
| Qwen3VLCausalLMOutputWithPast, | |
| ) | |
| def _pack_by_completion_mask( | |
| shifted_hs, | |
| shifted_labels, | |
| shifted_loss_mask, | |
| old_per_token_logps, | |
| ref_input=None, | |
| ): | |
| """Pack sequences to [B, max_valid_len, ...] so only valid (assistant) positions remain. | |
| Removes gaps from the middle (e.g. video-only segments). Mask is 1 for valid | |
| and 0 only for padding at the end, so no chunk is fully masked in the middle. | |
| Returns (packed_hs, packed_labels, packed_mask, packed_old, packed_ref_input), | |
| or None if max_valid_len == 0. advantages are not packed; pass [B] directly to the loss. | |
| """ | |
| B, L, H = shifted_hs.shape | |
| device = shifted_hs.device | |
| dtype_hs = shifted_hs.dtype | |
| valid_lens = shifted_loss_mask.sum(dim=1).long() # [B] | |
| max_valid_len = int(valid_lens.max().item()) | |
| if max_valid_len == 0: | |
| return None | |
| # Build packed tensors: for each b, take positions where mask[b]==1, then pad to max_valid_len | |
| packed_hs = torch.zeros(B, max_valid_len, H, device=device, dtype=dtype_hs) | |
| packed_labels = torch.zeros( | |
| B, max_valid_len, device=device, dtype=shifted_labels.dtype | |
| ) | |
| packed_mask = torch.zeros( | |
| B, max_valid_len, device=device, dtype=shifted_loss_mask.dtype | |
| ) | |
| if old_per_token_logps is not None: | |
| packed_old = torch.zeros( | |
| B, max_valid_len, device=device, dtype=old_per_token_logps.dtype | |
| ) | |
| else: | |
| packed_old = None | |
| if ref_input is not None: | |
| packed_ref_input = torch.zeros( | |
| B, max_valid_len, H, device=device, dtype=ref_input.dtype | |
| ) | |
| else: | |
| packed_ref_input = None | |
| for b in range(B): | |
| indices = (shifted_loss_mask[b] == 1).nonzero(as_tuple=True)[0] | |
| n = indices.numel() | |
| if n == 0: | |
| continue | |
| packed_hs[b, :n] = shifted_hs[b, indices] | |
| packed_labels[b, :n] = shifted_labels[b, indices] | |
| packed_mask[b, :n] = 1 | |
| if old_per_token_logps is not None: | |
| packed_old[b, :n] = old_per_token_logps[b, indices] | |
| if ref_input is not None: | |
| packed_ref_input[b, :n] = ref_input[b, indices] | |
| return ( | |
| packed_hs, | |
| packed_labels, | |
| packed_mask, | |
| packed_old, | |
| packed_ref_input, | |
| ) | |
| def _grpo_lce_forward_common( | |
| self, | |
| input_ids=None, | |
| attention_mask=None, | |
| position_ids=None, | |
| past_key_values=None, | |
| inputs_embeds=None, | |
| labels=None, | |
| use_cache=None, | |
| output_attentions=None, | |
| output_hidden_states=None, | |
| return_dict=None, | |
| pixel_values=None, | |
| pixel_values_videos=None, | |
| image_grid_thw=None, | |
| video_grid_thw=None, | |
| rope_deltas=None, | |
| cache_position=None, | |
| second_per_grid_ts=None, | |
| logits_to_keep=0, | |
| advantages=None, | |
| old_per_token_logps=None, | |
| ref_input=None, | |
| ref_weight=None, | |
| ref_bias=None, | |
| completion_mask=None, | |
| grpo_beta=0.04, | |
| grpo_loss_type="grpo", | |
| video_mask=None, | |
| output_cls=None, | |
| add_second_per_grid_ts=False, | |
| **kwargs, | |
| ): | |
| """Shared GRPO LCE forward logic. Call from model-specific forward with | |
| output_cls and add_second_per_grid_ts set (e.g. Qwen2.5-VL True, Qwen3-VL False). | |
| """ | |
| video_block_mask = build_video_block_mask(self, video_mask, attention_mask) | |
| output_attentions = ( | |
| output_attentions | |
| if output_attentions is not None | |
| else self.config.output_attentions | |
| ) | |
| output_hidden_states = ( | |
| output_hidden_states | |
| if output_hidden_states is not None | |
| else self.config.output_hidden_states | |
| ) | |
| return_dict = ( | |
| return_dict if return_dict is not None else self.config.use_return_dict | |
| ) | |
| backbone_kwargs = dict( | |
| input_ids=input_ids, | |
| pixel_values=pixel_values, | |
| pixel_values_videos=pixel_values_videos, | |
| image_grid_thw=image_grid_thw, | |
| video_grid_thw=video_grid_thw, | |
| position_ids=position_ids, | |
| attention_mask=attention_mask, | |
| past_key_values=past_key_values, | |
| inputs_embeds=inputs_embeds, | |
| use_cache=use_cache, | |
| output_attentions=output_attentions, | |
| output_hidden_states=output_hidden_states, | |
| return_dict=True, | |
| cache_position=cache_position, | |
| video_block_mask=video_block_mask, | |
| **kwargs, | |
| ) | |
| if add_second_per_grid_ts: | |
| backbone_kwargs["second_per_grid_ts"] = second_per_grid_ts | |
| outputs = self.model(**backbone_kwargs) | |
| hidden_states = outputs[0] | |
| loss = None | |
| logits = None | |
| if advantages is not None: | |
| assert completion_mask is not None | |
| shifted_hs = hidden_states[:, :-1, :].contiguous() | |
| shifted_labels = input_ids[:, 1:] | |
| shifted_loss_mask = completion_mask[:, 1:] | |
| adv = advantages.to(shifted_hs.device) | |
| packed = _pack_by_completion_mask( | |
| shifted_hs, | |
| shifted_labels, | |
| shifted_loss_mask, | |
| old_per_token_logps, | |
| ref_input=ref_input, | |
| ) | |
| if packed is None: | |
| loss = shifted_hs.new_zeros([]) | |
| else: | |
| packed_hs, packed_labels, packed_mask, packed_old, packed_ref_input = packed | |
| grpo_loss_fn = LigerFusedLinearGRPOLoss( | |
| beta=grpo_beta, | |
| loss_type=grpo_loss_type, | |
| use_ref_model=True, | |
| compiled=True, | |
| ) | |
| result = grpo_loss_fn( | |
| _input=packed_hs, | |
| lin_weight=self.lm_head.weight, | |
| selected_token_ids=packed_labels, | |
| attention_mask=packed_mask, | |
| advantages=adv, | |
| bias=self.lm_head.bias, | |
| old_per_token_logps=packed_old, | |
| ref_input=packed_ref_input, | |
| ref_weight=ref_weight, | |
| ref_bias=ref_bias, | |
| ) | |
| loss = result[0] if isinstance(result, tuple) else result | |
| else: | |
| slice_indices = ( | |
| slice(-logits_to_keep, None) | |
| if isinstance(logits_to_keep, int) | |
| else logits_to_keep | |
| ) | |
| logits = self.lm_head(hidden_states[:, slice_indices, :]) | |
| if labels is not None: | |
| text_config = getattr(self.config, "text_config", self.config) | |
| loss = self.loss_function( | |
| logits=logits, | |
| labels=labels, | |
| vocab_size=text_config.vocab_size, | |
| ) | |
| if not return_dict: | |
| output = (logits,) + outputs[1:] | |
| return (loss,) + output if loss is not None else output | |
| return output_cls( | |
| loss=loss, | |
| logits=logits, | |
| past_key_values=outputs.past_key_values, | |
| hidden_states=outputs.hidden_states, | |
| attentions=outputs.attentions, | |
| rope_deltas=getattr(outputs, "rope_deltas", None), | |
| ) | |
| def grpo_lce_forward_qwen2_5_vl( | |
| self, | |
| input_ids=None, | |
| attention_mask=None, | |
| position_ids=None, | |
| past_key_values=None, | |
| inputs_embeds=None, | |
| labels=None, | |
| use_cache=None, | |
| output_attentions=None, | |
| output_hidden_states=None, | |
| return_dict=None, | |
| pixel_values=None, | |
| pixel_values_videos=None, | |
| image_grid_thw=None, | |
| video_grid_thw=None, | |
| rope_deltas=None, | |
| cache_position=None, | |
| second_per_grid_ts=None, | |
| logits_to_keep=0, | |
| advantages=None, | |
| old_per_token_logps=None, | |
| ref_input=None, | |
| ref_weight=None, | |
| ref_bias=None, | |
| completion_mask=None, | |
| grpo_beta=0.04, | |
| grpo_loss_type="grpo", | |
| video_mask=None, | |
| **kwargs, | |
| ): | |
| """GRPO-aware forward for Qwen2.5-VL (uses LigerFusedLinearGRPOLoss when advantages given).""" | |
| return _grpo_lce_forward_common( | |
| self, | |
| input_ids=input_ids, | |
| attention_mask=attention_mask, | |
| position_ids=position_ids, | |
| past_key_values=past_key_values, | |
| inputs_embeds=inputs_embeds, | |
| labels=labels, | |
| use_cache=use_cache, | |
| output_attentions=output_attentions, | |
| output_hidden_states=output_hidden_states, | |
| return_dict=return_dict, | |
| pixel_values=pixel_values, | |
| pixel_values_videos=pixel_values_videos, | |
| image_grid_thw=image_grid_thw, | |
| video_grid_thw=video_grid_thw, | |
| rope_deltas=rope_deltas, | |
| cache_position=cache_position, | |
| second_per_grid_ts=second_per_grid_ts, | |
| logits_to_keep=logits_to_keep, | |
| advantages=advantages, | |
| old_per_token_logps=old_per_token_logps, | |
| ref_input=ref_input, | |
| ref_weight=ref_weight, | |
| ref_bias=ref_bias, | |
| completion_mask=completion_mask, | |
| grpo_beta=grpo_beta, | |
| grpo_loss_type=grpo_loss_type, | |
| video_mask=video_mask, | |
| output_cls=Qwen2_5_VLCausalLMOutputWithPast, | |
| add_second_per_grid_ts=True, | |
| **kwargs, | |
| ) | |
| def grpo_lce_forward_qwen3vl( | |
| self, | |
| input_ids=None, | |
| attention_mask=None, | |
| position_ids=None, | |
| past_key_values=None, | |
| inputs_embeds=None, | |
| labels=None, | |
| use_cache=None, | |
| output_attentions=None, | |
| output_hidden_states=None, | |
| return_dict=None, | |
| pixel_values=None, | |
| pixel_values_videos=None, | |
| image_grid_thw=None, | |
| video_grid_thw=None, | |
| rope_deltas=None, | |
| cache_position=None, | |
| second_per_grid_ts=None, | |
| logits_to_keep=0, | |
| advantages=None, | |
| old_per_token_logps=None, | |
| ref_input=None, | |
| ref_weight=None, | |
| ref_bias=None, | |
| completion_mask=None, | |
| grpo_beta=0.04, | |
| grpo_loss_type="grpo", | |
| video_mask=None, | |
| **kwargs, | |
| ): | |
| """GRPO-aware forward for Qwen3-VL (uses LigerFusedLinearGRPOLoss when advantages given).""" | |
| return _grpo_lce_forward_common( | |
| self, | |
| input_ids=input_ids, | |
| attention_mask=attention_mask, | |
| position_ids=position_ids, | |
| past_key_values=past_key_values, | |
| inputs_embeds=inputs_embeds, | |
| labels=labels, | |
| use_cache=use_cache, | |
| output_attentions=output_attentions, | |
| output_hidden_states=output_hidden_states, | |
| return_dict=return_dict, | |
| pixel_values=pixel_values, | |
| pixel_values_videos=pixel_values_videos, | |
| image_grid_thw=image_grid_thw, | |
| video_grid_thw=video_grid_thw, | |
| rope_deltas=rope_deltas, | |
| cache_position=cache_position, | |
| second_per_grid_ts=second_per_grid_ts, | |
| logits_to_keep=logits_to_keep, | |
| advantages=advantages, | |
| old_per_token_logps=old_per_token_logps, | |
| ref_input=ref_input, | |
| ref_weight=ref_weight, | |
| ref_bias=ref_bias, | |
| completion_mask=completion_mask, | |
| grpo_beta=grpo_beta, | |
| grpo_loss_type=grpo_loss_type, | |
| video_mask=video_mask, | |
| output_cls=Qwen3VLCausalLMOutputWithPast, | |
| add_second_per_grid_ts=False, | |
| **kwargs, | |
| ) | |
| # model_type -> GRPO LCE forward (same keys as thinkstream.model.MODEL_CLS) | |
| GRPO_LCE_FORWARD = { | |
| "qwen2.5vl": grpo_lce_forward_qwen2_5_vl, | |
| "qwen3vl": grpo_lce_forward_qwen3vl, | |
| } | |