雲端煉丹固然是極好的,但不能否認的是,成本要比本地高得多,同時考慮到深度學習的訓練相對於推理來說成本也更高,這主要是因為它需要大量的資料、計算資源和時間等資源,並且對超引數的調整也要求較高,更適合在雲端進行。
在推理階段,模型的權重和引數不再調整。相反,模型根據輸入資料的特徵進行計算,並輸出預測結果。推理階段通常需要較少的計算資源和時間,所以訓練我們可以放在雲端,而批次推理環節完全可以挪到本地,這樣更適合批次的聲音克隆場景。
首先需要在本地安裝PaddlePaddle框架,關於PaddlePaddle的本地設定,請移步:聲音好聽,顏值能打,基於PaddleGAN給人工智慧AI語音模型配上動態畫面(Python3.10),這裡不再贅述。
安裝好PaddlePaddle之後,執行命令本地安裝PaddleSpeech:
pip3 install paddlespeech
由於paddlespeech的依賴庫中包括webrtcvad,如果本地環境沒有安裝過Microsoft Visual C++ 14.0,大概率會報這個錯誤:
building 'Crypto.Random.OSRNG.winrandom' extension
error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual
C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools
此時需要安裝一下Microsoft Visual C++ 14.0的開發者工具,最好不要使用微軟的線上安裝包,推薦使用離線安裝包,下載地址:
連結:https://pan.baidu.com/s/1VSRHAMuDkhzQo7nM4JihEA?pwd=or7x
提取碼:or7x
安裝完C++ 14.0即可完成PaddleSpeech的安裝:
D:\work\speech\master_voice>python
Python 3.10.11 (tags/v3.10.11:7d4cc5a, Apr 5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import paddlespeech
>>>
音色模型就是之前我們在:聲音克隆,精緻細膩,人工智慧AI打造國師「一鏡到底」鬼畜視訊,基於PaddleSpeech(Python3.10)中訓練的國師的音色模型,下載地址:
連結:https://pan.baidu.com/s/1nKOPlI7P_u_a5UGdHX76fA?pwd=ygqp
提取碼:ygqp
隨後下載聲碼器,這裡推薦下載【PWGan】和【WaveRnn】兩款聲碼器,不推薦【HifiGan】,因為【HifiGan】的效果實在太糟糕,PWGan的效果差強人意,WaveRnn質量最高,但推理時間也最慢。
下載地址:
連結:https://pan.baidu.com/s/1KHIZS5CrydtANXm6CszdYQ?pwd=6lsk
提取碼:6lsk
下載之後,分別解壓到同一個目錄即可。
接下來我們就可以編寫推理指令碼了。
首先匯入需要的模組:
from pathlib import Path
import soundfile as sf
import os
from paddlespeech.t2s.exps.syn_utils import get_am_output
from paddlespeech.t2s.exps.syn_utils import get_frontend
from paddlespeech.t2s.exps.syn_utils import get_predictor
from paddlespeech.t2s.exps.syn_utils import get_voc_output
# 音色模型的路徑
am_inference_dir = "./master"
# 聲碼器的路徑
voc_inference_dir_pwgan = "./pwgan"
# 聲碼器的路徑
voc_inference_dir_wavernn = "./wavernn"
# 克隆音訊生成的路徑
wav_output_dir = "./output"
# 選擇裝置[gpu / cpu],預設選擇gpu,
device = "gpu"
這裡定義好模型和聲碼器的路徑,同時定義輸出路徑,預設採用gpu進行推理,速度更快。
隨後定義後要語音生成的文字:
text_dict = {
"1": "我原來想拿中石油的offer",
"2": "是不是很大膽",
"3": "中石油",
"4": "國企天花板",
"5": "就是中石油",
"6": "出差可以逛太古裡",
"7": "太爽了",
"8": "我最早準備面試的時候",
"9": "跟所有同學說的只面中石油",
"10": "所有的同學,包括親戚,朋友,他們所有人很興奮",
"11": "我女朋友也很興奮",
"12": "中石油",
"13": "一直說的是去中石油",
"14": "我一直在做去中石油的準備",
"15": "當時我面試的時候",
"16": "我說試用期只要20天",
"17": "或者只要25天",
"18": "兩週到三週",
"19": "hr說為什麼?",
"20": "我說很簡單",
"21": "我每天飛四川",
"22": "單程兩個小時",
"23": "早上去一次",
"24": "晚上去一次",
"25": "每天去兩次",
"26": "我堅持10天",
"27": "20次",
"28": "就是20次",
"29": "成都太古裡",
"30": "哇簡直太爽了",
"31": "逛街",
"32": "去10天就夠了",
"33": "然後前面的十天在北京",
"34": "上班",
"35": "嚴格地上班",
"36": "我說試用期只要二十天",
"37": "咱試用期就結束了",
"38": "哇hr說真的太厲害",
"39": "就挑戰性太大了",
"40": "一天都不能請假啊",
"41": "但是後來我還是放棄了,哈哈哈",
"42": "你知道為什麼",
"43": "我研究了大量的員工去成都的案例",
"44": "嗯,也有一些基層員工",
"45": "還有尤其是最近一段時間一些比較大膽的行為",
"46": "就是牽手那個我也看了",
"47": "我專門看",
"48": "研究",
"49": "就一直,我就一直下不了決心",
"50": "其實我真的非常想去啊,內心深處非常想",
"51": "你知道最大問題是什麼,當然這是一個專業問題,簡單地說最大問題就是街拍",
"52": "就是街拍",
"53": "因為你去了他就拍你啊",
"54": "就沒有辦法",
"55": "對一個員工",
"56": "對一個嚮往太古裡的員工",
"57": "一個經常逛太古裡的員工來說",
"58": "他給你來一個街拍",
"59": "全給你拍下來",
"60": "上傳抖音",
"61": "因為你不能蹭蹭蹭蹭",
"62": "逛的太快啊",
"63": "不能啊",
"64": "你從南邊到北邊",
"65": "你中間得逛啊",
"66": "就拍了",
"67": "就拍了",
"68": "第一是街拍避免不了",
"69": "無論怎麼樣",
"70": "我想來想去",
"71": "因為我算個內行嘛",
"72": "我不去了,我就知道街拍跑不了",
"73": "街拍,避免不了",
"74": "第二個",
"75": "你的工資會全都損失了",
"76": "不是損失一半的工資,一半無所謂",
"77": "是全部的工資,獎金,績效,年終獎全都沒有了",
"78": "然後你還得停職",
"79": "就很尷尬啊",
"80": "這樣子就不好混了",
"81": "真的不好混了",
"82": "最後我差不多一個多月的思想鬥爭",
"83": "那是個重大決定",
"84": "因為我都是按照去中石油準備的",
"85": "背面試題呢",
"86": "後來說放棄",
"87": "我自己決定放棄",
"88": "一個人做的決定,一個人的思考",
"89": "一個多月以後我放棄了,我第一個電話打給人力,我說我放棄去中石油。他,啊這,就不能接受",
"90": "他已經完全沉浸到去太古裡當中去了,你知道吧",
"91": "就想著太好了,就喜歡的不得了",
"92": "怎麼可能就過來說服我",
"93": "我說你不用跟我說",
"94": "你都不太清楚",
"95": "反正去中石油",
"96": "說怎麼可能,你能做到,就開始給我忽悠",
"97": "我放棄了",
"98": "然後我跟女朋友說放棄",
"99": "哎呀,她說她把包包裙子都買了,這那的",
"100": "所有人,大家都覺得太遺憾了。",
"101": "然後跟老闆說",
"102": "最有意思是跟老闆說",
"103": "說真的不去中石油了",
"104": "哎呀,哎呀",
"105": "就覺著好像就沒勁了,哈哈哈",
"106": "說你不是開玩笑吧",
"107": "哎呀就覺得,好像不想要我了似的",
"108": "開玩笑啊,開玩笑",
"109": "就所有人都沮喪而失落",
"110": "就我看到大家的反應",
"111": "我也很難過,很難過",
"112": "我我,我後來還是放棄了",
"113": "放棄了,嗯",
"114": "所以中石油offer是一個學習",
"115": "它對於一個追求太古裡的一個員工來說",
"116": "它是破壞性的",
"117": "你去了中石油又能怎麼樣呢?",
"118": "你丟掉了信仰",
"119": "丟掉了人格啊",
"120": "孰重孰輕啊",
"121": "所以我在學習",
"122": "我在學習做一個合格員工的思考",
"123": "這就是我的,遺憾",
"124": "但也許是我的一個清醒",
"125": "或者學習的心得",
}
這裡字典的key是檔名,value是音訊的內容。
隨後載入聲碼器地址中的組態檔:
# frontend
frontend = get_frontend(
lang="mix",
phones_dict=os.path.join(am_inference_dir, "phone_id_map.txt"),
tones_dict=None
)
# am_predictor
am_predictor = get_predictor(
model_dir=am_inference_dir,
model_file="fastspeech2_mix" + ".pdmodel",
params_file="fastspeech2_mix" + ".pdiparams",
device=device)
# voc_predictor
voc_predictor_pwgan = get_predictor(
model_dir=voc_inference_dir_pwgan,
model_file="pwgan_aishell3" + ".pdmodel",
params_file="pwgan_aishell3" + ".pdiparams",
device=device)
voc_predictor_wavernn = get_predictor(
model_dir=voc_inference_dir_wavernn,
model_file="wavernn_csmsc" + ".pdmodel",
params_file="wavernn_csmsc" + ".pdiparams",
device=device)
output_dir = Path(wav_output_dir)
output_dir.mkdir(parents=True, exist_ok=True)
sentences = list(text_dict.items())
這裡我們準備兩個聲碼器物件。
最後執行克隆函數:
def clone(voc_predictor):
merge_sentences = True
fs = 24000
for utt_id, sentence in sentences:
am_output_data = get_am_output(
input=sentence,
am_predictor=am_predictor,
am="fastspeech2_mix",
frontend=frontend,
lang="mix",
merge_sentences=merge_sentences,
speaker_dict=os.path.join(am_inference_dir, "phone_id_map.txt"),
spk_id=0, )
wav = get_voc_output(
voc_predictor=voc_predictor, input=am_output_data)
# 儲存檔案
sf.write(output_dir / (utt_id + ".wav"), wav, samplerate=fs)
if __name__ == '__main__':
clone(voc_predictor_pwgan)
這裡預設的取樣率是24000,am模型使用fastspeech2_mix,因為它可以相容英文的閱讀。
聲碼器選擇voc_predictor_pwgan,當然也可以將引數修改為voc_predictor_wavernn。
生成後的效果:
基於聲學模型 FastSpeech2的PaddleSpeech的產品力已經相當驚人,就算是放在全球人工智慧領域的尺度上,擺在微軟這種業界巨頭的最佳產品Azure-tts旁邊,也是毫不遜色的,感謝百度,讓普通人也能玩惡搞配音專案,最後奉上國師的鬼畜視訊一鍵生成專案,與眾鄉親同饗:
https://github.com/zcxey2911/zhangyimou_voice_clone_text