딥러닝 음성합성 multi-speaker-tacotron(tacotron+deepvoice)설치 및 사용법
딥러닝 음성합성 multi-speaker-tacotron(tacotron+deepvoice)설치 및 사용법
작성자 : 클루닉스 서진우 (alang@clunix.com)
작성일 : 2018년 3월 1일
음성합성(TTS)을 위한 딥러닝 오픈 모델인 tacotron 과 deepvoice 를 결합한 multi-speaker-tacotron 에 대해
개발 환경 구현 및 실제 음성 합성을 위한 딥러닝 학습 방법에 대해 정리한 문서이다.
본 개발 환경을 구현하기 위해서는 기본적으로 python 3.6 과 cuda 8.0, cudnn 6.0, tensorflow 혹은 tensorflow-gpu 1.3.0
이 설치되어 있어야 한다.
만일 tensorflow 1.3.0 이외의 버전을 이용할 경우 에러가 발생하니 주의해야 한다.
이밖에 운영체제 레벨에서 필요한 유틸리티로 ffmpeg, sox 등이 있으면 전후처리를 하는데 도움이 많이 된다.
참고로 개발환경에 이용된 운영체제는 Centos 7.4 이다.
일반적인 딥러닝 환경 구성(os, cuda, python, 기타 python library, package)에 대한 설치 방법은 별도로 다룰 계획이다.
본 문서에서는 multi-speaker-tacotron 설치 및 이용 방법에 대해서만 설명하고자 한다.
참고로 Multi-speaker-tacotron 메인 홈페이지는 https://carpedm20.github.io/tacotron/ 이다.
1. 설치
작업을 위한 가상 Python 환경을 생성한다.
$ source /APP/DeepLn/profile.d/python36.sh
$ source /APP/DeepLn/profile.d/cuda8_env.sh
$ virtualenv tf-tacotran
Multi-speaker-tacotron 소스를 다운로드 받는다.
$ git clone https://github.com/carpedm20/multi-speaker-tacotron-tensorflow.git
간혹 다른 서버로 개발환경 전체를 복제하는 경우가 종종 있어 virtualenv 로 생성된 python 과 ms-tacotron 패키지를
병합해서 관리한다.
$ mv multi-speaker-tacotron-tensorflow/* tf-tacotron
$ mv multi-speaker-tacotron-tensorflow/.git* tf-tacotron
가상환경을 적용한다.
$ source tf-tacotron/bin/activate
(tf-tacotron) [alang@GCT3DLM01 ~]$
Multi-speaker-tacotron 에 필요한 패키지를 설치 한다.
$ cd tf-tacotron
$ pip install -r requirements.txt
아래와 같이 많은 python package 가 설치될 것이다.
설치된 패키지를 확인한다.
$ pip freeze
Tensorflow 1.3.0 버전을 설치한다. GPGPU 가 장착된 시스템이라면 tensorflow-gpu 1.3.0 버전을 설치하도록 한다.
$ pip install tensorflow-gpu==1.3.0
Nltk의 punkt 데이터를 다운받는다
$ python -c “import nltk; nltk.download(‘punkt’)”
이것으로 기본적인 패키지 설치는 완료된다.
2. 전처리 사용 방법
일반적인 사용법은 tf-tacotron/datasets/<화자명>/audio 밑에 학습시킬 음성데이터를 복사해 둔다.
그리고 tf-tacotron/datasets/<화자명>/alignment.json 파일에 음성데이터와 해당 데이터의 text 에 해당하는 매핑 정보를
json 포맷으로 생성해야 한다.
/// 일반적 사용법
——————————————————————————–
datasets 디렉토리는 다음과 같이 구성되어야 합니다
datasets
├── son
│ ├── alignment.json
│ └── audio
│ ├── 1.mp3
│ ├── 2.mp3
│ ├── 3.mp3
│ └── …
└── 아무개
├── alignment.json
└── audio
├── 1.mp3
├── 2.mp3
├── 3.mp3
└── …
그리고 아무개/alignment.json는 아래와 같은 포멧으로 json 형태로 준비해 주세요.
{
“./datasets/아무개/audio/001.mp3”: “존경하는 국민 여러분”,
“./datasets/아무개/audio/002.mp3”: “국회의장과 국회의원 여러분”,
“./datasets/아무개/audio/003.mp3”: “저는 오늘”,
}
datasets와 아무개/alignment.json가 준비되면, 아래 명령어로 학습 데이터를 만드시면 됩니다:
python3 -m datasets.generate_data ./datasets/아무개/alignment.json
———————————————————————————
이 작업들은 수작업을 해야 하지만, 본 소스에는 이를 어느정도 자동화 시켜주는 스크립트를 제공한다.
자동화 스크립트는 tf-tacotron/scripts 디렉토리 밑에 존재한다.
$ cd tf-tacotron/scripts
기본 제공되는 스크립트는 손석희 앵커의 JTBC 뉴스룸의 브리핑 내용이다.
스크립트를 살펴 보면..
$ cat prepare_son.sh
—————————————————————————————————————————————————
#!/bin/sh
# 1. JTBC 홈페이지에서 뉴스룸의 앵커브리핑 영상과 음성원본파일을 다운받는다.
python -m datasets.jtbc.download
# 2. 한 방송 분량이 5분~10분정도의 내용으로 연속된 음성파일이다. 이를 한 문장열의 형태로 음성간 묵음을
기준으로 해서 파일을 분할한다.
python -m audio.silence –audio_pattern “./datasets/jtbc/audio/*.wav” –method=pydub
# 3. 분할된 wav 음성 파일을 구글의 STT(음성인식) API 를 통해 음성파일에 대한 text 를 추출한다.
python -m recognition.google –audio_pattern “./datasets/jtbc/audio/*.*.wav”
# 4. 구글 STT API 의 경우 정확도가 낮기 때문에 방송 대본을 비교해서 일정 score 이상의 내용만 선별한다.
python -m recognition.alignment –recognition_path “./datasets/jtbc/recognition.json” –score_threshold=0.5
# 5. 매 방송 시작 시 뉴스룸 앵커브리핑 MR 과 같이 음성이 섞이는 부분이 있는데 이부분을 학습 데이터에서 제거한다.
사실 이 부분은 download 단계에서 진행되기 보단 실제 학습 dataset 이 만들어진 이후 train 직전에 수행해야 한다.
rm datasets/jtbc/data/*.0000.npz
—————————————————————————————————————————————————
3. 설치 나 이용 과정에서 발생 문제 해결 방법
- Download 스크립트 3단계 과정
3 단계에서 구글 STT 를 이용하기 위해서는 아래와 같은 사전 준비가 필요한다.
구글 음성인식 API 이용 방법
https://cloud.google.com/docs/authentication/getting-started
In GCP Console, navigate to the [Create service account key] page.
[Create service account key] Link 로 가서 google 서비스 계정 만들고,
카드 등록하고, 음성인식 서비스 활성화 한다.
1년간 무료라고 함..뭔가 찝찝..
Key 를 json 형태로 만들면.<XXXXX-XXXXXX-43211bc49356.json> 같은 파일을 다운로드 받을 수 있음.
작업 서버에 옮겨둠. ..
스크립트를 실행한다.
$ export GOOGLE_APPLICATION_CREDENTIALS=”<PATH>/XXXXX-XXXXXX-43211bc49356.json”
$ sh prepare_son.sh
- Download 스크립트 4단계 과정
4단계 수행 시, unicodedecodeerror ‘cp949′ 에러가 발생하는 경우가 있다.
$ vi utils/__init__.py
89줄 : with open(path,encoding=encoding) as f:
을 with open(path,encoding=’UTF-8’) as f: 로 변경해 준다.
- 학습 진행 시, attention 그래프에서 한글이 깨지는 문제
Matplopt 으로 그래프를 생성하는 데 그래프에 attention 에 따른 한글 TEXT (자음,모음) 가 표기되는데, 폰트 인식 문제로
깨지는 경우가 있다. 해결 방법은 아래와 같다.
$ fc-cache -fv
$ rm -rf ~/.cache/matplotlib/*
# cp ~/multi-speaker-tacotron-tensorflow/utils/NanumBarunGothic.ttf
~/python3.6/lib64/python3.6/site-packages/matplotlib/mpl-data/fonts/ttf
# cp ~/multi-speaker-tacotron-tensorflow/utils/NanumBarunGothic.ttf /usr/share/fonts/nhn-nanum
4. 학습 및 이용 방법
Download 스크립트 단계가 완료되면 ./datasets/<화자>/alignment.json 파일이 생성되어 있을 것이다.
내용을 보면 아래와 같다.
$ cat datasets/son/alignment.json
{
“./datasets/son/audio/NB10584578.0001.wav”: “오늘 뉴스룸이 주목한 단어는 저돌입니다”,
“./datasets/son/audio/NB10584578.0005.wav”: “이렇게 얘기를 했습니다”,
“./datasets/son/audio/NB10584578.0007.wav”: “문구를 비대위원장이 저돌적으로 돌파 해야 할 과제는 과연 무엇인가”,
“./datasets/son/audio/NB10584578.0008.wav”: “첫 번째는 계파주의 청산입니다”,
“./datasets/son/audio/NB10584578.0010.wav”: “이런 보고서를 냈습니다”,
“./datasets/son/audio/NB10584578.0011.wav”: “계파정치 청산은 민주당의 미래를 위한 최우선 과제다”,
“./datasets/son/audio/NB10584578.0012.wav”: “아 이렇게 얘기했는데 그러나 아시는 것처럼 이 보고서는”,
“./datasets/son/audio/NB10584578.0013.wav”: “나갔다 집안 발 끝에 결국 채택되지 않았습니다”,
“./datasets/son/audio/NB10584578.0014.wav”: “아마 야당에서 한상진교수 좋아하는 사람 별로 없을 겁니다”,.
.
.
}
학습 데이터 셋을 생성한다.
$ python3 -m datasets.generate_data ./datasets/son/alignment.json
그럼 ./datasets/<화자>/data 디렉토리가 생기고, 그 안에 npz 포맷의 파일이 생성되어 있을 것이다.
손석희 데이터셋의 경우 Download 5단계 내용을 수행한다.
$ rm -f ./datasets/son/data/*.0000.npz
학습전에 hparams.py 파일에서 파라메터를 수정한다.
파라메터는 음성파일의 품질과 데이터셋의 정확도에 따라 몇 가지 조정이 가능한데, 이는 학습하는 데이터
에 따라 다를 수 있기 때문에 정확한 권장 값은 없다.
다만 손석희의 경우 아래 설정을 통해 의미있는 결과를 얻을 수 있었다.
$ vi hparams.py
‘cleaners’: ‘korean_cleaners’, #originally korean_cleaners
‘model_type’: ‘single’, # [single, simple, deepvoice]
‘attention_size’: f(256),
‘batch_size’: 32,
‘initial_learning_rate’: 0.002,
‘reduction_factor’: 4,
‘min_iters’: 20,
‘max_iters’: 200,
학습을 수행한다.
$ python3 train.py –data_path ./datasets/son
학습이 진행되면 logs/son_2018-01-28_16-53-12 식의 디렉토리가 생기고, 이 디렉토리에 500 step 마다 학습 결과에
해당하는 train, test 샘플 wav 파일과 그래프 파일인 png 확장 파일이 생긴다. 그리고 1000 step 마다 실제 음성합성에
이용할 수 있는 chkpt 파일이 생긴다.
$ eog test*000.png
또한 학습 진행 과정에서 학습 상태는 tensorboard 로 확인이 가능하다.
$ tensorboard –log_dir ./logs/son_2018-01-28_16-53-12
학습이 어느정도 정상적으로 이루어지고, Step 이 100,000 정도가 넘어가면 실제 합성을 해 볼 수가 있을 것이다.
음성 합성 방법은 아래와 같다.
$ python3 synthesizer.py –load_path logs/son-20171015 –text “이거 실화냐?”
그럼..기본적으로 tf-tacotron/samples 디렉토리 및에 wav, png 파일에 생성된다.
5. 학습 경험 정리
최소 손석희 데이터를 다운 받아 작업을 해보면 3만~4만 사이의 데이터를 얻을 수 있는데, 이를 가지고 그냥 작업을
하면 거의 원하는 결과를 얻기 힘들다. 실제 구글 STT API 를 통해 추출된 내용을 비교해보면 매우 참담했던 기억이
있다. 그렇다고, 이를 혼자서 수작업으로 다 수정하는 것은 무리라고 본다.
이리저리 다양한 방법으로 그나마 나은 데이터를 12000~13000 정도 선별한 후에야 정상적인 학습결과를 얻을 수
있었다.
개인적인 경험 상 단일 화자의 경우 일반적인 문장을 넣어 합성이 가능하게 할려면 적어도 정확도가 높은 데이터
10시간 분량은 필요했다. 다만 현실적으로 10시간 데이터를 확보하는 것이 매우 힘들었었다.
손석희의 경우 정확도 70% 이상의 데이터를 선별해서 데이터셋을 만들 경우 8~10시간 수준의 데이터를 확보 할 수
있었다. 손석희 데이터를 이용해서 단일 화자로 잘 학습되는 데이터 셋을 확보 한다.
이밖에 한국어 코퍼스 용으로 만들 여자 성우 데이터 (KSS.zip)의 경우 8시간 분량의 정확한 음성과 대본을 얻을 수
있었다. (다만, 정확한 음성과 TEXT 조합이지만, 파일 앞뒤에 불규칙적인 묵음이 상당수 존재하고, 대본 내용이 문어체와
구어체가 혼합되어 있어 다소 학습에 어려움이 존재하긴 함)
https://www.kaggle.com/bryanpark/korean-single-speaker-speech-dataset
이렇게 일정 분량이 확보된 데이터를 통해 1차 학습을 완료한 경우, 적은 분량 (1시간~4시간)의 데이터만 존재하는
화자의 음성도 학습이 가능했다.
예) 문재인 (1.8시간), 유인나 오디오북 (1시간), 유인나 볼륨을 높여라 방송(3시간)
Multi-speaker-tacotron 의 경우 단일 화자일 경우 hparams.py 에서 model_type 을 single 로, 다중 화자일 경우
Model_type 을 deepvoice 로 하여 학습을 하게 된다.
학습분량이 적은 화자의 경우 학습분량이 많은 화자의 데이터를 같이 학습하면 attention 을 형성할 수 있다.
다중화자 학습을 수행하는 방법은 아래와 같다
$ vi hparams.py
‘model_type’: ‘deepvoice’, # [single, simple, deepvoice]
$ python3 train.py –data_path ./datasets/moon,./datasets/son
개인적인 경우, 데이터가 적은 경우 유사한 문장열 길이의 데이터만을 모아서 학습을 하면 attention 을 형성하는데
효과가 있었다. 손석희, 문재인, 유인나(볼륨) 데이터의 경우 모두 문장열 길이의 차이가 크다.
이를 한번에 학습하는것 보다는 string_size 길이를 60~100, 100~140, 60~140으로 데이터를 나누어서 다중화자로
학습시키니깐 더 좋은 결과가 생성되었다.
또한 음성의 화체 (문어체, 구어체) 역시 학습 target 의 화자와 유사한 화체를 가진 데이터를 이용하는 것이 학습
결과에 영향을 주었다.
예를 들면 1시간 분량 데이터의 유인나 오디오북 데이터를 가지고 8시간 정도의 한국어 여자 코퍼스 데이터를
학습하는 경우와 10시간 분량의 손석희 데이터로 학습하는 경우, 손석희 데이터가 훨씬 좋은 결과를 나타내었다.
하지만 유인나 볼륨을 높여라 의 2~3시간 데이터 분량(정확도 낮음)의 경우 손석희 데이터보다 유사 화체를 가진
한국어 코퍼스 데이터를 사용하는 게 휠씬 좋은 결과를 얻을 수 있었다.
이 같은 방법으로 실제 합성에 성공하여 목소리는
손석희, 문재인, 유인나(볼륨버전), 유인나(오디오북버전), 한국어코퍼스 이다.
가장 난이도가 높았던 버전은 유인나(볼륨버전)이였다.
딥러닝 최적 개발 플랫폼 환경을 연구하기 위해 실제 딥러닝 응용을 다루어 볼 필요가 있어 10개월간 여러가지 모델을
Deploy 하면서 음성 합성 분야에 제일 많은 시간을 소비한 듯 합니다. Deploy 과정에서 좋은 소스를 공유해주신 개발자
분과 많은 정보를 공유해 주신 여러분들께 감사드립니다.
6. 음성 합성 결과 공유
아래는 그간 사내나 사외에서 딥러닝 플랫폼 관련 세미나를 할 때 참고하기 위해 만든 결과들입니다.
손석희 – 사내 세미나
문재인 – 사내 세미나
유인나(볼륨) – 딸에게 보내는 음성 편지
유인나(오디오북) – 해리포터
손석희 – 조선을 빛낸 100인의 위인
문재인 – 조선을 빛낸 100인의 위인
유인나(오디오북) – 조선을 빛낸 100인의 위인
한국어 코퍼스 – 조선을 빛낸 100인의 위인