本次分享一下如何將GPT-SoVITS接入SillyTavern-1.11.5專案,讓讓AI女友聲若幽蘭,首先明確一下,SillyTavern-1.11.5只是一個前端專案,它沒有任何大模型文字生成能力,所以後端必須有一個api服務來流式生成對話文字,這裡選擇koboldcpp。
首先看一下簡單的專案執行架構圖:
這裡SillyTavern作為前端負責向後端的Koboldcpp發起請求,Koboldcpp流式返回文字,SillyTavern接受聊天文字進行展示,當文字接受完畢後,SillyTavern再次向後端的GPT-SoVITS發起請求,將全量文字傳遞給後端GPT-SoVITS,GPT-SoVITS根據文字來生成語音,並將語音的二進位制檔案返回給SillyTavern,最後SillyTavern播放音訊,至此,一個完整的流程就走完了。
部署SillyTavern
首先克隆SillyTavern的官方專案:
git clone https://github.com/SillyTavern/SillyTavern.git
直接執行啟動指令碼即可:
shell start.sh
如果是windows平臺,執行bat:
start.bat
由於SillyTavern沒有預留GPT-SoVITS的位置,所有將原本的XTTS改為GPT-SoVITS:
async fetchTtsGeneration(inputText, voiceId) {
console.info(`Generating new TTS for voice_id ${voiceId}`);
if (this.settings.streaming) {
const params = new URLSearchParams();
params.append('text', inputText);
params.append('speaker_wav', voiceId);
params.append('language', this.settings.language);
return `${this.settings.provider_endpoint}/tts_stream/?${params.toString()}`;
}
const response = await doExtrasFetch(
`${this.settings.provider_endpoint}/tts_to_audio/`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache', // Added this line to disable caching of file so new files are always played - Rolyat 7/7/23
},
body: JSON.stringify({
'text': inputText,
'speaker_wav': voiceId,
'language': this.settings.language,
}),
},
);
if (!response.ok) {
toastr.error(response.statusText, 'TTS Generation Failed');
throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}
return response;
}
部署Koboldcpp
隨後部署後端的大模型api:
git clone https://github.com/LostRuins/koboldcpp.git
輸入編譯命令
windows平臺:
make
Mac平臺:
make LLAMA_METAL=1
安裝依賴:
pip install -r requirements.txt
啟動服務:
Python3 koboldcpp.py --model /Users/liuyue/Downloads/causallm_7b-dpo-alpha.Q5_K_M.gguf --gpulayers 40 --highpriority --threads 300
此時介面執行在http://localhost:5001
部署GPT-SoVITS
最後,部署GPT-SoVITS專案:
git clone https://github.com/RVC-Boss/GPT-SoVITS.git
安裝依賴:
pip3 install -r requirements.txt
修改一下api介面邏輯:
@app.post("/")
async def tts_endpoint(request: Request):
json_post_raw = await request.json()
return handle(
json_post_raw.get("refer_wav_path"),
json_post_raw.get("prompt_text"),
json_post_raw.get("prompt_language"),
json_post_raw.get("text"),
json_post_raw.get("text_language"),
json_post_raw.get("sweight"),
json_post_raw.get("gweight"),
)
@app.get("/")
async def tts_endpoint(
refer_wav_path: str = None,
prompt_text: str = None,
prompt_language: str = None,
text: str = None,
text_language: str = None,
sweight: str = None,
gweight: str = None,
):
return handle(refer_wav_path, prompt_text, prompt_language, text, text_language,sweight,gweight)
def speaker_handle():
return JSONResponse(["female_calm","female","male"], status_code=200)
@app.get("/speakers_list")
async def speakerlist_endpoint():
return speaker_handle()
def tts_to_audio_handle(text):
return handle(llama_audio,llama_text,llama_lang,text,"中英混合")
@app.post("/tts_to_audio/")
async def tts_to_audio(request: Request):
json_post_raw = await request.json()
return tts_to_audio_handle(json_post_raw.get("text"))
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=port, workers=1)
這裡新增新的基於get方法的speakers_list,是為了配合xtts介面的格式,同時基於post方法的tts_to_audio方法用來生成語音,它只接受一個引數text,也就是需要轉為語音的文字。
至此,三個服務就都配置好了,最後奉上影片教程:
https://www.bilibili.com/video/BV1uJ4m1a7L4/