@@ -699,6 +699,7 @@ def _attn_impl(
699699 output_sf : Optional [torch .Tensor ] = None ,
700700 attention_sinks : Optional [torch .Tensor ] = None ,
701701 has_lora : bool = False ,
702+ multi_item_part_lens : Optional [list [list [int ]]] = None ,
702703 ):
703704 num_tokens = attn_metadata .num_tokens
704705
@@ -735,6 +736,7 @@ def _attn_impl(
735736 attention_mask_data = attention_mask_data ,
736737 softmax_stats_tensor = softmax_stats ,
737738 attention_sinks = attention_sinks ,
739+ multi_item_part_lens = multi_item_part_lens ,
738740 ))
739741 if isinstance (attn_output , tuple ):
740742 attn_output = attn_output [0 ]
@@ -781,6 +783,7 @@ def _attn_impl(
781783 output = output [:num_tokens , :] if output is not None else None ,
782784 output_sf = output_sf ,
783785 attention_sinks = attention_sinks ,
786+ multi_item_part_lens = multi_item_part_lens ,
784787 ))
785788 if isinstance (attn_output , tuple ):
786789 assert len (
@@ -801,6 +804,7 @@ def forward_impl(
801804 mrope_config : Optional [dict ],
802805 attention_sinks : Optional [torch .Tensor ] = None ,
803806 has_lora : bool = False ,
807+ multi_item_part_lens : Optional [list [list [int ]]] = None ,
804808 ):
805809 mrope_rotary_cos_sin = None
806810 mrope_position_deltas = None
@@ -837,17 +841,20 @@ def forward_impl(
837841 output_sf ,
838842 )
839843 else :
840- output , output_sf = self ._attn_impl (q ,
841- k ,
842- v ,
843- attn_metadata ,
844- attention_mask ,
845- mrope_rotary_cos_sin ,
846- mrope_position_deltas ,
847- attention_window_size ,
848- attention_mask_data ,
849- attention_sinks = attention_sinks ,
850- has_lora = has_lora )
844+ output , output_sf = self ._attn_impl (
845+ q ,
846+ k ,
847+ v ,
848+ attn_metadata ,
849+ attention_mask ,
850+ mrope_rotary_cos_sin ,
851+ mrope_position_deltas ,
852+ attention_window_size ,
853+ attention_mask_data ,
854+ attention_sinks = attention_sinks ,
855+ has_lora = has_lora ,
856+ multi_item_part_lens = multi_item_part_lens ,
857+ )
851858 if output_sf is not None :
852859 output = Fp4QuantizedTensor (output , output_sf )
853860
@@ -865,6 +872,7 @@ def forward(
865872 attention_window_size : Optional [int ] = None ,
866873 attention_mask_data : Optional [torch .Tensor ] = None ,
867874 attention_sinks : Optional [torch .Tensor ] = None ,
875+ multi_item_part_lens : Optional [list [list [int ]]] = None ,
868876 ** kwargs ,
869877 ) -> torch .Tensor :
870878 """
@@ -924,6 +932,23 @@ def forward(
924932 position_ids = self ._adjust_position_ids_for_spec_dec (
925933 position_ids , attn_metadata )
926934
935+ if multi_item_part_lens is not None :
936+ # adjust RoPE positions for multi-item scoring
937+ current_idx = 0
938+ for req_multi_item_part_lens in multi_item_part_lens :
939+ req_prefix_len , * req_multi_item_part_lens = req_multi_item_part_lens
940+ # RoPE for prefix does not need updating and RoPE for delimiter does not matter
941+ current_idx += req_prefix_len + 1
942+ for item_len in req_multi_item_part_lens :
943+ next_idx = current_idx + item_len
944+ position_ids [0 , current_idx :next_idx ].copy_ (
945+ torch .arange (req_prefix_len ,
946+ req_prefix_len + item_len ,
947+ dtype = position_ids .dtype ,
948+ device = position_ids .device ),
949+ non_blocking = True )
950+ current_idx = next_idx + 1 # RoPE for delimiter does not matter
951+
927952 q , k , v = self .apply_rope (q , k , v , position_ids )
928953 q , k , v = self .convert_qkv (q , k , v )
929954
@@ -932,16 +957,19 @@ def forward(
932957 f"Attention sinks are only supported with attn_backend='TRTLLM'. "
933958 f"Current backend: { self .attn_backend } ." )
934959
935- attn_output = self .forward_impl (q ,
936- k ,
937- v ,
938- attn_metadata ,
939- attention_mask ,
940- attention_window_size ,
941- attention_mask_data ,
942- mrope_config = mrope_config ,
943- attention_sinks = attention_sinks ,
944- has_lora = bool (lora_params ))
960+ attn_output = self .forward_impl (
961+ q ,
962+ k ,
963+ v ,
964+ attn_metadata ,
965+ attention_mask ,
966+ attention_window_size ,
967+ attention_mask_data ,
968+ mrope_config = mrope_config ,
969+ attention_sinks = attention_sinks ,
970+ has_lora = bool (lora_params ),
971+ multi_item_part_lens = multi_item_part_lens ,
972+ )
945973
946974 if self .attn_output_gate :
947975 gate = torch .sigmoid (gate )
@@ -1658,12 +1686,14 @@ def _get_attn_scale(position_ids: torch.Tensor) -> torch.Tensor:
16581686 q = (q * attn_scale ).to (q .dtype )
16591687 return q
16601688
1661- def forward_impl (self ,
1662- position_ids : Optional [torch .Tensor ],
1663- hidden_states : torch .Tensor ,
1664- attn_metadata : AttentionMetadata ,
1665- output : torch .Tensor ,
1666- latent_cache_gen : Optional [torch .Tensor ] = None ) -> None :
1689+ def forward_impl (
1690+ self ,
1691+ position_ids : Optional [torch .Tensor ],
1692+ hidden_states : torch .Tensor ,
1693+ attn_metadata : AttentionMetadata ,
1694+ output : torch .Tensor ,
1695+ latent_cache_gen : Optional [torch .Tensor ] = None ,
1696+ ) -> None :
16671697 """
16681698 Forward pass for the MLA module. Writes result into output tensor in-place.
16691699
0 commit comments