chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:25:10 +08:00
commit c397331b1e
3684 changed files with 990993 additions and 0 deletions
+27
View File
@@ -0,0 +1,27 @@
# GRPC python Client for 2pass decoding
The client can send streaming or full audio data to server as you wish, and get transcribed text once the server respond (depends on mode)
In the demo client, audio_chunk_duration is set to 1000ms, and send_interval is set to 100ms
### 1. Install the requirements
```shell
git clone https://github.com/alibaba/FunASR.git && cd FunASR/funasr/runtime/python/grpc
pip install -r requirements.txt
```
### 2. Generate protobuf file
```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
```
### 3. Start grpc client
```
# Start client.
python grpc_main_client.py --host 127.0.0.1 --port 10100 --wav_path /path/to/your_test_wav.wav
```
## Acknowledge
1. This project is maintained by [FunASR community](https://github.com/modelscope/FunASR).
2. We acknowledge burkliu (刘柏基, liubaiji@xverse.cn) for contributing the grpc service.
+83
View File
@@ -0,0 +1,83 @@
"""
Copyright FunASR (https://github.com/alibaba-damo-academy/FunASR). All Rights
Reserved. MIT License (https://opensource.org/licenses/MIT)
2023 by burkliu(刘柏基) liubaiji@xverse.cn
"""
import logging
import argparse
import soundfile as sf
import time
import grpc
import paraformer_pb2_grpc
from paraformer_pb2 import Request, WavFormat, DecodeMode
class GrpcClient:
def __init__(self, wav_path, uri, mode):
self.wav, self.sampling_rate = sf.read(wav_path, dtype="int16")
self.wav_format = WavFormat.pcm
self.audio_chunk_duration = 1000 # ms
self.audio_chunk_size = int(self.sampling_rate * self.audio_chunk_duration / 1000)
self.send_interval = 100 # ms
self.mode = mode
# connect to grpc server
channel = grpc.insecure_channel(uri)
self.stub = paraformer_pb2_grpc.ASRStub(channel)
# start request
for respond in self.stub.Recognize(self.request_iterator()):
logging.info(
"[receive] mode {}, text {}, is final {}".format(
DecodeMode.Name(respond.mode), respond.text, respond.is_final
)
)
def request_iterator(self, mode=DecodeMode.two_pass):
is_first_pack = True
is_final = False
for start in range(0, len(self.wav), self.audio_chunk_size):
request = Request()
audio_chunk = self.wav[start : start + self.audio_chunk_size]
if is_first_pack:
is_first_pack = False
request.sampling_rate = self.sampling_rate
request.mode = self.mode
request.wav_format = self.wav_format
if request.mode == DecodeMode.two_pass or request.mode == DecodeMode.online:
request.chunk_size.extend([5, 10, 5])
if start + self.audio_chunk_size >= len(self.wav):
is_final = True
request.is_final = is_final
request.audio_data = audio_chunk.tobytes()
logging.info(
"[request] audio_data len {}, is final {}".format(
len(request.audio_data), request.is_final
)
) # int16 = 2bytes
time.sleep(self.send_interval / 1000)
yield request
if __name__ == "__main__":
logging.basicConfig(filename="", format="%(asctime)s %(message)s", level=logging.INFO)
parser = argparse.ArgumentParser()
parser.add_argument(
"--host", type=str, default="127.0.0.1", required=False, help="grpc server host ip"
)
parser.add_argument("--port", type=int, default=10100, required=False, help="grpc server port")
parser.add_argument("--wav_path", type=str, required=True, help="audio wav path")
args = parser.parse_args()
for mode in [DecodeMode.offline, DecodeMode.online, DecodeMode.two_pass]:
mode_name = DecodeMode.Name(mode)
logging.info("[request] start requesting with mode {}".format(mode_name))
st = time.time()
uri = "{}:{}".format(args.host, args.port)
client = GrpcClient(args.wav_path, uri, mode)
logging.info("mode {}, time pass: {}".format(mode_name, time.time() - st))
+25
View File
@@ -0,0 +1,25 @@
```
service ASR { //grpc service
rpc Recognize (stream Request) returns (stream Response) {} //Stub
}
message Request { //request data
bytes audio_data = 1; //audio data in bytes.
string user = 2; //user allowed.
string language = 3; //language, zh-CN for now.
bool speaking = 4; //flag for speaking.
bool isEnd = 5; //flag for end. set isEnd to true when you stop asr:
//vad:is_speech then speaking=True & isEnd = False, audio data will be appended for the specfied user.
//vad:silence then speaking=False & isEnd = False, clear audio buffer and do asr inference.
}
message Response { //response data.
string sentence = 1; //json, includes flag for success and asr text .
string user = 2; //same to request user.
string language = 3; //same to request language.
string action = 4; //server status:
//terminateasr stopped;
//speakinguser is speaking, audio data is appended;
//decoding: server is decoding;
//finish: get asr text, most used.
}
@@ -0,0 +1,39 @@
// Copyright FunASR (https://github.com/alibaba-damo-academy/FunASR). All Rights
// Reserved. MIT License (https://opensource.org/licenses/MIT)
//
// 2023 by burkliu(刘柏基) liubaiji@xverse.cn
syntax = "proto3";
option objc_class_prefix = "paraformer";
package paraformer;
service ASR {
rpc Recognize (stream Request) returns (stream Response) {}
}
enum WavFormat {
pcm = 0;
}
enum DecodeMode {
offline = 0;
online = 1;
two_pass = 2;
}
message Request {
DecodeMode mode = 1;
WavFormat wav_format = 2;
int32 sampling_rate = 3;
repeated int32 chunk_size = 4;
bool is_final = 5;
bytes audio_data = 6;
}
message Response {
DecodeMode mode = 1;
string text = 2;
bool is_final = 3;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

+2
View File
@@ -0,0 +1,2 @@
grpcio
grpcio-tools