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.
- chatterbox/__init__.py +11 -0
- chatterbox/models/__init__.py +0 -0
- chatterbox/models/s3gen/__init__.py +2 -0
- chatterbox/models/s3gen/configs.py +10 -0
- chatterbox/models/s3gen/const.py +2 -0
- chatterbox/models/s3gen/decoder.py +292 -0
- chatterbox/models/s3gen/f0_predictor.py +42 -0
- chatterbox/models/s3gen/flow.py +163 -0
- chatterbox/models/s3gen/flow_matching.py +140 -0
- chatterbox/models/s3gen/hifigan.py +350 -0
- chatterbox/models/s3gen/matcha/conformer_block.py +249 -0
- chatterbox/models/s3gen/matcha/decoder.py +412 -0
- chatterbox/models/s3gen/matcha/flow_matching.py +76 -0
- chatterbox/models/s3gen/matcha/transformer.py +235 -0
- chatterbox/models/s3gen/s3gen.py +293 -0
- chatterbox/models/s3gen/transformer/__init__.py +0 -0
- chatterbox/models/s3gen/transformer/activation.py +35 -0
- chatterbox/models/s3gen/transformer/attention.py +153 -0
- chatterbox/models/s3gen/transformer/convolution.py +97 -0
- chatterbox/models/s3gen/transformer/embedding.py +170 -0
- chatterbox/models/s3gen/transformer/encoder_layer.py +135 -0
- chatterbox/models/s3gen/transformer/positionwise_feed_forward.py +56 -0
- chatterbox/models/s3gen/transformer/subsampling.py +209 -0
- chatterbox/models/s3gen/transformer/upsample_encoder.py +219 -0
- chatterbox/models/s3gen/utils/class_utils.py +57 -0
- chatterbox/models/s3gen/utils/intmeanflow.py +33 -0
- chatterbox/models/s3gen/utils/mask.py +75 -0
- chatterbox/models/s3gen/utils/mel.py +76 -0
- chatterbox/models/s3gen/xvector.py +399 -0
- chatterbox/models/s3tokenizer/__init__.py +30 -0
- chatterbox/models/s3tokenizer/s3tokenizer.py +140 -0
- chatterbox/models/t3/__init__.py +1 -0
- chatterbox/models/t3/inference/t3_hf_backend.py +86 -0
- chatterbox/models/t3/llama_configs.py +106 -0
- chatterbox/models/t3/modules/cond_enc.py +80 -0
- chatterbox/models/t3/modules/learned_pos_emb.py +22 -0
- chatterbox/models/t3/modules/perceiver.py +169 -0
- chatterbox/models/t3/modules/t3_config.py +39 -0
- chatterbox/models/t3/t3.py +468 -0
- chatterbox/models/tokenizers/__init__.py +1 -0
- chatterbox/models/tokenizers/tokenizer.py +286 -0
- chatterbox/models/utils.py +4 -0
- chatterbox/models/voice_encoder/__init__.py +1 -0
- chatterbox/models/voice_encoder/config.py +18 -0
- chatterbox/models/voice_encoder/melspec.py +84 -0
- chatterbox/models/voice_encoder/voice_encoder.py +222 -0
- chatterbox/mtl_tts.py +331 -0
- chatterbox/tts.py +252 -0
- chatterbox/tts_turbo.py +283 -0
- chatterbox/vc.py +111 -0
- chatterbox_light-1.0.1.dist-info/METADATA +141 -0
- chatterbox_light-1.0.1.dist-info/RECORD +55 -0
- chatterbox_light-1.0.1.dist-info/WHEEL +5 -0
- chatterbox_light-1.0.1.dist-info/licenses/LICENSE +21 -0
- 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,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)
|