Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions paddlespeech/server/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,11 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import _locale

from .base_commands import BaseCommand
from .base_commands import HelpCommand
from paddlespeech.server.bin.paddlespeech_client import TTSClientExecutor
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

后面是否只有一个ClientExecutor?

from paddlespeech.server.bin.paddlespeech_server import ServerExecutor

_locale._getdefaultlocale = (lambda *args: ['en_US', 'utf8'])
49 changes: 49 additions & 0 deletions paddlespeech/server/base_commands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import List

from .entry import commands
from .util import cli_register
from .util import get_command

__all__ = [
'BaseCommand',
'HelpCommand',
]


@cli_register(name='paddleserver')
class BaseCommand:
def execute(self, argv: List[str]) -> bool:
help = get_command('paddleserver.help')
return help().execute(argv)


@cli_register(name='paddleserver.help', description='Show help for commands.')
class HelpCommand:
def execute(self, argv: List[str]) -> bool:
msg = 'Usage:\n'
msg += ' paddleserver <command> <options>\n\n'
msg += 'Commands:\n'
for command, detail in commands['paddleserver'].items():
if command.startswith('_'):
continue

if '_description' not in detail:
continue
msg += ' {:<15} {}\n'.format(command,
detail['_description'])

print(msg)
return True
14 changes: 14 additions & 0 deletions paddlespeech/server/bin/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from .paddlespeech_server import ServerExecutor
112 changes: 112 additions & 0 deletions paddlespeech/server/bin/paddlespeech_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import argparse
import base64
import io
import json
import os
import random
import time
from typing import List

import numpy as np
import requests
import soundfile

from paddlespeech.server.util import cli_register
from paddlespeech.server.utils.audio_process import wav2pcm


@cli_register(name='paddleserver.ttsclient', description='visit tts service')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

asr应该可以和tts共用一个executor吧?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我这边想的是分开的,asr 和 tts api所需要的输入不一样

class TTSClientExecutor():
def __init__(self):
super().__init__()
self.parser = argparse.ArgumentParser()
self.parser.add_argument(
'--server_ip', type=str, default='127.0.0.1', help='server ip')
self.parser.add_argument(
'--port', type=int, default=8090, help='server port')
self.parser.add_argument(
'--text',
type=str,
default="你好,欢迎使用语音合成服务",
help='A sentence to be synthesized')
self.parser.add_argument(
'--spk_id', type=int, default=0, help='Speaker id')
self.parser.add_argument(
'--speed', type=float, default=1.0, help='Audio speed')
self.parser.add_argument(
'--volume', type=float, default=1.0, help='Audio volume')
self.parser.add_argument(
'--sample_rate',
type=int,
default=0,
help='Sampling rate, the default is the same as the model')
self.parser.add_argument(
'--output',
type=str,
default="./out.wav",
help='Synthesized audio file')

# Request and response
def tts_client(self, args):
""" Request and response
Args:
text: A sentence to be synthesized
outfile: Synthetic audio file
"""
url = 'http://' + args.server_ip + ":" + str(
args.port) + '/paddlespeech/tts'
request = {
"text": args.text,
"spk_id": args.spk_id,
"speed": args.speed,
"volume": args.volume,
"sample_rate": args.sample_rate,
"save_path": args.output
}

response = requests.post(url, json.dumps(request))
response_dict = response.json()
wav_base64 = response_dict["result"]["audio"]

audio_data_byte = base64.b64decode(wav_base64)
# from byte
samples, sample_rate = soundfile.read(
io.BytesIO(audio_data_byte), dtype='float32')

# transform audio
outfile = args.output
if outfile.endswith(".wav"):
soundfile.write(outfile, samples, sample_rate)
elif outfile.endswith(".pcm"):
temp_wav = str(random.getrandbits(128)) + ".wav"
soundfile.write(temp_wav, samples, sample_rate)
wav2pcm(temp_wav, outfile, data_type=np.int16)
os.system("rm %s" % (temp_wav))
else:
print("The format for saving audio only supports wav or pcm")

return len(samples), sample_rate

def execute(self, argv: List[str]) -> bool:
args = self.parser.parse_args(argv)
st = time.time()
try:
samples_length, sample_rate = self.tts_client(args)
time_consume = time.time() - st
print("Save synthesized audio successfully on %s." % (args.output))
print("Inference time: %f" % (time_consume))
except:
print("Failed to synthesized audio.")
75 changes: 75 additions & 0 deletions paddlespeech/server/bin/paddlespeech_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import argparse
from typing import List

import uvicorn
from fastapi import FastAPI

from paddlespeech.server.engine.engine_factory import EngineFactory
from paddlespeech.server.restful.api import setup_router
from paddlespeech.server.util import cli_register
from paddlespeech.server.utils.config import get_config

app = FastAPI(
title="PaddleSpeech Serving API", description="Api", version="0.0.1")


@cli_register(name='paddleserver.server', description='Start the service')
class ServerExecutor():
def __init__(self):
super().__init__()
self.parser = argparse.ArgumentParser()
self.parser.add_argument(
"--config_file",
action="store",
help="yaml file of the app",
default="./conf/application.yaml")

self.parser.add_argument(
"--log_file",
action="store",
help="log file",
default="./log/paddlespeech.log")

def init(self, config) -> bool:
"""system initialization

Args:
config (CfgNode): config object

Returns:
bool:
"""
# init api
api_list = list(config.engine_backend)
api_router = setup_router(api_list)
app.include_router(api_router)

# init engine
engine_pool = []
for engine in config.engine_backend:
engine_pool.append(EngineFactory.get_engine(engine_name=engine))
if not engine_pool[-1].init(
config_file=config.engine_backend[engine]):
return False

return True

def execute(self, argv: List[str]) -> bool:
args = self.parser.parse_args(argv)
config = get_config(args.config_file)

if self.init(config):
uvicorn.run(app, host=config.host, port=config.port, debug=True)
Loading