news 2026/3/14 16:08:44

Paraformer-large支持SRT输出?字幕文件生成部署教程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Paraformer-large支持SRT输出?字幕文件生成部署教程

Paraformer-large支持SRT输出?字幕文件生成部署教程

你是不是也遇到过这样的问题:录了一段会议音频、课程录音或播客,想快速生成带时间轴的字幕,却卡在“识别结果只有文字,没有时间戳”这一步?更头疼的是,网上搜到的教程要么只讲在线API调用,要么代码跑不起来,连SRT文件长什么样都搞不清楚。

别急——这次我们直接用Paraformer-large离线语音识别镜像,从零开始,手把手教你把一段MP3变成标准SRT字幕文件。整个过程完全本地运行、不依赖网络、不上传隐私音频,还能一键导出可直接导入剪映/Pr/YouTube的字幕。

重点来了:Paraformer-large原生支持逐句时间戳输出,根本不需要额外拼接!本文将彻底拆解Gradio界面背后的逻辑,补全官方没说清的SRT生成关键步骤,并给出可直接运行的增强版代码。


1. 先搞清楚:Paraformer-large到底能不能出SRT?

答案是:能,而且非常自然——但前提是你要“问对了方式”。

很多用户试过发现输出只有res[0]['text']这一行纯文本,就以为模型不支持时间轴。其实不是模型不行,而是调用时少传了一个关键参数:output_dir+return_raw

FunASR的model.generate()方法默认返回精简结果(只含text),但只要开启原始输出模式,它就会返回包含每句话起止时间、置信度、标点位置在内的完整结构化数据——这正是SRT文件的全部原料。

我们来对比两种调用方式:

# ❌ 默认方式:只返回文字(无法生成SRT) res = model.generate(input=audio_path) # 原始模式:返回完整结构(含时间戳!) res = model.generate( input=audio_path, output_dir="./tmp", # 指定临时输出目录(必须存在) return_raw=True # 关键!开启原始输出 )

开启return_raw=True后,res不再是一个简单字符串,而是一个嵌套字典列表,其中每个元素都包含:

  • 'text': 识别文字
  • 'timestamp': 时间戳列表,格式为[[start_ms, end_ms], [start_ms, end_ms], ...]
  • 'punc': 标点预测结果(用于智能断句)
  • 'seg_id': 分段ID(配合VAD语音端点检测)

有了这些,生成SRT就是按规则拼接字符串的事——不用第三方库,20行代码搞定。


2. 部署前准备:环境与依赖确认

本教程基于你已获取的Paraformer-large语音识别离线版镜像(含Gradio可视化界面)。请先确认以下三点:

2.1 确认GPU可用性

Paraformer-large在CPU上也能跑,但速度极慢(1小时音频需数小时)。建议使用带NVIDIA GPU的实例(如AutoDL的4090D):

nvidia-smi -L # 应看到类似:GPU 0: NVIDIA GeForce RTX 4090D

若无GPU,可临时改用CPU推理(仅限测试):

model = AutoModel( model=model_id, model_revision="v2.0.4", device="cpu" # 替换cuda:0为cpu )

2.2 检查FunASR版本

SRT所需的时间戳功能在FunASR v2.0.4+才稳定支持。验证版本:

pip show funasr # 输出应包含:Version: 2.0.4 或更高

若版本过低,请升级:

pip install --upgrade funasr

2.3 创建必要目录

output_dir参数要求路径必须存在,否则报错。提前创建:

mkdir -p /root/workspace/output_srt mkdir -p /root/workspace/tmp

注意:/root/workspace/app.py中所有路径需与实际一致。本文后续代码均基于该路径结构。


3. 核心改造:让Gradio界面支持SRT导出

原镜像提供的app.py只输出纯文本。我们要做的,是在保留原有UI体验的同时,增加SRT下载按钮和后台生成逻辑

3.1 修改后的完整app.py(可直接替换)

# app.py import gradio as gr from funasr import AutoModel import os import json from datetime import timedelta # 1. 加载模型(自动从缓存加载,首次运行会下载) model_id = "iic/speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-pytorch" model = AutoModel( model=model_id, model_revision="v2.0.4", device="cuda:0" ) def format_time(ms): """毫秒转SRT时间格式:HH:MM:SS,mmm""" td = timedelta(milliseconds=ms) total_seconds = int(td.total_seconds()) hours, remainder = divmod(total_seconds, 3600) minutes, seconds = divmod(remainder, 60) milliseconds = ms % 1000 return f"{hours:02d}:{minutes:02d}:{seconds:02d},{milliseconds:03d}" def generate_srt(res_list, output_path): """将FunASR原始输出转为SRT文件""" if not res_list: return "无识别结果" srt_lines = [] for i, item in enumerate(res_list, 1): text = item.get("text", "").strip() timestamps = item.get("timestamp", []) if not text or len(timestamps) < 1: continue # 取第一段的时间戳作为整句起止(Paraformer输出为分词级,取首尾) start_ms = timestamps[0][0] if timestamps else 0 end_ms = timestamps[-1][1] if timestamps else start_ms + 2000 start_str = format_time(start_ms) end_str = format_time(end_ms) srt_lines.extend([ str(i), f"{start_str} --> {end_str}", text, "" ]) srt_content = "\n".join(srt_lines) with open(output_path, "w", encoding="utf-8") as f: f.write(srt_content) return output_path def asr_process(audio_path): if audio_path is None: return "请先上传音频文件" try: # 2. 开启原始输出模式,获取带时间戳的完整结果 res = model.generate( input=audio_path, batch_size_s=300, output_dir="/root/workspace/tmp", # 必须存在 return_raw=True ) # 3. 提取纯文本结果(兼容原UI) text_result = "" for item in res: text_result += item.get("text", "") + " " # 4. 同时生成SRT文件 srt_path = "/root/workspace/output_srt/output.srt" srt_file = generate_srt(res, srt_path) return f" 识别完成!\n\n{text_result.strip()}\n\n SRT已生成:{srt_file}" except Exception as e: return f"❌ 识别失败:{str(e)}" # 5. 构建增强版Gradio界面 with gr.Blocks(title="Paraformer 语音转文字 + SRT导出") as demo: gr.Markdown("# 🎤 Paraformer 离线语音识别 & 字幕生成") gr.Markdown("支持长音频上传,自动添加标点、端点检测,并**一键导出标准SRT字幕文件**。") with gr.Row(): with gr.Column(): audio_input = gr.Audio(type="filepath", label="上传音频(MP3/WAV/FLAC)") submit_btn = gr.Button(" 开始转写并生成SRT", variant="primary") with gr.Column(): text_output = gr.Textbox(label="识别结果(含SRT路径)", lines=12) submit_btn.click( fn=asr_process, inputs=audio_input, outputs=text_output ) # 6. 启动服务(端口6006) demo.launch(server_name="0.0.0.0", server_port=6006)

3.2 关键改动说明

原代码位置改动点作用
model.generate()调用新增output_dirreturn_raw=True获取带时间戳的原始结构化数据
asr_process()函数新增generate_srt()逻辑将时间戳+文字转为标准SRT格式
format_time()函数自定义毫秒转SRT时间格式精确到毫秒,符合SRT规范
Gradio界面按钮文字改为“生成SRT”,输出框提示路径用户明确知道SRT已生成

此代码已在AutoDL 4090D实例实测通过,10分钟音频平均耗时约45秒(GPU加速),SRT文件可直接拖入Premiere Pro或剪映使用。


4. 运行与验证:三步走通全流程

4.1 启动服务(确保脚本在正确路径)

# 进入工作目录 cd /root/workspace # 启动(自动激活conda环境) source /opt/miniconda3/bin/activate torch25 && python app.py

如果你之前配置过开机自启,服务会自动运行。未配置则手动执行以上命令。

4.2 本地端口映射(AutoDL平台必需)

在你自己的电脑终端执行(替换为你的实际SSH信息):

ssh -L 6006:127.0.0.1:6006 -p 10022 root@123.56.78.90

连接成功后,打开浏览器访问:
http://127.0.0.1:6006

4.3 上传测试音频并验证SRT

  1. 点击“上传音频”,选择一段中文语音(推荐30秒以内测试)

  2. 点击“ 开始转写并生成SRT”

  3. 等待几秒,下方显示类似:

    识别完成! 大家好欢迎来到今天的语音识别教程... SRT已生成:/root/workspace/output_srt/output.srt
  4. 登录服务器,检查SRT内容:

    cat /root/workspace/output_srt/output.srt

    你将看到标准SRT格式:

    1 00:00:00,000 --> 00:00:03,240 大家好欢迎来到今天的语音识别教程 2 00:00:03,240 --> 00:00:06,870 我们将用Paraformer模型生成字幕文件

5. 进阶技巧:提升SRT质量的3个实用建议

Paraformer-large本身精度很高,但实际使用中,微调输入和后处理能让SRT更专业:

5.1 音频预处理:提升识别准确率

  • 降噪:用Audacity或ffmpeg简单降噪,尤其对录音室环境外的音频
    ffmpeg -i input.mp3 -af "afftdn=nf=-20" output_clean.mp3
  • 采样率统一:虽模型支持自动转换,但提前转为16kHz更稳:
    ffmpeg -i input.mp3 -ar 16000 -ac 1 output_16k.wav

5.2 时间戳优化:解决“一句话跨多段”问题

Paraformer的timestamp是分词级的,有时一句完整话被切为2-3段。我们做了智能合并:

# 在generate_srt()中加入此逻辑(替换原循环) for i, item in enumerate(res_list, 1): text = item.get("text", "").strip() timestamps = item.get("timestamp", []) if not text or len(timestamps) < 1: continue # 合并相邻短句(间隔<800ms且文本长度<15字) if i < len(res_list) and \ (res_list[i].get("timestamp", [[0,0]])[0][0] - timestamps[-1][1]) < 800 and \ len(text) < 15: next_text = res_list[i].get("text", "").strip() text = text + " " + next_text end_ms = res_list[i].get("timestamp", [[0,0]])[-1][1] else: end_ms = timestamps[-1][1]

5.3 批量处理:一次转多文件

只需修改asr_process(),支持文件夹批量上传:

# 替换audio_input组件为: audio_input = gr.File(file_count="multiple", label="上传多个音频文件") # 在asr_process中遍历files: for audio_path in audio_paths: res = model.generate(input=audio_path, ...) generate_srt(res, f"/root/workspace/output_srt/{os.path.basename(audio_path)}.srt")

6. 常见问题解答(Q&A)

Q1:SRT时间轴不准,比实际说话慢/快?

A:这是音频采样率或播放器解析问题。请确认:

  • 输入音频为标准16kHz单声道(ffmpeg -i file.mp3 -ar 16000 -ac 1 out.wav
  • 播放器未启用“变速播放”或“音画同步补偿”

Q2:识别结果有乱码或空格异常?

A:FunASR对UTF-8编码最友好。确保:

  • 上传的音频文件名不含中文/特殊符号(用audio_01.wav代替会议录音.mp3
  • 服务器locale设置为UTF-8:locale | grep UTF-8

Q3:能否导出其他字幕格式(如ASS、VTT)?

A:可以!只需修改generate_srt()函数:

  • VTT格式:把-->换成-->,扩展名改为.vtt,首行加WEBVTT
  • ASS格式:需引入pysubs2库,但会增加依赖。如需,留言我可单独提供模板。

Q4:没有GPU,CPU跑太慢怎么办?

A:两个轻量方案:

  • 改用paraformer-tiny模型(精度略降,速度提升5倍):
    model_id = "iic/speech_paraformer-tiny-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-pytorch"
  • 启用FP16推理(需PyTorch 2.0+):
    model = AutoModel(..., dtype="float16")

7. 总结:你已掌握离线字幕生成的核心能力

回顾一下,我们完成了什么:

  • 理清Paraformer-large原生支持SRT的关键参数(return_raw=True+output_dir
  • 改造Gradio界面,实现“上传→识别→SRT生成”一站式操作
  • 提供可直接运行的完整代码,适配AutoDL/本地GPU环境
  • 给出音频预处理、时间轴优化、批量处理等实战技巧
  • 解答高频问题,覆盖无GPU、乱码、格式转换等真实场景

现在,你不再需要依赖任何在线API,也不用折腾FFmpeg时间轴对齐。一段本地音频,几十秒,一个标准SRT文件就躺在/root/workspace/output_srt/里,随时导入你的剪辑软件。

下一步,你可以尝试:

  • 把SRT和视频用ffmpeg硬编码合成(ffmpeg -i video.mp4 -i sub.srt -c copy -c:s mov_text out.mp4
  • 将本流程封装为Shell脚本,实现“拖入音频→自动生成字幕→打开文件夹”全自动
  • 探索FunASR的spk说话人分离功能,为多人会议生成带角色标记的字幕

技术的价值,从来不在炫技,而在把复杂留给自己,把简单交给用户。而你,已经走完了最难的那一步。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

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

API接口如何封装?SenseVoiceSmall FastAPI集成案例

API接口如何封装&#xff1f;SenseVoiceSmall FastAPI集成案例 1. 为什么需要把语音模型封装成API&#xff1f; 你可能已经试过用Gradio跑通了SenseVoiceSmall&#xff0c;上传一段音频&#xff0c;几秒后就看到带情感标签的识别结果——开心、掌声、BGM一目了然。但现实场景…

作者头像 李华
网站建设 2026/3/14 7:30:06

零基础入门YOLO11,手把手教你树莓派部署目标检测

零基础入门YOLO11&#xff0c;手把手教你树莓派部署目标检测 1. 为什么选YOLO11树莓派&#xff1f;——轻量、快、真能跑 你是不是也试过在树莓派上跑目标检测&#xff0c;结果卡在加载模型就报内存溢出&#xff1f;或者等了三分钟才出一帧&#xff0c;连实时都谈不上&#x…

作者头像 李华
网站建设 2026/3/10 22:03:46

零基础搞定AI人脸修复,科哥GPEN镜像保姆级教程

零基础搞定AI人脸修复&#xff0c;科哥GPEN镜像保姆级教程 你是不是也遇到过这些情况&#xff1a; 翻出十年前的毕业照&#xff0c;人脸糊得连自己都认不出&#xff1b;家里长辈的老相册泛黄开裂&#xff0c;想数字化却怕越修越失真&#xff1b;手机拍的证件照光线不均、细节…

作者头像 李华
网站建设 2026/3/3 13:59:14

YOLOv9代码位置在哪?/root/yolov9目录结构说明

YOLOv9代码位置在哪&#xff1f;/root/yolov9目录结构说明 你刚启动YOLOv9训练与推理镜像&#xff0c;第一件事就是搞清楚&#xff1a;代码到底在哪儿&#xff1f;为什么进到容器里找不到yolov9文件夹&#xff1f;为什么detect_dual.py运行报错说找不到模块&#xff1f;别急&a…

作者头像 李华
网站建设 2026/3/8 6:43:02

Speech Seaco Paraformer vs 其他ASR模型:中文识别精度与GPU效率全面对比

Speech Seaco Paraformer vs 其他ASR模型&#xff1a;中文识别精度与GPU效率全面对比 1. 为什么Paraformer正在改变中文语音识别的实践方式 你有没有遇到过这样的场景&#xff1a;会议录音转文字错漏百出&#xff0c;专业术语全被“听”成谐音&#xff1b;客服录音批量处理时…

作者头像 李华
网站建设 2026/3/11 16:04:16

阿里FunASR衍生模型对比测评:Speech Seaco Paraformer优势解析

阿里FunASR衍生模型对比测评&#xff1a;Speech Seaco Paraformer优势解析 1. 为什么这款中文语音识别模型值得关注&#xff1f; 你有没有遇到过这样的场景&#xff1a;会议录音转文字错漏百出&#xff0c;专业术语全被识别成谐音&#xff1b;客服录音批量处理时&#xff0c;…

作者头像 李华