ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

whisper.cpp 本地部署指南:视频自动生成中文SRT字幕的完整方案

whisper.cpp 本地部署指南:视频自动生成中文SRT字幕的完整方案 如果你也遇到过这种情况——手上有几十个视频要出中文字幕外包太贵、在线工具要传原片、手动听写又慢得想摔键盘——whisper.cpp 可能是目前性价比最高的解决方案之一。它是 OpenAI Whisper 语音转文字模型的一个纯 C/C 移植实现不需要联网、不需要 Python 环境、不强制要求 GPU一台普通笔记本就能跑并且原生支持中文识别能直接导出 SRT 字幕文件。这篇教程我会基于自己在 Windows 和 Linux 上的实际部署经历把模型选型、环境搭建、命令行参数、视频抽音频到 SRT 字幕生成的完整流程以及踩过的各种坑一次性讲清楚。整套内容也覆盖 macOS三类系统差异不大核心命令基本通用。1. 为什么选 whisper.cpp方案选型与核心优势1.1 免费离线这件事到底有多重要很多人第一次接触语音转文字第一反应是打开在线工具。在线工具确实方便但一旦涉及批量处理、敏感内容、无网环境问题就全出来了。我在处理一批公司内部培训视频时视频里涉及产品数据和非公开信息上传到任何第三方平台都有顾虑。whisper.cpp 完全本地运行所有音频数据不出机器模型文件也是本地加载从源头避免了数据外泄风险。这一点对很多场景是致命需求不是“优化项”而是“能不能用”的问题。离线还有一个隐形优势稳定性。在线 API 有并发限制、流量策略、服务维护等因素批量跑几个小时任务时经常中途断掉。本地跑没有限流问题只要机器不关机任务就能一直跑。对需要通宵处理几十集视频字幕的人来说这种“一次部署、长期免费”的模式非常香。1.2 whisper.cpp 和 openai-whisper / faster-whisper 怎么选市面上的 Whisper 衍生方案很多简单列一下主流选项维度whisper.cppopenai-whisperfaster-whisper实现语言C/CPython PyTorchPython CTranslate2部署体积几十 MB单文件可执行Python 环境 模型几个 GBPython 环境几百 MBCPU 推理速度快支持量化较慢快int8 量化GPU 加速支持CUDA、Metal、Vulkan支持支持依赖复杂度低不用装 Python需要 venv 大量依赖需要 ctranslate2适合场景本地工具、脚本、嵌入式研究、快速原型批量服务、后端接口我主力用 whisper.cpp 的原因很直接部署太省心。在需要自动化批量处理的服务器上我不用维护 Python 环境和一堆依赖下载一个可执行文件和一个模型文件就能跑。跨平台命令也基本一致Windows 和 Linux 上的脚本只要改一下路径就可以互换。如果只是临时给两三个视频加字幕用 openai-whisper 也没问题如果要做成常驻服务或者放到低配机器上whisper.cpp 明显更合适。faster-whisper 在 GPU 批量推理上很猛但配置复杂度也更高没必要为了一个字幕工具引入整套 Python 技术栈。1.3 模型体积、识别速度与精度的取舍whisper.cpp 支持从 tiny 到 large-v3 的多档模型选型直接决定识别速度和准确率尤其是中文场景差异非常大。官方模型体积大概是这样的模型参数量默认内存占用中文识别体验tiny39M约 75MB能听出个别词大量错字适合语音唤醒类测试base74M约 142MB短句、清晰录音勉强可用长句容易乱small244M约 466MB日常视频可接受噪声环境下开始出错medium769M约 1.5GB中文综合最推荐的平衡点large-v31550M约 3GB精度最高对复杂口音、背景音容忍度也最好实际使用中还常见带 q5_0、q8_0 后缀的量化模型。量化是把模型权重的精度压缩换来更小的体积和更快的推理速度代价是极少的精度损失。以 medium 为例ggml-medium-q5_0.bin 的实际体验和原版差距非常小但速度和内存占用改善明显是 CPU 推理的首选。我的选型经验是普通视频字幕默认 medium 的量化版人物多、术语多、背景有音乐的片段用 large-v3 量化版。base 只用来做快速预览跑一遍看看视频内容大概讲了什么决定要不要精修。2. 部署Windows / macOS / Linux 三步走2.1 Windows 部署源码编译与预编译两种路径Windows 上最稳妥的路径其实是直接用预编译包而不是自己编译。whisper.cpp 项目在 GitHub Releases 里会发布包含可执行文件的压缩包下载解压后看 bin 目录里面有 whisper-cli.exe 和配套的 DLL 文件。对于想自己编译最新代码的读者操作也不复杂。前置条件是 Git、CMake 和 Visual Studio 2022 的 C 桌面开发组件。打开“x64 Native Tools Command Prompt for VS 2022”依次执行git clone --recursive https://github.com/ggerganov/whisper.cpp.git cd whisper.cpp cmake -B build cmake --build build --config Release编译完成后可执行文件在build\bin\Release\whisper-cli.exe。注意--recursive参数不能省项目依赖的 ggml 子模块会一起拉下来少了它编译时找不到头文件。我自己的建议是小白直接用预编译版省去 VS 安装和编译过程需要修改源码或想精确控制编译参数的人再走源码编译。不要在环境搭建上耗太多时间后面模型识别才是重点。2.2 macOS 与 Linux 部署macOS 最简单的方式是用 Homebrewbrew install whisper-cpp装完直接有 whisper-cpp 命令。如果想用最新提交也可以走 cmake 编译步骤和 Linux 一致。Linux 上先装基础工具链sudo apt update sudo apt install build-essential cmake git git clone --recursive https://github.com/ggerganov/whisper.cpp.git cd whisper.cpp cmake -B build cmake --build build --config Release -j编译完成后的可执行文件在build/bin/whisper-cli。部分发行版的仓库里也直接带了 whisper-cpp 包可以通过包管理器安装但版本可能滞后个人还是推荐源码编译反正过程很快。Linux 部署唯一要注意的是 CPU 指令集。老 CPU 不支持 AVX 指令的话建议用较老的兼容构建版本否则跑起来会提示指令不支持。一般 2015 年以后的 x86 处理器都没有问题。2.3 模型文件下载与目录组织模型文件放在哪、叫什么名字直接影响后续命令的简洁度。我习惯在 whisper.cpp 目录下建一个models文件夹把模型统一放进去。Hugging Face 上ggerganov/whisper.cpp仓库里有全部官方转换好的 ggml 格式模型包括 tiny、base、small、medium、large-v3 以及各种量化版本。项目自带的脚本也可以帮助下载./models/download-ggml-model.sh mediumWindows 下如果不想装 Git Bash直接浏览器打开 Hugging Face 页面下载对应的ggml-medium-q5_0.bin文件即可。有一个非常实际的经验模型文件路径里不要出现中文或空格。Windows 命令行在某些编码环境下对中文路径处理有兼容问题报错会非常难排查。为了省心项目就放在C:\whisper-cpp模型放C:\whisper-cpp\models全部用英文路径。3. 基础使用命令行参数与中文优化3.1 第一次运行从 wav 到文字whisper.cpp 的输入最好是无压缩的 16kHz 单声道 WAV 文件。虽然新版本对更多格式有一定兼容但预处理成标准 WAV 是保证识别效果和稳定性的关键一步。先用 ffmpeg 做转换ffmpeg -i input.mp3 -ar 16000 -ac 1 -c:a pcm_s16le audio.wav然后运行 whisper.cppwhisper-cli -m models/ggml-medium-q5_0.bin -f audio.wav -l zh -otxt-m指定模型文件-f指定输入音频-l zh锁定中文-otxt输出纯文本。首次加载模型会等几秒之后屏幕上会滚动输出识别结果同时生成audio.wav.txt文件。如果你用的是旧版本可执行文件叫main.exe或者main参数基本一致只是新版本统一改成了whisper-cli。不确定的时候先跑一下whisper-cli --help看它自己列出的参数最准确。3.2 中文识别关键参数与调整思路中文识别不是简单把音频丢进去就行以下几个参数对效果影响很大。-l zh是必选项。不指定语言时Whisper 会先花时间做语言检测检测错误还会拿别的语言模型去拟合导致中文识别率断崖式下降。如果你确定音频就是中文锁死语言能同时提升速度和准确率。-t指定 CPU 线程数。建议设置为物理核心数减一留一个核心给系统和其他进程。线程数太小会明显变慢线程数拉满也不一定线性加速反而可能因为调度开销导致性能下降。--max-len控制每行字幕的最大长度按 token 计。中文场景我常用--max-len 30到40配合 SRT 字幕输出每屏不会堆太多文字观感好很多。-nt是禁用温度回退检测。Whisper 的默认解码策略里有一层温度回退音频不清时会自动多次尝试。离线批量场景下关闭温度回退能减少大量重复计算也避免模型在困难片段上反复“挣扎”导致速度骤降。清楚音频下它对准确率影响很小。CPU 推理时建议加上-fp16 false。虽然很多 CPU 推理路径默认不会真正启用 fp16但显式关闭可以避免个别版本在部分 CPU 上的兼容问题。一个完整的常用命令大概是这样whisper-cli -m models/ggml-medium-q5_0.bin -f audio.wav -l zh -t 8 -nt --max-len 30 -osrt -otxt3.3 输出格式一览与各自用途whisper.cpp 可以同时输出多种格式常见的有-otxt纯文本文件适合看全文、做内容摘要-osrtSRT 字幕文件时间码精确到毫秒剪辑软件都能直接导入-ovttWebVTT 格式网页video标签原生支持-ojJSON 格式带 token 级时间戳适合二次程序处理SRT 文件内容长这样1 00:00:00,000 -- 00:00:03,500 大家好欢迎来到本期教程 2 00:00:03,500 -- 00:00:07,200 今天我们聊一聊本地语音识别VTT 和 SRT 的差异主要是时间码格式和头部声明WEBVTT 00:00:00.000 -- 00:00:03.500 大家好欢迎来到本期教程批量场景下我习惯一次性生成 SRT 和 TXT-osrt -otxt同时输出省得之后想查全文还要重跑一遍。4. 实战视频生成 SRT 字幕全流程4.1 从视频抽音频ffmpeg 命令与注意事项给视频生成字幕的第一步是把视频里的音轨抽出来转成 whisper.cpp 需要的 WAV 格式。基础命令ffmpeg -i input.mp4 -vn -ar 16000 -ac 1 -c:a pcm_s16le audio.wav-vn丢弃视频轨-ar 16000重采样为 16kHz-ac 1转成单声道-c:a pcm_s16le指定无压缩 PCM 编码。这一步做完文件体积会因为转成 WAV 变大但这正是 whisper.cpp 最稳定、识别率最高的输入格式。这里有个容易忽略的坑如果视频音轨音量过小识别结果会大量漏词音量过大又可能削波爆音。ffmpeg 的 loudnorm 滤波器可以统一响度ffmpeg -i input.mp4 -vn -ar 16000 -ac 1 -c:a pcm_s16le -af loudnormI-16:TP-1.5:LRA11 audio.wav我处理一批来自不同拍摄设备的视频时音轨响度差异很大加上 loudnorm 后识别准确率明显提升这个预处理非常值得。如果音轨里噪音明显特别是低频环境噪音可以再加一个高通滤波器。语音频率一般在 80Hz 以上切掉 80Hz 以下的部分几乎不影响人声但能少很多噪音干扰ffmpeg -i input.mp4 -vn -ar 16000 -ac 1 -c:a pcm_s16le -af highpassf80,lowpassf8000 audio.wav4.2 生成 SRT 字幕并校验抽完音频后识别命令就很简单whisper-cli -m models/ggml-medium-q5_0.bin -f audio.wav -l zh -t 8 -nt --max-len 30 -osrt -otxt跑完后打开 SRT 文件重点检查三件事。第一是时间轴整体是否对齐。听一段比对一句确认没有全局延迟或提前。第二是断句是否合理。whisper.cpp 的断句依赖语音停顿和模型判断偶尔会把一句话拆成两半或者把两句话挤在一起需要人工调整。第三是专有名词和数字是否正确这类错误普遍存在和模型大小无关靠最后人工校对兜底。批量处理多个视频时可以用脚本循环。Windows PowerShell 下Get-ChildItem *.mp4 | ForEach-Object { $base $_.BaseName ffmpeg -i $_.Name -vn -ar 16000 -ac 1 -c:a pcm_s16le $base.wav whisper-cli -m models\ggml-medium-q5_0.bin -f $base.wav -l zh -t 8 -osrt -otxt }Linux 下对应的 bash 脚本for f in *.mp4; do ffmpeg -i $f -vn -ar 16000 -ac 1 -c:a pcm_s16le ${f%.mp4}.wav -y whisper-cli -m models/ggml-medium-q5_0.bin -f ${f%.mp4}.wav -l zh -t 8 -osrt -otxt done一次批量挂机跑完第二天收结果就行。4.3 时间码偏移修正做视频字幕时经常遇到一个场景成片片头有 8 秒的片头动画或者视频剪掉了前面一段但音频是从完整素材里抽出来的生成的 SRT 时间码整体偏移。最简单粗暴的方案是从源头解决抽音频时直接把开头不需要的部分切掉。ffmpeg -ss 8 -i input.mp4 -vn -ar 16000 -ac 1 -c:a pcm_s16le audio.wav-ss 8表示跳过前 8 秒生成的字幕时间码就会从 0 开始。但这个方法的局限是如果视频成片内部删减过片段整体便宜就不够用需要针对每个片段单独对齐。更通用的方式是后期统一平移 SRT 时间码。用 Python 的 pysubs2 库非常方便from pysubs2 import SSAFile subs SSAFile.load(audio.srt) subs.shift(ms-5000) # 提前 5 秒负值表示提前 subs.save(audio_fixed.srt)装库命令是pip install pysubs2不仅支持 SRT还支持 ASS、VTT 等多种字幕格式。如果你的时间轴错误是固定值用这个方法几分钟就能处理完所有字幕文件。4.4 长视频分段策略whisper.cpp 对长音频的容忍度不错但超过 30 分钟的整段音频处理时间会明显拉长内存占用也会持续走高。我有一个更保险的流程先把长音频切成 10 分钟一段逐段识别再合并字幕。ffmpeg 分段命令ffmpeg -i audio.wav -f segment -segment_time 600 -c copy part_%03d.wav每段单独跑 whisper.cpp生成各自的 SRT。合并时继续用 pysubs2from pysubs2 import SSAFile files [part_000.srt, part_001.srt, part_002.srt] offset 0 out SSAFile() for f in files: subs SSAFile.load(f) for event in subs: event.start offset event.end offset out.events.append(event) if subs.events: offset max(event.end for event in subs.events) out.save(merged.srt)分段的好处有两个一是任一段识别失败可以单独重跑不用整个音频重新来二是长时间挂机时内存更稳定。缺点是分段点可能会切断句子但从字幕角度看影响不大因为 SRT 本来就允许一句话分两行展示。如果音频在 20 分钟以内我一般直接整段跑省事。超过 30 分钟再分段。5. 常见问题排查与性能调优5.1 编译和运行的常见报错问题现象可能原因解决办法whisper-cli 不是内部或外部命令没切到可执行文件所在目录或 PATH 没配使用完整路径C:\whisper-cpp\build\bin\Release\whisper-cli.exe提示 unknown argument -l版本太老或用了错误的可执行文件查看whisper-cli --help确认参数名称找不到模型文件模型路径写错用绝对路径指定-m C:/whisper-cpp/models/ggml-medium-q5_0.bin打开 mp3/mp4 文件报错输入格式不是标准 WAV先用 ffmpeg 转成 16kHz 单声道 WAV输出乱码Windows 终端代码页问题执行chcp 65001切换到 UTF-8编译时找不到 ggml 头文件clone 时漏了--recursive在项目目录执行git submodule update --init --recursive后重新编译Windows 下还有个高频坑是杀毒软件误删 whisper-cli.exe 或者模型文件。不少安全软件会把读取音频并写文件的行为判定为可疑操作。解决办法是加白名单或者临时关闭实时防护再解压运行。5.2 识别结果不理想的排查方向模型输出大量错字时先别急着换大模型按下面的顺序排查。第一确认输入音频确实是 16kHz 单声道 WAV。有些转换命令写得不完整音频还是 44.1kHz 立体声whisper.cpp 虽然能跑但内部重采样质量不如 ffmpeg 预处理的好。第二检查背景音乐和音效。Whisper 对语音和背景音的区分能力有限背景音乐一旦盖过人声识别率立刻下降。先尝试加 highpass/lowpass 滤波器或者用 ffmpeg 的afftdn降噪ffmpeg -i audio.wav -af afftdnnf-25 audio_denoised.wav第三检查说话音量。whisper.cpp 对音量敏感过小的音频会导致大量漏字。可以用ffmpeg -af volume8dB提升音量后再识别。第四看看有没有人声重叠、设备采集的远场语音。这类场景对模型要求极高只能换 large-v3 甚至做音频预处理分离人声和伴奏。whisper.cpp 本身不擅长分离人声不要指望它在这种情况下还能完美转录。最后接受现实模型输出永远不可能 100% 正确。专业名词、生僻字、数字错误通常只能靠人工校对。批量场景下我习惯先全文生成再统一做关键词替换把高频错词一次性修正。5.3 性能调优量化模型、线程与 GPUCPU 场景下最大的性能提升来自量化模型。同样是 mediumggml-medium-q5_0.bin比原版ggml-medium.bin大概能快 30% 以上内存占用直接砍半识别精度差距却很难感知。除非你追求极限精度且有富余算力否则量化版是日常首选。线程参数也需要认真调。-t控制的是推理线程-p控制并行处理线程。在普通四核八线程笔记本上-t 4配合-p 2通常效果不错在八核十六线程的桌面 CPU 上-t 8 -p 4更合适。不是线程越多越快实测超过物理核心数后性能反而下降。如果机器的 CPU 支持 AVX2编译时默认会启用相关优化。Windows 预编译包通常也适配了主流 CPU 指令集不用额外配置。GPU 加速不是 whisper.cpp 的必需项但如果你有 NVIDIA 显卡且显存足够可以在编译时启用 CUDA 后端cmake -B build-cuda -DGGML_CUDAON cmake --build build-cuda --config Release -jmedium 模型在 GPU 上能实现数倍提速large-v3 也更实用。注意 large-v3 在部分显卡上会爆显存建议先用 q5_0 量化版显存不够时关闭 fp16。我自己的主力机器没有独显一直用 CPU 跑medium 量化版处理 1 小时音频大概需要 20 到 30 分钟完全能接受。5.4 与上层应用对接的格式坑whisper.cpp 识别出的 SRT 文件本身没有编码问题但 Windows 上很多老播放器只认 GBK 编码的 SRT。如果你的字幕在电脑上显示正常放到电视或老剪辑软件里乱码多半是编码问题。处理办法是用文本编辑器把 SRT 另存为 UTF-8 with BOM或者用 Python 批量转码for path in [audio.srt]: text open(path, encodingutf-8).read() open(path, w, encodingutf-8-sig).write(text)另外如果你把 whisper.cpp 封装成服务供给 Dify、FastAPI 这类应用调用最容易遇到接口报错。比如 Dify 语音转文字接口报 415 错误大概率是请求的 Content-Type 不对或者上传的音频格式不符合服务端预设的白名单。常规解法是先把音频转成标准的 wav 或 mp3再以 multipart/form-data 方式上传文件名后缀也要规范不要用audio这种无后缀的方式。这些坑不算 whisper.cpp 自身的问题但一旦踩到排查起来很耗时间。提前了解能省很多事。最后说点个人体会。我最初用 whisper.cpp 总想一步到位把字幕识别得完美无缺反复调参数、换大模型、改解码策略后来发现真正值得投入的前置工作是音频预处理。音量统一、降噪、去掉无用片头这几步做扎实了识别质量自然上去。模型反而不用频繁换同一批视频先拿 base 快速跑一遍了解内容再对重点片段用 large-v3 精修能省下一半时间。字幕生成不是终点拿到 SRT 后用 pysubs2 做一下整体偏移校验、编码转换再进剪辑软件整个流程会顺很多。
返回列表