HTS語音合成訓練(二)-自有數據訓練
簡介:
在《HTS語音合成訓練(一)》中我們安裝好了必要的軟件,並且跑通了DEMO,HTS語音合成訓練(二)則主要是用自己的數據來構建自己的語音合成系統,主要分為以下兩個步驟:
- 准備訓練數據
- HTS訓練模型和合成語音
1.准備訓練數據
1.1.准備16Khz音頻和txt.done.data文本
- 文件說明:
- 16Khz音頻:hts默認使用16Khz音頻,如果是其他采樣率的音頻則需要使用sox進行轉化
- txt.done.data文本:符合festival標准格式的音頻和對應句子文本文件
1.1.1.16Khz音頻
注意:本人音頻數據是由錄音人員提供,也可以使用cmu官方的語音數據,如果使用cmu的語音數據,則里面已經包含了txt.done.data文件和標准的16Khz語音,不需要進行轉化和准備txt.done.data
音頻文件必須是16Khz的單通道音頻,本人音頻為48Khz,所以需要使用sox進行轉化,可使用sudo apt-get install sox命令進行安裝,批量轉換腳本如下convert.sh:
-
wav_file路徑是存放由sox轉化的16Khz單通道音頻,
請將此腳本放在待轉化的音頻(本人為48Khz)同一目錄下執行,結果在wav_file目錄下查看
# convert.sh
#!/bin/bash
wav_file="/home/liyy/tts/hts_demo/data_1025/wav"
if [ ! -d $wav_file ]
then
makedir $wav_file
else
echo "wav_flle exists"
fi
for file in *.wav
do
# echo $file
c=${file}
echo $c
sox $c -r 16000 new_$c
# rm -rf $c
# mkdir ../wav
touch ${wav_file}/$c
mv new_$c ${wav_file}/$c
done
1.1.2.txt.done.data文本
生成音頻文本和音頻對應的EXCEL表格(由錄音人員提供),經過腳本將excel表格中的內容轉化為festival需要的格式(見【HTS語音合成訓練(一)2.4.demo訓練】下cmu_us_slt_arctic/etc/txt.done.data
注意:txt.done.data中不能帶.wav
- 音頻文件如下:
- 表格樣式如下,其中name為音頻的名稱,new_name為音頻對應文本
- 此excel名稱為festival_format.xls,表格名字為relations,這些請根據自己的實際情況進行更改,使用txtToFestivalFormat.py腳本將表格中內容轉換為txt.done.data標准文件
# txtToFestivalFormat.py
from genericpath import exists
import os
import pandas as pd
import copy
import shutil
import tqdm
def read_excel(information_d):
#方法一:默認讀取第一個表單
df=pd.read_excel(information_d["file_path"],sheet_name=information_d["table_name"],usecols=information_d["usecols"])#這個會直接默認讀取到這個Excel的第一個表單
df = df.fillna(method="ffill")
print(df)
return df
def to_format(text_path,format_wav_excel,table_name):
information_d = {"file_path":format_wav_excel,"usecols":[1,3],"table_name":table_name}
df = read_excel(information_d)
text_handle = open(text_path,'a+')
for index in df.index:
print(df.iloc[index,1])
try:
if df.iloc[index,1]:
old_name = df.iloc[index,1]
wav_name = str(df.iloc[index,1]).strip()
if wav_name.split(".")[-1] == "wav":
wav_name = os.path.splitext(wav_name)[0]
text = str(df.iloc[index,0].replace("\xa0"," ")).strip()
# 簡單的處理,這里請根據自己的實際情況進行處理,去掉不符合規范的字符
text = text.replace("…",",")
text = text.replace("√","true")
text = text.replace("×","false")
text = text.replace(".","")
if text.endswith("?"):
text = text[:-1] + "?"
label = "( " + wav_name + " " + "\"" + text + "\"" + " )\n"
print(label)
text_handle.writelines(label)
except Exception as e:
print(e)
text_handle.close()
if __name__ == "__main__":
text_path = r"D:\share\TTS調研\joint-voice\txt.done.data1103"
wav_path = r"D:\share\TTS調研\joint-voice\voice_test_1027"
format_wav_dir = os.path.join(wav_path,"xtc_female2")
format_wav_excel = os.path.join(format_wav_dir,"festival_format.xls")
table_name = "relations"
os.makedirs(format_wav_dir, exist_ok=True)
to_format(text_path,format_wav_excel,table_name)
- 音頻文件和txt.done.data中內容需要對應,個數不能多也不能少,使用checkFestivalTextAndWav.py腳本檢查對應是否有問題
- audio_path:音頻所在路徑
# checkFestivalTextAndWav.py
import os
# 使用log
import logging
# 配置log
logging.basicConfig(filename="debug.log",level=logging.WARNING)
file_name = 'txt.done.data'
pwd = os.getcwd()
audio_path = r"D:\share\TTS調研\joint-voice\wav"
audio_list = os.listdir(audio_path)
file_path = os.path.join(pwd,file_name)
wav_name_list = []
wav_name_set = {}
with open(file_path,"r") as f:
for line in f.readlines():
wav_name = line.split(" ")[1]
if not wav_name_set.get(wav_name):
wav_name_set[wav_name] = 1
else:
wav_name_set[wav_name] += 1
logging.warning("au重復:{}".format(wav_name))
if wav_name in audio_list:
wav_name_list.append(wav_name)
# continue
else:
logging.warning("audio不存在:{}".format(wav_name))
print(wav_name)
for au in audio_list:
# if not wav_name_set.get(au):
# wav_name_set[au] = 1
# else:
# wav_name_set[au] += 1
# logging.warning("au重復:{}".format(au))
if au in wav_name_list:
print(au)
else:
logging.warning("au不存在:{}".format(au))
print("錯誤:",au)
- 生成的txt.done.data文本示例
1.2.准備HTS訓練數據
- 本節包括以下幾個步驟
- Festvox安裝
- 准備原始數據:Raw audio (.raw)
- 准備上下文相關標注:Fullcontext training labels (.utt)
- 產生合成語音的標注:Generation labels for synthesis (.lab)
- 抽取特征
- 訓練流程參考地址
1.2.1.Festvox安裝
Festvox簡介:
Festvox項目旨在使新的合成聲音的構建更加系統和更好的文檔化,使任何人都可以構建一個新的聲音,這里我們主要使用Festvox提供的腳本進行對齊和語言學標注的任務
-
由於在《HTS語音合成訓練(一)》中安裝的festival版本為2.4,所以這里應該選擇festvox-2.7.0-release.tar.gz版本與之對應
# 編譯安裝
# sudo git clone https://github.com/festvox/festvox.git
# 如果遇到 A TLS packet with unexpected length was received,請參考:https://blog.csdn.net/u010609757/article/details/106857078
export ESTDIR=/home/liyy/tts/hts_demo/speech_tools
cd festvox
sudo ./configure
sudo make
# 如果github拉下來之后有問題可以嘗試下載編譯好的festvox,
# 下載地址:http://www.festvox.org/download.html
cd docbook
make doc
1.2.2生成.raw文件
- .raw文件:符合HTS訓練格式的文件,由wav文件轉化來
這里需要使用到SPTK/bin目錄下的ch_wave,這里由於環境中直接找不到ch_wave,所以我們用to_raw.sh腳本在speech_tools/bin目錄下面進行轉換,生成后可以在raw_file中查看
- raw_file為raw文件保存的目錄(根據自己實際情況更改)
- wav為16Khz的wav文件所在路徑(根據自己實際情況更改)
# to_raw.sh
#!/bin/bash
raw_file="/home/liyy/tts/hts_demo/data_1025/raw"
wav="/home/liyy/tts/hts_demo/data_1025/wav"
if [ ! -d $raw_file ]
then
mkdir -p $raw_file
else
echo "wav_flle exists"
fi
for file in ${wav}/*.wav
do
# echo $file
c=${file}
echo $c
raw_name=`echo $c | cut -d \. -f 1`
# 去除音頻文件路徑,保留wav名稱,##*/表示最后一個/和之前的字符串都丟棄
wav_name=${c##*/}
# 去除后綴.wav
pure_name=`echo $wav_name | cut -d \. -f 1`
echo $raw_name
./ch_wave -c 0 -F 32000 -otype raw $c | x2x +sf | interpolate -p 2 -d | ds -s 43 | x2x +fs > ${raw_name}.raw
# rm -rf $c
# mkdir ../wav
touch $raw_file/${pure_name}.raw
mv ${raw_name}.raw $raw_file/${pure_name}.raw
done
1.2.3.准備上下文相關標注
- 上下文標注:主要是提取出句子中和音頻中上下文之間的音素、音節、短語、單詞等相關特征,然后轉化為HTS標准格式(在后面章節中會提到),提供給后面的HTS訓練使用
這里的操作都是在festvox目錄下進行,主要用到的數據是前面准備的16Khz音頻和txt.done.data,主要工作是做HMM對齊和語言學特征標注,生成.utt標注文件,需要做如下三件事:
- 添加必要的環境變量,如果添加后無效,可以嘗試使用su命令進入root模式執行
- 將festvox中的wav文件鏈接到准備的16Khz音頻文件,可以使用ln軟連接,也可以直接將自己的音頻文件復制到wav目錄下
- 將txt.done.data復制到etc目錄下
轉換完之后的utt文件可以在festvox/festival/utts中進行查看
# 添加環境變量
vim ~/.bashrc
export PATH=/home/liyy/tts/hts_demo/festival:$PATH
export PATH=/home/liyy/tts/hts_demo/speech_tools/bin:$PATH
export FESTVOXDIR=/home/liyy/tts/hts_demo/festvox
export ESTDIR=/home/liyy/tts/hts_demo/speech_tools
# 更新
source ~/.bashrc
# 准備文件夾
$FESTVOXDIR/src/clustergen/setup_cg cmu us awb_arctic
# Copy or symlink your .wav files into the wav/ folder
cd wav
cp ../../data/cmu_us_slt_arctic/wav/* ./
# Put all the transcriptions into the file etc/txt.done.data
cd etc
cp ../../data/cmu_us_slt_arctic/etc/txt.done.data ./
# 運行標注和對齊命令,如果運行報錯見下面的報錯處理
./bin/do_build build_prompts
./bin/do_build label
./bin/do_build build_utts
# 錯誤信息:
# 指令如果報錯找不到環境變量,則使用sudo passwd root命令進入root試試
# 錯誤1:SIOD ERROR: could not open file /projects/festival/lib/dicts/cmu/cmulex.scm
# 解決方案1:查看系統中有沒有此文件夾,如果沒有,查看festival/lib/dicts/cmu/cmulex.scm文件是否存在,如果不存在則需要自己下載安裝festlex_CMU.tar.gz,下載地址見festival安裝地址章節,安裝要跟festival同一級目錄,安裝好之后festival/lib/dicts/cmu/cmulex.scm文件就會存在,與/projects/festival建立軟連接即可ln -s /home/liyy/tts/hts_demo//festival /projects/festival(也可使用sudo apt-get install festlex-cmu安裝,沒試過)
# 錯誤2:exicon english_poslex not defined
# 解決方案2:與錯誤1相同,下載festlex_POSLEX.tar.gz,與festival同級目錄安裝即可(也可使用festlex-poslex安裝,表示沒試過)
# 錯誤3:Wave files are missing. Aborting ehmm.
# 解決方案3:檢查txt.done.data中音頻文件名是否帶.wav后綴,如果帶.wav后綴則需要將后綴去掉,使用腳本檢測音頻文件和txt.done.data中的個數是否對應或者有重復
1.2.4.產生合成語音的標注
HTS本身並沒有fontend前端,所以如果要合成語音需要提前將想要產生的句子和標注准備好,這里我們直接沿用HTS語音合成訓練(一)的demo中HTS-demo_CMU-ARCTIC-SLT/data/labels/gen下的句子標注,如果想要自己產生標注數據,請參考上面鏈接
1.2.5.准備文件夾
在抽取特征前,需要先准備自己的訓練文件夾,這里我們直接復制HTS-demo_CMU-ARCTIC-SLT的demo文件夾並重命名為self_demo,復制好后,刪除HTS-demo_CMU-ARCTIC-SLT/data/raw和HTS-demo_CMU-ARCTIC-SLT/data/utts下的文件,將自己的文件放在目錄下
# Place your .raw files in yourvoicename/data/raw.
cd data/raw
rm *
cp ../../../data_1025/raw/*.raw ./
# Place your .utt files in yourvoicename/data/utts.
cd data/utts
rm *
cp ../../../festvox/festival/utts/xbzwx_* ./
# Place your gen labels in yourvoicename/data/labels/gen.
# 不用改動,直接沿用demo中的合成標注
可以更改Makefile中的LOWERF0和UPPERF0范圍值,有利用F0的提取,這里直接使用默認,如果需要更改請參考
1.2.6.抽取聲學特征
下面的操作將會從raw文件中抽取聲學特征,將會創建以下三個文件:
-
mgc(mel generalized cepstral): spectral features (頻譜特征)
-
lf0: log f0(基頻)
-
bap(Band Aperiodicity): if you are using STRAIGHT(STRAIGHT為一種聲碼器)
1.2.6.1.更改文件名和Makefile
由於data/Makefile中DATASET和SPEAKER是demo中的名字,如果使用自己的數據則需要進行更改由於我們raw的文件名是xbzwx_001_e.raw和xbzwx_002_e.raw這種格式,而demo中的為cmu_us_slt_*.raw格式,其中cmu_us代表DATASET為cmu的us發音,slt代表SPEAKER為女聲,所以我們將DATASET改為xbzwx,SPEAKER設置為slt,同時使用腳本更改raw文件名和utt文件名名稱格式
注意:這里不建議將SPEAKER設置為空,后面可能會有坑
# rename.sh
#!/bin/bash
# 更改raw文件時將.utt改成.raw即可,和文件放在同一級目錄執行
for file in `ls | grep .utt`
do
newfile=`echo $file | sed 's/_/_slt_/'`
mv $file $newfile
done
更改data/Makefile
1.2.6.2.抽取特征
# 執行抽取命令
make features
# This step composes the various different acoustic features extracted in the previous step into one combined .cmp file per utterance.
# 將特征整合到一個文件下面,便於訓練
make cmp
# This step "flattens" the structured .utt file format into the HTS .lab format
# 將utt文件轉為hts格式文件
make lab
# These files are "Master Label Files," which can contain all of the information in the .lab files in one file, or can contain pointers to the individual .lab files. We will be creating .mlf files that are pointers to the .lab files
# 創建mlf文件,創建完之后檢查文件里的路徑是不是自己的文件路徑,不是需要把路徑改成自己文件路徑
make mlf
# This step creates full.list, full_all.list, and mono.list, which are lists of all of the unique labels. full.list contains all of the fullcontext labels in the training data, and full_all.list contains all of the training labels plus all of the gen labels
# list包含了full和mono的labels和gen中的labels,而且是依賴於前面的cmp文件
make list
# This step creates training and generation script files, train.scp and gen.scp. This is just a list of the files you want to use to train the voice, and a list of files from which you want to synthesize examples
# 想要加入訓練的音頻和合成的例子
make scp
2.HTS訓練模型和合成語音
當我們准備好了所有數據之后,檢查數據是否滿足要求:
如果確認沒有問題之后,在回到self_demo目錄,更改script/Config.pm文件中dset選項,此文件也是各種參數的配置文件,如果需要修改參數可以在此文件中修改
# 執行訓練命令,可以在train.log中查看訓練進度,err.log中查看錯誤信息
perl scripts/Training.pl scripts/Config.pm > train.log 2> err.log
如果想知道訓練中的詳細細節,可以參考HTK book文檔,會對訓練細節有詳細的描述
訓練過程中,如果發生錯誤,可以在err.log中進行查看,請參考HTS官方論壇或者google搜索錯誤原因
修改完錯誤之后,在train.log中查看訓練的進度,如果發生錯誤后,為了可以繼續訓練,請先在train.log中查看自己的訓練進度,然后修改script/Config.pm中的Switch參數,參數為0時表示不再執行,為1時表示執行,將已經執行過的步驟改為0,然后運行訓練腳本即可繼續訓練
如果沒有問題,則等待訓練完之后可以在/gen/qst001/ver1中查看合成音頻效果,在voice目錄中可以看到.htsvoice后綴的文件是模型文件,此模型文件可以使用festival或者hts_engine中api進行加載
3.參考文檔
4.總結
本篇主要介紹了如果用自己數據怎么通過festvox和hts訓練模型以及訓練流程和相關注意事項,下一篇將會講解怎么利用festival+hts_engine構建一套完整的TTS系統,合成自己的語音
注:后面一篇改為理論基礎了,如果是直接參數合成的話可以接WORLD聲碼器,由於是進行的拼接合成,所以使用的HTS_enggine的API來提取的MFCC和基頻,然后通過構造損失函數,從語音庫中查找最佳片段合成語音,需要自己改下hts_engine代碼然后重新編譯,這部分暫時沒有時間整理出來