1.1 Whisper 的定位:OpenAI 开源语音识别模型
我最早把 Whisper 用在播客转写项目里,当时想找一套能离线跑、不按分钟计费的语音识别方案。OpenAI 把 Whisper 的代码和模型权重放出来以后,我这边终于可以在自己的机器上处理音频,会议录音、采访素材、课程视频都能转成文字。它的定位很清晰:通用自动语音识别模型,目标不是只服务某一种口音或某一种行业,而是用大规模多语言数据训练出一个覆盖面很广的 ASR 底座。
Whisper 的核心结构是 Transformer 编码器加解码器。音频先切成 30 秒片段,转成梅尔频谱,编码器读进去,解码器再吐出文本 token。训练数据规模很大,覆盖多语言、多任务,模型见过各种噪声、口音和表达方式。我拿它跑中文访谈时,明显感觉它比传统小模型更敢“猜”上下文,代价是偶尔也会猜过头。
我更愿意把 Whisper 看成开源语音识别的基础设施。它适合做本地部署、批量转写、字幕生成、语音翻译这些任务。有人把它塞进实时语音助手,效果能不能接受,要看延迟要求和硬件条件。OpenAI 开源了这个模型体系,社区又围绕它做了大量工程优化,实际用法远比“一个模型”丰富。
1.2 模型家族与规模:tiny、base、small、medium、large 等
Whisper 官方模型从 tiny 到 large 排成一条线。tiny 大约 3900 万参数,base 约 7400 万,small 约 2.44 亿,medium 约 7.69 亿,large 约 15.5 亿。参数越大,通常识别越稳,资源消耗也越高。我自己的测试里,tiny 在安静环境下转英文播客很快,换成中文电话录音就经常漏字;small 已经能应付不少日常内容;large 在嘈杂访谈里明显更少犯错。
模型名字后面常带 .en,这类是英文专用版。多语言版能处理约 99 种语言,做中文转写要选多语言模型,不要拿 .en 硬跑。large 系列还有 large-v2、large-v3、large-v3-turbo 等版本。turbo 的定位偏向速度和体积平衡,参数规模没有 large 那么大,推理更快,准确率会有些取舍。社区里还有 distil-whisper、faster-whisper、whisper.cpp 这些实现,它们不是官方模型家族的全部,但在我做本地部署时很常用。
我选择模型时不会只看参数。M2 MacBook Air 上跑 tiny、base 比较舒服,small 能跑但风扇会转;RTX 3060 12GB 跑 medium 要控制 batch size,跑 large 会紧张;A100 或 4090 上 large 才比较从容。做字幕初稿,我会用 small 或 medium 先跑一遍;做法律、医疗、专业访谈,我会直接上 large,再安排人工校对。
1.3 多语言、多任务与时间戳能力
Whisper 的多语言能力是我最喜欢的一点。它支持约 99 种语言,中文、英文、日文、韩文、西班牙文、法文、德文这些常见语言都能转写。多任务体现在解码 token 上:我可以让它做 transcribe,保留原语言文本;也可以让它做 translate,把非英文语音直接翻成英文。做跨国会议记录时,这个能力省掉了“先转写再翻译”的一整段流程。
时间戳方面,Whisper 原生输出的是片段级时间戳。做 SRT 字幕够用,做逐字歌词、精准对齐、词级编辑就不够细。我常用 whisper_timestamped、stable-ts、faster-whisper 这些工具补词级时间戳。它们有的靠强制对齐,有的靠解码策略调整,效果和音频质量关系很大。遇到语速快、音乐垫底、多人抢话,时间戳会漂移,我会加一段人工校准。
多语言和多任务放在一起,Whisper 的使用方式就很灵活。同一段中文音频,我可以输出中文文稿,也可以让它翻译成英文,还能带时间戳导出字幕文件。做课程视频时,我会先生成中文 SRT,再用翻译任务生成英文 SRT,收尾时人工核对专有名词。这个流程不算全自动,但比从零听写快很多。
1.4 适用边界与常见限制
Whisper 很能干,边界也要看清。它没有内置说话人分离,一段多人会议录音转出来,谁说了哪句话不会自动标出来。它也不是声纹识别工具,不能靠声音判断身份。实时语音转写需要流式改造,原生 Whisper 更适合一段一段地处理。低延迟场景里,我一般会看 faster-whisper、whisper.cpp 或流式方案,不会直接拿原版模型硬顶。
幻觉是另一个常见问题。静音段、音乐段、噪声段里,Whisper 有时会吐出不存在的句子,中文里会出现重复、语气词堆叠、标点乱加。长音频超过 30 秒窗口后,分块策略会影响上下文,切得不好会丢词或重复。专业术语、人名、地名、药品名、法律条文这些内容,模型经常按发音猜字。医疗、法律、金融场景里,我把 Whisper 当草稿工具,交付前一定安排人工复核。
我的使用经验是:安静单人语音、普通话标准、主题日常,Whisper 表现很好;口音重、背景吵、多人重叠、专业词汇密集,错误率会上去。本地部署能保护隐私,也能省 API 费用,硬件和维护成本要算进去。想用它做产品,最好准备一套后处理流程:热词替换、标点整理、术语表、人工校对、质量抽检。这样才能把开源模型的潜力变成稳定可用的能力。
2.1 本地部署前的硬件与系统准备
我第一次在本地跑 Whisper 的时候,拿的是一台 2019 款 MacBook Pro,16GB 内存,Intel i7 处理器,没有独立显卡。tiny 模型勉强能跑,转写一段十分钟的音频要等好几分钟,风扇从开始转到结束。那台机器让我明白一件事:Whisper 对硬件不是特别挑剔,不同规模的模型对资源的需求差距很大。选硬件之前,先想清楚你要跑哪个模型、处理多长的音频、对速度有没有要求。
纯 CPU 环境能跑 Whisper,速度慢一些。Intel 或 AMD 的现代多核处理器跑 tiny、base 没问题,small 需要多等一会儿,medium 和 large 在 CPU 上做批量转写就很熬人了。我的建议是 CPU 跑 tiny 到 small,把 large 留给 GPU。内存方面,tiny 和 base 占 1GB 到 2GB,small 大约 2GB 到 4GB,medium 需要 5GB 到 8GB,large 在 10GB 左右。系统内存比模型权重大两三倍会比较稳,不然加载和推理时容易触发交换分区。
GPU 是本地部署最有效的加速手段。NVIDIA 显卡走 CUDA,RTX 3060 12GB 能比较舒服地跑 medium,large 需要控制 batch size 或者用更省显存的实现。RTX 4090、A100 这类卡跑 large 很从容。AMD 显卡走 ROCm,支持面比 CUDA 窄一些,安装时容易踩坑。Apple Silicon 走 MPS,M1、M2、M3 系列都能用,统一内存架构让大模型更容易装下,M2 Pro 32GB 跑 large 的体验比很多同价位 PC 笔记本好。
操作系统方面,Linux 对 CUDA 和 Python 生态最友好,Ubuntu 22.04 或 24.04 是我常用的选择。Windows 上跑 Whisper 也能用,安装 CUDA 驱动和 PyTorch 时多留意版本匹配。macOS 用 Homebrew 管理依赖,FFmpeg 和 Python 都方便装。我自己的主力环境是 Ubuntu 加 RTX 3090,出门用 M2 MacBook Air,两套配置跑同一份代码,区别主要在速度和可用模型规模。
硬盘空间别忽视。每个模型文件从几十兆到几个 GB 不等,large-v3 单模型大约 3GB。缓存里放多个模型,再加上音频和处理中间文件,预留 50GB 到 100GB 比较安心。音频格式方面,Whisper 依赖 FFmpeg 解码,wav、mp3、m4a、flac、ogg 这些常规格式都能读。16kHz 单声道 wav 是它内部使用的采样格式,输入音频质量太差或者采样率太怪,转写前用 FFmpeg 转一道会更稳。
2.2 Python、PyTorch、FFmpeg 等依赖安装
Python 版本我推荐 3.10 到 3.12。3.8 和 3.9 有些新版本 PyTorch 已经不支持,3.13 又可能遇到包兼容问题。我用 conda 或者 venv 建独立环境,不把 Whisper 装进系统 Python。命令大概是这样:python -m venv whisper-env,然后 source whisper-env/bin/activate。Windows 上激活脚本在 Scripts 目录里。环境隔离能避免不同项目之间 PyTorch 版本打架,后面升级或者重装都方便。
PyTorch 安装是整个流程里最容易卡住的一步。官方安装命令要根据 CUDA 版本选。RTX 30 系和 40 系显卡通常装 CUDA 12.1 或 12.4 对应的 PyTorch。命令去 pytorch.org 的 Get Started 页面选一下,复制粘贴最稳妥。我习惯先装 PyTorch,再装 openai-whisper。这样能确认 torch 能正常调用 GPU,用 python -c "import torch; print(torch.cuda.is_available())" 检查,返回 True 说明 CUDA 通了。Mac 用户装 PyTorch 时选 MPS 版本,检查语句换成 torch.backends.mps.is_available()。纯 CPU 用户直接装默认版,不用折腾 CUDA。
FFmpeg 是 Whisper 处理音频的底层依赖。它负责把 mp3、m4a 这些格式解码成模型能读的数组。Ubuntu 上 sudo apt install ffmpeg 就行。macOS 用 brew install ffmpeg。Windows 上要去官网下载编译好的包,把 bin 目录加到 PATH 环境变量里。装完在终端敲 ffmpeg -version,能看到版本号说明配置好了。我遇到过 FileNotFoundError: ffmpeg 的报错,基本都是 PATH 没配对,或者 conda 环境里没装 ffmpeg 包。
openai-whisper 的安装命令是 pip install openai-whisper。它会自动拉取 torch、numpy、tiktoken 这些依赖。如果你已经装好特定版本的 PyTorch,pip 可能还是会尝试调整版本。我通常先 pip install torch torchvision torchaudio 按官方命令装好,再 pip install openai-whisper --no-deps,然后手动补 pip install tiktoken numba numpy。这样能避免 pip 把 CUDA 版 PyTorch 换成 CPU 版。装完用 whisper --help 验证命令行工具是否可用。
系统级依赖还有几个容易漏。Ubuntu 上可能需要 sudo apt install build-essential,因为 numba 或者某些包要编译。macOS 上 Xcode Command Line Tools 要装好,xcode-select --install 跑一遍。Windows 用户建议用 WSL2,Ubuntu 子系统的体验比原生 Windows 顺畅很多,CUDA 在 WSL2 里也能用。我帮朋友在 Windows 原生环境装过一次,驱动、CUDA、cuDNN、PATH 来回折腾了两个小时,换 WSL2 后二十分钟搞定。
2.3 模型下载与缓存管理
Whisper 第一次运行时会自动下载对应模型。下载源在 OpenAI 的 CDN 上,国内网络有时候很慢或者断流。我试过下载 large-v3 花了四十多分钟,中间断了一次还得重来。解决办法有两个:提前手动下载模型文件放到缓存目录,或者用镜像站加速。缓存目录默认在 ~/.cache/whisper,Windows 在 C:\Users\用户名\.cache\whisper。你可以用 --model_dir 参数指定其他路径。
手动下载的模型文件命名有规律。tiny 是 tiny.pt,base 是 base.pt,small、medium、large-v2、large-v3 依次类推。多语言版不带后缀,英文专用版带 .en。large-v3-turbo 的文件名是 large-v3-turbo.pt。把下载好的 .pt 文件放进缓存目录,Whisper 启动时发现文件存在就不会重新下载。我习惯在服务器上建一个 /data/models/whisper 目录,所有模型集中放,多个项目共用,也方便备份。
Hugging Face 上也有 Whisper 模型的镜像仓库。用 huggingface-cli download 可以拉取,速度比 OpenAI CDN 稳定。有些社区版本会把模型转成 safetensors 格式,加载方式略有不同。如果你用 faster-whisper,它默认从 Hugging Face 拉 CTranslate2 格式的模型,缓存路径在 ~/.cache/huggingface/hub。whisper.cpp 用的是 GGML 格式,模型文件从项目仓库或者 Hugging Face 下载,放在 models 目录下。
缓存管理有几个实用技巧。模型文件很大,磁盘紧张时可以只保留常用的两三个。~/.cache/whisper 里除了 .pt 文件没有别的东西,删起来放心。多人共用的服务器上,把缓存目录指向共享存储,能省掉每个人重复下载。环境变量 XDG_CACHE_HOME 可以改缓存根目录,WHISPER_CACHE_DIR 不是官方变量,用 --model_dir 参数更可靠。我现在的做法是模型放 NAS,本地用符号链接指过去,换机器时重新链一下就行。
模型校验也值得做一次。下载中断可能产生不完整的 .pt 文件,加载时报错或者输出乱码。检查文件大小和官方发布的大小是否一致,是最简单的校验方式。large-v3 大约 2.9GB,medium 大约 1.5GB,small 大约 460MB。如果文件明显偏小,删掉重新下载。我遇到过下载到 99% 断掉的情况,文件存在但加载失败,排查了半天才发现是文件不完整。
2.4 命令行、Python API 与批量转写示例
命令行是最快的上手方式。基本用法是 whisper audio.mp3 --model small --language Chinese --output_format srt。它会输出同名的 srt 字幕文件。常用参数里,--model 指定模型,--language 指定语言,--task translate 做翻译,--output_dir 指定输出目录,--output_format 支持 txt、srt、vtt、json、tsv 等。--fp16 False 在 CPU 上跑的时候要加上,不然可能报错。--verbose False 让输出干净一些。
我用命令行做过一批播客转写,脚本大概是这样:for f in *.mp3; do whisper "$f" --model medium --language Chinese --output_format srt --output_dir ./srt; done。这个循环会把当前目录所有 mp3 转成 srt。实际用的时候要加错误处理和日志,单个文件失败不影响后面的任务。--threads 参数控制 CPU 线程数,GPU 模式下不生效。--beam_size 默认是 5,调低能提速,调高可能提升准确率,我一般保持默认。
Python API 更适合集成到项目里。核心代码很短:import whisper; model = whisper.load_model("small"); result = model.transcribe("audio.mp3", language="Chinese")。result["text"] 是全文,result["segments"] 是带时间戳的片段列表。每个 segment 有 start、end、text 字段。想导出 srt,自己写个格式化函数就行,或者用 whisper.utils.get_writer 里的 writer。我封装过一个 transcribe_file 函数,接受路径和参数,返回统一结构,方便批量调用。
批量转写要考虑内存和显存。一次加载模型,循环处理多个文件,比每个文件重新加载模型快很多。代码结构是:加载模型一次,然后 for 循环调用 model.transcribe。显存不够时,处理完一个文件手动 torch.cuda.empty_cache()。长音频文件在 transcribe 时会自动分块,显存峰值和音频长度不完全线性相关,但特别长的文件还是可能爆。我的做法是超过一小时的音频先切段,每段二十分钟左右,转完再合并。
参数调优有几个实用选项。initial_prompt 可以给模型一些上下文,比如专有名词列表,能提升特定领域的识别效果。temperature 控制采样随机性,默认从 0 开始尝试,失败后升高。condition_on_previous_text 设为 False 能减少重复循环,长音频里这个参数很有用。word_timestamps=True 会输出词级时间戳,速度慢一些,做精细字幕时值得开。fp16 在支持的 GPU 上默认开启,速度比 fp32 快不少。
2.5 Docker 与无网络环境部署要点
Docker 部署适合需要环境一致性的场景。我维护过一个 Whisper 服务,开发机、测试机、生产机都用同一个镜像,省掉了“在我机器上能跑”的问题。Dockerfile 基础镜像选 nvidia/cuda:12.1.1-cudnn8-runtime-ubuntu22.04,装 Python、FFmpeg、PyTorch、openai-whisper。模型文件不放进镜像,运行时用 volume 挂载进去。这样镜像体积控制在一两个 GB,模型更新时不用重新构建镜像。
GPU 容器要装 nvidia-container-toolkit,运行时加 --gpus all 参数。docker run --gpus all -v /data/models:/models -v /data/audio:/audio whisper:latest whisper /audio/test.mp3 --model_dir /models --model small。这个命令把模型目录和音频目录挂进去,容器里能访问宿主机的 GPU。Docker Compose 写起来更清晰,服务定义里配 deploy.resources.reservations.devices 声明 GPU。我现在的生产环境用 Compose 管理,重启和更新都方便。
无网络环境部署的关键是提前把依赖和模型准备好。pip 包可以用 pip download 下载 wheel 文件,拷到目标机器用 pip install --no-index --find-links 安装。系统包用 apt-get download 或者离线镜像源。模型文件直接拷贝 .pt 文件到缓存目录。Docker 镜像可以 docker save 成 tar 包,目标机器 docker load 导入。这套流程我在内网服务器上跑过,全程不需要外网。
离线环境还有个坑是 Hugging Face 的默认检查。faster-whisper 和 transformers 库启动时可能尝试联网检查模型更新,没网时会卡住或者报错。设置环境变量 HF_HUB_OFFLINE=1 和 TRANSFORMERS_OFFLINE=1 能关掉这些检查。tts 或者 tokenizer 相关的下载也要提前做好。我习惯在离线部署前,在有网的机器上完整跑一遍流程,把缓存目录整个打包,到目标机器解压到相同路径,这样最省事。
容器里的音频路径和输出路径要规划好。我一般挂载 /audio/input 和 /audio/output 两个目录,输入音频放前者,转写结果写后者。文件权限要注意,容器里默认用 root 跑,输出文件属主是 root,宿主机上普通用户可能改不了。启动容器时加 --user $(id -u):$(id -g) 参数,输出文件权限就和宿主机用户一致了。日志方面,--verbose True 的输出重定向到文件,排查问题时有依据。
3.1 中文准确率评测指标:WER、CER 与语义可读性
我最早接触 Whisper 的时候,拿它转写一段普通话播客,然后一个字一个字跟原文对,数错了多少、漏了多少、多出来多少。这个笨办法其实就是 WER 的原始逻辑。WER 是 Word Error Rate,词错误率,计算公式是(替换+删除+插入)除以总词数。英文里词和词之间用空格隔开,好数。中文没这个便利,所以中文场景下更常用 CER,Character Error Rate,字错误率,把每个汉字当成一个单位来算。
WER 和 CER 这两个指标我用下来有个体会:它们衡量的是“字面准确率”,不是“意思对不对”。一段话转写出来 CER 只有 5%,但如果错的那几个字刚好是人名、地名、药名,读起来就是废的。反过来,有些句子字面上错了好几个,意思完全没跑偏,人读的时候会自动纠正。我做过一次测试,同一段医疗访谈,用 medium 模型转,CER 大约 8%,但医生名字被转成了毫不相干的词,整段记录的可信度直接掉了一半。
语义可读性这个词是我自己习惯叫的,没有一个统一公式。我的做法是转写完先不看原文,直接读一遍,标记出“读起来卡壳”的地方,再跟原文对照。卡壳的地方往往就是错得关键的地方。评测中文 ASR 我一般同时看三个数:CER、实体词(人名、机构名、专业词)的准确率、还有句子级别的完全正确率。三个数一起看,比单看 CER 有信息量得多。我给客户做评测报告时也是这么排的,先给 CER 让人有整体感觉,再用实体词准确率说明可用性,最后用句子完全正确率说明需要人工校对的比例。
3.2 不同模型规模的中文识别表现对比
我在同一批测试集上跑过 tiny、base、small、medium、large-v2、large-v3 六个模型。测试集是我自己攒的,大概三小时音频,包含访谈、会议、播客、电话录音四类。环境是 RTX 3090,fp16 开启,语言指定 Chinese,其他参数默认。结果挺有意思:tiny 的 CER 在 25% 到 35% 之间浮动,基本只能抓到大意,细节全丢。base 好一些,CER 大概 18% 到 25%。small 是个分水岭,CER 掉到 12% 到 18%,日常内容开始能看懂。medium 再降一档,8% 到 13%。large-v2 和 large-v3 差距不大,干净音频上都在 5% 到 10%。
这些数字只是粗略量级,换一批音频结果会变。我印象最深的是 large-v3 对比 v2 的差别不在平均准确率上,而在标点、断句和数字规范化上。v3 自动加逗号句号更自然,阿拉伯数字和中文数字的选择更符合习惯,时间、金额这些表达更规整。转写长访谈时,v3 输出看起来更像人写的。medium 和 large 之间还有一个明显差距是专有名词,large 系列对人名、公司名、产品名的识别明显更稳。
速度上差距也大。tiny 和 base 在 3090 上几乎是实时的十几倍,small 五六倍,medium 两三倍,large-v3 大概 1 倍出头,也就是处理一小时音频要花接近一小时 GPU 时间。我现在的默认策略是这样:快速草稿或者内容筛选用 small,正式交付用 large-v3,中间想省成本就用 medium。纯 CPU 环境反过来,我基本只考虑 tiny 和 base,small 在 CPU 上跑长音频会让人等到怀疑人生。
3.3 口音、背景噪声、专业术语对准确率的影响
中文口音对 Whisper 的影响比我想象中大。标准普通话的 CER 可以压到 5% 左右,换成带明显南方口音的普通话,同一个模型 CER 能翻一倍。我测过几段川普和广普的音频,large-v3 的 CER 分别到了 12% 和 14%。粤语更极端,如果语言指定 Chinese,模型会努力把粤语“翻译”成普通话文本,出来的东西语义上大致对,字面上已经面目全非。要认粤语得显式指定 language 为 Cantonese,或者干脆用支持粤语的其他方案。
背景噪声是另一个大变量。安静室内录的访谈,和咖啡厅、地铁、车载环境录的同一段话,CER 能差三到五倍。我对噪声的感知是,稳态噪声(空调、风扇)Whisper 处理得还行,模型会把它们当背景忽略。突发噪声(关门、敲桌子、咳嗽)危害更大,容易在转写里插入莫名其妙的词,或者把相邻的字切碎。做录音采集时,一个领夹麦就能把准确率拉高一大截,比换模型划算得多。
专业术语是中文场景里最容易被低估的坑。通用语料上训练出来的模型,碰到医学术语、法律条款、金融产品名、内部项目代号,几乎必错。我做过一段法律访谈的测试,large-v3 在通用文本上 CER 6%,一段合同术语密集的对话 CER 冲到 20% 以上。错误模式很有规律:同音替换为主,比如把“抵押权”写成“低押权”,把“不可抗力”写成“不可抗拒”。这种情况光靠加大模型没用,得靠后面的热词和提示词手段去补。
还有一个常被忽略的因素是说话风格。语速快、连读多、停顿少、夹杂英文单词的中文,Whisper 处理起来普遍更吃力。我录过一段技术分享,讲者中英混着说,转写结果里英文部分反而准确率更高,中文部分错得更多。我猜是模型对英文的 token 更熟悉,中文部分在中英切换的边界容易迷路。
3.4 提示词、热词、微调与后处理优化策略
initial_prompt 是我用得最多的一个优化手段。它相当于给模型一段上下文,让它在解码时倾向于某些用词。我通常会把这批音频里高频出现的专有名词塞进 prompt,比如“本次会议涉及的产品是星云平台、青松数据库、灵犀中台”。模型看到这些词之后,后续转写里出现这些词的概率明显上升。prompt 长度有限制,塞太多反而干扰,我一般控制在几十个字到一百字之间。prompt 里用词要和音频里实际说话风格接近,太书面反而会让转写也变得书面。
热词表或者叫词表偏置,在 faster-whisper 和一些第三方实现里支持得更好。它的原理是在解码时对给定词序列加权,比 prompt 那种软性引导更硬。我用 faster-whisper 的 hotwords 参数测过一批人名和产品名,准确率从原来的六成多提升到八成以上。代价是如果热词表塞得太杂,模型会强行把发音相近的词也替换成热词,反而引入新错误。热词表要精简,宁可少,不可滥。
微调我一直持谨慎态度。Whisper 的微调不像传统 ASR 那么直接,模型规模大、训练数据要求高、显存消耗也大。我自己只在一个垂直领域试过 LoRA 微调,用大概二十小时标注数据,在 large-v3 上跑,最终 CER 从 9% 降到 6.5%,提升有限,边际成本很高。如果领域非常窄、错误模式又非常集中,微调值得试。否则我更愿意把预算花在采集端和热词表上。
后处理是性价比最高的一环,尤其是中文。我常做的后处理包括:把阿拉伯数字和中文数字按场景统一、把英文缩写规范成标准写法、把“嗯”“啊”“那个”这类口头语按需删掉、把明显违反语法的片段用规则或者大模型修一遍。我最近的一个做法是用本地跑的一个小语言模型对每段转写做“错别字纠正”,只改同音字、不改句式,CER 能再降两到三个点。这一步听着像雕花,落到实际交付上,客户感知的提高非常明显。
衡量这些优化有没有用,我一般固定一个测试集,每次都拿同一批音频跑,比对 CER、实体词准确率和句子完全正确率。测试集我分成了“干净”“噪声”“方言”“专业”四组,每组半小时左右,跑一轮下来大概二十分钟 GPU 时间。这个习惯让我省了不少“感觉变好了但其实没变”的自我感动。
4.1 会议记录与访谈转写
我接过一个客户是做企业咨询的,他们每天平均有六到八场客户会议,之前全靠实习生边听录音边打字,一份一小时的会议纪要要花三四个小时才能出稿。他们的核心诉求不是把每句话写得漂亮,而是别漏掉客户提到的关键需求、预算数字、时间节点。我拿 Whisper 给他们搭了一套流程:会议录音丢进去,large-v3 跑一遍,输出带时间戳的文本,再叠一层后处理把数字和专有名词规范化。实习生不再逐字听,改成拿着转写稿做核查和提炼。一份纪要的处理时间从三小时压到四十分钟左右。
访谈转写跟会议有个挺不一样的地方。会议里大家说话相对规整,有主持人控制节奏。访谈是一对一深聊,被访者会停顿、会自我修正、会突然跑题。我做过一批用户调研访谈的转写,发现 Whisper 在长停顿的地方容易把两句话拼到一起,说话人切换的位置也猜得不准。这套场景里 diarization(说话人分离)比转写本身还重要。我的做法是 Whisper 负责出文本和时间戳,再用 pyannote 之类的工具做说话人标注,两边按时间轴对齐。对齐这一步有不少坑,时间戳有偏差的时候会把一句话算到另一个人头上,得手动校准。
落地到实际交付,我一般会给客户一个“可用率”的口径:转写稿里不需要人工修改就能直接引用的句子占多大比例。会议场景通过 prompt 喂进参会人名单和议题关键词,可用率能拉到八成以上。访谈场景因为口语化程度高,可用率通常六到七成,剩下三成主要是语气词、重复词和说话人归属需要人工过一遍。客户对这个数字接受度挺高,他们算过账,人工成本省下来的部分远大于机器跑一轮的电费。
4.2 音视频字幕生成与翻译
字幕生成是我帮个人创作者用得最多的一块。一条十分钟的视频,用 small 或 medium 跑一遍,出来带时间戳的 SRT,直接丢进剪辑软件里微调。这个流程我做过几十次了,感受是技术本身没有太大门槛,难的是时间轴质量。Whisper 输出的时间戳有时候会漂,尤其是背景音乐存在、人声不连续的时候,字幕会一闪而过或者停留太长。我的补救办法是在调字幕时把最短显示时长和最长显示时长设个范围,再用工具自动拉平,最后人工过一遍断句。
翻译这块是另一个维度。Whisper 本身带 translate 任务,能把非英语音频直接转成英文文本。我拿中文播客试过,转出来的英文大意对,但句式偏直译,读起来像机器翻译的早期产品。给双语字幕用的场景,我更倾向于先用 Whisper 出原文,再用单独的翻译模型或者大语言模型过一遍,译文自然度和术语一致性都好得多。成本是多跑一步,质量提升带来的收益比省下的时间更值。
有一种情况需要特别留意,就是多语种混杂的视频。我处理过一个中英日三种语言混着说的访谈,Whisper 指定语言为中文时,英文部分转得不错,日文部分直接崩了。后来改成让它自动检测语言,它会在语种切换的地方做切换,但断句稳定性下降。这类内容我现在的处理方式是先做语种分段,再按段指定语言分别转,最后合并。听起来笨,实际效果比图省事跑一遍好得多。
4.3 实时语音转写与语音助手
实时这块上,我对 Whisper 的态度一直是“能用,但不是天生为它设计的”。Whisper 是整段音频喂进去、整段文本出来的架构,要做实时,只能靠不停的滑窗——攒一小段音频,转一次,再攒一小段,再转一次。窗口长度、重叠长度、延迟、准确率这四个参数互相拉扯。我把窗口设得太短,句子上文不够,模型经常把半个词拼出来。窗口设长了,延迟就上去了,用户说话要等好几秒才看到字。我试出来的一个相对舒服的区间是两秒窗口配半秒重叠,延迟控制在可接受范围,准确率也还行。
语音助手场景比实时转写要求更高。语音助手不是把话转成字就完了,它要转完字之后去理解意图、调工具、再合成语音回复。整条链路下来,Whisper 只是最前面的一环。我帮一个团队做过内测版的语音问答助手,转写这一环用 faster-whisper 跑在本地 GPU 上,端到端延迟大概在一秒半到三秒之间。用户体验上,超过两秒就开始感觉到“不流畅”,所以后来把模型从 large 换成了 small,准确率掉一点,响应速度救回来一大截。这个取舍在实时场景里几乎是必然的。
真正把实时做扎实的,一般不是靠 Whisper 单打独斗。我见过比较成熟的方案是流式 ASR 引擎做初稿,Whisper 做离线校对。用户看到的字幕是流式引擎出的,延迟低但有小错;等说完一句话之后,后台用 Whisper 重跑一遍,把定稿覆盖上去。这种“先快后准”的两段式结构,我最近半年在好几个项目里都见到类似思路。Whisper 在这里的角色更像后端质检,不是前端冲锋。
4.4 播客、课程、法律与医疗等垂直场景
播客是我个人用得最舒服的场景。音频录得干净,说话人固定,语速平稳,背景音乐基本没有。这种条件下 large-v3 转出来的文本,我大概只需要改几个词就能直接当show notes 或者文字稿发出去。我做过一个系列播客的转写,一共二十期,每期四十分钟,全程用 large-v3,转录加校对平均一期花四十分钟人工时间。以前纯手打,一期要六个小时。这个差距对个人内容创作者来说是改变工作方式的级别。
课程场景比播客复杂一点。老师讲课会写板书、放PPT、点名提问、讲着讲着跑题再拉回来。这些内容在音频里表现为大量的停顿、嘈杂的互动、突然的语速变化。我给一家在线教育机构做过课程字幕转写,转完之后的实际可用率大概七成。漏掉的往往不是知识点,而是老师临场举的例子和互动环节。他们的处理方式是只把知识点段落做成字幕,互动部分留给助教手动补。这个取舍挺务实,机器擅长什么就让它干什么,别硬求全。
法律和医疗是我最谨慎对待的两块。这两个领域错一个字代价就很大,一个药名错了或者一个条款用词错了,后果不是“读起来别扭”那么轻。我在医疗场景里的做法是:Whisper 出初稿,热词表把药品名、诊断名、科室名塞进去,再用一层规则+小语言模型做同音纠错,最后人工逐句过。整个链路里机器负责的是“把八成工作做完”,那两成的关键校对绝对不能省。有客户问能不能全自动,我的回答一直是暂时别想,风险不对等。
法律场景跟医疗的差别在于,法律文本的句式长、嵌套多、条款之间会引用。Whisper 碰到“根据第X条第X款之规定,若……则……”这种结构,断句容易乱,逗号句号乱加,条款编号也容易错。我现在的做法是在 prompt 里把合同涉及的常见条款关键词塞进去,转写完之后再跑一遍编号规范化,把“第三条第二款”这类表达统一格式。这一套组合下来 CER 能压到比较可用的水平,但离“不用人看”还有距离。我给客户的定位一直很明确:Whisper 是帮你把重复劳动干掉,不是帮你去承担责任。
5.1 GPU、CPU 与 Apple Silicon 推理加速方案
我最早跑 Whisper 是在一台没有独立显卡的笔记本上,tiny 模型转十分钟音频要等好几分钟,换成 base 更慢。后来上了 RTX 3060,large 模型也能跑到接近实时。GPU 加速的核心是 CUDA 和 cuDNN,PyTorch 版本要匹配。装对了之后,fp16 推理比 fp32 快一倍多,显存占用也降。我一般推荐至少 8GB 显存跑 large,6GB 跑 medium,4GB 跑 small。量化是另一条路,int8 能在 CPU 上把速度拉起来,精度损失有限。
CPU 场景我试过用 OpenVINO 和 oneDNN 优化过的 PyTorch,速度比默认版快不少,但离 GPU 还是有距离。适合没有显卡、音频量不大的用户。我拿一台 i7 笔记本跑 small 模型,实时率大概 1.5 到 2 倍,也就是转一小时音频要一个半到两小时。这速度做批处理勉强,做实时完全不行。
Apple Silicon 是独立的一档,M1/M2/M3 的神经引擎和统一内存让 whisper.cpp 跑得挺舒服。我拿 M2 MacBook Air 试过 whisper.cpp 的 medium 模型,实时率大概 0.5 到 0.8,转一小时播客要四十多分钟。好处是功耗低、风扇不转、不占显存。Core ML 后端也能用,但模型转换麻烦,社区支持不如 whisper.cpp 成熟。我一般给 Mac 用户推荐 whisper.cpp 配 Metal 后端,省心。
5.2 faster-whisper、whisper.cpp 等实现对比
faster-whisper 是我现在生产环境的主力。它底层用 CTranslate2,把 PyTorch 模型转成更高效的推理格式,支持 fp16、int8 量化,显存占用比原版低不少。速度上,同样 GPU 跑 large-v3,faster-whisper 比 openai-whisper 快三到四倍,批处理开起来还能再快。API 跟原版接近,迁移成本低。我拿它跑长音频,配合 VAD 和批处理,一小时音频几分钟就出结果。
whisper.cpp 是纯 C/C++ 实现,不依赖 PyTorch,编译完一个二进制文件就能跑。它最吸引我的是部署简单,树莓派、老 Mac、甚至手机都能跑。量化模型文件小,tiny 不到 100MB,base 一百多兆。缺点是 GPU 加速支持有限,CUDA 版本有但不如 faster-whisper 成熟,Apple Silicon 的 Metal 后端倒是挺好。我一般给不想装 Python 环境、或者要在边缘设备上跑的用户推荐 whisper.cpp。
还有几个实现值得一提,比如 WhisperX 加了强制对齐和说话人分离,Hugging Face transformers 管道适合快速实验。我做过一个对比表,选型时看三个维度:硬件、精度、延迟要求。要极致速度上 faster-whisper + GPU;要便携和低依赖上 whisper.cpp;要研究实验用 transformers。没有哪个实现通吃。
5.3 长音频分块、批处理与流式处理策略
Whisper 原版对输入音频长度有限制,30 秒窗口。长音频直接喂进去会被截断或者效果差。我最早偷懒,把整段音频切成 30 秒硬切,结果句子在切点断开,转出来的文本拼接处经常重复或漏词。后来改用 VAD 检测静音点,在静音处切,切点自然多了。VAD 我一般用 Silero VAD,轻量、准确、支持多语言。切块长度控制在 20 到 30 秒,前后留 0.5 秒重叠,避免边界丢字。
批处理是提升吞吐的关键。faster-whisper 支持 batch size,GPU 上把多个音频块拼成一个 batch 送进去,显存够的话能显著提高利用率。我试过 batch size 从 1 调到 8,large-v3 的吞吐量提升接近三倍。代价是显存占用上升,延迟也会增加一点。批处理适合离线转写,不适合实时。我一般根据显存设 batch size,8GB 显存跑 large-v3 用 batch 4 比较稳。
流式处理是另一套思路。Whisper 不是流式模型,硬做流式只能滑窗。我试过 1 秒窗口加 0.5 秒重叠,延迟低但准确率掉得厉害,句子断断续续。后来改成 2 秒窗口加 0.5 秒重叠,延迟两秒左右,勉强能用。更成熟的做法是流式引擎出初稿,Whisper 后台定稿覆盖。我最近在做一个会议实时字幕项目,前端用流式 ASR,后端用 faster-whisper 每五秒校对一次,用户看到的是先快后准的体验。
5.4 显存、内存、延迟与成本控制
显存是 GPU 部署的硬门槛。我整理过一份粗略的显存占用表:large-v3 fp16 大概 5GB 到 6GB,int8 能压到 3GB 左右;medium fp16 约 3GB,int8 不到 2GB;small 和 base 更小。实际跑起来还要看 batch size 和音频长度,长音频分块后峰值显存会涨。我一般留 20% 余量,避免 OOM。CPU 推理主要吃内存,large 模型加载要 6GB 以上,int8 量化后能降到 3GB 左右。
延迟和成本是一对矛盾。云 GPU 按小时计费,跑 large 模型每小时几美元,批量转写时我会选 spot 实例或者竞价实例,成本能降一半以上,代价是可能被中断,需要断点续跑。本地部署前期投入大,长期成本低。我算过一笔账,每天转写量超过十小时音频的话,买一张二手 3090 比租云 GPU 划算。低于这个量,云上按需跑更灵活。
成本控制还有一些小技巧。模型缓存别重复下载,Hugging Face 的缓存目录设到数据盘。转写任务排队,闲时跑批量,忙时只跑实时。音频预处理降采样到 16kHz 单声道,能减少 IO 和推理负载。我用 ffmpeg 做预处理,把视频里的音轨抽出来、降噪、归一化,转写准确率和速度都有提升。这些细节看着小,堆起来对整体成本影响不小。
6.1 Whisper 与商用 ASR、其他开源模型对比
我自己掏钱用过好几家商用 ASR,国内的有讯飞、阿里云、腾讯云,国外的有 Google Speech-to-Text、Azure Speech、AWS Transcribe。拿它们跟 Whisper 比,第一感受是商用 API 省心。注册、拿 key、调接口,几分钟就能跑通,不用管显卡、不用管模型下载。但账单也是真金白银,按分钟计费,量大了一个月几百上千很正常。Whisper 本地跑,除了电费和硬件折旧,几乎没有边际成本。这是我当初下决心折腾本地的核心原因。
准确率上,商用 ASR 在中文通用场景确实有优势,尤其是带标点、数字规范化、专有名词这些细节。我拿同一段一小时会议录音做过盲测,讯飞和阿里云的转写结果直接能读,Whisper large-v3 漏标点、偶尔断句怪,需要后处理。英文场景差距小很多,Whisper 甚至在一些带口音的音频上更稳。噪声环境下商用 API 普遍更抗造,它们背后都有专门的降噪和远场模型。Whisper 对噪声敏感,得靠前端预处理补。
开源阵营里,除了 Whisper,我用过 Kaldi、ESPnet、WeNet、FunASR。Kaldi 太老,配置复杂,新项目基本不碰。ESPnet 适合研究,工程化门槛高。WeNet 和 FunASR 是国内团队做的,中文优化明显,FunASR 的 Paraformer 模型在中文识别上跟 Whisper large 有得一拼,速度还快。我现在的做法是 Whisper 做多语言和英文主力,中文纯场景用 FunASR 或 Paraformer 兜底。没有哪个模型通吃,看语言、看场景、看团队技术栈。
6.2 本地部署常见报错与解决方案
装 Whisper 踩过的坑能写一本书。最常见的报错是 CUDA 版本不匹配,PyTorch 报 “CUDA error: no kernel image is available for execution on the device”。这基本是 PyTorch 编译时的 CUDA 版本和驱动不搭,或者显卡算力太老不被新版本支持。我的解法是先 nvidia-smi 看驱动支持的最高 CUDA 版本,再去 PyTorch 官网找对应 wheel。别用 conda 默认装的,版本经常不对。
FFmpeg 缺失是另一个高频问题,报错 “FileNotFoundError: [Errno 2] No such file or directory: 'ffmpeg'”。Whisper 读音频靠 ffmpeg,系统里没装或者没加进 PATH 就会这样。Windows 上尤其常见,我一般让用户去官网下静态编译版,解压后把 bin 目录加进环境变量。Linux 上 apt install ffmpeg 基本能解决。Mac 用 brew。装完记得开新终端,旧终端 PATH 不会刷新。
显存 OOM 报 “CUDA out of memory”,这个我遇到太多次。解法分几层:换小模型、开 int8 量化、减小 batch size、缩短音频块。我一般从减 batch size 开始试,不行再换量化。还有一个隐蔽的坑是模型下载中断,Hugging Face 缓存里留了半个文件,下次加载报校验错误。手动删掉 ~/.cache/huggingface/hub 里对应模型目录重下就行。国内网络建议配镜像站,HF_ENDPOINT 环境变量指向 hf-mirror,速度快很多。
6.3 中文场景下的模型与部署选型建议
中文用户选型,我的第一句话是别迷信 large。large-v3 中文识别确实比 small、medium 好,但速度慢、显存吃得多。如果音频清晰、说话人标准普通话,medium 甚至 small 的准确率够用,速度能快好几倍。我做过测试,一段清晰的新闻播报,small 的 CER 只比 large 高两三个百分点,但转写速度快了六七倍。日常会议记录我用 medium 起步,访谈类带口音的才上 large。
部署方式看量。个人用户、每天转写一两小时,CPU 加 int8 量化跑 small 或 base 完全够,不用买显卡。小团队、每天十几小时,一张 3060 或 4060 跑 faster-whisper 的 medium 性价比最高。专业转写、每天几十小时,建议 3090 或 4090 配 faster-whisper 批处理,吞吐拉满。Mac 用户直接 whisper.cpp,M 系列芯片的能效比在长时间批处理上很香。云上跑的话,按小时租 GPU 做批量,比按 API 分钟计费省。
中文优化有几个实操点。提示词里塞入领域词汇和人名,Whisper 的 initial prompt 能显著改善专有名词识别。热词表 faster-whisper 支持,把公司名、产品名、专业术语加进去,召回率提升明显。后处理用大语言模型做标点恢复和错字纠正,我常用 Qwen 或 GLM 做这一步,转写稿可读性上一个台阶。音频前端降噪、去混响、16kHz 单声道,这些预处理对中文识别帮助比对英文更大,中文声调对噪声更敏感。
6.4 多模态、实时化与边缘部署趋势
我关注 Whisper 生态这两年,最大的感受是它正在从单一 ASR 模型变成一个组件。多模态方向,Whisper 的音频编码器被拿去做语音情感识别、音频事件检测、甚至语音翻译的底座。GPT-4o 那类端到端语音模型出来后,传统 ASR 加 LLM 的流水线受到冲击,但 Whisper 这种专用模型在成本和可控性上仍有空间。我判断未来几年 Whisper 会更多地作为语音前端,后端接大模型做理解和生成。
实时化是另一条明显的线。Whisper 本身不是流式架构,社区搞出了各种滑窗、分块、投机解码的方案。我试过 Whisper-Streaming 和 whisper.cpp 的 stream 示例,延迟能压到一秒以内,代价是准确率打折。更务实的路线是双轨制,低延迟小模型出草稿,Whisper 后台校正覆盖。会议字幕、直播字幕这类场景,用户对“先看到再变准”的接受度比“等三秒一次给对”高。我手上两个项目都用了这个思路。
边缘部署我特别看好。whisper.cpp 把模型压到几十兆,树莓派 5、Jetson Orin、手机都能跑。离线语音助手、车载语音、工业巡检这些场景,数据不出设备、不依赖网络,隐私和延迟都占优。我拿树莓派 5 跑 tiny 模型做过实验,实时率接近 1,简单指令识别够用。量化技术还在进步,int4、混合精度这些手段会让边缘端能跑的模型越来越大。Whisper 的下一站,我觉得在端侧。