[내목소리 TTS 만들기] 03.1 Glow-TTS 학습하기(로컬)
#TTS #coqui #tts #학습 #glow #docker #학습 #training
[내목소리 TTS 만들기] 03. Glow-TTS 학습하기
앞서 소개한 tts 사이트 설명대로는 google colaboratory에서 진행하면 되는데(https://colab.research.google.com/drive/1L5o8joH8LDV37eupNUpqqWrOcw1sGCit),
몇가지 오류때문에 여러번 고치다가(파이썬 버전문제 등) 너무 불편해서 glow-tts 소스를 로컬에 받아다가 진행해본다.
* 학습에는 매우 좋은 사양의 컴퓨터가 필요합니다.
* 저는 27일 정도 걸려서 포기하고 다시 Google Colaboratory로 변경하니, 사양이 안좋으신 분들은 다시 고려하시길...
- 도커 centOS 이미지 실행 및 파이썬 설치
우선 Glow-TTS 학습을 위해 사이트에서 제안한 coqui TTS 라이브러리를 다운받아야 하는데,,
README를 먼저 읽어봅니다.
https://github.com/sce-tts/TTS
좀 예전 라이브러리라 파이썬 3.9 미만으로 설치를 해야하네요.
예전에 했을 때는 파이썬 다운그레이드보다 삭제 후 새로 까는 게 더 빨랐었는데요..
생각해보니 지금 윈도우에 도커가 설치되어 있으니 도커를 이용해봅니다.
파이썬만 설치되는 이미지도 있는데요, 저는 centOS 이미지를 먼저 받고 그 안에 파이썬 버전을 3.6으로 맞추겠습니다.
(윈도우용 도커는 GUI에서 원격 이미지 받을 때 로그인을 요구하는데요.. 파워쉘 등에서 하면 로그인 안해도 됩니다.)
docker run -it centos:7
yum -y update
yum -y install python36
// python 명령어 기본 버전 3.6으로 변경
alias python='python3.6'

2. git 설치
깃허브에 있는 라이브러리를 클론하기 위해 깃도 설치합니다
yum -y install git

3. 모델 라이브러리 받기
적혀있는대로 깃 클론과 setup.py 실행을 해봅니다.

저는 home 디렉토리 아래로 이동해서 할게요
cd home
git clone --depth 1 https://github.com/sce-tts/TTS.git -b sce-tts
cd TTS/
python setup.py develop

SyntaxError: Non-ASCII character '\xc3' in file setup.py on line 69, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details
# -*- coding: utf-8 -*-
를 추가하면 해결날 거라는데,,,
우선 vi로 해봅니다.
vi setup.py

했는데도 똑같은 오류가 나네요...
잘못한 줄 알았는데,, 해당 선언문을 맨 첫줄로 해야하는 것이었군요.
이번엔 numpy 문제
ImportError: No module named numpy

지금 pip도 conda도 없으니 우선 pip를 설치합니다.
3. 라이브러리 dependecies 설치
curl https://bootstrap.pypa.io/pip/3.6/get-pip.py -o get-pip.py
python3.6 get-pip.py

그리고 넘파이 설치

pip install numpy
했는데 보니 다른 것들도 다 설치해야해서 requirements.txt 전체 설치
pip3.6 install -r requirements.txt
하고 setup.py 실행했더니 이번엔 또 다른 오류...
unable to execute 'gcc': No such file or directory
error: command 'gcc' failed with exit status 1
c 컴파일러가 필요한가 봅니다.
설치합니다
yum install gcc
하고 실행했는데 또 뭐가 필요하다그래서 python-devel 설치

yum install python36-devel
그리고 setup.py를 실행하니 이번엔 대강 된 것 같은 느낌입니다.

4. 음성파일 옮기기

TTS 디렉토리 안으로 filelists.zip을 가져온다음 압축풀기를 하면 되는 군요
그럼 로컬에 있는 압축파일을 도커 컨테이너 안으로 옮겨보도록 하겠습니다.
docker cp C:\Users\mycom\Downloads\filelists.zip distracted_moore:/home/TTS/
docker exec -it distracted_moore bash
cd home/TTS
unzip이 없군요... 또 설치
yum install zip unzip
unzip -q filelists.zip -d ./filelists
5. 사전학습데이터 받고, 학습자료 정보 저장

저는 /home/TTS/glow-tts 에 받았어요
gdown --id 1DMKLdfZ_gzc_z0qDod6_G8fEXj0zCHvC -O glowtts-v2.zip
unzip -q glowtts-v2.zip -d ./
+++ 혹시 모르니 glowtts-v2/config.json 내부 경로들 미리 수정합니다.

python3.6 TTS/bin/compute_statistics.py "/home/TTS/glow-tts/glowtts-v2/config.json" "/home/TTS/glow-tts/glowtts-v2/scale_stats_new.npy" --data_path "/home/TTS/filelists/filelists/wavs/"
저는 여기서 제로디비전 에러가 나서 되지 않았습니다.
소스 고치러 들어갔더니... 비슷하게 생긴 코드가 많아서 하나만 예외처리 할 게 아닌 거 같더군요
| > max_norm:4.0
| > clip_norm:True
| > do_trim_silence:False
| > trim_db:60
| > do_sound_norm:False
| > stats_path:None
| > base:10
| > hop_length:256
| > win_length:1024
> There are 0 files.
0it [00:00, ?it/s]
Traceback (most recent call last):
File "TTS/bin/compute_statistics.py", line 96, in <module>
main()
File "TTS/bin/compute_statistics.py", line 65, in main
mel_mean = mel_sum / N
ZeroDivisionError: division by zero
알고보니 filelists 경로설정을 잘못....
제대로 고쳐서 하니 이번엔 또 다른 오류입니다.
> There are 1500 files.
9%|####### | 132/1500 [00:03<00:34, 39.90it/s]
Traceback (most recent call last):
File "TTS/bin/compute_statistics.py", line 99, in <module>
main()
File "TTS/bin/compute_statistics.py", line 55, in main
linear = ap.spectrogram(wav)
File "/home/TTS/TTS/utils/audio.py", line 275, in spectrogram
D = self._stft(self.apply_preemphasis(y))
File "/home/TTS/TTS/utils/audio.py", line 259, in apply_preemphasis
return scipy.signal.lfilter([1, -self.preemphasis], [1], x)
File "/usr/local/lib64/python3.6/site-packages/scipy/signal/signaltools.py", line 1890, in lfilter
out_full = np.apply_along_axis(lambda y: np.convolve(b, y), axis, x)
File "<__array_function__ internals>", line 6, in apply_along_axis
File "/usr/local/lib64/python3.6/site-packages/numpy/lib/shape_base.py", line 379, in apply_along_axis
res = asanyarray(func1d(inarr_view[ind0], *args, **kwargs))
File "/usr/local/lib64/python3.6/site-packages/scipy/signal/signaltools.py", line 1890, in <lambda>
out_full = np.apply_along_axis(lambda y: np.convolve(b, y), axis, x)
File "<__array_function__ internals>", line 6, in convolve
File "/usr/local/lib64/python3.6/site-packages/numpy/core/numeric.py", line 815, in convolve
raise ValueError('v cannot be empty')
ValueError: v cannot be empty
132번째 파일에서 에러가 났네요,
metadata.csv에서 132번째 파일을 찾아봅니다.

성동일에서 문제가 났나봅니다
오디오도 찾아서 들어봅니다.


말하다 짤리는 거 보니, 중간에 문제가 있었던 파일인가보네요.
우선 목록을 제거해봅니다.

metadata.csv
vi 로 한 줄 삭제, 하고 wavs 들어가서 wav 파일도 삭제했는데요...
그래도 해결이 안나네요.
print를 compute_statistics.py 에 넣어서 알아봅니다.


예상했던 대로 wav 파일의 문제가 맞는 것 같은데, 제가 파일을 잘못 골랐나보네요

문제가 되는 파일명을 보기위해 프린트에 item을 추가합니다.

찾았다요놈
그럼 filelists/wavs/319~.wav 파일을 찾아 삭제하고, metadata.csv 에서도 해당 목록을 제거합니다.


파일도 제거
테스트로 잘되는지 확인하고, compute_statistics.py 에 추가했던 프린트는 주석하고 다시 실행해봅니다.
python3.6 TTS/bin/compute_statistics.py "/home/TTS/glow-tts/glowtts-v2/config.json" "/home/TTS/glow-tts/glowtts-v2/scale_stats_new.npy" --data_path "/home/TTS/filelists/filelists/wavs/"

또 같은 에러가 났습니다.
이번엔 원인을 알고 있으니 위의 방법으로 다시 해결해보겠습니다.
전체를 프린트하는 대신 wav가 빈 배열로 들어올때만 프린트하게 하면 되겠죠

드디어 진행완료.
두 개의 파일에 문제가 있었네요.
6. 테스트 문장 만들기

이거는... 쉘에서 한글이 안먹혀서 로컬에서 작성해서 옮겼습니다.
docker cp D:\tts\test_sentences.txt busy_heisenberg:/home/TTS/
7. TensorBoard 실행
텐서보드를 사용하려면 텐서플로우를 설치해야 한다고 하네요.
pip install tensorflow
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
tts 0.0.14.1 requires numpy==1.18.5, but you have numpy 1.19.5 which is incompatible.
하지만 넘파이 버전때문에 문제가 생겼군요.
라이브러리를 실행하는 게 중요하니, 넘파이를 다운그레이드 합니다.
pip uninstall numpy
pip install numpy==1.18.5
이러면 텐서플로랑 버전이 안맞아서 텐서플로도 낮은 버전으로 바꿉니다.
pip uninstall tensorflow
pip install tensorflow==1.15.0
그럼 이제 텐서보드를 실행해봅니다.

tensorboard --logdir="/home/tensorboard-log"

근데... 포트 매핑을 안해놔서 로컬에서 접속이 안되네요..
매핑을 위해 현재컨테이너를 이미지로 저장하고 포트 설정해서 다시 런 합니다..
보시는 분들은 처음에 이미지 런 할 때 부터 매핑하시길...
docker stop distracted_moore
docker commit distracted_moore tts-glow
docker run -it -p 6006:6006 tts-glow
tensorboard --logdir="/home/tensorboard-log"

일단 됐습니다.
8. glow-tts 학습진행

위치들이 구글 드라이브 기준으로 되어있으니 다 바꿔서 진행해야 합니다.
cd /home/TTS
python3.6 /home/TTS/TTS/bin/train_glow_tts.py --config_path "/home/TTS/glow-tts/glowtts-v2/config.json" --coqpit.datasets.0.path "/home/TTS/filelists/filelists" --coqpit.audio.stats_path "/home/TTS/glow-tts/glowtts-v2/scale_stats.npy" --coqpit.test_sentences_file "/home/TTS/test_sentences.txt" --coqpit.output_path "/home/TTS/glow-tts/glowtts-v2/" --coqpit.num_loader_workers 2 --coqpit.num_val_loader_workers 2 --restore_path "/home/TTS/glow-tts/glowtts-v2/model_file.pth.tar"
그리고 바로 에러ㅣ....
! Run is removed from /home/TTS/glow-tts/glowtts-v2/glowtts-v2-May-06-2023_07+26AM-3aa165a
Traceback (most recent call last):
File "/home/TTS/TTS/bin/train_glow_tts.py", line 588, in <module>
main(args)
File "/home/TTS/TTS/bin/train_glow_tts.py", line 564, in main
eval_avg_loss_dict = evaluate(eval_loader, model, criterion, ap, global_step, epoch)
File "/usr/local/lib64/python3.6/site-packages/torch/autograd/grad_mode.py", line 28, in decorate_context
return func(*args, **kwargs)
File "/home/TTS/TTS/bin/train_glow_tts.py", line 418, in evaluate
test_sentences = [s.strip() for s in f.readlines()]
File "/usr/lib64/python3.6/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xec in position 3: ordinal not in range(128)
train_glow_tts.py 로 들어가서 utf-8 설정을 추가해줍니다.

이제는 문제없이 돌아가는 것 같은데...

텐서보드는 새로고침해도 여전히 그대로네요....
뭐... 안보인다고 안돌아가는 것 같지는 않으니 우선 이대로 둬 봅니다.
집컴이 엄청나게 좋은 성능은 아니니, 학습은 한참 기다려야 합니다.

진행하다가 평균속도 계산해보니 전체 다 돌리려면 27일 정도 필요하네요^^
학습시도까지는 ... 성공했지만 하드웨어 문제로 다시.... Google Colaboratory로 갑니다...
네이버 게시글 옮기는 중...작성일: 2023. 5. 6. 16:55