NeMo 声纹识别VPR-实战

声纹识别(VPR) ,生物识别技术的一种,也称为说话人识别 ,是从说话人发出的语音信号中提取声纹信息,从应用上看,可分为:

  • 说话人辨认(Speaker Identification):用以判断某段语音是若干人中的哪一个所说的,是“多选一”问题;
  • 说话人确认(Speaker Verification):用以确认某段语音是否是指定的某个人所说的,是“一对一判别”问题。

本文主要是识别两个声音是否为同一个人。

应用场景:APP声纹验证登录、坐席辅助助手登录后坐席是否为原坐席、客户进行业务申请时验证是否为客户本人。

使用Titanet-L模型,不需要训练,即可以直接针对中文/英文声音进行识别验证。

1、环境安装

pip install -U nemo_toolkit[all] ASR-metrics fastapi python-multipart uvicorn -i https://pypi.tuna.tsinghua.edu.cn/simple

2、接口代码:

from fastapi import FastAPI, Request, File, UploadFile, Form
from fastapi.responses import HTMLResponse
from transformers import AutoTokenizer, AutoModel
import uvicorn, json, datetime
import torch
from fastapi.middleware.cors import CORSMiddleware
import nemo.collections.asr as nemo_asr
import os
import librosa

DEVICE = "cuda"
DEVICE_ID = "0"
CUDA_DEVICE = f"{DEVICE}:{DEVICE_ID}" if DEVICE_ID else DEVICE
print("GPU:", CUDA_DEVICE)

def torch_gc():
    if torch.cuda.is_available():
        with torch.cuda.device(CUDA_DEVICE):
            torch.cuda.empty_cache()
            torch.cuda.ipc_collect()

扫描二维码关注公众号,回复: 16914281 查看本文章


app = FastAPI()
app.add_middleware(
        CORSMiddleware,
        allow_origins=["*"],
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )

@app.get("/")
async def upload():
    content = """
<title>声纹识别</title>
<B>声纹识别</B>
<body>
<form action="/sv/" enctype="multipart/form-data" method="post">
<p>请求序号: <input type="text" name="request_id" value='3F2504E0-4F89-11D3-9A0C-0305E82C3301'/></p>
<p>
原始声纹:
<input name="oracle_file" type="file" accept=".wav,.mp3,.m4a,.amr">
</p>
<p>
开场声纹:
<input name="system_file" type="file" accept=".wav,.mp3,.m4a,.amr">
<input type="submit">
</p>
</form>
<p>
请求序号:由调用方维护,建议使用uuid,调用后原样返回,用于标识请求和调用方存储识别结果。
</p>
<p>
原始声纹:代表坐席的声纹。
</p>
<p>
开场声纹:登录坐席的声纹。
</p>
<p>
声纹要求:16K采样,单通道,小于10秒,支持格式:.wav/.mp3/.m4a/.amr
</p>

</body>
    """
    return HTMLResponse(content=content)
@app.post("/sv")
async def speaker_verify(request_id: str = Form(...), oracle_file: UploadFile = File(...), system_file: UploadFile = File(...)):
    global model
    data_path = '.'+ os.sep + 'data' + os.sep + request_id
    if not os.path.isdir(data_path):
        os.makedirs(data_path)
        
    oracle_file_name = data_path + os.sep + oracle_file.filename
    system_file_name = data_path + os.sep + system_file.filename
    with open(oracle_file_name, 'wb') as o:
        o.write(oracle_file.file.read())
    with open(system_file_name, 'wb') as s:
        s.write(system_file.file.read())
        
    d_o = librosa.get_duration(filename=oracle_file_name)
    d_s = librosa.get_duration(filename=system_file_name)
    
    if d_o>10 or d_s>10:
        now = datetime.datetime.now()
        time = now.strftime("%Y-%m-%d %H:%M:%S")
        return {
        "request_id": request_id,
        "result": repr("audio duration over 10s"),
        "status": 300,
        "time": time
    }
    
    result = model.verify_speakers(oracle_file_name, system_file_name)
    
    now = datetime.datetime.now()
    time = now.strftime("%Y-%m-%d %H:%M:%S")
    answer = {
        "request_id": request_id,
        "result": result,
        "status": 200,
        "time": time
    }
    log = "[" + time + "] " + '", request_id:"' + request_id + '", result:"' + repr(result) + '"'
    print(log)
    torch_gc()
    return answer


if __name__ == '__main__':
    model = nemo_asr.models.EncDecSpeakerLabelModel.restore_from('titanet-l.nemo')
    print('声纹模型已准备就绪')
    uvicorn.run(app, host='0.0.0.0', port=8500, workers=1)

3、接口界面:

4、验证结果:

猜你喜欢

转载自blog.csdn.net/wxl781227/article/details/132295177
今日推荐