- 人工智能
- 语音
- 音频
- NLP
- 媒体生成
【免费下载链接】PaddleSpeech
Easy-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.
导读
视频字幕自动生成是语音识别(ASR)在实际场景中最直接的应用之一:给定一段带语音的视频,无需人工转写即可自动得到带标点的字幕文本。本文将基于 PaddleSpeech 仓库中的 automatic_video_subtitiles demo,完整讲解从视频下载、音频抽取、语音识别到标点恢复的端到端流程,并深入源码剖析ASRExecutor与TextExecutor的底层调用链,帮助读者掌握用单条命令或几行 Python 代码为任意视频生成字幕的完整方案。
一、Demo 整体流程与原理
视频字幕生成的核心思路是:先把视频中的语音轨道转成标准音频,再用 ASR 模型把语音转成无标点文本,最后通过标点恢复模型为文本添加标点,得到可直接用于字幕渲染的文本。
整个流程在 run.sh 中体现得十分清晰,包含四个关键环节:
- 下载视频:通过
wget获取包含目标语言语音的视频文件; - 抽取音频:用
ffmpeg将视频中的音轨提取为单声道(1 channel)、16kHz 采样率的.wav文件; - 语音识别(ASR):调用
ASRExecutor将wav转为文本; - 标点恢复(Punctuation Restoration):调用
TextExecutor为识别文本补全标点。
其中步骤 3、4 分别对应 PaddleSpeech 的asr与text两个任务,两者通过paddlespeech.cli下定义的执行器(Executor)封装,用户既可以在 Python 中直接调用,也可以通过命令行使用,还可以借助仓库自带的脚本一键完成。
二、环境准备与安装
在使用 demo 前,需要先安装 PaddleSpeech 及其依赖。官方提供了三档安装方式(easy / medium / hard),详见仓库中的 英文安装文档 与 中文安装文档:
- easy:通过
pip install paddlespeech安装发布包,适合只想快速体验的开发者; - medium:在安装发布包基础上额外安装
kaldi等可选依赖,覆盖更多功能; - hard:从源码编译安装,适合需要定制或参与开发的场景。
此外,由于 demo 需要处理视频文件,还需要确保环境中已安装ffmpeg(用于音视频抽取)和wget(用于下载示例视频)。若希望启用 GPU 推理,还需要安装匹配版本的 PaddlePaddle GPU 版本,并在调用时通过device参数指定。
三、准备输入:从视频到标准 WAV
PaddleSpeech 的 ASR 模型对输入音频有明确要求:16kHz、16bit、单声道 WAV。因此第一步是获取视频,第二步是用 ffmpeg 完成音频抽取与重采样。
3.1 下载示例视频
demo 提供了一个可直接下载的中文示例视频:
wget -c https://paddlespeech.cdn.bcebos.com/demos/asr_demos/subtitle_demo1.mp4实际使用中可将该命令替换为任何包含目标语言语音的视频文件。
3.2 抽取单声道 16kHz 音频
ffmpeg -i subtitle_demo1.mp4 -ac 1 -ar 16000 -vn input.wav各参数含义如下:
| 参数 | 含义 |
|---|---|
-i subtitle_demo1.mp4 | 指定输入视频文件 |
-ac 1 | 强制输出为单声道(1 channel) |
-ar 16000 | 强制输出采样率为 16000 Hz |
-vn | 丢弃视频流,只保留音频 |
input.wav | 输出的 WAV 文件 |
这一步之所以至关重要,是因为 ASR 前端特征(Fbank)直接依赖采样率。虽然ASRExecutor内部具备自动重采样能力(见第五节源码分析),但预先输出符合模型要求的 WAV 能避免额外转换带来的精度损耗。
四、三种使用方式
demo 提供了 Python API、一键脚本和命令行三种使用路径,覆盖从入门到集成的全部需求。
4.1 方式一:Python API(README 原始用法)
这是 README 中给出的核心用法,全部代码仅需几行:
import paddle from paddlespeech.cli.asr import ASRExecutor from paddlespeech.cli.text import TextExecutor asr_executor = ASRExecutor() text_executor = TextExecutor() text = asr_executor( audio_file='input.wav', device=paddle.get_device()) result = text_executor( text=text, task='punc', model='ernie_linear_p3_wudao', device=paddle.get_device()) print('Text Result: \n{}'.format(result))执行后输出示例(来自 README):
Text Result: 当我说我可以把三十年的经验变成一个准确的算法,他们说不可能。当我说我们十个人就能实现对十九个城市变电站七乘二十四小时的实时监管,他们说不可能。可以看到:第一段调用完成了语音到文字的识别,第二段调用为无标点文本补全了逗号、句号,两者组合即得到可直接使用的字幕文本。paddle.get_device()会自动返回当前可用的设备(如cpu或gpu:0)。
4.2 方式二:一键脚本(run.sh + recognize.py)
仓库在 run.sh 中把下载、抽取、识别封装成了一键脚本:
#!/bin/bash video_url=https://paddlespeech.cdn.bcebos.com/demos/asr_demos/subtitle_demo1.mp4 video_file=$(basename ${video_url}) audio_file=$(echo ${video_file} | awk -F'.' '{print $1}').wav num_channels=1 sr=16000 # Download video if [ ! -f ${video_file} ]; then wget -c ${video_url} fi # Extract audio from video if [ ! -f ${audio_file} ]; then ffmpeg -i ${video_file} -ac ${num_channels} -ar ${sr} -vn ${audio_file} fi python -u recognize.py --input ${audio_file} exit 0脚本通过if [ ! -f ... ]判断实现断点续传与幂等性:视频和音频已存在时跳过下载与抽取,直接进入识别。其对应的 recognize.py 则对 README 中的 Python 代码做了命令行参数化增强:
import argparse import os import paddle from paddlespeech.cli.asr import ASRExecutor from paddlespeech.cli.text import TextExecutor parser = argparse.ArgumentParser(__doc__) parser.add_argument("--input", type=str, required=True) parser.add_argument("--device", type=str, default=paddle.get_device()) args = parser.parse_args() if __name__ == "__main__": asr_executor = ASRExecutor() text_executor = TextExecutor() text = asr_executor( audio_file=os.path.abspath(os.path.expanduser(args.input)), device=args.device) result = text_executor( text=text, task='punc', model='ernie_linear_p3_wudao', device=args.device) print('ASR Result: \n{}'.format(text)) print('Text Result: \n{}'.format(result))与 README 中直接传入相对路径不同,这里通过os.path.abspath(os.path.expanduser(args.input))将输入路径规范化为绝对路径,支持~/xxx.wav这类带波浪号的路径。运行方式:
bash run.sh # 或手动指定音频 python recognize.py --input input.wav --device cpu4.3 方式三:纯命令行
PaddleSpeech 为每个任务都注册了 CLI 入口(命令分发逻辑见 entry.py)。根据 CLI 使用文档,上述流程可完全用命令行完成,无需编写 Python:
# 第一步:语音识别 paddlespeech asr --lang zh --input input_16k.wav # 第二步:标点恢复 paddlespeech text --task punc --input 今天的天气真不错啊你下午有空吗我想约你一起去吃饭其中paddlespeech text默认使用ernie_linear_p7_wudao模型,也可通过--model切换为与 demo 一致的ernie_linear_p3_wudao(或追求更快的ernie_linear_p3_wudao_fast)。这种方式适合在 shell 脚本或 CI 流水线中直接集成。
五、源码剖析:ASRExecutor 的识别流水线
demo 之所以能「几行代码跑通」,依赖于 paddlespeech/cli/asr/infer.py 中ASRExecutor对「资源加载 → 校验 → 预处理 → 推理 → 后处理」五个阶段的封装。其继承自 executor.py 中的BaseExecutor抽象基类。
5.1 默认参数与可选参数
ASRExecutor在__init__中通过argparse定义了完整参数集,其中默认值直接决定了 demo 的行为:
| 参数 | 默认值 | 说明 |
|---|---|---|
--model | conformer_u2pp_online_wenetspeech | 默认使用基于 WenetSpeech 训练的 U2++ Conformer 流式/离线两用模型 |
--lang | zh | 语言,可选zh、en、zh_en |
--codeswitch | False | 是否启用中英文混语 code-switch |
--sample_rate | 16000 | 采样率,可选8000、16000 |
--decode_method | attention_rescoring | 解码方式,可选ctc_greedy_search、ctc_prefix_beam_search、attention、attention_rescoring |
--device | paddle.get_device() | 推理设备 |
值得注意的是 demo 的 Python 调用只传了audio_file和device,其余全部走默认值,这正体现了 Executor 设计上的「开箱即用」特性。
5.2 资源自动下载与模型加载(_init_from_path)
当未显式传入cfg_path/ckpt_path时,_init_from_path会根据model_type-lang-sample_rate的组合(如conformer_u2pp_online_wenetspeech-zh-16k)自动从CommonTaskResource中查找并下载预训练模型、配置与权重,然后:
- 用
CfgNode.merge_from_file读取模型 YAML 配置; - 通过
TextFeaturizer构建词表/SPM 前端; - 依据模型类型(
deepspeech2/conformer/transformer)从配置反序列化模型结构并加载.pdparams权重; - 对 transformer 类模型计算最大可处理时长
self.max_len(由 subsample 率、帧移与位置编码最大长度共同决定)。
5.3 音频校验与自动重采样(_check)
_check方法对输入音频做了三道把关,这部分对 demo 实践非常关键:
- 时长限制:从源码可见
self.max_len = 50(秒)为默认上限,超过 50 秒的音频会被拒绝,并提示Please input audio file less then 50 seconds。对于长视频,需要先做分段处理(如按句切分或按固定时长切窗),这也是「自动字幕」落地时最常见的工程点; - 格式校验:
soundfile.read无法打开的文件会提示使用sox转换格式,例如sox input.xx --rate 16k --bits 16 --channels 1 output.wav; - 重采样确认:当输入采样率与
--sample_rate不一致时,程序会交互式询问Input(Y/N)是否自动重采样;若在 CLI 中附加--yes参数则可跳过询问直接转换。
从preprocess的实现可以看到重采样的具体路径:soundfile.read以 int16 读入 → 多声道取均值 →_pcm16to32转浮点 →librosa.resample重采样 →_pcm32to16还原 int16 → 再经Transformation提取 Fbank 特征并封装为paddle.Tensor。
5.4 解码与输出(infer / postprocess)
infer在@paddle.no_grad()下执行模型前向:对 transformer 类模型,调用model.decode并传入decoding_method、beam_size、ctc_weight、decoding_chunk_size等解码参数(均来自模型配置中的decode段),最终postprocess返回首个识别结果字符串。
此外,ASRExecutor还内置了--rtf选项用于统计实时率(Real-time Factor),帮助评估推理速度;支持.txt/.scp/.job批量输入文件(每行id path格式),便于对整批视频/音频批量生成字幕。
六、源码剖析:TextExecutor 的标点恢复
ASR 直接输出的文本通常没有标点,直接渲染字幕会严重影响可读性,因此 demo 的第二段调用至关重要。其实现位于 paddlespeech/cli/text/infer.py。
6.1 参数与模型选择
result = text_executor( text=text, task='punc', model='ernie_linear_p3_wudao', device=paddle.get_device())task目前仅支持'punc'(标点恢复);model='ernie_linear_p3_wudao'指定基于 ERNIE 的线性标点模型(demo 所用);该 Executor 的默认模型是ernie_linear_p7_wudao;- 在
__call__中,ernie_linear_p7_wudao与ernie_linear_p3_wudao走旧版初始化路径,其余模型走_init_from_path_new新路径——两者在 tokenizer 选择(ernie-1.0或快速版ernie-3.0-mini-zh)上存在差异。
6.2 标点预测的调用链
从源码可以看到完整处理链:
_init_from_path:从资源目录加载配置、权重和标点词表vocab_file(每行一个标点符号),实例化ErnieLinear模型与 ERNIE tokenizer;_clean_text:将文本小写化并过滤非字母数字/中文字符,同时剔除已有标点;preprocess:用 tokenizer 将文本切分为 token 序列,得到input_ids、seg_ids、seq_len;infer:paddle.argmax(logits, axis=-1)为每个 token 预测一个标点类别;postprocess:将预测类别映射回标点词表,在非零类别对应的 token 后插入标点,l != 0表示该位置需要插入标点,最终拼出带标点的完整文本。
6.3 标点词表
从_punc_list的加载逻辑(跳过首行、索引 0 为无标点)可以推断,标点词表通常包含,。!?等常用中文标点。demo 输出中的「,」「。」正是由该模型在识别文本的合适位置插入的。
七、进阶实践建议
7.1 长视频处理
由于ASRExecutor默认限制单段音频不超过 50 秒,处理完整视频字幕时需要先按静音或固定时长将长音频切分为短段,逐段识别后再按时间轴合并成字幕文件(如 SRT 格式)。PaddleSpeech 仓库中的 streaming_asr_server demo 与 speech_recognition demo 提供了长音频/流式场景的更多参考实现。
7.2 模型与语言扩展
- 识别英文视频时,可在 ASR 调用中指定
lang='en'(对应transformer_librispeech-en-16k模型),或使用lang='zh_en'配合codeswitch=True处理中英混语; - 标点恢复可切换
ernie_linear_p3_wudao_fast以获得更快的推理速度; - 有自定义模型时,可通过
config与ckpt_path显式传入配置文件与权重路径,跳过自动下载。
7.3 批量处理与速度评估
在 CLI 中,ASR 支持传入.txt/.scp批量清单文件,配合--rtf参数可以统计批处理的平均实时率;-d参数可将结果落盘保存,便于后续生成字幕文件。
八、总结
视频自动字幕生成是 ASR 技术落地最直观的场景之一。通过本文可以确认:PaddleSpeech 将「语音识别(ASRExecutor)」与「标点恢复(TextExecutor)」封装为统一执行器,配合 ffmpeg 的音频抽取,即可用一条命令或几行 Python完成从视频到带标点字幕文本的全流程;同时,recognize.py 与 run.sh 展示了参数化与自动化封装的工程实践,源码中关于采样率校验、50 秒时长限制、批量输入等细节则为长视频字幕落地提供了明确的技术边界与扩展方向。
- 人工智能
- 语音
- 音频
- NLP
- 媒体生成
【免费下载链接】PaddleSpeech
Easy-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.
相关推荐
PaddleSpeech 视频自动字幕生成实战:从视频语音识别到标点恢复的完整流程
PaddleSpeech 视频自动字幕生成实战:从视频语音识别到标点恢复的完整流程 导读 视频字幕生成(Automatic Video Subtitles)是指
人工智能语音音频PaddleSpeech 流式语音识别服务实战:基于 WebSocket 的流式 ASR、标点预测与 SRT 字幕生成完整指南
PaddleSpeech 流式语音识别服务实战:基于 WebSocket 的流式 ASR、标点预测与 SRT 字幕生成完整指南 本指南围绕 PaddleSpee
人工智能语音音频NLP媒体生成FlatBuffers TypeScript 使用指南:从 Schema 生成、缓冲区读写到 Object Based API 实战
FlatBuffers TypeScript 使用指南:从 Schema 生成、缓冲区读写到 Object Based API 实战 本文以 FlatBuffe
人工智能语音音频
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考