PaddleSpeech RESTful 服务响应模型全解析:统一响应结构、字段语义与错误码设计
【免费下载链接】PaddleSpeechEasy-to-use Speech Toolkit including Self-Supervised Learning model, SOTA/Streaming ASR with punctuation, Streaming TTS with text frontend, Speaker Verification System, End-to-End Speech Translation and Keyword Spotting. Won NAACL2022 Best Demo Award.项目地址: https://gitcode.com/gh_mirrors/pa/PaddleSpeech
导读
本文围绕 PaddleSpeech 服务端paddlespeech/server/restful/response.py模块展开,系统讲解其定义的统一 RESTful 响应骨架(success/code/message/result)、ASR、TTS、CLS、Text、Vector、ACS 六大任务的响应数据模型,以及错误响应与错误码的设计规范。读完本文,你将掌握 PaddleSpeech 离线服务 HTTP 接口的返回格式约定、每个字段的类型与含义,并能结合 FastAPI 路由注册机制(response_model)自行解析、校验甚至扩展服务端响应。
一、模块定位:RESTful 服务的"响应契约"
docs/source/api/paddlespeech.server.restful.response.rst是 PaddleSpeech 文档站中关于paddlespeech.server.restful.response模块的 API 索引页,通过 Sphinxautomodule指令将该模块的类定义与文档字符串渲染为在线文档。该模块的实际代码位于 paddlespeech/server/restful/response.py,是整个服务端对外暴露 HTTP 接口时统一使用的"响应契约"。
在paddlespeech/server/restful/目录下,各任务 API 文件(asr_api.py、tts_api.py、cls_api.py、text_api.py、vector_api.py、acs_api.py)与 request.py(请求模型)一样,均基于PydanticBaseModel定义数据结构,用于 FastAPI 接口的参数校验与响应序列化。从模块的__all__可以看出,它对外导出的全部响应类为:
__all__ = [ 'ASRResponse', 'TTSResponse', 'CLSResponse', 'TextResponse', 'VectorResponse', 'VectorScoreResponse', 'ACSResponse' ]这些类共同保证了:无论客户端调用哪个任务接口,收到的 JSON 都遵循同一套外层结构,方便统一解析与错误处理。
二、统一响应骨架:success/code/message/result
所有业务响应模型(ASRResponse、TTSResponse、CLSResponse、TextResponse、VectorResponse、VectorScoreResponse、ACSResponse)与错误响应ErrorResponse都共享同一外层结构:
| 字段 | 类型 | 说明 |
|---|---|---|
success | bool | 请求是否处理成功 |
code | int | 业务/HTTP 状态码,成功时为200(或示例中的0) |
message | Message | 描述性信息对象 |
result | 各任务自己的 Result 模型 | 任务执行结果,错误响应中没有该字段 |
其中message使用的是统一的Message模型,只包含一个字符串字段:
class Message(BaseModel): description: str也就是说,响应中的message形如{"description": "success"}或{"description": "Unknown error occurred."}。Message没有设置默认值,因此在构造响应时必须显式赋值(见下文 Vector 接口中error_reponse.message.description = ...的用法)。
三、各任务响应模型详解
3.1 ASR 响应:ASRResponse/AsrResult
语音识别接口POST /paddlespeech/asr的响应模型定义及官方示例:
class AsrResult(BaseModel): transcription: str class ASRResponse(BaseModel): """ response example { "success": true, "code": 0, "message": { "description": "success" }, "result": { "transcription": "你好,飞桨" } } """ success: bool code: int message: Message result: AsrResultresult.transcription为识别出的文本字符串。在 asr_api.py 的实现中,请求体中的 base64 音频经base64.b64decode解码后交给PaddleASRConnectionHandler处理,connection_handler.postprocess()返回的识别结果被填入result.transcription;服务端通过response_model=Union[ASRResponse, ErrorResponse]声明该接口的合法返回类型。
3.2 TTS 响应:TTSResponse/TTSResult
语音合成接口POST /paddlespeech/tts的响应模型是字段最丰富的一个:
class TTSResult(BaseModel): lang: str = "zh" spk_id: int = 0 speed: float = 1.0 volume: float = 1.0 sample_rate: int duration: float save_path: Optional[str] = None audio: str class TTSResponse(BaseModel): """ response example { "success": true, "code": 200, "message": { "description": "success" }, "result": { "lang": "zh", "spk_id": 0, "speed": 1.0, "volume": 1.0, "sample_rate": 24000, "duration": 3.6125, "audio": "LTI1OTIuNjI1OTUwMzQsOTk2OS41NDk4...", "save_path": "./tts.wav" } } """ success: bool code: int message: Message result: TTSResultTTSResult字段语义如下:
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
lang | str | "zh" | 合成语言 |
spk_id | int | 0 | 说话人 ID |
speed | float | 1.0 | 语速倍率 |
volume | float | 1.0 | 音量倍率 |
sample_rate | int | 必填 | 合成音频实际采样率(如 24000) |
duration | float | 必填 | 音频时长(秒) |
save_path | Optional[str] | None | 音频本地保存路径(可选) |
audio | str | 必填 | 音频的 base64 编码字符串 |
注意:sample_rate与duration没有默认值,即它们在任何 TTS 响应中都必须出现;save_path允许为None。这些字段与 request.py 中的TTSRequest遥相呼应——请求中可传spk_id、speed、volume、sample_rate、save_path,而tts_api.py会在处理前对参数做范围校验(speed、volume须在(0, 3],sample_rate只允许0/8000/16000,save_path只能以pcm或wav结尾),不合法时直接返回错误响应。
3.3 CLS 响应:CLSResponse/CLSResult/CLSResults
音频分类接口POST /paddlespeech/cls的响应包含 Top-K 结果列表:
class CLSResults(BaseModel): class_name: str prob: float class CLSResult(BaseModel): topk: int results: List[CLSResults] class CLSResponse(BaseModel): """ response example { "success": true, "code": 0, "message": { "description": "success" }, "result": { topk: 1 results: [ { "class":"Speech", "prob": 0.9027184844017029 } ] } } """ success: bool code: int message: Message result: CLSResult这里体现了响应模型对"嵌套列表"的支持:CLSResult中的results是List[CLSResults],每个元素包含类别名class_name(示例 JSON 中写作class)与置信度prob。topk字段与请求参数topk(见 request.py 中CLSRequest.topk,默认值为 1)保持一致,表示返回置信度最高的前 K 个类别。
3.4 Text 响应:TextResponse/TextResult
标点恢复接口POST /paddlespeech/text的响应模型:
class TextResult(BaseModel): punc_text: str class TextResponse(BaseModel): """ response example { "success": true, "code": 0, "message": { "description": "success" }, "result": { "punc_text": "你好,飞桨" } } """ success: bool code: int message: Message result: TextResultresult.punc_text为带标点的文本。在 text_api.py 的实现中有一个细节值得注意:当PaddleTextConnectionHandler.run(text)返回None时,服务端会回退为原始文本(punc_text = text),保证响应的punc_text字段始终非空。
3.5 Vector 响应:VectorResponse/VectorScoreResponse
说话人向量提取接口POST /paddlespeech/vector与打分接口POST /paddlespeech/vector/score分别使用两个响应模型:
class VectorResult(BaseModel): vec: list class VectorResponse(BaseModel): """ response example { "success": true, "code": 0, "message": { "description": "success" }, "result": { "vec": [1.0, 1.0] } } """ success: bool code: int message: Message result: VectorResult class VectorScoreResult(BaseModel): score: float class VectorScoreResponse(BaseModel): """ response example { "success": true, "code": 0, "message": { "description": "success" }, "result": { "score": 1.0 } } """ success: bool code: int message: Message result: VectorScoreResultVectorResult.vec是说话人嵌入向量(list类型),VectorScoreResult.score是两个音频之间的相似度得分。在 vector_api.py 中,服务端会检查向量实例是否为numpy.ndarray:若不是,则直接构造ErrorResponse实例并将错误描述写入error_reponse.message.description后返回——这是响应模型在运行时被手动实例化的典型用法;若是,则将向量通过audio_vec.tolist()转为 Python 列表填入result.vec。
3.6 ACS 响应:ACSResponse/AcsResult
音频内容搜索(Audio Content Search)接口使用ACSResponse,其result同时包含识别文本与分段对齐信息:
class AcsResult(BaseModel): transcription: str acs: list class ACSResponse(BaseModel): """ response example { "success": true, "code": 0, "message": { "description": "success" }, "result": { "transcription": "你好,飞桨" "acs": [(你好, 0.0, 0.45)] } } """ success: bool code: int message: Message result: AcsResult其中transcription为整段语音的识别结果,acs为(文本片段, 起始时间, 结束时间)形式的分段信息列表,可用于关键词定位与内容检索场景(对应 demos 目录下的 audio_content_search 示例)。
四、错误响应与错误码体系
4.1ErrorResponse:失败时的统一返回体
class ErrorResponse(BaseModel): """ response example { "success": false, "code": 0, "message": { "description": "Unknown error occurred." } } """ success: bool code: int message: Message与业务响应不同,ErrorResponse没有result字段,success恒为false。它被所有任务 API 以Union[XXXResponse, ErrorResponse]的方式声明为合法返回类型,例如 asr_api.py 中的response_model=Union[ASRResponse, ErrorResponse]。
4.2ErrorCode与failed_response
错误码枚举与失败响应的构造逻辑位于 paddlespeech/server/utils/errors.py:
class ErrorCode(IntEnum): SERVER_OK = 200 # success. SERVER_PARAM_ERR = 400 # Input parameters are not valid. SERVER_TASK_NOT_EXIST = 404 # Task is not exist. SERVER_INTERNAL_ERR = 500 # Internal error. SERVER_NETWORK_ERR = 502 # Network exception. SERVER_UNKOWN_ERR = 509 # Unknown error occurred.各任务 API 的异常处理模式高度一致(以asr_api.py为例):
except ServerBaseException as e: response = failed_response(e.error_code, e.msg) except BaseException: response = failed_response(ErrorCode.SERVER_UNKOWN_ERR) traceback.print_exc()failed_response(code, msg="")会从ErrorMsg映射表取出默认错误描述,构造形如{"success": False, "code": ..., "message": {"description": ...}}的 JSON,并以application/json类型返回。这套机制确保了"业务异常返回明确错误码、未知异常兜底为 509"的健壮行为。
五、响应模型在服务架构中的实际调用链
将各模块串联起来,一次 RESTful 调用的完整链路为:
- 客户端发起
POST /paddlespeech/<task>请求,FastAPI 依据路由声明(见 paddlespeech/server/restful/api.py 中的setup_router,它根据配置engine_list动态挂载各任务的APIRouter)将请求体解析为对应的 Request 模型; - 路由处理函数从 engine pool 获取任务引擎(如
engine_pool['asr']),创建 ConnectionHandler 执行推理; - 处理函数构造与 Response 模型结构完全一致的 Python 字典(如
{"success": True, "code": 200, "message": {...}, "result": {...}}); - FastAPI 依据
response_model=Union[XXXResponse, ErrorResponse]对返回字典进行校验与序列化,输出给客户端; - 若发生
ServerBaseException或其他异常,则走failed_response生成ErrorResponse结构的 JSON。
从源码结构可以推断:Response 模型不仅是文档与类型约束,还承担了 FastAPI 的响应校验职责——result字段缺失、类型不符等错误会在响应阶段被 Pydantic 拦截,从而保证客户端拿到的 JSON 永远是符合约定的。
六、实战验证:启动服务并观察响应
6.1 启动服务端
服务配置位于 paddlespeech/server/conf/application.yaml,默认监听0.0.0.0:8090,engine_list可同时包含多个任务(例如['asr_python', 'tts_python', 'cls_python', 'text_python', 'vector_python'])。启动命令:
paddlespeech_server start --config_file ./conf/application.yaml提示:若容器内服务启动正常但客户端访问 IP 不可达,可将配置中的
host改为本机 IP 地址(见 paddlespeech/server/README.md)。
6.2 使用官方客户端验证响应
# ASR:返回 result.transcription paddlespeech_client asr --server_ip 127.0.0.1 --port 8090 --input input_16k.wav # TTS:返回 result.audio(base64 音频)等字段 paddlespeech_client tts --server_ip 127.0.0.1 --port 8090 \ --input "你好,欢迎使用百度飞桨深度学习框架!" --output output.wav # CLS:返回 result.results 列表 paddlespeech_client cls --server_ip 127.0.0.1 --port 8090 --input input.wav # Vector:提取说话人向量 / 计算相似度得分 paddlespeech_client vector --task spk --server_ip 127.0.0.1 --port 8090 --input 85236145389.wav paddlespeech_client vector --task score --server_ip 127.0.0.1 --port 8090 \ --enroll 123456789.wav --test 85236145389.wav每个任务还提供GET /paddlespeech/<task>/help帮助接口(如 asr_api.py 中返回输入输出说明),便于联调时快速确认字段约定。你也可以用任意 HTTP 客户端直接构造 JSON 请求体(字段格式见 request.py 中的 docstring 示例)并对照本文的响应结构进行解析。
6.3 扩展自定义响应模型的建议
由于所有响应模型均为 PydanticBaseModel,若要为自定义任务扩展响应,可以参照response.py的模式:定义任务专属的XXXResult模型并挂到统一的XXXResponse外层结构下,然后在新增的 API 路由中声明response_model=Union[XXXResponse, ErrorResponse],并在 api.py 的setup_router中注册对应engine_list名称。这样即可复用服务端统一的错误处理与参数校验能力。
七、小结
paddlespeech/server/restful/response.py是 PaddleSpeech 服务端对外 API 的"响应契约":它以 Pydantic 模型固化了success / code / message / result的统一结构,覆盖 ASR、TTS、CLS、Text、Vector、ACS 六大任务,并配合ErrorResponse与 errors.py 中的ErrorCode/failed_response形成完整的成功/失败响应体系。理解这一模块,是二次开发 PaddleSpeech 服务端、编写客户端解析逻辑或排查接口异常的第一步。
【免费下载链接】PaddleSpeechEasy-to-use Speech Toolkit including Self-Supervised Learning model, SOTA/Streaming ASR with punctuation, Streaming TTS with text frontend, Speaker Verification System, End-to-End Speech Translation and Keyword Spotting. Won NAACL2022 Best Demo Award.项目地址: https://gitcode.com/gh_mirrors/pa/PaddleSpeech
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考