# Service with grpc-cpp ## For the Server ### Build [onnxruntime](./onnxruntime_cpp.md) as it's document ### Compile and install grpc v1.52.0 in case of grpc bugs ``` export GRPC_INSTALL_DIR=/data/soft/grpc export PKG_CONFIG_PATH=$GRPC_INSTALL_DIR/lib/pkgconfig git clone -b v1.52.0 --depth=1 https://github.com/grpc/grpc.git cd grpc git submodule update --init --recursive mkdir -p cmake/build pushd cmake/build cmake -DgRPC_INSTALL=ON \ -DgRPC_BUILD_TESTS=OFF \ -DCMAKE_INSTALL_PREFIX=$GRPC_INSTALL_DIR \ ../.. make make install popd echo "export GRPC_INSTALL_DIR=/data/soft/grpc" >> ~/.bashrc echo "export PKG_CONFIG_PATH=\$GRPC_INSTALL_DIR/lib/pkgconfig" >> ~/.bashrc echo "export PATH=\$GRPC_INSTALL_DIR/bin/:\$PKG_CONFIG_PATH:\$PATH" >> ~/.bashrc source ~/.bashrc ``` ### Compile and start grpc onnx paraformer server ``` # set -DONNXRUNTIME_DIR=/path/to/asrmodel/onnxruntime-linux-x64-1.14.0 ./rebuild.sh ``` ### Start grpc paraformer server ``` ./cmake/build/paraformer-server --port-id [--punc-config ] [--punc-model ] --am-config --am-cmvn --am-model [--vad-config ] [--vad-cmvn ] [--vad-model ] [--] [--version] [-h] Where: --port-id (required) port id --am-config (required) am config path --am-cmvn (required) am cmvn path --am-model (required) am model path --punc-config punc config path --punc-model punc model path --vad-config vad config path --vad-cmvn vad cmvn path --vad-model vad model path Required: --port-id --am-config --am-cmvn --am-model If use vad, please add: [--vad-config ] [--vad-cmvn ] [--vad-model ] If use punc, please add: [--punc-config ] [--punc-model ] ``` ## For the client ### Install the requirements as in [grpc-python](./docs/grpc_python.md) ```shell git clone https://github.com/alibaba/FunASR.git && cd FunASR cd funasr/runtime/python/grpc pip install -r requirements_client.txt ``` ### Generate protobuf file Run on server, the two generated pb files are both used for server and client ```shell # paraformer_pb2.py and paraformer_pb2_grpc.py are already generated, # regenerate it only when you make changes to ./proto/paraformer.proto file. python -m grpc_tools.protoc --proto_path=./proto -I ./proto --python_out=. --grpc_python_out=./ ./proto/paraformer.proto ``` ### Start grpc client ``` # Start client. python grpc_main_client_mic.py --host 127.0.0.1 --port 10095 ``` [//]: # (```) [//]: # (# go to ../python/grpc to find this package) [//]: # (import paraformer_pb2) [//]: # () [//]: # () [//]: # (class RecognizeStub:) [//]: # ( def __init__(self, channel):) [//]: # ( self.Recognize = channel.stream_stream() [//]: # ( '/paraformer.ASR/Recognize',) [//]: # ( request_serializer=paraformer_pb2.Request.SerializeToString,) [//]: # ( response_deserializer=paraformer_pb2.Response.FromString,) [//]: # ( )) [//]: # () [//]: # () [//]: # (async def send(channel, data, speaking, isEnd):) [//]: # ( stub = RecognizeStub(channel)) [//]: # ( req = paraformer_pb2.Request()) [//]: # ( if data:) [//]: # ( req.audio_data = data) [//]: # ( req.user = 'zz') [//]: # ( req.language = 'zh-CN') [//]: # ( req.speaking = speaking) [//]: # ( req.isEnd = isEnd) [//]: # ( q = queue.SimpleQueue()) [//]: # ( q.put(req)) [//]: # ( return stub.Recognize(iter(q.get, None))) [//]: # () [//]: # (# send the audio data once) [//]: # (async def grpc_rec(data, grpc_uri):) [//]: # ( with grpc.insecure_channel(grpc_uri) as channel:) [//]: # ( b = time.time()) [//]: # ( response = await send(channel, data, False, False)) [//]: # ( resp = response.next()) [//]: # ( text = '') [//]: # ( if 'decoding' == resp.action:) [//]: # ( resp = response.next()) [//]: # ( if 'finish' == resp.action:) [//]: # ( text = json.loads(resp.sentence)['text']) [//]: # ( response = await send(channel, None, False, True)) [//]: # ( return {) [//]: # ( 'text': text,) [//]: # ( 'time': time.time() - b,) [//]: # ( }) [//]: # () [//]: # (async def test():) [//]: # ( # fc = FunAsrGrpcClient('127.0.0.1', 9900)) [//]: # ( # t = await fc.rec(wav.tobytes())) [//]: # ( # print(t)) [//]: # ( wav, _ = sf.read('z-10s.wav', dtype='int16')) [//]: # ( uri = '127.0.0.1:9900') [//]: # ( res = await grpc_rec(wav.tobytes(), uri)) [//]: # ( print(res)) [//]: # () [//]: # () [//]: # (if __name__ == '__main__':) [//]: # ( asyncio.run(test())) [//]: # () [//]: # (```) ## Acknowledge 1. This project is maintained by [FunASR community](https://github.com/alibaba-damo-academy/FunASR). 2. We acknowledge [DeepScience](https://www.deepscience.cn) for contributing the grpc service.