chatterbox-light 1.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. chatterbox/__init__.py +11 -0
  2. chatterbox/models/__init__.py +0 -0
  3. chatterbox/models/s3gen/__init__.py +2 -0
  4. chatterbox/models/s3gen/configs.py +10 -0
  5. chatterbox/models/s3gen/const.py +2 -0
  6. chatterbox/models/s3gen/decoder.py +292 -0
  7. chatterbox/models/s3gen/f0_predictor.py +42 -0
  8. chatterbox/models/s3gen/flow.py +163 -0
  9. chatterbox/models/s3gen/flow_matching.py +140 -0
  10. chatterbox/models/s3gen/hifigan.py +350 -0
  11. chatterbox/models/s3gen/matcha/conformer_block.py +249 -0
  12. chatterbox/models/s3gen/matcha/decoder.py +412 -0
  13. chatterbox/models/s3gen/matcha/flow_matching.py +76 -0
  14. chatterbox/models/s3gen/matcha/transformer.py +235 -0
  15. chatterbox/models/s3gen/s3gen.py +293 -0
  16. chatterbox/models/s3gen/transformer/__init__.py +0 -0
  17. chatterbox/models/s3gen/transformer/activation.py +35 -0
  18. chatterbox/models/s3gen/transformer/attention.py +153 -0
  19. chatterbox/models/s3gen/transformer/convolution.py +97 -0
  20. chatterbox/models/s3gen/transformer/embedding.py +170 -0
  21. chatterbox/models/s3gen/transformer/encoder_layer.py +135 -0
  22. chatterbox/models/s3gen/transformer/positionwise_feed_forward.py +56 -0
  23. chatterbox/models/s3gen/transformer/subsampling.py +209 -0
  24. chatterbox/models/s3gen/transformer/upsample_encoder.py +219 -0
  25. chatterbox/models/s3gen/utils/class_utils.py +57 -0
  26. chatterbox/models/s3gen/utils/intmeanflow.py +33 -0
  27. chatterbox/models/s3gen/utils/mask.py +75 -0
  28. chatterbox/models/s3gen/utils/mel.py +76 -0
  29. chatterbox/models/s3gen/xvector.py +399 -0
  30. chatterbox/models/s3tokenizer/__init__.py +30 -0
  31. chatterbox/models/s3tokenizer/s3tokenizer.py +140 -0
  32. chatterbox/models/t3/__init__.py +1 -0
  33. chatterbox/models/t3/inference/t3_hf_backend.py +86 -0
  34. chatterbox/models/t3/llama_configs.py +106 -0
  35. chatterbox/models/t3/modules/cond_enc.py +80 -0
  36. chatterbox/models/t3/modules/learned_pos_emb.py +22 -0
  37. chatterbox/models/t3/modules/perceiver.py +169 -0
  38. chatterbox/models/t3/modules/t3_config.py +39 -0
  39. chatterbox/models/t3/t3.py +468 -0
  40. chatterbox/models/tokenizers/__init__.py +1 -0
  41. chatterbox/models/tokenizers/tokenizer.py +286 -0
  42. chatterbox/models/utils.py +4 -0
  43. chatterbox/models/voice_encoder/__init__.py +1 -0
  44. chatterbox/models/voice_encoder/config.py +18 -0
  45. chatterbox/models/voice_encoder/melspec.py +84 -0
  46. chatterbox/models/voice_encoder/voice_encoder.py +222 -0
  47. chatterbox/mtl_tts.py +331 -0
  48. chatterbox/tts.py +252 -0
  49. chatterbox/tts_turbo.py +283 -0
  50. chatterbox/vc.py +111 -0
  51. chatterbox_light-1.0.1.dist-info/METADATA +141 -0
  52. chatterbox_light-1.0.1.dist-info/RECORD +55 -0
  53. chatterbox_light-1.0.1.dist-info/WHEEL +5 -0
  54. chatterbox_light-1.0.1.dist-info/licenses/LICENSE +21 -0
  55. chatterbox_light-1.0.1.dist-info/top_level.txt +1 -0
chatterbox/__init__.py ADDED
@@ -0,0 +1,11 @@
1
+ try:
2
+ from importlib.metadata import version
3
+ except ImportError:
4
+ from importlib_metadata import version # For Python <3.8
5
+
6
+ __version__ = version("chatterbox-light")
7
+
8
+
9
+ from .tts import ChatterboxTTS
10
+ from .vc import ChatterboxVC
11
+ from .mtl_tts import ChatterboxMultilingualTTS, SUPPORTED_LANGUAGES
File without changes
@@ -0,0 +1,2 @@
1
+ from .s3gen import S3Token2Wav as S3Gen
2
+ from .const import S3GEN_SR
@@ -0,0 +1,10 @@
1
+ from ..utils import AttrDict
2
+
3
+ CFM_PARAMS = AttrDict({
4
+ "sigma_min": 1e-06,
5
+ "solver": "euler",
6
+ "t_scheduler": "cosine",
7
+ "training_cfg_rate": 0.2,
8
+ "inference_cfg_rate": 0.7,
9
+ "reg_loss_type": "l1"
10
+ })
@@ -0,0 +1,2 @@
1
+ S3GEN_SR = 24000
2
+ S3GEN_SIL = 4299
@@ -0,0 +1,292 @@
1
+ import torch
2
+ import torch.nn as nn
3
+ import torch.nn.functional as F
4
+ from einops import pack, rearrange, repeat
5
+
6
+ from .utils.mask import add_optional_chunk_mask
7
+ from .matcha.decoder import SinusoidalPosEmb, Block1D, ResnetBlock1D, Downsample1D, \
8
+ TimestepEmbedding, Upsample1D
9
+ from .matcha.transformer import BasicTransformerBlock
10
+ from .utils.intmeanflow import get_intmeanflow_time_mixer
11
+
12
+
13
+ def mask_to_bias(mask: torch.Tensor, dtype: torch.dtype) -> torch.Tensor:
14
+ assert mask.dtype == torch.bool
15
+ assert dtype in [torch.float32, torch.bfloat16, torch.float16]
16
+ mask = mask.to(dtype)
17
+ mask = (1.0 - mask) * -1.0e+10
18
+ return mask
19
+
20
+
21
+
22
+ class Transpose(torch.nn.Module):
23
+ def __init__(self, dim0: int, dim1: int):
24
+ super().__init__()
25
+ self.dim0 = dim0
26
+ self.dim1 = dim1
27
+
28
+ def forward(self, x: torch.Tensor):
29
+ x = torch.transpose(x, self.dim0, self.dim1)
30
+ return x
31
+
32
+
33
+ class CausalBlock1D(Block1D):
34
+ def __init__(self, dim: int, dim_out: int):
35
+ super(CausalBlock1D, self).__init__(dim, dim_out)
36
+ self.block = torch.nn.Sequential(
37
+ CausalConv1d(dim, dim_out, 3),
38
+ Transpose(1, 2),
39
+ nn.LayerNorm(dim_out),
40
+ Transpose(1, 2),
41
+ nn.Mish(),
42
+ )
43
+
44
+ def forward(self, x: torch.Tensor, mask: torch.Tensor):
45
+ output = self.block(x * mask)
46
+ return output * mask
47
+
48
+
49
+ class CausalResnetBlock1D(ResnetBlock1D):
50
+ def __init__(self, dim: int, dim_out: int, time_emb_dim: int, groups: int = 8):
51
+ super(CausalResnetBlock1D, self).__init__(dim, dim_out, time_emb_dim, groups)
52
+ self.block1 = CausalBlock1D(dim, dim_out)
53
+ self.block2 = CausalBlock1D(dim_out, dim_out)
54
+
55
+
56
+ class CausalConv1d(torch.nn.Conv1d):
57
+ def __init__(
58
+ self,
59
+ in_channels: int,
60
+ out_channels: int,
61
+ kernel_size: int,
62
+ stride: int = 1,
63
+ dilation: int = 1,
64
+ groups: int = 1,
65
+ bias: bool = True,
66
+ padding_mode: str = 'zeros',
67
+ device=None,
68
+ dtype=None
69
+ ) -> None:
70
+ super(CausalConv1d, self).__init__(in_channels, out_channels,
71
+ kernel_size, stride,
72
+ padding=0, dilation=dilation,
73
+ groups=groups, bias=bias,
74
+ padding_mode=padding_mode,
75
+ device=device, dtype=dtype)
76
+ assert stride == 1
77
+ self.causal_padding = (kernel_size - 1, 0)
78
+
79
+ def forward(self, x: torch.Tensor):
80
+ x = F.pad(x, self.causal_padding)
81
+ x = super(CausalConv1d, self).forward(x)
82
+ return x
83
+ class ConditionalDecoder(nn.Module):
84
+ def __init__(
85
+ self,
86
+ in_channels=320,
87
+ out_channels=80,
88
+ causal=True,
89
+ channels=[256],
90
+ dropout=0.0,
91
+ attention_head_dim=64,
92
+ n_blocks=4,
93
+ num_mid_blocks=12,
94
+ num_heads=8,
95
+ act_fn="gelu",
96
+ meanflow=False,
97
+ ):
98
+ super().__init__()
99
+ channels = tuple(channels)
100
+ self.meanflow = meanflow
101
+ self.in_channels = in_channels
102
+ self.out_channels = out_channels
103
+ self.causal = causal
104
+ self.time_embeddings = SinusoidalPosEmb(in_channels)
105
+ time_embed_dim = channels[0] * 4
106
+ self.time_mlp = TimestepEmbedding(
107
+ in_channels=in_channels,
108
+ time_embed_dim=time_embed_dim,
109
+ act_fn="silu",
110
+ )
111
+
112
+ self.down_blocks = nn.ModuleList([])
113
+ self.mid_blocks = nn.ModuleList([])
114
+ self.up_blocks = nn.ModuleList([])
115
+
116
+ self.static_chunk_size = 0
117
+
118
+ output_channel = in_channels
119
+ for i in range(len(channels)):
120
+ input_channel = output_channel
121
+ output_channel = channels[i]
122
+ is_last = i == len(channels) - 1
123
+ resnet = CausalResnetBlock1D(dim=input_channel, dim_out=output_channel, time_emb_dim=time_embed_dim) if self.causal else \
124
+ ResnetBlock1D(dim=input_channel, dim_out=output_channel, time_emb_dim=time_embed_dim)
125
+ transformer_blocks = nn.ModuleList(
126
+ [
127
+ BasicTransformerBlock(
128
+ dim=output_channel,
129
+ num_attention_heads=num_heads,
130
+ attention_head_dim=attention_head_dim,
131
+ dropout=dropout,
132
+ activation_fn=act_fn,
133
+ )
134
+ for _ in range(n_blocks)
135
+ ]
136
+ )
137
+ downsample = (
138
+ Downsample1D(output_channel) if not is_last else
139
+ CausalConv1d(output_channel, output_channel, 3) if self.causal else nn.Conv1d(output_channel, output_channel, 3, padding=1)
140
+ )
141
+ self.down_blocks.append(nn.ModuleList([resnet, transformer_blocks, downsample]))
142
+
143
+ for _ in range(num_mid_blocks):
144
+ input_channel = channels[-1]
145
+ out_channels = channels[-1]
146
+ resnet = CausalResnetBlock1D(dim=input_channel, dim_out=output_channel, time_emb_dim=time_embed_dim) if self.causal else \
147
+ ResnetBlock1D(dim=input_channel, dim_out=output_channel, time_emb_dim=time_embed_dim)
148
+
149
+ transformer_blocks = nn.ModuleList(
150
+ [
151
+ BasicTransformerBlock(
152
+ dim=output_channel,
153
+ num_attention_heads=num_heads,
154
+ attention_head_dim=attention_head_dim,
155
+ dropout=dropout,
156
+ activation_fn=act_fn,
157
+ )
158
+ for _ in range(n_blocks)
159
+ ]
160
+ )
161
+
162
+ self.mid_blocks.append(nn.ModuleList([resnet, transformer_blocks]))
163
+
164
+ channels = channels[::-1] + (channels[0],)
165
+ for i in range(len(channels) - 1):
166
+ input_channel = channels[i] * 2
167
+ output_channel = channels[i + 1]
168
+ is_last = i == len(channels) - 2
169
+ resnet = CausalResnetBlock1D(
170
+ dim=input_channel,
171
+ dim_out=output_channel,
172
+ time_emb_dim=time_embed_dim,
173
+ ) if self.causal else ResnetBlock1D(
174
+ dim=input_channel,
175
+ dim_out=output_channel,
176
+ time_emb_dim=time_embed_dim,
177
+ )
178
+ transformer_blocks = nn.ModuleList(
179
+ [
180
+ BasicTransformerBlock(
181
+ dim=output_channel,
182
+ num_attention_heads=num_heads,
183
+ attention_head_dim=attention_head_dim,
184
+ dropout=dropout,
185
+ activation_fn=act_fn,
186
+ )
187
+ for _ in range(n_blocks)
188
+ ]
189
+ )
190
+ upsample = (
191
+ Upsample1D(output_channel, use_conv_transpose=True)
192
+ if not is_last
193
+ else CausalConv1d(output_channel, output_channel, 3) if self.causal else nn.Conv1d(output_channel, output_channel, 3, padding=1)
194
+ )
195
+ self.up_blocks.append(nn.ModuleList([resnet, transformer_blocks, upsample]))
196
+ self.final_block = CausalBlock1D(channels[-1], channels[-1]) if self.causal else Block1D(channels[-1], channels[-1])
197
+ self.final_proj = nn.Conv1d(channels[-1], self.out_channels, 1)
198
+ self.initialize_weights()
199
+ self.time_embed_mixer = None
200
+ if self.meanflow:
201
+ self.time_embed_mixer = get_intmeanflow_time_mixer(time_embed_dim)
202
+
203
+
204
+ @property
205
+ def dtype(self):
206
+ return self.final_proj.weight.dtype
207
+
208
+ def initialize_weights(self):
209
+ for m in self.modules():
210
+ if isinstance(m, nn.Conv1d):
211
+ nn.init.kaiming_normal_(m.weight, nonlinearity="relu")
212
+ if m.bias is not None:
213
+ nn.init.constant_(m.bias, 0)
214
+ elif isinstance(m, nn.GroupNorm):
215
+ nn.init.constant_(m.weight, 1)
216
+ nn.init.constant_(m.bias, 0)
217
+ elif isinstance(m, nn.Linear):
218
+ nn.init.kaiming_normal_(m.weight, nonlinearity="relu")
219
+ if m.bias is not None:
220
+ nn.init.constant_(m.bias, 0)
221
+
222
+ def forward(self, x, mask, mu, t, spks=None, cond=None, r=None):
223
+ t = self.time_embeddings(t).to(t.dtype)
224
+ t = self.time_mlp(t)
225
+
226
+ if self.meanflow:
227
+ r = self.time_embeddings(r).to(t.dtype)
228
+ r = self.time_mlp(r)
229
+ concat_embed = torch.cat([t, r], dim=1)
230
+ t = self.time_embed_mixer(concat_embed)
231
+
232
+ x = pack([x, mu], "b * t")[0]
233
+
234
+ if spks is not None:
235
+ spks = repeat(spks, "b c -> b c t", t=x.shape[-1])
236
+ x = pack([x, spks], "b * t")[0]
237
+ if cond is not None:
238
+ x = pack([x, cond], "b * t")[0]
239
+
240
+ hiddens = []
241
+ masks = [mask]
242
+ for resnet, transformer_blocks, downsample in self.down_blocks:
243
+ mask_down = masks[-1]
244
+ x = resnet(x, mask_down, t)
245
+ x = rearrange(x, "b c t -> b t c").contiguous()
246
+ attn_mask = add_optional_chunk_mask(x, mask_down.bool(), False, False, 0, self.static_chunk_size, -1)
247
+ attn_mask = mask_to_bias(attn_mask == 1, x.dtype)
248
+ for transformer_block in transformer_blocks:
249
+ x = transformer_block(
250
+ hidden_states=x,
251
+ attention_mask=attn_mask,
252
+ timestep=t,
253
+ )
254
+ x = rearrange(x, "b t c -> b c t").contiguous()
255
+ hiddens.append(x)
256
+ x = downsample(x * mask_down)
257
+ masks.append(mask_down[:, :, ::2])
258
+ masks = masks[:-1]
259
+ mask_mid = masks[-1]
260
+
261
+ for resnet, transformer_blocks in self.mid_blocks:
262
+ x = resnet(x, mask_mid, t)
263
+ x = rearrange(x, "b c t -> b t c").contiguous()
264
+ attn_mask = add_optional_chunk_mask(x, mask_mid.bool(), False, False, 0, self.static_chunk_size, -1)
265
+ attn_mask = mask_to_bias(attn_mask == 1, x.dtype)
266
+ for transformer_block in transformer_blocks:
267
+ x = transformer_block(
268
+ hidden_states=x,
269
+ attention_mask=attn_mask,
270
+ timestep=t,
271
+ )
272
+ x = rearrange(x, "b t c -> b c t").contiguous()
273
+
274
+ for resnet, transformer_blocks, upsample in self.up_blocks:
275
+ mask_up = masks.pop()
276
+ skip = hiddens.pop()
277
+ x = pack([x[:, :, :skip.shape[-1]], skip], "b * t")[0]
278
+ x = resnet(x, mask_up, t)
279
+ x = rearrange(x, "b c t -> b t c").contiguous()
280
+ attn_mask = add_optional_chunk_mask(x, mask_up.bool(), False, False, 0, self.static_chunk_size, -1)
281
+ attn_mask = mask_to_bias(attn_mask == 1, x.dtype)
282
+ for transformer_block in transformer_blocks:
283
+ x = transformer_block(
284
+ hidden_states=x,
285
+ attention_mask=attn_mask,
286
+ timestep=t,
287
+ )
288
+ x = rearrange(x, "b t c -> b c t").contiguous()
289
+ x = upsample(x * mask_up)
290
+ x = self.final_block(x, mask_up)
291
+ output = self.final_proj(x * mask_up)
292
+ return output * mask
@@ -0,0 +1,42 @@
1
+ import torch
2
+ import torch.nn as nn
3
+ from torch.nn.utils.parametrizations import weight_norm
4
+
5
+
6
+ class ConvRNNF0Predictor(nn.Module):
7
+ def __init__(self,
8
+ num_class: int = 1,
9
+ in_channels: int = 80,
10
+ cond_channels: int = 512
11
+ ):
12
+ super().__init__()
13
+
14
+ self.num_class = num_class
15
+ self.condnet = nn.Sequential(
16
+ weight_norm(
17
+ nn.Conv1d(in_channels, cond_channels, kernel_size=3, padding=1)
18
+ ),
19
+ nn.ELU(),
20
+ weight_norm(
21
+ nn.Conv1d(cond_channels, cond_channels, kernel_size=3, padding=1)
22
+ ),
23
+ nn.ELU(),
24
+ weight_norm(
25
+ nn.Conv1d(cond_channels, cond_channels, kernel_size=3, padding=1)
26
+ ),
27
+ nn.ELU(),
28
+ weight_norm(
29
+ nn.Conv1d(cond_channels, cond_channels, kernel_size=3, padding=1)
30
+ ),
31
+ nn.ELU(),
32
+ weight_norm(
33
+ nn.Conv1d(cond_channels, cond_channels, kernel_size=3, padding=1)
34
+ ),
35
+ nn.ELU(),
36
+ )
37
+ self.classifier = nn.Linear(in_features=cond_channels, out_features=self.num_class)
38
+
39
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
40
+ x = self.condnet(x)
41
+ x = x.transpose(1, 2)
42
+ return torch.abs(self.classifier(x).squeeze(-1))
@@ -0,0 +1,163 @@
1
+ import logging
2
+ import random
3
+ from typing import Dict, Optional
4
+
5
+ logger = logging.getLogger(__name__)
6
+ import torch
7
+ import torch.nn as nn
8
+ from torch.nn import functional as F
9
+ from .utils.mask import make_pad_mask
10
+ from .configs import CFM_PARAMS
11
+
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ def _repeat_batch_dim(tnsr, B, ndim):
17
+ if tnsr is not None:
18
+ while tnsr.ndim < ndim:
19
+ tnsr = tnsr[None]
20
+ if B > 1 and tnsr.size(0) == 1:
21
+ tnsr = tnsr.repeat(B, *([1] * (ndim - 1)))
22
+ assert tnsr.ndim == ndim, f"Expected {ndim=}, got {tnsr.ndim=}"
23
+ return tnsr
24
+
25
+
26
+ class CausalMaskedDiffWithXvec(torch.nn.Module):
27
+ def __init__(self,
28
+ input_size: int = 512,
29
+ output_size: int = 80,
30
+ spk_embed_dim: int = 192,
31
+ output_type: str = "mel",
32
+ vocab_size: int = 6561,
33
+ input_frame_rate: int = 25,
34
+ only_mask_loss: bool = True,
35
+ token_mel_ratio: int = 2,
36
+ pre_lookahead_len: int = 3,
37
+ encoder: torch.nn.Module = None,
38
+ decoder: torch.nn.Module = None,
39
+ decoder_conf: Dict = {'in_channels': 240, 'out_channel': 80, 'spk_emb_dim': 80, 'n_spks': 1,
40
+ 'cfm_params': CFM_PARAMS,
41
+ 'decoder_params': {'channels': [256, 256], 'dropout': 0.0,
42
+ 'attention_head_dim': 64,
43
+ 'n_blocks': 4, 'num_mid_blocks': 12, 'num_heads': 8,
44
+ 'act_fn': 'gelu'}},
45
+ mel_feat_conf: Dict = {'n_fft': 1024, 'num_mels': 80, 'sampling_rate': 22050,
46
+ 'hop_size': 256, 'win_size': 1024, 'fmin': 0, 'fmax': 8000}):
47
+ super().__init__()
48
+ self.input_size = input_size
49
+ self.output_size = output_size
50
+ self.decoder_conf = decoder_conf
51
+ self.mel_feat_conf = mel_feat_conf
52
+ self.vocab_size = vocab_size
53
+ self.output_type = output_type
54
+ self.input_frame_rate = input_frame_rate
55
+ logging.info(f"input frame rate={self.input_frame_rate}")
56
+ self.input_embedding = nn.Embedding(vocab_size, input_size)
57
+ self.spk_embed_affine_layer = torch.nn.Linear(spk_embed_dim, output_size)
58
+ self.encoder = encoder
59
+ self.encoder_proj = torch.nn.Linear(self.encoder.output_size(), output_size)
60
+ self.decoder = decoder
61
+ self.only_mask_loss = only_mask_loss
62
+ self.token_mel_ratio = token_mel_ratio
63
+ self.pre_lookahead_len = pre_lookahead_len
64
+
65
+ def compute_loss(
66
+ self,
67
+ batch: dict,
68
+ device: torch.device,
69
+ ) -> Dict[str, Optional[torch.Tensor]]:
70
+ token = batch['speech_token'].to(device)
71
+ token_len = batch['speech_token_len'].to(device)
72
+ feat = batch['speech_feat'].to(device)
73
+ feat_len = batch['speech_feat_len'].to(device)
74
+ embedding = batch['embedding'].to(device)
75
+
76
+ embedding = F.normalize(embedding, dim=1)
77
+ embedding = self.spk_embed_affine_layer(embedding)
78
+
79
+ mask = (~make_pad_mask(token_len)).float().unsqueeze(-1).to(device)
80
+ token = self.input_embedding(torch.clamp(token, min=0)) * mask
81
+
82
+ h, h_lengths = self.encoder(token, token_len)
83
+ h = self.encoder_proj(h)
84
+
85
+ conds = torch.zeros(feat.shape, device=token.device)
86
+ for i, j in enumerate(feat_len):
87
+ if random.random() < 0.5:
88
+ continue
89
+ index = random.randint(0, int(0.3 * j))
90
+ conds[i, :, :index] = feat[i, :, :index]
91
+
92
+ mask = (~make_pad_mask(h_lengths.sum(dim=-1).squeeze(dim=1))).to(h)
93
+ loss, _ = self.decoder.compute_loss(
94
+ feat.contiguous(),
95
+ mask.unsqueeze(1),
96
+ h.transpose(1, 2).contiguous(),
97
+ embedding,
98
+ cond=conds,
99
+ )
100
+ return {'loss': loss}
101
+
102
+ @torch.inference_mode()
103
+ def inference(self,
104
+ token,
105
+ token_len,
106
+ prompt_token,
107
+ prompt_token_len,
108
+ prompt_feat,
109
+ prompt_feat_len,
110
+ embedding,
111
+ finalize,
112
+ n_timesteps=10,
113
+ noised_mels=None,
114
+ meanflow=False):
115
+
116
+ B = token.size(0)
117
+
118
+ embedding = torch.atleast_2d(embedding)
119
+ embedding = F.normalize(embedding, dim=1)
120
+ embedding = self.spk_embed_affine_layer(embedding)
121
+
122
+ prompt_token = _repeat_batch_dim(prompt_token, B, ndim=2)
123
+ prompt_token_len = _repeat_batch_dim(prompt_token_len, B, ndim=1)
124
+ prompt_feat = _repeat_batch_dim(prompt_feat, B, ndim=3)
125
+ prompt_feat_len = _repeat_batch_dim(prompt_feat_len, B, ndim=1)
126
+ embedding = _repeat_batch_dim(embedding, B, ndim=2)
127
+
128
+ token, token_len = torch.concat([prompt_token, token], dim=1), prompt_token_len + token_len
129
+ mask = (~make_pad_mask(token_len)).unsqueeze(-1).to(embedding)
130
+
131
+ if (token >= self.vocab_size).any():
132
+ logger.error(f"{token.max()}>{self.vocab_size}\n out-of-range special tokens found in flow, fix inputs!")
133
+ token = self.input_embedding(token.long()) * mask
134
+
135
+ h, h_masks = self.encoder(token, token_len)
136
+ if finalize is False:
137
+ h = h[:, :-self.pre_lookahead_len * self.token_mel_ratio]
138
+
139
+ h_lengths = h_masks.sum(dim=-1).squeeze(dim=-1)
140
+ mel_len1, mel_len2 = prompt_feat.shape[1], h.shape[1] - prompt_feat.shape[1]
141
+ h = self.encoder_proj(h)
142
+
143
+ conds = torch.zeros([B, mel_len1 + mel_len2, self.output_size], device=token.device).to(h.dtype)
144
+ conds[:, :mel_len1] = prompt_feat
145
+ conds = conds.transpose(1, 2)
146
+
147
+ mask = (~make_pad_mask(h_lengths)).unsqueeze(1).to(h)
148
+
149
+ if mask.shape[0] != B:
150
+ mask = mask.repeat(B, 1, 1)
151
+
152
+ feat, _ = self.decoder(
153
+ mu=h.transpose(1, 2).contiguous(),
154
+ mask=mask,
155
+ spks=embedding,
156
+ cond=conds,
157
+ n_timesteps=n_timesteps,
158
+ noised_mels=noised_mels,
159
+ meanflow=meanflow,
160
+ )
161
+ feat = feat[:, :, mel_len1:]
162
+ assert feat.shape[2] == mel_len2
163
+ return feat, None
@@ -0,0 +1,140 @@
1
+ import threading
2
+ import torch
3
+ import torch.nn.functional as F
4
+ from .matcha.flow_matching import BASECFM
5
+ from .configs import CFM_PARAMS
6
+ from tqdm import tqdm
7
+
8
+
9
+ def cast_all(*args, dtype):
10
+ return [a if (not a.dtype.is_floating_point) or a.dtype == dtype else a.to(dtype) for a in args]
11
+
12
+
13
+ class ConditionalCFM(BASECFM):
14
+ def __init__(self, in_channels, cfm_params, n_spks=1, spk_emb_dim=64, estimator: torch.nn.Module = None):
15
+ super().__init__(
16
+ n_feats=in_channels,
17
+ cfm_params=cfm_params,
18
+ n_spks=n_spks,
19
+ spk_emb_dim=spk_emb_dim,
20
+ )
21
+ self.t_scheduler = cfm_params.t_scheduler
22
+ self.training_cfg_rate = cfm_params.training_cfg_rate
23
+ self.inference_cfg_rate = cfm_params.inference_cfg_rate
24
+ in_channels = in_channels + (spk_emb_dim if n_spks > 0 else 0)
25
+ self.estimator = estimator
26
+
27
+ @torch.inference_mode()
28
+ def forward(self, mu, mask, n_timesteps, temperature=1.0, spks=None, cond=None, prompt_len=0, flow_cache=torch.zeros(1, 80, 0, 2)):
29
+
30
+ raise NotImplementedError("unused, needs updating for meanflow model")
31
+
32
+ z = torch.randn_like(mu).to(mu.device).to(mu.dtype) * temperature
33
+ cache_size = flow_cache.shape[2]
34
+ if cache_size != 0:
35
+ z[:, :, :cache_size] = flow_cache[:, :, :, 0]
36
+ mu[:, :, :cache_size] = flow_cache[:, :, :, 1]
37
+ z_cache = torch.concat([z[:, :, :prompt_len], z[:, :, -34:]], dim=2)
38
+ mu_cache = torch.concat([mu[:, :, :prompt_len], mu[:, :, -34:]], dim=2)
39
+ flow_cache = torch.stack([z_cache, mu_cache], dim=-1)
40
+
41
+ t_span = torch.linspace(0, 1, n_timesteps + 1, device=mu.device, dtype=mu.dtype)
42
+ if self.t_scheduler == 'cosine':
43
+ t_span = 1 - torch.cos(t_span * 0.5 * torch.pi)
44
+ return self.solve_euler(z, t_span=t_span, mu=mu, mask=mask, spks=spks, cond=cond), flow_cache
45
+
46
+ def solve_euler(self, x, t_span, mu, mask, spks, cond, meanflow=False):
47
+ in_dtype = x.dtype
48
+ x, t_span, mu, mask, spks, cond = cast_all(x, t_span, mu, mask, spks, cond, dtype=self.estimator.dtype)
49
+
50
+ B, T = mu.size(0), x.size(2)
51
+ x_in = torch.zeros([2 * B, 80, T], device=x.device, dtype=x.dtype)
52
+ mask_in = torch.zeros([2 * B, 1, T], device=x.device, dtype=x.dtype)
53
+ mu_in = torch.zeros([2 * B, 80, T], device=x.device, dtype=x.dtype)
54
+ t_in = torch.zeros([2 * B ], device=x.device, dtype=x.dtype)
55
+ spks_in = torch.zeros([2 * B, 80 ], device=x.device, dtype=x.dtype)
56
+ cond_in = torch.zeros([2 * B, 80, T], device=x.device, dtype=x.dtype)
57
+ r_in = torch.zeros([2 * B ], device=x.device, dtype=x.dtype)
58
+
59
+ for t, r in zip(t_span[:-1], t_span[1:]):
60
+ t = t.unsqueeze(dim=0)
61
+ r = r.unsqueeze(dim=0)
62
+
63
+ x_in[:B] = x_in[B:] = x
64
+ mask_in[:B] = mask_in[B:] = mask
65
+ mu_in[:B] = mu
66
+ t_in[:B] = t_in[B:] = t
67
+ spks_in[:B] = spks
68
+ cond_in[:B] = cond
69
+ r_in[:B] = r_in[B:] = r
70
+ dxdt = self.estimator.forward(
71
+ x=x_in, mask=mask_in, mu=mu_in, t=t_in, spks=spks_in, cond=cond_in,
72
+ r=r_in if meanflow else None,
73
+ )
74
+ dxdt, cfg_dxdt = torch.split(dxdt, [B, B], dim=0)
75
+ dxdt = ((1.0 + self.inference_cfg_rate) * dxdt - self.inference_cfg_rate * cfg_dxdt)
76
+ dt = r - t
77
+ x = x + dt * dxdt
78
+
79
+
80
+
81
+ return x.to(in_dtype)
82
+
83
+ def compute_loss(self, x1, mask, mu, spks=None, cond=None):
84
+ b, _, t = mu.shape
85
+
86
+ t = torch.rand([b, 1, 1], device=mu.device, dtype=mu.dtype)
87
+ if self.t_scheduler == 'cosine':
88
+ t = 1 - torch.cos(t * 0.5 * torch.pi)
89
+ z = torch.randn_like(x1)
90
+
91
+ y = (1 - (1 - self.sigma_min) * t) * z + t * x1
92
+ u = x1 - (1 - self.sigma_min) * z
93
+
94
+ if self.training_cfg_rate > 0:
95
+ cfg_mask = torch.rand(b, device=x1.device) > self.training_cfg_rate
96
+ mu = mu * cfg_mask.view(-1, 1, 1)
97
+ spks = spks * cfg_mask.view(-1, 1)
98
+ cond = cond * cfg_mask.view(-1, 1, 1)
99
+
100
+ pred = self.estimator(y, mask, mu, t.squeeze(), spks, cond)
101
+ loss = F.mse_loss(pred * mask, u * mask, reduction="sum") / (torch.sum(mask) * u.shape[1])
102
+ return loss, y
103
+
104
+
105
+ class CausalConditionalCFM(ConditionalCFM):
106
+ def __init__(self, in_channels=240, cfm_params=CFM_PARAMS, n_spks=1, spk_emb_dim=80, estimator=None):
107
+ super().__init__(in_channels, cfm_params, n_spks, spk_emb_dim, estimator)
108
+ self.rand_noise = None
109
+
110
+ @torch.inference_mode()
111
+ def forward(self, mu, mask, n_timesteps, temperature=1.0, spks=None, cond=None, noised_mels=None, meanflow=False):
112
+
113
+ B = mu.size(0)
114
+ z = torch.randn_like(mu)
115
+
116
+ if noised_mels is not None:
117
+ prompt_len = mu.size(2) - noised_mels.size(2)
118
+ z[..., prompt_len:] = noised_mels
119
+
120
+ t_span = torch.linspace(0, 1, n_timesteps + 1, device=mu.device, dtype=mu.dtype)
121
+ if (not meanflow) and (self.t_scheduler == 'cosine'):
122
+ t_span = 1 - torch.cos(t_span * 0.5 * torch.pi)
123
+
124
+ if meanflow:
125
+ return self.basic_euler(z, t_span=t_span, mu=mu, mask=mask, spks=spks, cond=cond), None
126
+
127
+ return self.solve_euler(z, t_span=t_span, mu=mu, mask=mask, spks=spks, cond=cond, meanflow=meanflow), None
128
+
129
+ def basic_euler(self, x, t_span, mu, mask, spks, cond):
130
+ in_dtype = x.dtype
131
+ x, t_span, mu, mask, spks, cond = cast_all(x, t_span, mu, mask, spks, cond, dtype=self.estimator.dtype)
132
+
133
+ print("S3 Token -> Mel Inference...")
134
+ for t, r in tqdm(zip(t_span[..., :-1], t_span[..., 1:]), total=t_span.shape[-1] - 1):
135
+ t, r = t[None], r[None]
136
+ dxdt = self.estimator.forward(x, mask=mask, mu=mu, t=t, spks=spks, cond=cond, r=r)
137
+ dt = r - t
138
+ x = x + dt * dxdt
139
+
140
+ return x.to(in_dtype)