fdugyt commited on
Commit
76b7f70
·
verified ·
1 Parent(s): 91cf823

modify sdpa implementation

Browse files
Files changed (1) hide show
  1. modeling_moss_audio_tokenizer.py +49 -2
modeling_moss_audio_tokenizer.py CHANGED
@@ -972,8 +972,55 @@ class MossAudioTokenizerMultiheadAttention(StreamingModule):
972
  batch_size, max_seqlen, _ = x.shape
973
  q, k, v = self._project_qkv(x)
974
  q, k = self._apply_dense_rope(q, k)
975
- attn_bias = self._build_non_streaming_sdpa_bias(input_lengths, max_seqlen, x.device)
976
- out = F.scaled_dot_product_attention(q, k, v, attn_bias, dropout_p=0.0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
977
  valid_q = (torch.arange(max_seqlen, device=x.device).view(1, max_seqlen) < input_lengths.view(-1, 1)).view(
978
  batch_size, 1, max_seqlen, 1
979
  )
 
972
  batch_size, max_seqlen, _ = x.shape
973
  q, k, v = self._project_qkv(x)
974
  q, k = self._apply_dense_rope(q, k)
975
+
976
+ # The native SDPA path accepts the full local-causal mask, but on long
977
+ # codec sequences that materializes a large T x T bias and can also hit
978
+ # backend-specific silent errors. Query chunking keeps the exact same
979
+ # non-streaming attention pattern while bounding each SDPA call.
980
+ query_chunk_size = 1500
981
+ if max_seqlen <= query_chunk_size:
982
+ attn_bias = self._build_non_streaming_sdpa_bias(input_lengths, max_seqlen, x.device)
983
+ out = F.scaled_dot_product_attention(q, k, v, attn_bias, dropout_p=0.0)
984
+ else:
985
+ out = torch.empty_like(q)
986
+ all_positions = torch.arange(max_seqlen, device=x.device, dtype=torch.long)
987
+ for q_start in range(0, max_seqlen, query_chunk_size):
988
+ q_end = min(q_start + query_chunk_size, max_seqlen)
989
+ if self.causal:
990
+ k_end = q_end
991
+ else:
992
+ k_end = max_seqlen
993
+
994
+ if self.context is not None:
995
+ k_start = max(0, q_start - self.context + 1)
996
+ else:
997
+ k_start = 0
998
+
999
+ q_positions = all_positions[q_start:q_end]
1000
+ k_positions = all_positions[k_start:k_end]
1001
+ valid_k = k_positions.view(1, 1, -1) < input_lengths.view(-1, 1, 1)
1002
+ if not self.causal and self.context is None:
1003
+ attn_bias = valid_k[:, None, :, :].expand(-1, 1, q_end - q_start, -1)
1004
+ else:
1005
+ delta = q_positions.view(1, -1, 1) - k_positions.view(1, 1, -1)
1006
+ attn_bias = torch.ones(
1007
+ (1, q_end - q_start, k_end - k_start),
1008
+ device=x.device,
1009
+ dtype=torch.bool,
1010
+ )
1011
+ if self.causal:
1012
+ attn_bias = attn_bias & (delta >= 0)
1013
+ if self.context is not None:
1014
+ attn_bias = attn_bias & (delta < self.context)
1015
+ attn_bias = (attn_bias & valid_k)[:, None, :, :]
1016
+
1017
+ out[:, :, q_start:q_end, :] = F.scaled_dot_product_attention(
1018
+ q[:, :, q_start:q_end, :],
1019
+ k[:, :, k_start:k_end, :],
1020
+ v[:, :, k_start:k_end, :],
1021
+ attn_bias,
1022
+ dropout_p=0.0,
1023
+ )
1024
  valid_q = (torch.arange(max_seqlen, device=x.device).view(1, max_seqlen) < input_lengths.view(-1, 1)).view(
1025
  batch_size, 1, max_seqlen, 1
1026
  )