Artrajz commited on
Commit
5de6046
·
1 Parent(s): b43ef32

Update GPT-SoVITS

Browse files
gpt_sovits/AR/models/t2s_model.py CHANGED
@@ -506,18 +506,32 @@ class Text2SemanticDecoder(nn.Module):
506
 
507
  def infer_panel_batch_infer_with_flash_attn(
508
  self,
509
- x, #####全部文本token
510
- x_lens,
511
- prompts, ####参考音频token
512
- bert_feature,
513
  top_k: int = -100,
514
  top_p: float = 100,
515
  early_stop_num: int = -1,
516
  temperature: float = 1.0,
517
  ):
518
-
519
- bert_feature = self.bert_proj(bert_feature.transpose(1, 2))
520
- x = self.ar_text_embedding(x)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
521
  x = x + bert_feature
522
  x = self.ar_text_position(x)
523
 
@@ -660,17 +674,33 @@ class Text2SemanticDecoder(nn.Module):
660
 
661
  def infer_panel_batch_only(
662
  self,
663
- x, #####全部文本token
664
- x_lens,
665
- prompts, ####参考音频token
666
- bert_feature,
667
  top_k: int = -100,
668
- top_p: float = 100,
669
  early_stop_num: int = -1,
670
  temperature: float = 1.0,
671
  ):
672
- x = self.ar_text_embedding(x)
673
- x = x + self.bert_proj(bert_feature.transpose(1, 2))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
674
  x = self.ar_text_position(x)
675
 
676
  # AR Decoder
@@ -709,19 +739,35 @@ class Text2SemanticDecoder(nn.Module):
709
  y = torch.zeros(x.shape[0], 0, dtype=torch.int, device=x.device)
710
  ref_free = True
711
 
712
- x_attn_mask_pad = F.pad(
 
 
 
 
 
 
 
 
 
 
713
  x_attn_mask,
714
  (0, y_len), ###xx的纯0扩展到xx纯0+xy纯1,(x,x+y)
715
  value=True,
716
  )
717
- y_attn_mask = F.pad( ###yy的右上1扩展到左边xy的0,(y,x+y)
718
  torch.triu(torch.ones(y_len, y_len, dtype=torch.bool), diagonal=1),
719
  (x_len, 0),
720
  value=False,
721
  )
722
- xy_attn_mask = torch.concat([x_attn_mask_pad, y_attn_mask], dim=0).to(
723
- x.device
724
- )
 
 
 
 
 
 
725
 
726
  y_list = [None] * y.shape[0]
727
  batch_idx_map = list(range(y.shape[0]))
@@ -817,4 +863,4 @@ class Text2SemanticDecoder(nn.Module):
817
 
818
  if ref_free:
819
  return y_list, [0] * x.shape[0]
820
- return y_list, idx_list
 
506
 
507
  def infer_panel_batch_infer_with_flash_attn(
508
  self,
509
+ x: List[torch.LongTensor], #####全部文本token
510
+ x_lens: torch.LongTensor,
511
+ prompts: torch.LongTensor, ####参考音频token
512
+ bert_feature: List[torch.LongTensor],
513
  top_k: int = -100,
514
  top_p: float = 100,
515
  early_stop_num: int = -1,
516
  temperature: float = 1.0,
517
  ):
518
+ # 先对phones进行embedding、对bert_features进行project,再pad到相同长度,以缓解复读问题。(可能还有其他因素导致复读)
519
+ max_len = 0
520
+ for x_item, bert_item in zip(x, bert_feature):
521
+ max_len = max(max_len, x_item.shape[0], bert_item.shape[1])
522
+ x_list = [self.ar_text_embedding(item) for item in x]
523
+ x_list = [F.pad(item, (0, 0, 0, max_len - item.shape[0]), value=0) if item.shape[0] < max_len else item for item
524
+ in x_list]
525
+ x = torch.stack(x_list, dim=0)
526
+
527
+ bert_features_list = [self.bert_proj(item.transpose(0, 1)) for item in bert_feature]
528
+ bert_features_list = [
529
+ F.pad(item, (0, 0, 0, max_len - item.shape[0]), value=0) if item.shape[0] < max_len else item for item in
530
+ bert_features_list]
531
+ bert_feature = torch.stack(bert_features_list, dim=0)
532
+
533
+ # bert_feature = self.bert_proj(bert_feature.transpose(1, 2))
534
+ # x = self.ar_text_embedding(x)
535
  x = x + bert_feature
536
  x = self.ar_text_position(x)
537
 
 
674
 
675
  def infer_panel_batch_only(
676
  self,
677
+ x: List[torch.LongTensor], #####全部文本token
678
+ x_lens: torch.LongTensor,
679
+ prompts: torch.LongTensor, ####参考音频token
680
+ bert_feature: List[torch.LongTensor],
681
  top_k: int = -100,
682
+ top_p: int = 100,
683
  early_stop_num: int = -1,
684
  temperature: float = 1.0,
685
  ):
686
+ # 先对phones进行embedding、对bert_features进行project,再pad到相同长度,以缓解复读问题。(可能还有其他因素导致复读)
687
+ max_len = 0
688
+ for x_item, bert_item in zip(x, bert_feature):
689
+ max_len = max(max_len, x_item.shape[0], bert_item.shape[1])
690
+ x_list = [self.ar_text_embedding(item) for item in x]
691
+ x_list = [F.pad(item, (0, 0, 0, max_len - item.shape[0]), value=0) if item.shape[0] < max_len else item for item
692
+ in x_list]
693
+ x = torch.stack(x_list, dim=0)
694
+
695
+ bert_features_list = [self.bert_proj(item.transpose(0, 1)) for item in bert_feature]
696
+ bert_features_list = [
697
+ F.pad(item, (0, 0, 0, max_len - item.shape[0]), value=0) if item.shape[0] < max_len else item for item in
698
+ bert_features_list]
699
+ bert_feature = torch.stack(bert_features_list, dim=0)
700
+
701
+ # bert_feature = self.bert_proj(bert_feature.transpose(1, 2))
702
+ # x = self.ar_text_embedding(x)
703
+ x = x + bert_feature
704
  x = self.ar_text_position(x)
705
 
706
  # AR Decoder
 
739
  y = torch.zeros(x.shape[0], 0, dtype=torch.int, device=x.device)
740
  ref_free = True
741
 
742
+ ##### create mask #####
743
+ bsz = x.shape[0]
744
+ src_len = x_len + y_len
745
+ y_lens = torch.LongTensor([y_len] * bsz).to(x.device)
746
+ y_mask = make_pad_mask(y_lens)
747
+ x_mask = make_pad_mask(x_lens)
748
+
749
+ # (bsz, x_len + y_len)
750
+ xy_padding_mask = torch.concat([x_mask, y_mask], dim=1)
751
+
752
+ x_mask = F.pad(
753
  x_attn_mask,
754
  (0, y_len), ###xx的纯0扩展到xx纯0+xy纯1,(x,x+y)
755
  value=True,
756
  )
757
+ y_mask = F.pad( ###yy的右上1扩展到左边xy的0,(y,x+y)
758
  torch.triu(torch.ones(y_len, y_len, dtype=torch.bool), diagonal=1),
759
  (x_len, 0),
760
  value=False,
761
  )
762
+
763
+ xy_mask = torch.concat([x_mask, y_mask], dim=0).view(1, src_len, src_len).expand(bsz * self.num_head, -1,
764
+ -1).to(x.device)
765
+ # xy_mask = torch.triu(torch.ones(src_len, src_len, dtype=torch.bool, device=x.device), diagonal=1)
766
+ xy_padding_mask = xy_padding_mask.view(bsz, 1, src_len).expand(bsz, src_len, src_len).repeat(self.num_head, 1,
767
+ 1)
768
+ xy_attn_mask = xy_mask.logical_or(xy_padding_mask)
769
+ new_attn_mask = torch.zeros_like(xy_attn_mask, dtype=x.dtype)
770
+ xy_attn_mask = new_attn_mask.masked_fill(xy_attn_mask, float("-inf"))
771
 
772
  y_list = [None] * y.shape[0]
773
  batch_idx_map = list(range(y.shape[0]))
 
863
 
864
  if ref_free:
865
  return y_list, [0] * x.shape[0]
866
+ return y_list, idx_list
gpt_sovits/text/tone_sandhi.py CHANGED
@@ -663,32 +663,29 @@ class ToneSandhi:
663
  # input seg: [('听', 'v'), ('一', 'm'), ('听', 'v')]
664
  # output seg: [['听一听', 'v']]
665
  def _merge_yi(self, seg: List[Tuple[str, str]]) -> List[Tuple[str, str]]:
666
- new_seg = [] * len(seg)
667
  # function 1
668
- i = 0
669
- while i < len(seg):
670
- word, pos = seg[i]
671
  if (
672
- i - 1 >= 0
673
- and word == "一"
674
- and i + 1 < len(seg)
675
- and seg[i - 1][0] == seg[i + 1][0]
676
- and seg[i - 1][1] == "v"
 
677
  ):
678
  new_seg[i - 1][0] = new_seg[i - 1][0] + "一" + new_seg[i - 1][0]
679
- i += 2
680
  else:
681
  if (
682
- i - 2 >= 0
683
- and seg[i - 1][0] == "一"
684
- and seg[i - 2][0] == word
685
- and pos == "v"
686
  ):
687
  continue
688
  else:
689
  new_seg.append([word, pos])
690
- i += 1
691
- seg = [i for i in new_seg if len(i) > 0]
692
  new_seg = []
693
  # function 2
694
  for i, (word, pos) in enumerate(seg):
 
663
  # input seg: [('听', 'v'), ('一', 'm'), ('听', 'v')]
664
  # output seg: [['听一听', 'v']]
665
  def _merge_yi(self, seg: List[Tuple[str, str]]) -> List[Tuple[str, str]]:
666
+ new_seg = []
667
  # function 1
668
+ for i, (word, pos) in enumerate(seg):
 
 
669
  if (
670
+ i - 1 >= 0
671
+ and word == "一"
672
+ and i + 1 < len(seg)
673
+ and seg[i - 1][0] == seg[i + 1][0]
674
+ and seg[i - 1][1] == "v"
675
+ and seg[i + 1][1] == "v"
676
  ):
677
  new_seg[i - 1][0] = new_seg[i - 1][0] + "一" + new_seg[i - 1][0]
 
678
  else:
679
  if (
680
+ i - 2 >= 0
681
+ and seg[i - 1][0] == "一"
682
+ and seg[i - 2][0] == word
683
+ and pos == "v"
684
  ):
685
  continue
686
  else:
687
  new_seg.append([word, pos])
688
+ seg = new_seg
 
689
  new_seg = []
690
  # function 2
691
  for i, (word, pos) in enumerate(seg):
gpt_sovits/text/zh_normalization/num.py CHANGED
@@ -172,7 +172,23 @@ def replace_range(match) -> str:
172
  return result
173
 
174
 
175
- def _get_value(value_string: str, use_zero: bool=True) -> List[str]:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
  stripped = value_string.lstrip('0')
177
  if len(stripped) == 0:
178
  return []
@@ -202,7 +218,7 @@ def verbalize_cardinal(value_string: str) -> str:
202
  result_symbols = _get_value(value_string)
203
  # verbalized number starting with '一十*' is abbreviated as `十*`
204
  if len(result_symbols) >= 2 and result_symbols[0] == DIGITS[
205
- '1'] and result_symbols[1] == UNITS[1]:
206
  result_symbols = result_symbols[1:]
207
  return ''.join(result_symbols)
208
 
 
172
  return result
173
 
174
 
175
+ # ~至表达式
176
+ RE_TO_RANGE = re.compile(
177
+ r'((-?)((\d+)(\.\d+)?)|(\.(\d+)))(%|°C|℃|度|摄氏度|cm2|cm²|cm3|cm³|cm|db|ds|kg|km|m2|m²|m³|m3|ml|m|mm|s)[~]((-?)((\d+)(\.\d+)?)|(\.(\d+)))(%|°C|℃|度|摄氏度|cm2|cm²|cm3|cm³|cm|db|ds|kg|km|m2|m²|m³|m3|ml|m|mm|s)')
178
+
179
+
180
+ def replace_to_range(match) -> str:
181
+ """
182
+ Args:
183
+ match (re.Match)
184
+ Returns:
185
+ str
186
+ """
187
+ result = match.group(0).replace('~', '至')
188
+ return result
189
+
190
+
191
+ def _get_value(value_string: str, use_zero: bool = True) -> List[str]:
192
  stripped = value_string.lstrip('0')
193
  if len(stripped) == 0:
194
  return []
 
218
  result_symbols = _get_value(value_string)
219
  # verbalized number starting with '一十*' is abbreviated as `十*`
220
  if len(result_symbols) >= 2 and result_symbols[0] == DIGITS[
221
+ '1'] and result_symbols[1] == UNITS[1]:
222
  result_symbols = result_symbols[1:]
223
  return ''.join(result_symbols)
224
 
gpt_sovits/text/zh_normalization/text_normlization.py CHANGED
@@ -33,6 +33,7 @@ from .num import RE_NUMBER
33
  from .num import RE_PERCENTAGE
34
  from .num import RE_POSITIVE_QUANTIFIERS
35
  from .num import RE_RANGE
 
36
  from .num import replace_default_num
37
  from .num import replace_frac
38
  from .num import replace_negative_num
@@ -40,6 +41,7 @@ from .num import replace_number
40
  from .num import replace_percentage
41
  from .num import replace_positive_quantifier
42
  from .num import replace_range
 
43
  from .phonecode import RE_MOBILE_PHONE
44
  from .phonecode import RE_NATIONAL_UNIFORM_NUMBER
45
  from .phonecode import RE_TELEPHONE
@@ -65,7 +67,7 @@ class TextNormalizer():
65
  if lang == "zh":
66
  text = text.replace(" ", "")
67
  # 过滤掉特殊字符
68
- text = re.sub(r'[——《》【】<=>{}()()#&@“”^_|\\]', '', text)
69
  text = self.SENTENCE_SPLITOR.sub(r'\1\n', text)
70
  text = text.strip()
71
  sentences = [sentence.strip() for sentence in re.split(r'\n+', text)]
@@ -73,8 +75,8 @@ class TextNormalizer():
73
 
74
  def _post_replace(self, sentence: str) -> str:
75
  sentence = sentence.replace('/', '每')
76
- sentence = sentence.replace('~', '至')
77
- sentence = sentence.replace('~', '至')
78
  sentence = sentence.replace('①', '一')
79
  sentence = sentence.replace('②', '二')
80
  sentence = sentence.replace('③', '三')
@@ -111,7 +113,7 @@ class TextNormalizer():
111
  sentence = sentence.replace('ψ', '普赛').replace('Ψ', '普赛')
112
  sentence = sentence.replace('ω', '欧米伽').replace('Ω', '欧米伽')
113
  # re filter special characters, have one more character "-" than line 68
114
- sentence = re.sub(r'[-——《》【】<=>{}()()#&@“”^_|\\]', '', sentence)
115
  return sentence
116
 
117
  def normalize_sentence(self, sentence: str) -> str:
@@ -128,6 +130,8 @@ class TextNormalizer():
128
  sentence = RE_TIME_RANGE.sub(replace_time, sentence)
129
  sentence = RE_TIME.sub(replace_time, sentence)
130
 
 
 
131
  sentence = RE_TEMPERATURE.sub(replace_temperature, sentence)
132
  sentence = replace_measure(sentence)
133
  sentence = RE_FRAC.sub(replace_frac, sentence)
 
33
  from .num import RE_PERCENTAGE
34
  from .num import RE_POSITIVE_QUANTIFIERS
35
  from .num import RE_RANGE
36
+ from .num import RE_TO_RANGE
37
  from .num import replace_default_num
38
  from .num import replace_frac
39
  from .num import replace_negative_num
 
41
  from .num import replace_percentage
42
  from .num import replace_positive_quantifier
43
  from .num import replace_range
44
+ from .num import replace_to_range
45
  from .phonecode import RE_MOBILE_PHONE
46
  from .phonecode import RE_NATIONAL_UNIFORM_NUMBER
47
  from .phonecode import RE_TELEPHONE
 
67
  if lang == "zh":
68
  text = text.replace(" ", "")
69
  # 过滤掉特殊字符
70
+ text = re.sub(r'[——《》【】<=>{}()()#&@“”^_|\\]', '', text)
71
  text = self.SENTENCE_SPLITOR.sub(r'\1\n', text)
72
  text = text.strip()
73
  sentences = [sentence.strip() for sentence in re.split(r'\n+', text)]
 
75
 
76
  def _post_replace(self, sentence: str) -> str:
77
  sentence = sentence.replace('/', '每')
78
+ # sentence = sentence.replace('~', '至')
79
+ # sentence = sentence.replace('~', '至')
80
  sentence = sentence.replace('①', '一')
81
  sentence = sentence.replace('②', '二')
82
  sentence = sentence.replace('③', '三')
 
113
  sentence = sentence.replace('ψ', '普赛').replace('Ψ', '普赛')
114
  sentence = sentence.replace('ω', '欧米伽').replace('Ω', '欧米伽')
115
  # re filter special characters, have one more character "-" than line 68
116
+ sentence = re.sub(r'[-——《》【】<=>{}()()#&@“”^_|\\]', '', sentence)
117
  return sentence
118
 
119
  def normalize_sentence(self, sentence: str) -> str:
 
130
  sentence = RE_TIME_RANGE.sub(replace_time, sentence)
131
  sentence = RE_TIME.sub(replace_time, sentence)
132
 
133
+ # 处理~波浪号作为至的替换
134
+ sentence = RE_TO_RANGE.sub(replace_to_range, sentence)
135
  sentence = RE_TEMPERATURE.sub(replace_temperature, sentence)
136
  sentence = replace_measure(sentence)
137
  sentence = RE_FRAC.sub(replace_frac, sentence)