Paraformer实时语音识别Python API

本文介绍Paraformer实时语音识别Python API的使用。

前提条件

模型列表

模型名

模型简介

paraformer-realtime-v2

推荐使用。Paraformer最新多语种实时语音识别模型。

  • 适用场景:直播、会议等实时语音处理场景

  • 支持的采样率:任意

  • 支持的语种:中文(包含中文普通话和各种方言)、英文、日语、韩语

    支持的中文方言(单击查看详情)

    上海话、吴语、闽南语、东北话、甘肃话、贵州话、河南话、湖北话、湖南话、江西话、宁夏话、山西话、陕西话、山东话、四川话、天津话、云南话、粤语

  • 核心能力:

    • 支持标点符号预测

    • 支持逆文本正则化(ITN)

  • 特色功能:

    • 指定语种:通过language_hints参数能够指定待识别语种,提升识别效果

    • 支持定制热词

paraformer-realtime-8k-v2

推荐使用。Paraformer最新8k中文实时语音识别模型,模型结构升级,具有更快的推理速度和更好的识别效果。

  • 适用场景:电话客服、语音信箱等 8kHz 音频的实时识别,需快速推理与高准确率的场景(如实时字幕生成)等

  • 支持的采样率:8kHz

  • 支持的语种:中文

  • 核心能力:

    • 支持标点符号预测

    • 支持逆文本正则化(ITN)

  • 特色功能:

paraformer-realtime-v1

Paraformer中文实时语音识别模型。

  • 适用场景:视频直播、会议等实时场景

  • 支持的采样率:16kHz

  • 支持的语种:中文

  • 核心能力:

    • 支持标点符号预测

    • 支持逆文本正则化(ITN)

  • 特色功能:

paraformer-realtime-8k-v1

Paraformer中文实时语音识别模型。

  • 适用场景:8kHz电话客服等场景

  • 支持的采样率:8kHz

  • 支持的语种:中文

  • 核心能力:

    • 支持标点符号预测

    • 支持逆文本正则化(ITN)

  • 特色功能:

调用模式

核心类(Recognition)提供了同步调用和流式调用等接口。请根据实际需求选择合适的调用模式:

  • 同步调用:对本地文件进行识别,并一次性输出完整结果。

  • 流式调用:直接对音频流(无论是从外部设备如麦克风获取的音频流,还是从本地文件读取的音频流)进行识别,并流式输出结果。

同步调用

提交单个语音实时转写任务,通过传入本地文件的方式同步阻塞地拿到转写结果。

image
  1. 实例化核心类(Recognition)并设置请求参数

    recognition = Recognition(model='paraformer-realtime-v2',
                              format='wav',
                              sample_rate=16000,
                              # “language_hints”只支持paraformer-realtime-v2模型
                              language_hints=['zh', 'en'],
                              callback=None)
  2. 同步调用

    调用核心类(Recognition)call方法进行识别。call方法返回实时识别结果(RecognitionResult)

    result = recognition.call('asr_example.wav')

点击查看完整示例

示例中用到的音频为:asr_example.wav

from http import HTTPStatus
from dashscope.audio.asr import Recognition

# 若没有将API Key配置到环境变量中,需将下面这行代码注释放开,并将apiKey替换为自己的API Key
# import dashscope
# dashscope.api_key = "apiKey"

recognition = Recognition(model='paraformer-realtime-v2',
                          format='wav',
                          sample_rate=16000,
                          # “language_hints”只支持paraformer-realtime-v2模型
                          language_hints=['zh', 'en'],
                          callback=None)
result = recognition.call('asr_example.wav')
if result.status_code == HTTPStatus.OK:
    print('识别结果:')
    print(result.get_sentence())
else:
    print('Error: ', result.message)
    
print(
    '[Metric] requestId: {}, first package delay ms: {}, last package delay ms: {}'
    .format(
        recognition.get_last_request_id(),
        recognition.get_first_package_delay(),
        recognition.get_last_package_delay(),
    ))

流式调用

提交单个语音实时转写任务,通过实现回调接口的方式流式输出实时识别结果。

image
  1. 实例化回调接口(RecognitionCallback)

  2. 实例化核心类(Recognition)设置请求参数

    recognition = Recognition(model='paraformer-realtime-v2',
                              format='wav',
                              sample_rate=16000,
                              # “language_hints”只支持paraformer-realtime-v2模型
                              language_hints=['zh', 'en'],
                              callback=callback)
  3. 调用核心类(Recognition)start方法开启任务。

  4. 分段发送二进制音频

    您需要调用核心类(Recognition)实例的send_audio_frame方法,将从本地文件或设备(如麦克风)读取的二进制音频流分段发送给服务端。每次发送的音频时长建议为100ms左右,数据大小建议在1KB16KB之间。在发送音频数据的同时,服务端会回调RecognitionCallback实例的方法将识别结果返回给客户端。

    try:
        audio_data: bytes = None
        f = open("asr_example.wav", 'rb')
        if os.path.getsize("asr_example.wav"):
            while True:
                audio_data = f.read(12800)
                if not audio_data:
                    break
                else:
                    recognition.send_audio_frame(audio_data)
        else:
            raise Exception(
                'The supplied file was empty (zero bytes long)')
        f.close()
    except Exception as e:
        raise e
  5. 结束任务:调用核心类(Recognition)stop方法

    请不要遗漏该步骤。stop方法会阻塞当前线程,直到RecognitionCallbackon_complete或者on_error方法被回调才会解除对当前线程的阻塞。

    recognition.stop();

点击查看完整示例

识别传入麦克风的语音

# For prerequisites running the following sample, visit https://help.aliyun.com/zh/model-studio/getting-started/first-api-call-to-qwen
import os
import signal  # for keyboard events handling (press "Ctrl+C" to terminate recording)
import sys

import dashscope
import pyaudio
from dashscope.audio.asr import *

mic = None
stream = None

# Set recording parameters
sample_rate = 16000  # sampling rate (Hz)
channels = 1  # mono channel
dtype = 'int16'  # data type
format_pcm = 'pcm'  # the format of the audio data
block_size = 3200  # number of frames per buffer


def init_dashscope_api_key():
    """
        Set your DashScope API-key. More information:
        https://github.com/aliyun/alibabacloud-bailian-speech-demo/blob/master/PREREQUISITES.md
    """

    if 'DASHSCOPE_API_KEY' in os.environ:
        dashscope.api_key = os.environ[
            'DASHSCOPE_API_KEY']  # load API-key from environment variable DASHSCOPE_API_KEY
    else:
        dashscope.api_key = '<your-dashscope-api-key>'  # set API-key manually


# Real-time speech recognition callback
class Callback(RecognitionCallback):
    def on_open(self) -> None:
        global mic
        global stream
        print('RecognitionCallback open.')
        mic = pyaudio.PyAudio()
        stream = mic.open(format=pyaudio.paInt16,
                          channels=1,
                          rate=16000,
                          input=True)

    def on_close(self) -> None:
        global mic
        global stream
        print('RecognitionCallback close.')
        stream.stop_stream()
        stream.close()
        mic.terminate()
        stream = None
        mic = None

    def on_complete(self) -> None:
        print('RecognitionCallback completed.')  # recognition completed

    def on_error(self, message) -> None:
        print('RecognitionCallback task_id: ', message.request_id)
        print('RecognitionCallback error: ', message.message)
        # Stop and close the audio stream if it is running
        if 'stream' in globals() and stream.active:
            stream.stop()
            stream.close()
        # Forcefully exit the program
        sys.exit(1)

    def on_event(self, result: RecognitionResult) -> None:
        sentence = result.get_sentence()
        if 'text' in sentence:
            print('RecognitionCallback text: ', sentence['text'])
            if RecognitionResult.is_sentence_end(sentence):
                print(
                    'RecognitionCallback sentence end, request_id:%s, usage:%s'
                    % (result.get_request_id(), result.get_usage(sentence)))


def signal_handler(sig, frame):
    print('Ctrl+C pressed, stop recognition ...')
    # Stop recognition
    recognition.stop()
    print('Recognition stopped.')
    print(
        '[Metric] requestId: {}, first package delay ms: {}, last package delay ms: {}'
        .format(
            recognition.get_last_request_id(),
            recognition.get_first_package_delay(),
            recognition.get_last_package_delay(),
        ))
    # Forcefully exit the program
    sys.exit(0)


# main function
if __name__ == '__main__':
    init_dashscope_api_key()
    print('Initializing ...')

    # Create the recognition callback
    callback = Callback()

    # Call recognition service by async mode, you can customize the recognition parameters, like model, format,
    # sample_rate For more information, please refer to https://help.aliyun.com/document_detail/2712536.html
    recognition = Recognition(
        model='paraformer-realtime-v2',
        # 'paraformer-realtime-v1'、'paraformer-realtime-8k-v1'
        format=format_pcm,
        # 'pcm'、'wav'、'opus'、'speex'、'aac'、'amr', you can check the supported formats in the document
        sample_rate=sample_rate,
        # support 8000, 16000
        semantic_punctuation_enabled=False,
        callback=callback)

    # Start recognition
    recognition.start()

    signal.signal(signal.SIGINT, signal_handler)
    print("Press 'Ctrl+C' to stop recording and recognition...")
    # Create a keyboard listener until "Ctrl+C" is pressed

    while True:
        if stream:
            data = stream.read(3200, exception_on_overflow=False)
            recognition.send_audio_frame(data)
        else:
            break

    recognition.stop()

识别本地语音文件

示例中用到的音频为:asr_example.wav

# For prerequisites running the following sample, visit https://help.aliyun.com/document_detail/611472.html

import os
import time
from dashscope.audio.asr import *

# 若没有将API Key配置到环境变量中,需将下面这行代码注释放开,并将apiKey替换为自己的API Key
# import dashscope
# dashscope.api_key = "apiKey"

from datetime import datetime

def get_timestamp():
    now = datetime.now()
    formatted_timestamp = now.strftime("[%Y-%m-%d %H:%M:%S.%f]")
    return formatted_timestamp

class Callback(RecognitionCallback):
    def on_complete(self) -> None:
        print(get_timestamp() + ' Recognition completed')  # recognition complete

    def on_error(self, result: RecognitionResult) -> None:
        print('Recognition task_id: ', result.request_id)
        print('Recognition error: ', result.message)
        exit(0)

    def on_event(self, result: RecognitionResult) -> None:
        sentence = result.get_sentence()
        if 'text' in sentence:
            print(get_timestamp() + ' RecognitionCallback text: ', sentence['text'])
            if RecognitionResult.is_sentence_end(sentence):
                print(get_timestamp() + 
                    'RecognitionCallback sentence end, request_id:%s, usage:%s'
                    % (result.get_request_id(), result.get_usage(sentence)))


callback = Callback()

recognition = Recognition(model='paraformer-realtime-v2',
                          format='wav',
                          sample_rate=16000,
                          # “language_hints”只支持paraformer-realtime-v2模型
                          language_hints=['zh', 'en'],
                          callback=callback)

recognition.start()

try:
    audio_data: bytes = None
    f = open("asr_example.wav", 'rb')
    if os.path.getsize("asr_example.wav"):
        while True:
            audio_data = f.read(3200)
            if not audio_data:
                break
            else:
                recognition.send_audio_frame(audio_data)
            time.sleep(0.1)
    else:
        raise Exception(
            'The supplied file was empty (zero bytes long)')
    f.close()
except Exception as e:
    raise e

recognition.stop()

print(
    '[Metric] requestId: {}, first package delay ms: {}, last package delay ms: {}'
    .format(
        recognition.get_last_request_id(),
        recognition.get_first_package_delay(),
        recognition.get_last_package_delay(),
    ))

并发调用

Python中,由于存在全局解释器锁,同一时刻只有一个线程可以执行Python代码(虽然某些性能导向的库可能会去除此限制)。如果您想更好地利用多核心计算机的计算资源,推荐您使用multiprocessingconcurrent.futures.ProcessPoolExecutor。 多线程在较高并发下会显著增加SDK调用延迟。

请求参数

请求参数通过核心类(Recognition)的构造方法(_init_)进行设置。

参数

类型

默认值

是否必须

说明

model

str

-

用于实时语音识别的模型。

sample_rate

int

-

待识别音频采样率。

因模型而异:

  • paraformer-realtime-v2 支持任意采样率。

  • paraformer-realtime-v1 仅支持16kHz采样。

  • paraformer-realtime-8k-v2 仅支持8kHz采样率。

  • paraformer-realtime-8k-v1 仅支持8kHz采样率。

format

str

-

待识别音频格式。

支持的音频格式:'pcm'、'wav'、'mp3'、'opus'、'speex'、'aac'、'amr'。

vocabulary_id

str

-

最新热词ID,支持最新v2系列模型并配置语种信息,此次语音识别中生效此热词ID对应的热词信息。默认不启用。使用方法请参考定制热词

phrase_id

str

-

热词ID,此次语音识别中生效此热词ID对应的热词信息。默认不启用。

注:phrase_idv1版本模型热词方案,不支持v2及后续系列模型。支持该方式热词的模型列表请参考Paraformer语音识别热词定制与管理

disfluency_removal_enabled

bool

False

过滤语气词,默认关闭。

language_hints

list[str]

["zh", "en"]

指定识别语音中语言的代码列表。

该参数仅适用于paraformer-realtime-v2模型。

支持的语言代码:

  • zh: 中文

  • en: 英文

  • ja: 日语

  • yue: 粤语

  • ko: 韩语

仅对支持多语言的模型生效。如果不填写则模型会自动识别语种。

semantic_punctuation_enabled

bool

True

是否开启语义断句,服务默认开启语义断句,如果关闭则使用VAD (Voice Activity Detection)断句。一般而言,VAD断句延迟低适用于交互场景,语义断句准确适用于会议转写场景。

此功能只有v2系列模型支持。

重要

该参数默认开启(True),但对延迟敏感的场景建议设置为False。

max_sentence_silence

int

800

语音断句检测阈值,如果一段语音后的静音时长超过该阈值,会被认为一个句子已经结束,参数范围200ms~6000ms,默认值800ms。

此功能只有v2系列模型支持。

说明

关闭语义断句(semantic_punctuation_enabled=False)后才生效。

inverse_text_normalization_enabled

bool

True

是否开启ITN(逆文本,Inverse Text Normalization),开启后(设置为True)中文数字会转换为阿拉伯数字。

此功能只有v2系列模型支持。

callback

RecognitionCallback

-

回调接口。详情请参见回调接口(RecognitionCallback)

响应结果

实时识别结果(RecognitionResult

RecognitionResult代表一次实时识别的结果。

成员方法

方法签名

说明

get_sentence

def get_sentence(self) -> Union[Dict[str, Any], List[Any]]

获取当前识别的句子及时间戳信息。回调中返回的是单句信息,所以此方法返回类型为Dict[str, Any]。

详情请参见单句信息(Sentence)

get_request_id

def get_request_id(self) -> str

获取请求的request_id。

is_sentence_end

@staticmethod
def is_sentence_end(sentence: Dict[str, Any]) -> bool

判断给定句子是否已经结束。

单句信息(Sentence

Sentence类成员如下:

参数

类型

说明

begin_time

int

句子开始时间,单位为ms。

end_time

int

句子结束时间,单位为ms。

text

str

识别文本。

words

list[Word]

字时间戳信息。

详情请参见字时间戳信息(Word)

emo_tag

str

当前句子的情感:

  • positive:正面情感,如开心、满意

  • negative:负面情感,如愤怒、沉闷

  • neutral:无明显情感

仅在关闭语义断句(semantic_punctuation_enabled=False),并且is_sentence_end=True时生效。

paraformer-realtime-8k-v2模型支持情感识别。

emo_confidence

float

当前句子识别情感的置信度,取值范围:[0.0,1.0]。值越大表示置信度越高。

paraformer-realtime-8k-v2模型支持情感识别。

字时间戳信息(Word

Word类成员如下:

参数

类型

说明

begin_time

int

字开始时间,单位为ms。

end_time

int

字结束时间,单位为ms。

text

str

字。

punctuation

str

标点。

关键接口

核心类(Recognition

Recognition可以通过“from dashscope.audio.asr import *”方式引入。

成员方法

方法签名

说明

call

def call(self, file: str, phrase_id: str = None, **kwargs) -> RecognitionResult

基于本地文件的同步调用,该方法会阻塞当前线程直到全部音频读完,该方法要求所识别文件具有可读权限。

识别结果以RecognitionResult类型数据返回。

start

def start(self, phrase_id: str = None, **kwargs)

开始语音识别。

基于回调形式的流式实时识别,该方法不会阻塞当前线程。需要配合send_audio_framestop使用。

send_audio_frame

def send_audio_frame(self, buffer: bytes)

推送音频。每次推送的音频流不宜过大或过小,建议每包音频时长为100ms左右,大小在1KB~16KB之间。

识别结果通过回调接口(RecognitionCallback)on_event方法获取。

stop

def stop(self)

停止语音识别,阻塞到服务将收到的音频都识别后结束任务。

get_last_request_id

def get_last_request_id(self)

获取request_id,在构造函数调用(创建对象)后可以使用。

get_first_package_delay

def get_first_package_delay(self)

获取首包延迟,从发送第一包音频到收到首包识别结果延迟,在任务完成后使用。

get_last_package_delay

def get_last_package_delay(self)

获得尾包延迟,发送stop指令到最后一包识别结果下发耗时,在任务完成后使用。

get_response

def get_response(self)

获取最后一次报文,可以用于获取task-failed报错。

回调接口(RecognitionCallback

流式调用时,服务端会通过回调的方式,将关键流程信息和数据返回给客户端。您需要实现回调方法,处理服务端返回的信息或者数据。

点击查看示例

class Callback(RecognitionCallback):
    def on_open(self) -> None:
        print('连接成功')

    def on_event(self, result: RecognitionResult) -> None:
        # 实现接收识别结果的逻辑

    def on_complete(self) -> None:
        print('任务完成')

    def on_error(self, result: RecognitionResult) -> None:
        print('出现异常:', result)

    def on_close(self) -> None:
        print('连接关闭')


callback = Callback()

方法

参数

返回值

描述

def on_open(self) -> None

当和服务端建立连接完成后,该方法立刻被回调。

def on_event(self, result: RecognitionResult) -> None

result实时识别结果(RecognitionResult)

当服务有回复时会被回调。

def on_complete(self) -> None

当所有识别结果全部返回后进行回调。

def on_error(self, result: RecognitionResult) -> None

result实时识别结果(RecognitionResult)

发生异常时该方法被回调。

def on_close(self) -> None

当服务已经关闭连接后进行回调。

错误码

在使用API过程中,如果调用失败并返回错误信息,请参见错误信息进行解决。

更多示例

更多示例,请参见GitHub

常见问题

请参见GitHub QA