本文档介绍如何通过WebSocket协议实时访问大模型流式语音识别服务 (ASR),主要包含鉴权相关、协议详情、常见问题和使用Demo四部分。
双向流式模式使用的接口地址是 wss://openspeech.bytedance.com/api/v3/sauc/bigmodel
流式输入模式使用的接口地址是 wss://openspeech.bytedance.com/api/v3/sauc/bigmodel_nostream
两者都是每输入一个包返回一个包,双向流式模式会尽快返回识别到的字符,速度较快。
流式输入模式会在输入音频达到15s或发送最后一包(负包)后返回识别到的结果,准确率更高。
在 websocket 建连的 HTTP 请求头(Header 中)添加以下信息
Key | 说明 | Value 示例 |
---|---|---|
X-Api-App-Key | 使用火山引擎控制台获取的APP ID,可参考 控制台使用FAQ-Q1 | 123456789 |
X-Api-Access-Key | 使用火山引擎控制台获取的Access Token,可参考 控制台使用FAQ-Q1 | your-access-key |
X-Api-Resource-Id | 表示调用服务的资源信息 ID,是固定值
| 小时版:volc.bigasr.sauc.duration |
X-Api-Connect-Id | 用于追踪当前连接的标志 ID,推荐设置UUID等 | 67ee89ba-7050-4c04-a3d7-ac61a63499b3 |
websocket 握手成功后,会返回这些 Response header。强烈建议记录X-Tt-Logid(logid)作为排错线索。
Key | 说明 | Value 示例 |
---|---|---|
X-Tt-Logid | 服务端返回的 logid,建议用户获取和打印方便定位问题 | 202407261553070FACFE6D19421815D605 |
// 建连 HTTP 请求头示例 GET /api/v3/sauc/bigmodel Host: openspeech.bytedance.com X-Api-App-Key: 123456789 X-Api-Access-Key: your-access-key X-Api-Resource-Id: volc.bigasr.sauc.duration X-Api-Connect-Id: 随机生成的UUID ## 返回 Header X-Tt-Logid: 202407261553070FACFE6D19421815D605
WebSocket 使用二进制协议传输数据。协议的组成由至少 4 个字节的可变 header、payload size 和 payload 三部分组成,其中 header 描述消息类型、序列化方式以及压缩格式等信息,payload size 是 payload 的长度,payload 是具体负载内容,依据消息类型不同 payload 内容不同。
需注意:协议中整数类型的字段都使用大端表示。
Byte \ Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
0 | Protocol version | Header size | ||||||
1 | Message type | Message type specific flags | ||||||
2 | Message serialization method | Message compression | ||||||
3 | Reserved | |||||||
4 | [Optional header extensions] | |||||||
5 | [Payload, depending on the Message Type] | |||||||
6 | ... |
字段 (size in bits) | 说明 | 值 |
---|---|---|
Protocol version (4) | 将来可能会决定使用不同的协议版本,因此此字段是为了使客户端和服务器在版本上达成共识。 | 0b0001 - version 1 (目前只有该版本) |
Header (4) | Header 大小。实际 header 大小(以字节为单位)是 header size value x 4 。 | 0b0001 - header size = 4 (1 x 4) |
Message type (4) | 消息类型。 | 0b0001 - 端上发送包含请求参数的 full client request |
Message type specific flags (4) | Message type 的补充信息。 | Request: Response: Bit 位含义说明: |
Message serialization method (4) | full client request 的 payload 序列化方法; | 0b0000 - 无序列化 |
Message Compression (4) | 定义 payload 的压缩方法; | 0b0000 - no compression |
Reserved (8) | 保留以供将来使用,还用作填充(使整个标头总计4个字节)。 |
根据 WebSocket 协议本身的机制,client 会发送 HTTP GET 请求和 server 建立连接做协议升级。
需要在其中根据身份认证协议加入鉴权签名头。设置方法请参考鉴权。
WebSocket 建立连接后,发送的第一个请求是 full client request。格式是:
31 ... 24 | 23 ... 16 | 15 ... 8 | 7 ... 0 |
---|---|---|---|
Header | |||
Payload size (4B, unsigned int32) | |||
Payload |
字段 | 说明 | 层级 | 格式 | 是否必填 | 备注 |
---|---|---|---|---|---|
user | 用户相关配置 | 1 | dict | 提供后可供服务端过滤日志 | |
uid | 用户标识 | 2 | string | 建议采用 IMEI 或 MAC。 | |
did | 设备名称 | 2 | string | ||
platform | 操作系统及API版本号 | 2 | string | iOS/Android/Linux | |
sdk_version | sdk版本 | 2 | string | ||
app_version | app 版本 | 2 | string | ||
audio | 音频相关配置 | 1 | dict | ✓ | |
format | 音频容器格式 | 2 | string | ✓ | pcm(pcm_s16le) / wav(pcm_s16le) / ogg |
codec | 音频编码格式 | 2 | string | raw / opus,默认为 raw(pcm) 。 | |
rate | 音频采样率 | 2 | int | 默认为 16000,目前只支持16000 | |
bits | 音频采样点位数 | 2 | int | 默认为 16。 | |
channel | 音频声道数 | 2 | int | 1(mono) / 2(stereo),默认为1。 | |
request | 请求相关配置 | 1 | dict | ✓ | |
model_name | 模型名称 | 2 | string | ✓ | 目前只有bigmodel |
enable_itn | 启用itn | 2 | bool | 默认为false。 | |
enable_punc | 启用标点 | 2 | bool | 默认为false。 | |
enable_ddc | 启用顺滑 | 2 | bool | 默认为false。 | |
show_utterances | 输出语音停顿、分句、分词信息 | 2 | bool | ||
corpus | 语料/干预词等 | 2 | string | ||
boosting_table_name | 自学习平台上设置的热词词表名称 | 3 | string | 热词功能和设置方法可以参考文档 | |
result_type | 结果返回方式 | 2 | string | 默认为"full",全量返回。 | |
vad_segment_duration | vad切句的阈值 | 2 | int | 单位ms,最低800,适用于双向流式接口。默认的断句方式是通过语义的,如果设置一个较小的vad数值(小于3000ms),则会变为通过vad阈值断句 |
参数示例:
{ "user": { "uid": "388808088185088" }, "audio": { "format": "wav", "rate": 16000, "bits": 16, "channel": 1, "language": "zh-CN" }, "request": { "model_name": "bigmodel", "enable_itn": false, "enable_ddc": false, "enable_punc": false, "corpus": { "boosting_table_id": "通过自学习平台配置热词的词表id", } } }
Client 发送 full client request 后,再发送包含音频数据的 audio-only client request。音频应采用 full client request 中指定的格式(音频格式、编解码器、采样率、声道)。格式如下:
31 ... 24 | 23 ... 16 | 15 ... 8 | 7 ... 0 |
---|---|---|---|
Header | |||
Payload size (4B, unsigned int32) | |||
Payload |
Payload 是使用指定压缩方法,压缩音频数据后的内容。可以多次发送 audio only request 请求,例如在流式语音识别中如果每次发送 100ms 的音频数据,那么 audio only request 中的 Payload 就是 100ms 的音频数据。
Client 发送的 full client request 和 audio only request,服务端都会返回 full server response。格式如下:
31 ... 24 | 23 ... 16 | 15 ... 8 | 7 ... 0 |
---|---|---|---|
Header | |||
Sequence | |||
Payload size (4B, unsigned int32) | |||
Payload |
Payload 内容是包含识别结果的 JSON 格式,字段说明如下:
字段 | 说明 | 层级 | 格式 | 是否必填 | 备注 |
---|---|---|---|---|---|
result | 识别结果 | 1 | list | 仅当识别成功时填写 | |
text | 整个音频的识别结果文本 | 2 | string | 仅当识别成功时填写。 | |
confidence | 识别结果文本置信度 | 2 | int | 仅当识别成功时填写。 | |
utterances | 识别结果语音分句信息 | 2 | list | 仅当识别成功且开启show_utterances时填写。 | |
text | utterance级的文本内容 | 3 | string | 仅当识别成功且开启show_utterances时填写。 | |
start_time | 起始时间(毫秒) | 3 | int | 仅当识别成功且开启show_utterances时填写。 | |
end_time | 结束时间(毫秒) | 3 | int | 仅当识别成功且开启show_utterances时填写。 | |
definite | 是否是一个确定分句 | 3 | bool | 仅当识别成功且开启show_utterances时填写。 |
{ "audio_info": {"duration": 10000}, "result": { "text": "这是字节跳动, 今日头条母公司。", "utterances": [ { "definite": true, "end_time": 1705, "start_time": 0, "text": "这是字节跳动,", "words": [ { "blank_duration": 0, "end_time": 860, "start_time": 740, "text": "这" }, { "blank_duration": 0, "end_time": 1020, "start_time": 860, "text": "是" }, { "blank_duration": 0, "end_time": 1200, "start_time": 1020, "text": "字" }, { "blank_duration": 0, "end_time": 1400, "start_time": 1200, "text": "节" }, { "blank_duration": 0, "end_time": 1560, "start_time": 1400, "text": "跳" }, { "blank_duration": 0, "end_time": 1640, "start_time": 1560, "text": "动" } ] }, { "definite": true, "end_time": 3696, "start_time": 2110, "text": "今日头条母公司。", "words": [ { "blank_duration": 0, "end_time": 3070, "start_time": 2910, "text": "今" }, { "blank_duration": 0, "end_time": 3230, "start_time": 3070, "text": "日" }, { "blank_duration": 0, "end_time": 3390, "start_time": 3230, "text": "头" }, { "blank_duration": 0, "end_time": 3550, "start_time": 3390, "text": "条" }, { "blank_duration": 0, "end_time": 3670, "start_time": 3550, "text": "母" }, { "blank_duration": 0, "end_time": 3696, "start_time": 3670, "text": "公" }, { "blank_duration": 0, "end_time": 3696, "start_time": 3696, "text": "司" } ] } ] }, "audio_info": { "duration": 3696 } }
当 server 发现无法解决的二进制/传输协议问题时,将发送 Error message from server 消息(例如,client 以 server 不支持的序列化格式发送消息)。格式如下:
31 ... 24 | 23 ... 16 | 15 ... 8 | 7 ... 0 |
---|---|---|---|
Header | |||
Error message code (4B, unsigned int32) | |||
Error message size (4B, unsigned int32) | |||
Error message (UTF8 string) |
下面的 message flow 会发送多次消息,每个消息都带有版本、header 大小、保留数据。由于每次消息中这些字段值相同,所以有些消息中这些字段省略了。
Message flow:
b0001
(4 bits)b0001
(4 bits)b0001
(Full client request) (4bits)b0000
(use_specific_pos_sequence) (4bits)b0001
(JSON) (4 bits)b0001
(Gzip) (4bits)0x00
(1 byte)b0001
b0001
b1001
(Full server response)b0001
(none)b0001
(JSON 和请求相同)b0001
(Gzip 和请求相同)0x00
b0001
b0001
b0010
(audio only client request)b0000
(用户设置正数 sequence number)b0000
(none - raw bytes)b0001
(Gzip)0x00
0b1001
- Full server response0b0001
(none)0b0001
(JSON, 和请求相同)0b0001
(Gzip, 和请求相同)0x00
b0010
(audio only client request)b0010
(最后一包音频请求)b0000
(none - raw bytes)b0001
(Gzip)0x00
b1001
(Full server response)b0011
(最后一包音频结果)b0001
(JSON)b0001
(Gzip)0x00
0x00 0x00 0x00 0x03
(4byte) sequence=3b1111
(error response)b0000
(none)b0001
(JSON)b0000
(none)0x00
0x2A 0x0D 0x0A2 0xff
(4byte) 错误码错误码 | 含义 | 说明 |
---|---|---|
20000000 | 成功 | |
45000001 | 请求参数无效 | 请求参数缺失必需字段 / 字段值无效 / 重复请求。 |
45000002 | 空音频 | |
45000081 | 等包超时 | |
45000151 | 音频格式不正确 | |
550xxxxx | 服务内部处理错误 | |
55000031 | 服务器繁忙 | 服务过载,无法处理当前请求。 |
单工演示demo,即发送和接收均在同一个线程或者协程中,整体识别速度可能会略慢。配置下面两行即可运行:
# access token header["X-Api-Access-Key"] = "" # app id header["X-Api-App-Key"] = ""