news 2026/9/23 7:46:48

PaddleSpeech 视频自动字幕生成实战:基于 ASR 与标点恢复的完整流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PaddleSpeech 视频自动字幕生成实战:基于 ASR 与标点恢复的完整流程
  • 人工智能
  • 语音
  • 音频
  • 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.

项目地址:https://gitcode.com/paddlepaddle/PaddleSpeech
点击查看免费下载

导读

视频字幕自动生成是语音识别(ASR)在实际场景中最直接的应用之一:给定一段带语音的视频,无需人工转写即可自动得到带标点的字幕文本。本文将基于 PaddleSpeech 仓库中的 automatic_video_subtitiles demo,完整讲解从视频下载、音频抽取、语音识别到标点恢复的端到端流程,并深入源码剖析ASRExecutorTextExecutor的底层调用链,帮助读者掌握用单条命令或几行 Python 代码为任意视频生成字幕的完整方案。

一、Demo 整体流程与原理

视频字幕生成的核心思路是:先把视频中的语音轨道转成标准音频,再用 ASR 模型把语音转成无标点文本,最后通过标点恢复模型为文本添加标点,得到可直接用于字幕渲染的文本。

整个流程在 run.sh 中体现得十分清晰,包含四个关键环节:

  1. 下载视频:通过wget获取包含目标语言语音的视频文件;
  2. 抽取音频:用ffmpeg将视频中的音轨提取为单声道(1 channel)、16kHz 采样率.wav文件;
  3. 语音识别(ASR):调用ASRExecutorwav转为文本;
  4. 标点恢复(Punctuation Restoration):调用TextExecutor为识别文本补全标点。

其中步骤 3、4 分别对应 PaddleSpeech 的asrtext两个任务,两者通过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()会自动返回当前可用的设备(如cpugpu: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 cpu

4.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 的行为:

参数默认值说明
--modelconformer_u2pp_online_wenetspeech默认使用基于 WenetSpeech 训练的 U2++ Conformer 流式/离线两用模型
--langzh语言,可选zhenzh_en
--codeswitchFalse是否启用中英文混语 code-switch
--sample_rate16000采样率,可选800016000
--decode_methodattention_rescoring解码方式,可选ctc_greedy_searchctc_prefix_beam_searchattentionattention_rescoring
--devicepaddle.get_device()推理设备

值得注意的是 demo 的 Python 调用只传了audio_filedevice,其余全部走默认值,这正体现了 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 实践非常关键:

  1. 时长限制:从源码可见self.max_len = 50(秒)为默认上限,超过 50 秒的音频会被拒绝,并提示Please input audio file less then 50 seconds对于长视频,需要先做分段处理(如按句切分或按固定时长切窗),这也是「自动字幕」落地时最常见的工程点;
  2. 格式校验soundfile.read无法打开的文件会提示使用sox转换格式,例如sox input.xx --rate 16k --bits 16 --channels 1 output.wav
  3. 重采样确认:当输入采样率与--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_methodbeam_sizectc_weightdecoding_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_wudaoernie_linear_p3_wudao走旧版初始化路径,其余模型走_init_from_path_new新路径——两者在 tokenizer 选择(ernie-1.0或快速版ernie-3.0-mini-zh)上存在差异。

6.2 标点预测的调用链

从源码可以看到完整处理链:

  1. _init_from_path:从资源目录加载配置、权重和标点词表vocab_file(每行一个标点符号),实例化ErnieLinear模型与 ERNIE tokenizer;
  2. _clean_text:将文本小写化并过滤非字母数字/中文字符,同时剔除已有标点;
  3. preprocess:用 tokenizer 将文本切分为 token 序列,得到input_idsseg_idsseq_len
  4. inferpaddle.argmax(logits, axis=-1)为每个 token 预测一个标点类别;
  5. 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以获得更快的推理速度;
  • 有自定义模型时,可通过configckpt_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.

项目地址:https://gitcode.com/paddlepaddle/PaddleSpeech
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/23 7:45:53

6GB显存跑35B MoE:FreeToken极限优化配置实测

6GB显存跑35B参数量的MoE模型,放在两年前我会觉得这是段子。Full精度下光模型权重就要70GB,哪怕做4bit量化也还要20GB上下,怎么看都和6GB不搭边。但MoE架构把这个"不可能"变成了"有条件地可能"——35B是总参数&#xff0…

作者头像 李华
网站建设 2026/9/23 7:45:42

Labelme转YOLOv8语义分割数据集:Python脚本实战指南

简介:基于Python开发,可将Labelme标注格式转换为YoloV8语义分割数据集,并自动完成训练集与验证集的划分,极大减少人工整理标注数据的时间。面向计算机视觉学习者、高校师生、科研人员以及正在准备毕业设计或课程设计的学生&#x…

作者头像 李华
网站建设 2026/9/23 7:44:13

多机器人覆盖路径规划:蒙特卡洛树搜索实战指南

简介:本资源面向计算机、人工智能、自动化等专业的在校学生与研究人员,提供一套基于蒙特卡洛树搜索算法实现多机器人区域覆盖路径规划的完整项目源码,可用于课程设计、毕业设计或算法学习进阶。压缩包共6个文件,包含4个Python脚本…

作者头像 李华
网站建设 2026/9/23 7:43:52

基于 Java Spring Boot 的关爱自闭症儿童服务平台设计与实现

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 1. 项目背景与意义 自闭症谱系障碍是一种广泛性发育障碍,近年来发病率呈上升趋势。由于自闭症儿童在社交沟通、行为模式等方面存在特殊需求,其家…

作者头像 李华