接下來,則是介紹如何使用中文語音合成。本文是引用 Tacotron2-Mandarin 這個專案來測試的,其實也有幾個類似的專案,只能說剛好這個被我測成功。有純英文的、有使用 tensorflow 的,這個是唯一有順利試成功的,效果也不錯。
基本環境安裝
一些基本的環境 (如 anaconda、共用 script) 的設定,已經寫在【共同操作】 這篇文章裡,請先看一下,確保所以指令可以正確運作。
建立 conda env
由於每個專案的相依性都不同,這裡會為每個案子都建立環境。
1 |
conda create -n tacotron2 python=3.9 |
專案下載
這個專案主要的訓練是由下面這個專案完成
1 2 3 4 5 6 |
cd projects git clone https://github.com/foamliu/Tacotron2-Mandarin cd Tacotron2-Mandarin echo "conda activate tacotron2" > env.sh echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/anaconda3/envs/tacotron2/lib/' >> env.sh source ./env.sh |
安裝套件
1 2 3 4 5 6 |
#conda install pytorch torchvision torchaudio cudatoolkit=11.1 -c pytorch -c nvidia -y #pip install torch==1.11.0+cu113 torchvision==0.12.0+cu113 torchaudio==0.11.0 --extra-index-url https://download.pytorch.org/whl/cu113 #pip install tensorflow chardet pip install transformers==4.26.1 pandas jieba scikit-learn conda install -c "nvidia/label/cuda-11.8.0" cuda-toolkit #依自己cuda版本更新 pip install torch tqdm opencv-python matplotlib |
安裝該專案套件
1 2 |
pip install -r requirements.txt pip install librosa==0.9.2 |
但要合成語音則需要下載另一個專案,及其預訓練的模型
1 2 |
git clone https://github.com/NVIDIA/waveglow cp waveglow/glow.py . |
將waveglow下的glow.py複制到Tacotron2-Mandarin,可能是Tacotron2-Mandarin裡的glow.py比較舊,用起來會有問題。
另外還要下載 waveglow 已經訓練好的模型,可由此處下載 https://api.ngc.nvidia.com/v2/models/nvidia/waveglow_ljs_256channels/versions/3/files/waveglow_256channels_ljs_v3.pt。將其改名成 waveglow_256channels.pt 放進 Tacotron2-Mandrain的目錄下。此檔案還有好幾個版本,目前只試到ljs_v3可使用. 個人筆記指令如下
1 |
ln -s /cache/common/models/tacotron2-mandarin/waveglow_256channels_ljs_v3.pt waveglow_256channels.pt |
數據集下載
訓練的數據集是使用BZNSYP(標貝) 的數具集。原專案的只提供該公司的官網,並無法下載。但在另一個專案 Tacotron-2-Chinese 中,有給出另外的下載連結 。讀者可由此處下載
下載後,將其在 data/ 下解壓,得到一個 BZNSYP 目錄。下面會有三個目錄
- PhoneLabeling: 每一句的時間
- ProsodyLabeling: 每一個檔的中文與拼音
- Wave: 每一句話的音檔
1 2 3 4 |
mkdir -p data/BZNSYP cd data/BZNSYP unrar x /cache/common/datasets/BZNSYP.rar rm -f Wave/desktop.ini |
音檔預處理
原始的音檔是以 48k 做採樣,但訓練的程式是以22050的採樣率來做處理,所以每次載入音檔後還要用CPU做重取樣,會使得 GPU 閒置,拉長整個訓練時間。所以這邊我們做了一個預處理,來將每個檔案都先轉先 22050 HZ。轉換腳本如下
1 2 3 4 5 6 7 |
#!/bin/bash for i in `ls Wave/*` do echo $i ffmpeg -y -i $i -ar 22050 /tmp/tmp.wav cp -f /tmp/tmp.wav $i done |
執行完切回主要的專案目錄
進行訓練
這個語音訓練的腳本,是我自己做時所時用的,可以避免checkpoint被覆蓋。自人的測試結果是epochs 要1000以上才比較能用,預設是10000次。所以也會用到 checkpoint / pretrained 機制。我是以下列自己的腳本做訓練
1 2 3 4 5 6 |
#!/bin/bash if [ -e checkpoint.tar ];then python train.py --checkpoint=checkpoint.tar else python train.py fi |
使用 RTX4090 每個 epoch 大概是120 秒,加上一些其它的時間,大概要15秒,一個epoch就算150秒好了。600次以前的結果,有像人聲,但是不知道在說什麼。800次,就可以聽到明顯的可瞭解的語音了,約1000可以比較好一些,我是覺得訓練到3000次就可以了。
不過預設是10000次,也許效果到那時會更好
進行測試
進行測試,則執行下列命令先將 checkpoint 的檔案輸出成模型檔案 tacotron2-cn.pt
1 |
python export.py |
接著再以 python demo.py 來產生wave檔案 output.wav 就可以聽聽看結果了。
訓練結果
Epoch 1
Epoch 236
Epoch 522
Epoch 2462
Epcoh 3894
官方範例 (可能是 Epoch 10000)