fx overwriting pattern antidiagonals
Browse files- audiocraft/builders.py +6 -14
- audiocraft/lm.py +8 -15
- demo.py +22 -19
audiocraft/builders.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1 |
import omegaconf
|
2 |
import torchaudio
|
3 |
-
from torch import nn
|
4 |
import torch
|
5 |
import numpy as np
|
6 |
from huggingface_hub import hf_hub_download
|
@@ -11,7 +10,7 @@ from .lm import LMModel
|
|
11 |
from .seanet import SEANetDecoder
|
12 |
from .vq import ResidualVectorQuantizer
|
13 |
|
14 |
-
N_REPEAT =
|
15 |
|
16 |
def _shift(x):
|
17 |
n = x.shape[0]
|
@@ -38,7 +37,7 @@ def dict_from_config(cfg):
|
|
38 |
return dct
|
39 |
|
40 |
|
41 |
-
class AudioGen(nn.Module):
|
42 |
|
43 |
# https://huggingface.co/facebook/audiogen-medium
|
44 |
|
@@ -57,11 +56,9 @@ class AudioGen(nn.Module):
|
|
57 |
):
|
58 |
|
59 |
with torch.no_grad():
|
60 |
-
print('\nCUSTOM\n',int(duration / N_REPEAT * self.compression_model.frame_rate), 'DURATION TOKENS AudioGen')
|
61 |
-
|
62 |
gen_tokens = self.lm.generate(
|
63 |
descriptions=[descriptions] * N_REPEAT,
|
64 |
-
max_tokens=int(duration / N_REPEAT * self.compression_model.frame_rate)) # [bs, 4, 37 * self.lm.n_draw]
|
65 |
x = self.compression_model.decode(gen_tokens, None) #[bs, 1, 11840]
|
66 |
|
67 |
x = x[:, 0, :] # last samples have splash sounds DISCARD 25000 last samples
|
@@ -70,16 +67,14 @@ class AudioGen(nn.Module):
|
|
70 |
|
71 |
x = self.resample_fn(x) # [N_REPEAT, duration]
|
72 |
|
73 |
-
x = x.
|
74 |
|
75 |
-
for _ in range(7):
|
76 |
-
|
77 |
-
|
78 |
|
79 |
print(x.abs().max(), 'MAX')
|
80 |
return x / (x.abs().max() + 1e-7)
|
81 |
|
82 |
-
# == BUILD Fn
|
83 |
def get_quantizer(self, quantizer, cfg, dimension):
|
84 |
klass = {
|
85 |
'no_quant': None,
|
@@ -90,7 +85,6 @@ class AudioGen(nn.Module):
|
|
90 |
kwargs['dimension'] = dimension
|
91 |
return klass(**kwargs)
|
92 |
|
93 |
-
|
94 |
def get_encodec_autoencoder(self, cfg):
|
95 |
kwargs = dict_from_config(getattr(cfg, 'seanet'))
|
96 |
_ = kwargs.pop('encoder')
|
@@ -98,8 +92,6 @@ class AudioGen(nn.Module):
|
|
98 |
decoder_kwargs = {**kwargs, **decoder_override_kwargs}
|
99 |
decoder = SEANetDecoder(**decoder_kwargs)
|
100 |
return decoder
|
101 |
-
|
102 |
-
|
103 |
|
104 |
def get_compression_model(self, cfg):
|
105 |
"""Instantiate a compression model."""
|
|
|
1 |
import omegaconf
|
2 |
import torchaudio
|
|
|
3 |
import torch
|
4 |
import numpy as np
|
5 |
from huggingface_hub import hf_hub_download
|
|
|
10 |
from .seanet import SEANetDecoder
|
11 |
from .vq import ResidualVectorQuantizer
|
12 |
|
13 |
+
N_REPEAT = 2 # num (virtual batch_size) clones of audio sounds
|
14 |
|
15 |
def _shift(x):
|
16 |
n = x.shape[0]
|
|
|
37 |
return dct
|
38 |
|
39 |
|
40 |
+
class AudioGen(torch.nn.Module):
|
41 |
|
42 |
# https://huggingface.co/facebook/audiogen-medium
|
43 |
|
|
|
56 |
):
|
57 |
|
58 |
with torch.no_grad():
|
|
|
|
|
59 |
gen_tokens = self.lm.generate(
|
60 |
descriptions=[descriptions] * N_REPEAT,
|
61 |
+
max_tokens=int(duration / (N_REPEAT * self.lm.n_draw) * self.compression_model.frame_rate)) # [bs, 4, 37 * self.lm.n_draw]
|
62 |
x = self.compression_model.decode(gen_tokens, None) #[bs, 1, 11840]
|
63 |
|
64 |
x = x[:, 0, :] # last samples have splash sounds DISCARD 25000 last samples
|
|
|
67 |
|
68 |
x = self.resample_fn(x) # [N_REPEAT, duration]
|
69 |
|
70 |
+
x = x.reshape(-1)
|
71 |
|
72 |
+
# for _ in range(7):
|
73 |
+
# x = _shift(x)
|
|
|
74 |
|
75 |
print(x.abs().max(), 'MAX')
|
76 |
return x / (x.abs().max() + 1e-7)
|
77 |
|
|
|
78 |
def get_quantizer(self, quantizer, cfg, dimension):
|
79 |
klass = {
|
80 |
'no_quant': None,
|
|
|
85 |
kwargs['dimension'] = dimension
|
86 |
return klass(**kwargs)
|
87 |
|
|
|
88 |
def get_encodec_autoencoder(self, cfg):
|
89 |
kwargs = dict_from_config(getattr(cfg, 'seanet'))
|
90 |
_ = kwargs.pop('encoder')
|
|
|
92 |
decoder_kwargs = {**kwargs, **decoder_override_kwargs}
|
93 |
decoder = SEANetDecoder(**decoder_kwargs)
|
94 |
return decoder
|
|
|
|
|
95 |
|
96 |
def get_compression_model(self, cfg):
|
97 |
"""Instantiate a compression model."""
|
audiocraft/lm.py
CHANGED
@@ -19,7 +19,7 @@ class LMModel(nn.Module):
|
|
19 |
self.condition_provider = T5Conditioner(name='t5-large',
|
20 |
output_dim=dim)
|
21 |
self.card = card # 2048 ?
|
22 |
-
self.n_draw =
|
23 |
# the batch is more expensive than n_draw as it re-runs the model bs times
|
24 |
# n_draw just draws more phonemes from the multinomial - after running the lm
|
25 |
embed_dim = self.card + 1
|
@@ -111,11 +111,11 @@ class LMModel(nn.Module):
|
|
111 |
# NO OVerWriting
|
112 |
if offset == 0:
|
113 |
|
114 |
-
next_token[:, :, 1:4] = 2048 # self.card
|
115 |
|
116 |
elif offset == 1:
|
117 |
|
118 |
-
next_token[:, :, 2:4] = 2048
|
119 |
|
120 |
elif offset == 2:
|
121 |
|
@@ -123,15 +123,15 @@ class LMModel(nn.Module):
|
|
123 |
|
124 |
elif offset == max_tokens:
|
125 |
|
126 |
-
next_token[:, :, 0:1] = 2048
|
127 |
|
128 |
elif offset == (max_tokens + 1):
|
129 |
|
130 |
-
next_token[:, :, 0:
|
131 |
|
132 |
elif offset == (max_tokens + 2):
|
133 |
|
134 |
-
next_token[:, :, 0:
|
135 |
|
136 |
else: # offset 3,4,5,6,7...... max_tokens-1 # FILL Complete n_q = 4 ANTIDIAGONAL ENTRIES
|
137 |
|
@@ -139,15 +139,8 @@ class LMModel(nn.Module):
|
|
139 |
|
140 |
out_codes[:, :, [0, 1, 2, 3], torch.tensor([3, 2, 1, 0]) + offset + 1] = next_token
|
141 |
|
142 |
-
|
143 |
-
#
|
144 |
-
# print(out_codes[0, 0, :, :]) # do we pass 2048 to Seanet - There wil result in AtenIndexingError as it has no 2048
|
145 |
-
# out_codes = torch.cat([out_codes[:, :, 0:1, 4:max_tokens+4], # first row starts to be filled at offset = 4
|
146 |
-
# out_codes[:, :, 1:2, 3:max_tokens+3],
|
147 |
-
# out_codes[:, :, 2:3, 2:max_tokens+2],
|
148 |
-
# out_codes[:, :, 3:4, 1:max_tokens+1]], 2)
|
149 |
-
print('\n_____ALIGN____\n', out_codes[0, 0, :, 4:max_tokens+4]) # do we pass 2048 to Seanet - There wil result in AtenIndexingError as it has no 2048
|
150 |
-
|
151 |
out_codes = out_codes[:, :, :, 4:max_tokens+4].transpose(1, 2).reshape(bs, 4, self.n_draw * max_tokens) # [bs, 4, duration*n_draw] DISCARD FILL 2048
|
152 |
|
153 |
for lay in self.transformer.layers:
|
|
|
19 |
self.condition_provider = T5Conditioner(name='t5-large',
|
20 |
output_dim=dim)
|
21 |
self.card = card # 2048 ?
|
22 |
+
self.n_draw = 3 # replicate so many times the generation of each text in batch
|
23 |
# the batch is more expensive than n_draw as it re-runs the model bs times
|
24 |
# n_draw just draws more phonemes from the multinomial - after running the lm
|
25 |
embed_dim = self.card + 1
|
|
|
111 |
# NO OVerWriting
|
112 |
if offset == 0:
|
113 |
|
114 |
+
next_token[:, :, 1:4] = 2048 # self.card - bottom 3 entries of the antidiagonal should remain 2048
|
115 |
|
116 |
elif offset == 1:
|
117 |
|
118 |
+
next_token[:, :, 2:4] = 2048 # bottom 2 entries of the antidiagonal should remain 2048
|
119 |
|
120 |
elif offset == 2:
|
121 |
|
|
|
123 |
|
124 |
elif offset == max_tokens:
|
125 |
|
126 |
+
next_token[:, :, 0:1] = 2048 # top 1 entry of the antidiagonal should stay to 2048
|
127 |
|
128 |
elif offset == (max_tokens + 1):
|
129 |
|
130 |
+
next_token[:, :, 0:2] = 2048
|
131 |
|
132 |
elif offset == (max_tokens + 2):
|
133 |
|
134 |
+
next_token[:, :, 0:3] = 2048
|
135 |
|
136 |
else: # offset 3,4,5,6,7...... max_tokens-1 # FILL Complete n_q = 4 ANTIDIAGONAL ENTRIES
|
137 |
|
|
|
139 |
|
140 |
out_codes[:, :, [0, 1, 2, 3], torch.tensor([3, 2, 1, 0]) + offset + 1] = next_token
|
141 |
|
142 |
+
print('\n_____ALIGN____\n', out_codes[1, 2, :, 4:max_tokens+4]) # do we pass 2048 to Seanet - There wil result in AtenIndexingError as it has no 2048
|
143 |
+
# EXTRACT COLUMNS AS ALIGN IS ALREADY DONE by FILLING DIAGONALLY
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
144 |
out_codes = out_codes[:, :, :, 4:max_tokens+4].transpose(1, 2).reshape(bs, 4, self.n_draw * max_tokens) # [bs, 4, duration*n_draw] DISCARD FILL 2048
|
145 |
|
146 |
for lay in self.transformer.layers:
|
demo.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
import numpy as np
|
2 |
import soundfile
|
3 |
import msinference
|
4 |
-
|
5 |
# Prepend »Vom Prof. Friedrich ist noch eine .. string in the beginning brings the male voice in deu MMS TTS (if later string is much longer
|
6 |
# sometimes the woman voices pronounces words <dass>) TODO amplify attn weights of first hidden states / certain voice
|
7 |
|
@@ -16,26 +16,25 @@ def tts_entry(text='»Vom Prof. Friedrich ist noch eine recht schöne große Lan
|
|
16 |
'A quick brown fox jumps over the lazy dog. Sweet dreams are made of this, I traveled the world and the seven seas.'
|
17 |
'DESCIPTION Bronzezeitlicher Zeremonialhut („Berliner Goldhut“), gefertigt aus einem Stück nahtlos getriebenem Goldblech und mit Kreisornamenten in Repousse-Technik verziert. Kalotte kegelförmig überhöht und mit breiter umlaufender Krempe. Krempe und Kalotte durch flaches Bronzeband verstärkt. An der Krempe außen tordierter Bronzedraht. Die Anordnung der Ornamentik auf Kalotte und Krempe des Zeremonialhutes wird als Darstellung eines Kalendersystems gedeutet, mit dem sich die Verschiebungen zwischen Sonnen- und Mondjahr berechnen und Mondfinsternisse voraussagen lassen.'
|
18 |
'Vorderseite: L IVL AVR SVLP ANTONINVS [LP ligiert]. Panzerbüste des Uranius Antoninus mit Lorbeerkranz in der Brustansicht nach l., Pteryges des r. Armansatzes sind zur Angabe eines erhobenen Armes waagerecht dargestellt. Rückseite: CONSERVATO-R AVG. Der Stein des Baal von Emesa auf einem Viergespann (quadriga) nach l. Auf dem Stein, der von zwei Schirmen gerahmt ist, ist das Relief eines Adlers zu sehen. Kommentar: Baldus (1971) 84 ff. 87 zur Frage der Münzstätte, ebd. 128 ff. zur Pterygesanhebung (Andeutung eines erhobenen Armes), die als alexanderhafter Gestus gilt. - Uranius Antoninus wurde im Sommer 253 n. Chr. im syrischen Emesa zum Kaiser erhoben und bewährte sich bald darauf bei der erfolgreichen Abwehr eines Einfalls der Sasaniden. Uranius Antoninus stammte möglicherweise aus der Familie der Iulia Domna, war Priester des Baals von Emesa, und ist mit dem literarisch überlieferten Sampsigeramus identisch, der als Organisator des Widerstandes gegen die Sasaniden in der Region belegt ist. Nach 254 n. Chr. fehlen Informationen über Uranius Antoninus, möglicherweise trat er nach Bereinigung der Notsituation hinter den Kaiser Valerianus zurück. Zu diesem Stück wurden 2017 im Zuge der Ausstellung Syria Antiqua zwei vergrößerte Reproduktionen (3D-Ausdrucke) erstellt, die bei den Galvanos in Schrank 81/121 liegen. Literatur: A. von Sallet, ZfN 17, 1890, 241 f. Taf. 4,9 (dieses Stück); H. R. Baldus, Uranius Antoninus (1971) 198 Nr. 85 Taf. 7,85; 12,85 (dieses Stück, mit Lit., 253/254 n. Chr. bzw. Stempelgruppe VIII ca. Dez. 253-Anfang 254 n. Chr.); RIC IV-3 Nr. 2 c; RPC IX Nr. 1940,2 Taf. 131 (dieses Stück).',
|
19 |
-
voice='deu',
|
20 |
-
speed=1.14,
|
21 |
-
affect = True # False = higher clarity
|
|
|
22 |
):
|
23 |
-
'''
|
24 |
|
25 |
-
voice : 'en_US/vctk_low#p276' #
|
26 |
|
27 |
or
|
28 |
|
29 |
-
voice : 'af_ZA_google-nwu_1919' #
|
30 |
|
31 |
or
|
32 |
|
33 |
-
voice : 'deu' #
|
34 |
'''
|
35 |
|
36 |
-
# StyleTTS2 -
|
37 |
-
|
38 |
-
# mimic-3 format of voice (English txt - English accent)
|
39 |
|
40 |
if ('en_US/' in voice) or ('en_UK/' in voice):
|
41 |
a = '' if affect else 'v2/'
|
@@ -47,7 +46,7 @@ def tts_entry(text='»Vom Prof. Friedrich ist noch eine recht schöne große Lan
|
|
47 |
x = msinference.inference(text,
|
48 |
style_vector)
|
49 |
|
50 |
-
#
|
51 |
|
52 |
elif '_' in voice:
|
53 |
style_vector = msinference.compute_style('assets/wavs/mimic3_foreign_4x/' + voice.replace(
|
@@ -59,19 +58,23 @@ def tts_entry(text='»Vom Prof. Friedrich ist noch eine recht schöne große Lan
|
|
59 |
style_vector)
|
60 |
|
61 |
|
62 |
-
# Fallback - MMS TTS - Non-English
|
63 |
|
64 |
else:
|
65 |
-
|
66 |
-
# MMS TTS - list of sentences
|
67 |
x = msinference.foreign(text=text,
|
68 |
-
lang=voice,
|
69 |
-
speed=speed) #
|
70 |
|
71 |
# volume
|
72 |
|
73 |
x /= np.abs(x).max() + 1e-7 # amplify speech to full [-1,1]
|
74 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
return x
|
76 |
|
77 |
-
soundfile.write(f'
|
|
|
1 |
import numpy as np
|
2 |
import soundfile
|
3 |
import msinference
|
4 |
+
from audiocraft.builders import AudioGen
|
5 |
# Prepend »Vom Prof. Friedrich ist noch eine .. string in the beginning brings the male voice in deu MMS TTS (if later string is much longer
|
6 |
# sometimes the woman voices pronounces words <dass>) TODO amplify attn weights of first hidden states / certain voice
|
7 |
|
|
|
16 |
'A quick brown fox jumps over the lazy dog. Sweet dreams are made of this, I traveled the world and the seven seas.'
|
17 |
'DESCIPTION Bronzezeitlicher Zeremonialhut („Berliner Goldhut“), gefertigt aus einem Stück nahtlos getriebenem Goldblech und mit Kreisornamenten in Repousse-Technik verziert. Kalotte kegelförmig überhöht und mit breiter umlaufender Krempe. Krempe und Kalotte durch flaches Bronzeband verstärkt. An der Krempe außen tordierter Bronzedraht. Die Anordnung der Ornamentik auf Kalotte und Krempe des Zeremonialhutes wird als Darstellung eines Kalendersystems gedeutet, mit dem sich die Verschiebungen zwischen Sonnen- und Mondjahr berechnen und Mondfinsternisse voraussagen lassen.'
|
18 |
'Vorderseite: L IVL AVR SVLP ANTONINVS [LP ligiert]. Panzerbüste des Uranius Antoninus mit Lorbeerkranz in der Brustansicht nach l., Pteryges des r. Armansatzes sind zur Angabe eines erhobenen Armes waagerecht dargestellt. Rückseite: CONSERVATO-R AVG. Der Stein des Baal von Emesa auf einem Viergespann (quadriga) nach l. Auf dem Stein, der von zwei Schirmen gerahmt ist, ist das Relief eines Adlers zu sehen. Kommentar: Baldus (1971) 84 ff. 87 zur Frage der Münzstätte, ebd. 128 ff. zur Pterygesanhebung (Andeutung eines erhobenen Armes), die als alexanderhafter Gestus gilt. - Uranius Antoninus wurde im Sommer 253 n. Chr. im syrischen Emesa zum Kaiser erhoben und bewährte sich bald darauf bei der erfolgreichen Abwehr eines Einfalls der Sasaniden. Uranius Antoninus stammte möglicherweise aus der Familie der Iulia Domna, war Priester des Baals von Emesa, und ist mit dem literarisch überlieferten Sampsigeramus identisch, der als Organisator des Widerstandes gegen die Sasaniden in der Region belegt ist. Nach 254 n. Chr. fehlen Informationen über Uranius Antoninus, möglicherweise trat er nach Bereinigung der Notsituation hinter den Kaiser Valerianus zurück. Zu diesem Stück wurden 2017 im Zuge der Ausstellung Syria Antiqua zwei vergrößerte Reproduktionen (3D-Ausdrucke) erstellt, die bei den Galvanos in Schrank 81/121 liegen. Literatur: A. von Sallet, ZfN 17, 1890, 241 f. Taf. 4,9 (dieses Stück); H. R. Baldus, Uranius Antoninus (1971) 198 Nr. 85 Taf. 7,85; 12,85 (dieses Stück, mit Lit., 253/254 n. Chr. bzw. Stempelgruppe VIII ca. Dez. 253-Anfang 254 n. Chr.); RIC IV-3 Nr. 2 c; RPC IX Nr. 1940,2 Taf. 131 (dieses Stück).',
|
19 |
+
voice='deu', #'af_ZA_google-nwu_1919', # 'serbian', 'en_US/vctk_low#p276', 'isl',
|
20 |
+
speed=1.14,
|
21 |
+
affect = True, # False = higher clarity
|
22 |
+
soundscape = 'dogs barg in dungeons n dragons'
|
23 |
):
|
24 |
+
'''24kHz
|
25 |
|
26 |
+
voice : 'en_US/vctk_low#p276' # Native English voices -> https://audeering.github.io/shift/
|
27 |
|
28 |
or
|
29 |
|
30 |
+
voice : 'af_ZA_google-nwu_1919' # Non-Native English voices -> https://huggingface.co/dkounadis/artificial-styletts2/discussions/1#6783e3b00e7d90facec060c6
|
31 |
|
32 |
or
|
33 |
|
34 |
+
voice : 'deu' # Foreign languages -> https://huggingface.co/dkounadis/artificial-styletts2/blob/main/Utils/all_langs.csv
|
35 |
'''
|
36 |
|
37 |
+
# StyleTTS2 - find voice from folder
|
|
|
|
|
38 |
|
39 |
if ('en_US/' in voice) or ('en_UK/' in voice):
|
40 |
a = '' if affect else 'v2/'
|
|
|
46 |
x = msinference.inference(text,
|
47 |
style_vector)
|
48 |
|
49 |
+
# find voice from mimic-3 folder with styles
|
50 |
|
51 |
elif '_' in voice:
|
52 |
style_vector = msinference.compute_style('assets/wavs/mimic3_foreign_4x/' + voice.replace(
|
|
|
58 |
style_vector)
|
59 |
|
60 |
|
61 |
+
# Fallback - MMS TTS - Non-English voice/language
|
62 |
|
63 |
else:
|
|
|
|
|
64 |
x = msinference.foreign(text=text,
|
65 |
+
lang=voice,
|
66 |
+
speed=speed) # volume normalis.
|
67 |
|
68 |
# volume
|
69 |
|
70 |
x /= np.abs(x).max() + 1e-7 # amplify speech to full [-1,1]
|
71 |
+
|
72 |
+
if soundscape is not None:
|
73 |
+
sound_gen = AudioGen().to('cuda:0').eval()
|
74 |
+
background = sound_gen.generate(soundscape,
|
75 |
+
duration=len(x)/24000 + .74, # sound duration in seconds
|
76 |
+
).detach().cpu().numpy() # bs, 11400 @.74s
|
77 |
+
x = .5 * x + .5 * background[:len(x)]
|
78 |
return x
|
79 |
|
80 |
+
soundfile.write(f'demo.wav', tts_entry(), 24000)
|