Hola, hoy te presentaré cómo usar el vocoder VocGAN para entrenar tu propio conjunto de datos.
original
VocGAN: un codificador de voz en tiempo real de alta fidelidad con una red adversaria anidada jerárquicamente
Si desea comprender la tesis, consulte este artículo mío ~
Este blog incluye principalmente los siguientes contenidos:
Tabla de contenido
2.Procesamiento de conjuntos de datos
2.1.Conjunto de datos LJSpeech
3. Conjunto de datos de entrenamiento
4. Entrenar un conjunto de datos personalizado
Errores encontrados durante el proceso y sus soluciones.
【PS1】AttributeError: el módulo 'torch._C' no tiene el atributo 'DoubleStorageBase'
【PS3】ValueError: num_samples debería ser un valor entero positivo, pero obtuvo num_samples=0
1.Configuración del entorno
git clone https://github.com/rishikksh20/VocGAN
cd VocGAN
conda create -n gan python=3.8
conda activate gan
pip install -r requirements.txt
- Descargue el conjunto de datos para entrenamiento. Puede ser cualquier archivo wav con una frecuencia de muestreo de 22050 Hz. (LJSpeech se utiliza en el artículo)
- Preprocesamiento:
python preprocess.py -c config/default.yaml -d [data's root path]
- Editar
yaml
archivo de configuración
Revisarpreprocess.py中的配置文件和数据集路径
2.数据集处理
2.1.数据集
LJDiscurso
Cree una nueva carpeta de datos , descargue el conjunto de datos LJSpeech, luego descomprímalo y cree una nueva carpeta mels . Consulte [ descarga del conjunto de datos LJSpeech ] 13100 voces.
python preprocess.py -c config/ljs.yaml -d /workspace/tts/VocGAN/data/LJSpeech-1.1/wavs
Aparece después de correr
Luego vaya al siguiente paso 3. Conjunto de datos de entrenamiento
2.2.Conjunto de datos KSS
在kss文件夹下新建了文件夹valid,mels
data: # root path of train/validation data (either relative/absoulte path is ok)
train: '/workspace/tts/Fastspeech2-Korean/data/kss/wavs_bak'
validation: '/workspace/tts/Fastspeech2-Korean/data/kss/valid'
mel_path: '/workspace/tts/Fastspeech2-Korean/data/kss/mels'
eval_path: ''
---
train:
rep_discriminator: 1
discriminator_train_start_steps: 100000
num_workers: 8
batch_size: 16
optimizer: 'adam'
adam:
lr: 0.0001
beta1: 0.5
beta2: 0.9
---
audio:
n_mel_channels: 80
segment_length: 16000
pad_short: 2000
filter_length: 1024
hop_length: 256 # WARNING: this can't be changed.
win_length: 1024
sampling_rate: 22050
mel_fmin: 0.0
mel_fmax: 8000.0
---
model:
feat_match: 10.0
lambda_adv: 1
use_subband_stft_loss: False
feat_loss: False
out_channels: 1
generator_ratio: [4, 4, 2, 2, 2, 2] # for 256 hop size and 22050 sample rate
mult: 256
n_residual_layers: 4
num_D : 3
ndf : 16
n_layers: 3
downsampling_factor: 4
disc_out: 512
stft_loss_params:
fft_sizes: [1024, 2048, 512] # List of FFT size for STFT-based loss.
hop_sizes: [120, 240, 50] # List of hop size for STFT-based loss
win_lengths: [600, 1200, 240] # List of window length for STFT-based loss.
window: "hann_window" # Window function for STFT-based loss
subband_stft_loss_params:
fft_sizes: [384, 683, 171] # List of FFT size for STFT-based loss.
hop_sizes: [30, 60, 10] # List of hop size for STFT-based loss
win_lengths: [150, 300, 60] # List of window length for STFT-based loss.
window: "hann_window" # Window function for STFT-based loss
---
log:
summary_interval: 1
validation_interval: 5
save_interval: 20
chkpt_dir: 'chkpt'
log_dir: 'logs'
entonces corre
python preprocess.py -c config/default.yaml -d /workspace/tts/Fastspeech2-Korean/data/kss/wavs_bak
Si comete un error, consulte 【PS1】
3. Conjunto de datos de entrenamiento
3.1.Entrenamiento de LJSpeech
Copie VocGAN/config/default.yaml y cámbiele el nombre a ljs.yaml
Modifique la ruta del tren y la ruta de validación en los datos en ljs.yaml (estos dos son obligatorios, eval también puede estar vacío)
Por lo tanto, necesitamos dividir el conjunto de datos en un conjunto de entrenamiento y un conjunto de validación, ingresar a la carpeta de datos y crear un nuevo splitdata.py.
import os
import random
def main():
random.seed(0) # 设置随机种子,保证随机结果可复现
files_path = "/workspace/tts/VocGAN/data/LJSpeech-1.1/wavs"
assert os.path.exists(files_path), "path: '{}' does not exist.".format(files_path)
val_rate = 0.3 #验证集比例设置为0.3
#获取数据集的名字(不包含后缀),排序后存放到files_name列表中
files_name = sorted([file.split(".")[0] for file in os.listdir(files_path)])
files_num = len(files_name)
val_index = random.sample(range(0, files_num), k=int(files_num*val_rate))
train_files = []
val_files = []
for index, file_name in enumerate(files_name):
if index in val_index:
val_files.append(file_name)
else:
train_files.append(file_name)
try:
train_f = open("train.txt", "x")
eval_f = open("val.txt", "x")
train_f.write("\n".join(train_files))
eval_f.write("\n".join(val_files))
except FileExistsError as e:
print(e)
exit(1)
if __name__ == '__main__':
main()
y luego dividir
cd data
python splitdata.py
El resultado es como se muestra en la figura.
entrenamiento por fin
python trainer.py -c config/ljs.yaml -n ljs_ckpt
parámetro:
- -c es --config es el archivo de configuración requerido
- - n significa --name es el nombre de la carpeta donde se guarda el archivo de peso después de los datos de entrenamiento requeridos.
Después del entrenamiento, puedes ver
tensorboard --logdir logs/
4. Entrenar un conjunto de datos personalizado
Conjunto de datos de voz recopilados por uno mismo, incluidos voz y texto de voz.
La recopilación de datos de voz incluye: grabación integrada en teléfonos móviles y ordenadores, y grabación mediante software.
La frecuencia de muestreo de la grabación de un teléfono móvil se refiere a la cantidad de muestras recopiladas por segundo al grabar sonido. Cuanto mayor sea la frecuencia de muestreo, más preciso será el sonido grabado, pero también aumentará el tamaño del archivo. La frecuencia de muestreo predeterminada de la mayoría de las aplicaciones de grabación de teléfonos móviles es 44,1 kHz, que es la misma que la calidad del sonido del CD. Sin embargo, algunas aplicaciones permiten a los usuarios personalizar la frecuencia de muestreo, permitiéndoles elegir entre el tamaño del archivo y la calidad del sonido.
Cambiar el nombre de los datos
import os
path_in = "/workspace/tts/Korean-FastSpeech2-Pytorch/data/DyonVoice/wavs" # 待批量重命名的文件夹
class_name = ".wav" # 重命名后的文件名后缀
file_in = os.listdir(path_in) # 返回文件夹包含的所有文件名
num_file_in = len(file_in) # 获取文件数目
for i in range(0, num_file_in):
t = str(i + 1)
new_name = os.rename(path_in + "/" + file_in[i], path_in + "/" +t+ class_name) # 重命名文件名
file_out = os.listdir(path_in)
print(file_out) # 输出修改后的结果`
Debido a que vocgan requiere una frecuencia de muestreo de 22050,
Si se registra en un teléfono móvil, la frecuencia de muestreo puede ser diferente, por lo que la frecuencia de muestreo debe unificarse a 22050 en lotes.
tasa de remuestreo.py
import os
import librosa
import tqdm
import soundfile as sf
if __name__ == '__main__':
# 要查找的音频类型
audioExt = 'wav'
# 待处理音频的采样率
input_sample = 22050
# 重采样的音频采样率
output_sample = 16000
# 待处理音频的多个文件夹
#audioDirectory = ['/data/orgin/train', '/data/orgin/test']
audioDirectory = ['/workspace/tts/Korean-FastSpeech2-Pytorch/data/DyonVoice/wavs']
# 重采样输出的多个文件夹
#outputDirectory = ['/data/traindataset', '/data/testdataset']
outputDirectory = ['/workspace/tts/Korean-FastSpeech2-Pytorch/data/DyonVoice/wav']
# for 循环用于遍历所有待处理音频的文件夹
for i, dire in enumerate(audioDirectory):
# 寻找"directory"文件夹中,格式为“ext”的音频文件,返回值为绝对路径的列表类型
clean_speech_paths = librosa.util.find_files(
directory=dire,
ext=audioExt,
recurse=True, # 如果选择True,则对输入文件夹的子文件夹也进行搜索,否则只搜索输入文件夹
)
# for 循环用于遍历搜索到的所有音频文件
for file in tqdm.tqdm(clean_speech_paths, desc='No.{} dataset resampling'.format(i)):
# 获取音频文件的文件名,用作输出文件名使用
fileName = os.path.basename(file)
# 使用librosa读取待处理音频
y, sr = librosa.load(file, sr=input_sample)
# 对待处理音频进行重采样
y_16k = librosa.resample(y, orig_sr=sr, target_sr=output_sample)
# 构建输出文件路径
outputFileName = os.path.join(outputDirectory[i], fileName)
# 将重采样音频写回硬盘,注意输出文件路径
sf.write(outputFileName, y_16k, output_sample)
Python /workspace/tts/VocGAN/data/resampling.py
Primero procese la voz y convierta el archivo wav en un archivo mel.
python preprocess.py -c config/maydata.yaml -d /workspace/tts/Korean-FastSpeech2-Pytorch/data/DyonVoice/wavs
Después de dividir tren y val
luego entrena
python trainer.py -c config/mydata.yaml -n dyon
Si no hay ningún error, consulte 【PS3】
El resultado después de ejecutar es como se muestra en la figura.
Nota: Si se interrumpe accidentalmente aquí, el entrenamiento comenzará desde el principio.
razonamiento
# python inference.py -p checkpoint路径 -i 输入mel的路径
python inference.py -p /workspace/tts/VocGAN/chkpt/dyon/dyon_2dfbde2_33680.pt -i /workspace/tts/Korean-FastSpeech2-Pytorch/data/DyonVoice/mels
Errores encontrados durante el proceso y sus soluciones.
【PS1】AttributeError: el módulo 'torch._C' no tiene el atributo 'DoubleStorageBase'
La causa del error puede ser que la versión de la antorcha y la versión de cuda sean incompatibles.
Consulta la versión de cuda: nvcc -v, puedes ver cuda11.8
Cambiar versión
conda install pytorch==1.10.0 torchvision==0.11.0 torchaudio==0.10.0 cudatoolkit=11.3 -c pytorch -c conda-forge
Aún hay error después del reemplazo
intentar
conda install pytorch torchvision torchaudio pytorch-cuda=11.8 -c pytorch -c nvidia
Después de la actualización
Importar antorcha no es problema
Pero al ejecutar aparece
ImportError: no se puede importar el nombre 'COMMON_SAFE_ASCII_CHARACTERS' desde 'charset_normalizer.constant' (/opt/miniconda3/envs/gan/lib/python3.8/site-packages/charset_normalizer/constant.py) El error al informar el nombre de importación "COMMON_SAFE_ASCII_CHARACTERS"
puede debe ser causado por un problema de versión con el módulo charset_normalizer. Intente actualizar el módulo charset_normalizer a la última versión o use una versión anterior y vea si eso resuelve el problema. Puede probar el siguiente comando para actualizar el módulo:
pip install --upgrade charset-normalizer
AttributeError: el módulo 'numpy' no tiene el atributo 'complejo'.
Haga clic en el código correspondiente
"/opt/miniconda3/envs/gan/lib/python3.8/site-packages/librosa/core/constantq.py", línea 1058,
np.complex
es complex
un alias obsoleto para el archivo integrado.
Alternativamente np.complex
, puedes usar:
complex(1) #output (1+0j)
#or
np.complex128(1) #output (1+0j)
#or
np.complex_(1) #output (1+0j)
#or
np.cdouble(1) #output (1+0j)
Como se muestra en la imagen después de la modificación.
Entonces está bien ~
【PS2】AssertionError: la frecuencia de muestreo no coincide. Se esperaba 22050, obtuve 48000 en /workspace/tts/Korean-FastSpeech2-Pytorch/data/Voice/wavs/72.wav
Porque el archivo .wav es estéreo, pero es necesario convertirlo a mono. Utilice la siguiente guía para convertir por lotes un lote de archivos a formato mono .
【PS3】ValueError: num_samples debería ser un valor entero positivo, pero obtuvo num_samples=0
Solución:
1. Verifique la ruta en el conjunto de datos. La ruta es incorrecta y los datos no se pueden leer.
2. Compruebe por qué la función __len__() del conjunto de datos genera cero
Expandir
train: '/workspace/tts/Korean-FastSpeech2-Pytorch/data/Voice/wavs'
validation: '/workspace/tts/Korean-FastSpeech2-Pytorch/data/Voice/vaild'
mel_path: '/workspace/tts/Korean-FastSpeech2-Pytorch/data/Voice/mels'
eval_path: '/workspace/tts/Korean-FastSpeech2-Pytorch/data/Voice/korean_corpus.csv'
python preprocess.py -c config/mydata.yaml -d /workspace/tts/Korean-FastSpeech2-Pytorch/data/DyonVoice/wavs