chatTTS系列之-apiServer

背景

在之前文章中我们对chattts有了一个大致的了解并对webui进行了一定的优化。然而,还有很多情况下我们还需要进行api调用。gradio虽然也提供了sdk,但只有python和node两种语言,远远不如http接口来的泛用。因此,我们来对chatts更近一步优化,来编写一个apiServer。

技术方案

技术方案我们选用FastAPI。

我们对FastAPI做一个简要的介绍

fastapi,一个用于构建 API 的现代、快速(高性能)的web框架。

fastapi是建立在Starlette和Pydantic基础上的,Pydantic是一个基于Python类型提示来定义数据验证、序列化和文档的库。Starlette是一种轻量级的ASGI框架/工具包,是构建高性能Asyncio服务的理性选择。

  • 快速:可与 NodeJS 和 Go 比肩的极高性能(归功于 StarlettePydantic),是最快的 Python web 框架之一。
  • 高效编码:提高功能开发速度约 200% 至 300%。
  • 更少bug:减少约 40% 的人为(开发者)导致错误。
  • 智能:极佳的编辑器支持。处处皆可自动补全,减少调试时间。
  • 简单:设计的易于使用和学习,阅读文档的时间更短。
  • 简短:使代码重复最小化。通过不同的参数声明实现丰富功能。
  • 健壮:生产可用级别的代码。还有自动生成的交互式文档

方案实现

安装FastAPI

pip install "fastapi[all]"
pip install "uvicorn[standard]"

编写一个入口

 from fastapi import FastAPI  # FastAPI 是一个为你的 API 提供了所有功能的 Python 类。
 import uvicorn

 app = FastAPI()  # 这个实例将是创建你所有 API 的主要交互对象。这个 app 同样在如下命令中被 uvicorn 所引用
 
 @app.get("/")
 async def root():
     return {"message": "Hello yuan"}
    
if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8087)

一个简单案例就做好了,和其它很多框架一样,我们需要引入路由分组

app = FastAPI()
app.include_router(prefix="/chat", router=audio_router)

不同分组就不再是通过app来修饰

router = APIRouter()

@router.post("/generate_audio")
async def generate_audio(request: GenerateAudioRequest):
    ...

逻辑实现

全局只维护一个chat对象

如何每次创建一个chat对象,显存将很快被耗完。每创建完一个对象大约消耗1GB显存,小于4GB显存将强制使用CPU进行推理

def create_chat(local_path=None):
    """创建ChatTTS实例"""
    if "chat" in cf:
        logging.info("cached chat")
        return cf['chat']
    local_model_path = os.getenv('MODEL_LOCAL_PATH', None)
    # 导入模型实例
    chat = ChatTTS.Chat()
    if local_model_path is None:
        chat.load_models()
    else:
        logging.info('local model path:', local_model_path)
        chat.load_models('local', local_path=local_model_path)
    cf['chat'] = chat
    return chat

生成随机音色

def determine_seed(seed):
    """限定模型使用的种子值"""
    torch.manual_seed(seed)
    np.random.seed(seed)
    torch.cuda.manual_seed(seed)
    torch.backends.cudnn.deterministic = True
    torch.backends.cudnn.benchmark = False



def build_random_speaker(chat, request: GenerateAudioRequest):
    """
    生成随机音色
    :param chat:
    :param request:
    :return:
    """
    # 使用音色种子值创建音色
    audio_seed_input = request.audio_seed_input
    determine_seed(audio_seed_input)
    return chat.sample_random_speaker()

合成一个完整音频

# 将所有的语音片段合并成一个完整的音频
audio_data_all = np.concatenate(audio_data_all)
sample_rate = 24000
# 写入WAV文件
file_name = wav_utils.build_wav_name()
file_path = str(Path(global_info.AUDIO_TEMP_PATH).joinpath(file_name).resolve())
wavfile.write(file_path, sample_rate, audio_data_all)

返回结果

在每次音频生成结束后,返回音频名称,并将tensor等参数一并返回,方便保存

return {
        "out_put_text": "\n".join(text_data_all),
        "audio_name": file_name,
        "tensor": speak_tensor.tolist()
 }

总结

我们可以根据这些核心需求编写chattts的服务端,满足自己的接口调用需求。本文代码见

chatts-manger




# 总结

我们可以根据这些核心需求编写chattts的服务端,满足自己的接口调用需求。本文代码见

[chatts-manger](https://github.com/MaterialShadow/ChatTTS-manager/tree/master/apiServer)
  • 18
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值