
给素材库加语音转写Whisper 本地部署与批量字幕生成实践你大概也有过这种时刻明明记得三个月前录过一段讲素材命名的口播里面有个特别妙的比喻可翻遍硬盘面对几十个DSC_0417.mp4毫无头绪最后只能从头再看一遍。视频这种格式内容再好检索性也是零——除非你把它变成文字。这篇记录我给素材库加语音转写的全过程本地部署、批量脚本、SRT 处理以及转写文本怎么反过来变成素材库的检索入口。 文章目录一、Whisper 是什么一句话原理二、本地部署与模型选择三、批量转写脚本四、SRT 格式处理五、转写文本如何成为素材检索的素材常见问题 FAQ写在最后 一、Whisper 是什么一句话原理Whisper 是 OpenAI 开源的语音识别模型原理一句话讲完用约 68 万小时的多语言弱监督音频训练出的 encoder-decoder Transformer把 30 秒音频段直接映射成文本 token。因为它吃过大量真实世界的口语、噪声、中英混杂数据不需要针对你的素材做任何微调开箱就能用——对只想解决问题的创作者来说这是决定性优点。拆开再讲两句帮你建立正确预期。第一它对烂音频的耐受度远超传统方案背景音乐、键盘敲击、窗外车流识别率会下降但不会崩盘因为训练数据里本来就混着大量真实噪声——你不需要先做一段降噪预处理直接丢给它是更省事也更不容易失真的做法。第二它的 30 秒分段机制决定了两个边界超长的句子会被硬切长静音段可能被跳过甚至出现幻听——明明没人说话输出里却冒出一句谢谢观看。知道这两点后面处理 SRT 时你就不会奇怪字幕为什么会跳时间或者凭空多出一句。 二、本地部署与模型选择部署本体只需要一行pipinstall-Uopenai-whisper# 依赖 ffmpeg没装的话先brew install ffmpegmacOS一个小提醒给转写环境单独建一个虚拟环境别装进系统 Python——Whisper 的依赖尤其 torch 一家版本要求挑剔和别的项目混装迟早打架报错信息还往往指鹿为马。建环境一条命令的事能省掉日后无数排错时间。单个文件立即可以转whisper input.mp4--modelmedium--languagezh--output_formatsrt模型选择直接决定速度和质量的平衡模型参数量显存需求中文效果适用场景tiny / base39M / 74M1GB错误较多快速出草稿、纯英文内容small244M~2GB可用CPU 机器的务实选择medium769M~5GB较好口播转写的甜点位large-v31.55B~10GB最好有显卡、追求字幕直接可用我的结论中文口播 medium 起步无独显就用 small配合 faster-whisper 还能再提速。补充一个容易被忽略的点模型文件是全局缓存的装一次 medium 之后所有项目共用不会每个目录重复下载真正要规划的是显存——单条转写任务 medium 约占 5 GB如果你想边转写边开剪辑软件8 GB 显存的卡就开始捉襟见肘这时候要么让转写任务排队跑要么退回 small。第一次运行会先下载模型到本地缓存medium 约 1.5 GB之后完全离线可用。一次完整的转写过程长这样$ whisper input.mp4 --model medium --language zh --output_format srt 100%|██████████| 297600/297600 [02:41.20, 1842.30frames/s]3 分钟的口播medium 在 RTX 3060 上跑了 2 分 41 秒大约实时速度输出就是同名的input.srt打开是标准三行结构序号、时间轴、文本。同样的文件换成 CPUM 系列芯片的 Mac耗时涨到 8–10 分钟——这就是后文推荐 faster-whisper 的原因模型相同工程实现不同速度差三到四倍。思考 模型是不是越大越好一步到位上 large-v3 显存和耐心都得跟得上。large-v3 中文确实更准但速度约为 medium 的三分之一CPU 上基本没法用。我的建议是先跑 medium 看错误类型如果是同音字错升级模型有用如果是专有名词错产品名、人名多大的模型都救不了得靠后期修正——那就没必要为用不上的提升买单。 三、批量转写脚本单个文件转写没有门槛工程量在让整个素材库都过一遍。一个支持断点续跑的批处理脚本importsubprocessfrompathlibimportPath LIBPath(/data/videos)# 素材库根目录MODELmediumforfinsorted(LIB.rglob(*.mp4)):srtf.with_suffix(.srt)ifsrt.exists():# 断点续跑有结果就跳过continuesubprocess.run([whisper,str(f),--model,MODEL,--language,zh,--output_format,srt,--output_dir,str(f.parent)],checkTrue)print(ftranscribed:{f.name})三个细节跳过已存在结果让脚本可随时中断重跑几百个文件的批任务必须留这个后门--language zh显式指定语言避免短音频被误判嫌官方实现慢就换 faster-whisperCTranslate2 重写版同模型 int8 量化在 CPU 上能快 3–4 倍pipinstallfaster-whisper# faster-whisper 提供 Python API参数与官方版基本对应换 faster-whisper 之后我把常用参数固化成了这样fromfaster_whisperimportWhisperModel modelWhisperModel(medium,devicecuda,compute_typeint8_float16)segments,infomodel.transcribe(input.mp4,languagezh,beam_size5,vad_filterTrue,condition_on_previous_textFalse,)几个参数的取舍直接列成调优表参数默认值我的建议作用beam_size5保持 5束搜索宽度越大越准也越慢超过 5 收益很小vad_filter关闭开启先用静音检测切分消灭大部分幻听和长静音误判condition_on_previous_text开启关闭切断上文传递避免一处错认连累后文compute_typefloat16int8_float16量化档位速度与质量的折中点脚本本身的工程细节也值得展开。rglob(*.mp4)递归遍历子目录素材库无论套多少层文件夹都能扫到但要顺手把.mov、.mkv加进后缀列表否则苹果设备录制的原生格式会被漏掉。checkTrue让子进程失败时立刻抛异常停下——批处理最忌讳带病狂奔一个文件损坏还继续跑几百个文件的输出可能全是残次品。真实跑一次的规模感我的素材库 214 个视频、约 6 小时素材medium 加独显挂机 4 小时跑完平均每个文件不到 70 秒第二天醒来多出 214 个同名 srt。批处理跑起来之后的报错八成逃不出下面这张表报错信息常见成因解决办法找不到 ffmpeg 可执行文件系统没装或不在环境变量里macOS 先装 ffmpegWindows 安装后把目录加进环境变量显存不足直接退出模型太大塞不进显存降级模型medium 换 small或指定用 CPU 跑中文转出来是繁体字训练数据里繁体、粤语样本的干扰加--initial_prompt 以下是普通话的句子。引导简体输出一句话原地重复十几条上文条件把错误传递给了后续段落关闭上文条件或开启 VAD 先切静音思考 为什么转写结果要和素材同名、放同目录 因为字幕是素材的附属资产。文件名和路径是最低成本的主外键——素材挪到哪字幕跟到哪任何工具都能通过同名约定找到它不依赖数据库。反例是集中存放方案把所有字幕收进一个统一目录素材一移动、一改名对应关系就断了而且这个断是无声的——你不会收到报错只会在某天打开素材时发现字幕没了。✂️ 四、SRT 格式处理Whisper 输出的 SRT 常有两个毛病一行太长、长视频时间轴累计漂移。一段脚本解决importrefrompathlibimportPathdeffix_srt(path:Path,max_len:int25):textpath.read_text(encodingutf-8)blocksre.split(r\n\n,text.strip())out[]fori,binenumerate(blocks,1):linesb.splitlines()# [序号, 时间轴, 文本...]body.join(lines[2:])# 按长度切分保持序号连续、时间轴不变chunks[body[j:jmax_len]forjinrange(0,len(body),max_len)]forcinchunks:out.append(f{len(out)1}\n{lines[1]}\n{c}\n)path.write_text(\n.join(out),encodingutf-8)forsrtinPath(/data/videos).rglob(*.srt):fix_srt(srt)切行策略按画面安全框调max_len时间轴若整体偏移加一个固定毫秒偏移再写回即可比逐条手改省事得多。处理前后的对比最直观。原始输出的一条字幕长这样12 00:01:36,000 -- 00:01:42,500 大家好今天我们来讲一下素材的命名规范因为很多朋友的素材库其实就是一个更贵的废纸篓五十来个字挤在一条里观众根本读不完。跑完fix_srtmax_len 取 24后被切成两到三条序号自动重排、时间轴原样保留观感立刻回到可交付水平。这个函数唯一要注意的是lines[2:]的假设标准 SRT 每块第二行必是时间轴但如果文件来自其他工具、块里混入了空行切片就会错位——所以批量处理前先抽查两三个文件确认格式干净再全量跑。时间轴漂移多说两句成因Whisper 按 30 秒窗口滑动识别窗口边界若切在句中时间戳会整体后移半秒到一秒长视频累积下来就有几秒误差。对策不是逐条手改而是抽片头、片中、片尾三个点核对——偏差一致就整体加固定偏移偏差线性增大就按比例缩放时间轴两行代码的事比人眼逐条对齐靠谱得多。思考 转写字幕能直接交付吗 能覆盖九成工作量但不能裸交。专有名词、同音字、标点是重灾区。我的做法是通读一遍顺手改掉——比起从零敲字幕这十分钟依然是大赚。 五、转写文本如何成为素材检索的素材这一步才是整个事情的价值所在。转写不是为了字幕是为了让视频内容可被搜索。算一笔账就明白了一条 20 分钟的口播看一遍要 20 分钟读一遍转写稿只要 3 分钟——检索效率差着一个数量级。素材库积累到几百条之后里面说过什么这个问题的答案只能靠文字承载。我的落地做法分三层层落点作用原文层与素材同名的 .txt/.srt全文检索的原始语料标签层从转写文本抽取的关键词、主题词结构化筛选入口事实层转写时间戳定位到那句话在视频里的位置有了这三层开头那个找三个月前的比喻就变成一次关键词搜索搜命名命中那期素材再顺时间戳跳到原话的位置。一个真实的找回案例上个月写素材命名规范这篇内容时我只记得某期口播里用过图书馆不放索引卡这个比喻。全文检索索引两个字三秒命中去年 11 月的素材时间戳指向 04 分 17 秒——点开拖到那个位置比喻原话就在那里。没有转写文本的时候这个动作等于把 40 分钟的视频从头看一遍有了它就是一次关键词搜索。素材库的价值不在于存了多少在于找得回多少。三层里有两层其实是顺手得来的原文层零成本——转写脚本多存一份同名 txt 即可系统自带的全局搜索就能跑通第一版检索事实层是天然产物——SRT 自带时间戳不需要额外做任何事。真正需要投入的只有标签层而且别急着建体系先把高频搜索词记下来重复出现五次以上的才配成为正式标签。全量的增量投入只有每周一次的标签整理十分钟的量。我自己的素材库工作流跑的就是这套——转写文本和标签一起挂在素材详情上检索命中内容而不是文件名。翻硬盘找素材的那半小时本质是对当时没做索引的延迟付费。图素材详情页。转写出的文本和人工标签挂在一起搜内容才有了落点。思考 全文检索和打标签哪个更值得先做 先做全文。标签靠人打会懒、会漏、口径会漂移全文检索是自动且完备的兜底。等检索用出感觉再把高频搜索词沉淀成标签——让真实需求驱动词表。❓ 常见问题 FAQQ1中文内容选哪个模型Asmall 是底线medium 是甜点位。tiny/base 对中文的错字率会让你怀疑人生除非只是出草稿否则不建议。判断方法很简单拿一段你自己能背出来的口播分别用 small 和 medium 转一遍肉眼对比错字——差别一目了然比看任何评测都直接。Q2没有显卡几十个小时的素材转得完吗A转得完但要有耐心。CPU 上用 faster-whisper 跑 smallint8速度约为音频时长的 0.3–1 倍挂一晚上能消化不少。实测参考M2 笔记本跑 smallint8一小时素材约两小时出稿挂两个晚上就能消化掉一周的素材量——机器在夜里干活从不抱怨这是本地部署的隐藏福利。Q3Whisper 转写会碰我的隐私数据吗A本地部署不会。模型跑在自己机器上音频不出本机——这也是我坚持本地而非云端 API 的原因素材库里的原始素材不该出门。Q4转写文本存在哪里最合适A与素材同名、同目录最抗迁移。进阶做法是同步进素材库的备注或描述字段让工具层直接参与检索。同名同目录还有个衍生命题换电脑时把整个目录树原样拷走字幕关系一个都不会断——任何依赖数据库存索引的方案都要多回答一句数据库坏了怎么办而文件系统不会。 写在最后做内容久了会明白一个道理你说过的每句话都有价值前提是你还能找到它。素材库里躺着的几百条视频本质上是一个没被索引的图书馆语音转写就是给这个图书馆编目。工具会一直换但让积累可检索这件事值得从第一天就开始做。这套转写即入库的流程我也在做给自己的素材库工具时实现了。影栈是面向创作者的素材库产品——短视频素材资产管理平台。它把抖音、B站、小红书、快手等平台获取的图文、视频、音频素材统一管理起来智能集合筛选、项目工作区、素材对比同步播放、一键拖入剪辑软件让创作者的每一次收藏都变成可复用的资产。后续我会在 CSDN 持续更新这款工具的实战记录感兴趣的可以关注我的博客主页。参考文献[1] OpenAI. “Whisper: Robust Speech Recognition via Large-Scale Weak Supervision.” https://github.com/openai/whisper[2] SYSTRAN. “faster-whisper: Faster Whisper transcription with CTranslate2.” https://github.com/SYSTRAN/faster-whisper[3] Wikipedia. “SubRip (SRT 字幕格式).” https://en.wikipedia.org/wiki/SubRip[4] Georgi Gerganov. “whisper.cpp.” https://github.com/ggerganov/whisper.cpp