ASRT_SpeechRecognition/asrserver_grpc.py

183 lines
6.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2016-2099 Ailemon.net
#
# This file is part of ASRT Speech Recognition Tool.
#
# ASRT is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# ASRT is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with ASRT. If not, see <https://www.gnu.org/licenses/>.
# ============================================================================
"""
@author: nl8590687
ASRT语音识别基于gRPC协议的API服务器程序
"""
import argparse
import time
from concurrent import futures
import grpc
from assets.asrt_pb2_grpc import AsrtGrpcServiceServicer, add_AsrtGrpcServiceServicer_to_server
from assets.asrt_pb2 import SpeechResponse, TextResponse
from speech_model import ModelSpeech
from speech_model_zoo import SpeechModel251BN
from speech_features import Spectrogram
from language_model3 import ModelLanguage
from utils.ops import decode_wav_bytes
API_STATUS_CODE_OK = 200000 # OK
API_STATUS_CODE_OK_PART = 206000 # 部分结果OK用于stream
API_STATUS_CODE_CLIENT_ERROR = 400000
API_STATUS_CODE_CLIENT_ERROR_FORMAT = 400001 # 请求数据格式错误
API_STATUS_CODE_CLIENT_ERROR_CONFIG = 400002 # 请求数据配置不支持
API_STATUS_CODE_SERVER_ERROR = 500000
API_STATUS_CODE_SERVER_ERROR_RUNNING = 500001 # 服务器运行中出错
parser = argparse.ArgumentParser(description='ASRT gRPC Protocol API Service')
parser.add_argument('--listen', default='0.0.0.0', type=str, help='the network to listen')
parser.add_argument('--port', default='20002', type=str, help='the port to listen')
args = parser.parse_args()
AUDIO_LENGTH = 1600
AUDIO_FEATURE_LENGTH = 200
CHANNELS = 1
# 默认输出的拼音的表示大小是1428即1427个拼音+1个空白块
OUTPUT_SIZE = 1428
sm251bn = SpeechModel251BN(
input_shape=(AUDIO_LENGTH, AUDIO_FEATURE_LENGTH, CHANNELS),
output_size=OUTPUT_SIZE
)
feat = Spectrogram()
ms = ModelSpeech(sm251bn, feat, max_label_length=64)
ms.load_model('save_models/' + sm251bn.get_model_name() + '.model.h5')
ml = ModelLanguage('model_language')
ml.load_model()
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
class ApiService(AsrtGrpcServiceServicer):
'''
继承AsrtGrpcServiceServicer,实现hello方法
'''
def __init__(self):
pass
def Speech(self, request, context):
'''
具体实现Speech的方法, 并按照pb的返回对象构造SpeechResponse返回
:param request:
:param context:
:return:
'''
wav_data = request.wav_data
wav_samples = decode_wav_bytes(samples_data=wav_data.samples,
channels=wav_data.channels, byte_width=wav_data.byte_width)
result = ms.recognize_speech(wav_samples, wav_data.sample_rate)
print("语音识别声学模型结果:", result)
return SpeechResponse(status_code=API_STATUS_CODE_OK, status_message='',
result_data=result)
def Language(self, request, context):
'''
具体实现Language的方法, 并按照pb的返回对象构造TextResponse返回
:param request:
:param context:
:return:
'''
print('Language收到了请求:', request)
result = ml.pinyin_to_text(list(request.pinyins))
print('Language结果:', result)
return TextResponse(status_code=API_STATUS_CODE_OK, status_message='',
text_result=result)
def All(self, request, context):
'''
具体实现All的方法, 并按照pb的返回对象构造TextResponse返回
:param request:
:param context:
:return:
'''
wav_data = request.wav_data
wav_samples = decode_wav_bytes(samples_data=wav_data.samples,
channels=wav_data.channels, byte_width=wav_data.byte_width)
result_speech = ms.recognize_speech(wav_samples, wav_data.sample_rate)
result = ml.pinyin_to_text(result_speech)
print("语音识别结果:", result)
return TextResponse(status_code=API_STATUS_CODE_OK, status_message='',
text_result=result)
def Stream(self, request_iterator, context):
'''
具体实现Stream的方法, 并按照pb的返回对象构造TextResponse返回
:param request:
:param context:
:return:
'''
result = list()
tmp_result_last = list()
beam_size = 100
for request in request_iterator:
wav_data = request.wav_data
wav_samples = decode_wav_bytes(samples_data=wav_data.samples,
channels=wav_data.channels,
byte_width=wav_data.byte_width)
result_speech = ms.recognize_speech(wav_samples, wav_data.sample_rate)
for item_pinyin in result_speech:
tmp_result = ml.pinyin_stream_decode(tmp_result_last, item_pinyin, beam_size)
if len(tmp_result) == 0 and len(tmp_result_last) > 0:
result.append(tmp_result_last[0][0])
print("流式语音识别结果:", ''.join(result))
yield TextResponse(status_code=API_STATUS_CODE_OK, status_message='',
text_result=''.join(result))
result = list()
tmp_result = ml.pinyin_stream_decode([], item_pinyin, beam_size)
tmp_result_last = tmp_result
yield TextResponse(status_code=API_STATUS_CODE_OK_PART, status_message='',
text_result=''.join(tmp_result[0][0]))
if len(tmp_result_last) > 0:
result.append(tmp_result_last[0][0])
print("流式语音识别结果:", ''.join(result))
yield TextResponse(status_code=API_STATUS_CODE_OK, status_message='',
text_result=''.join(result))
def run(host, port):
'''
gRPC API服务启动
:return:
'''
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
add_AsrtGrpcServiceServicer_to_server(ApiService(),server)
server.add_insecure_port(''.join([host, ':', port]))
server.start()
print("start service...")
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
server.stop(0)
if __name__ == '__main__':
run(host=args.listen, port=args.port)