关于 faster-whisper
使用 faster-whisper 进行本地语音转文字的技能;它是 Whisper 的 CTranslate2 重实现,支持多语言转录、字幕、说话人标记和批量处理。
主要功能
- 01本地多语言转录
- 02导出多种字幕格式
- 03说话人分离与音频导出
- 04URL、RSS 和批量转录
- 05转录文本搜索与章节检测
- 06音频标准化与降噪
适用场景
- 01转录访谈和讲座
- 02从视频生成字幕
- 03搜索录音中的特定语句
- 04处理播客 RSS 节目
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ theplasmak/ faster-whisper --skill faster-whisper安装后在 Claude Code 中输入/faster-whisper确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
requirements.txt.clawdhubignoreLICENSE.gitignoreREADME.mdCHANGELOG.mdskill.jsonsetup.ps1setup.shscripts/transcribe.cmdtranscribe.ps1transcribetranscribe.py详细介绍
Faster Whisper
使用 faster-whisper 在本地进行语音转文字。faster-whisper 是 OpenAI Whisper 的 CTranslate2 重实现,速度快 4-6 倍,准确度相同。使用 GPU 加速时,转录速度可达实时速度的 约 20 倍(10 分钟的音频文件约需 30 秒)。
适用场景
在以下情况下使用此技能:
- 转录音频/视频文件——会议、访谈、播客、讲座、YouTube 视频
- 生成字幕——SRT、VTT、ASS、LRC 或 TTML 广播标准字幕
- 识别说话人——通过说话人分离标记谁说了什么(
--diarize) - 转录 URL 内容——YouTube 链接和直连音频 URL(通过 yt-dlp 自动下载)
- 转录播客源——
--rss <feed-url>会获取并转录节目 - 批量处理文件——支持 glob 模式、目录和跳过已有文件;自动显示预计剩余时间
- 在本地将语音转换为文字——无需 API 费用,下载模型后可离线运行
- 翻译成英语——使用
--translate将任意语言翻译成英语 - 进行多语言转录——支持 99 种以上语言并自动检测
- 批量转录不同语言的文件——
--language-map为每个文件指定不同的语言 - 转录多语言音频——对混合语言音频使用
--multilingual - 转录包含特定术语的音频——对充满行话的内容或其他需要留意的术语使用
--initial-prompt - 预处理嘈杂音频(转录前)——转录前使用
--normalize和--denoise - 流式输出——使用
--stream在片段转录完成时即时显示 - 截取时间范围——使用
--clip-timestamps转录指定片段 - 搜索转录文本——使用
--search "term"查找词语/短语出现的所有时间戳 - 检测章节——使用
--detect-chapters根据静音间隔查找章节分界 - 导出说话人音频——使用
--export-speakers DIR将每位说话人的发言分别保存为 WAV 文件 - 电子表格输出——使用
--format csv生成带正确引号和时间戳的 CSV 文件
触发短语: “转录这段音频”、“将语音转换为文字”、“他们说了什么”、“生成转录文本”、 “音频转文字”、“为这个视频添加字幕”、“谁在说话”、“翻译这段音频”、“翻译成英语”、 “查找提到 X 的位置”、“搜索转录文本中的内容”、“他们什么时候说的”、“在什么时间戳”、 “添加章节”、“检测章节”、“查找音频中的停顿”、“这段录音的目录”、 “TTML 字幕”、“DFXP 字幕”、“广播格式字幕”、“Netflix 格式”、 “ASS 字幕”、“aegisub 格式”、“advanced substation alpha”、“mpv 字幕”、 “LRC 字幕”、“带时间戳的歌词”、“卡拉 OK 字幕”、“音乐播放器歌词”、 “HTML 转录文本”、“按置信度着色的转录文本”、“彩色编码的转录文本”、 “按说话人分离音频”、“导出说话人音频”、“按说话人拆分”、 “将转录文本输出为 CSV”、“电子表格输出”、“转录播客”、“播客 RSS 源”、 “批量处理不同语言”、“每个文件使用不同语言”、 “以多种格式转录”、“同时输出 srt 和 txt”、“同时输出 srt 和文本”、 “删除填充词”、“清理嗯啊等语气词”、“去掉犹豫声”、“删除‘你知道’和‘我是说’”、 “转录左声道”、“转录右声道”、“立体声声道”、“仅左声道”、 “换行显示字幕行”、“每行字符数限制”、“每条字幕的最大字符数”、 “检测段落”、“段落分隔”、“按段落分组”、“添加段落间距”
⚠️ Agent 指南——尽量减少调用参数:
CORE RULE:默认命令(./scripts/transcribe audio.mp3)是最快的处理方式——仅在用户明确要求相应功能时才添加标志。
转录:
- 只有当用户询问“谁说了什么”/“识别说话者”/“标注说话者”时,才添加
--diarize - 只有当用户要求生成特定格式的字幕/说明文字时,才添加
--format srt/vtt/ass/lrc/ttml - 只有当用户要求 CSV 或电子表格输出时,才添加
--format csv - 只有当用户需要词级时间戳时,才添加
--word-timestamps - 只有在需要使用特定领域术语进行预热时,才添加
--initial-prompt - 只有当用户想将非英语音频翻译成英语时,才添加
--translate - 只有当用户提到音频质量差或有噪声时,才添加
--normalize/--denoise - 只有当用户需要长文件的实时/渐进式输出时,才添加
--stream - 只有当用户需要指定时间范围时,才添加
--clip-timestamps - 只有当模型在音乐/静音部分产生幻觉时,才添加
--temperature 0.0 - 只有当 VAD 过于激进地截断语音或纳入噪声时,才添加
--vad-threshold - 只有在知道说话者数量时,才添加
--min-speakers/--max-speakers - 只有当令牌未缓存在
~/.cache/huggingface/token时,才添加--hf-token - 只有当长片段需要提高字幕可读性时,才添加
--max-words-per-line - 只有当转录内容包含明显伪影(音乐标记、重复内容)时,才添加
--filter-hallucinations - 只有当用户要求按句子划分字幕条目时,才添加
--merge-sentences - 只有当用户要求删除填充词(um、uh、you know、I mean、犹豫声)时,才添加
--clean-filler - 只有当用户提到立体声轨道、双声道录音或指定声道时,才添加
--channel left|right - 只有当用户指定每行字幕的字符数限制(例如,“Netflix 格式”、“每行 42 个字符”)时,才添加
--max-chars-per-line N;其优先级高于--max-words-per-line - 只有当用户要求分段或结构化文本输出时,才添加
--detect-paragraphs;只有当用户要求自定义间隔时,才添加--paragraph-gap(默认值为 3.0s) - 只有当用户提供了真实姓名,用于替换 SPEAKER_1/2 时,才添加
--speaker-names "Alice,Bob"——必须同时使用--diarize - 只有当用户指定了
--initial-prompt难以处理的特定生僻词时,才添加--hotwords WORDS;一般领域术语优先使用--initial-prompt - 只有当用户知道音频开头的确切词语时,才添加
--prefix TEXT - 只有当用户只想识别语言而不需要转录时,才添加
--detect-language-only - 只有当用户要求性能统计、RTF 或基准测试信息时,才添加
--stats-file PATH - 只有大型 CPU 批处理任务才添加
--parallel N;GPU 可高效地独立处理一个文件——单个文件或小批量任务不要添加 - 只有当输入不可靠(URL、网络文件)且可能出现暂时性故障时,才添加
--retries N - 只有当用户明确要求将字幕嵌入/烧录到视频中时,才添加
--burn-in OUTPUT;需要 ffmpeg 和视频文件输入 - 只有当用户可能会重新处理同一 URL,以避免重复下载时,才添加
--keep-temp - 只有当用户在批处理模式下指定了自定义命名模式时,才添加
--output-template - 多格式输出(
--format srt,text):只有当用户明确要求一次生成多种格式时才使用;始终与-o <dir>配对 - 任何词级功能都会自动运行 wav2vec2 对齐(额外耗时约 5-10s)
--diarize会在此基础上额外增加约 20-30s
搜索:
- 只有当用户要求在音频中查找/定位/搜索特定词语或短语时,才添加
--search "term" --search会替代常规转录输出——仅打印带时间戳的匹配片段- 只有当用户提到近似/部分匹配或拼写错误时,才添加
--search-fuzzy - 要将搜索结果保存到文件,请使用
-o results.txt
章节检测:
- 只有当用户要求章节、分节、目录或询问“主题在哪里发生变化”时,才添加
--detect-chapters - 默认的
--chapter-gap 8(8 秒静音 = 新章节)适用于大多数播客/讲座;内容密集时可调低 --chapter-format youtube(默认)会输出适用于 YouTube 的时间戳;程序化使用时请用json- 将章节与转录文本输出结合时,始终使用
--chapters-file PATH— 避免把章节标记混入转录文本 - 如果用户只需要章节(而不是转录文本),请将 stdout 管道输出到文件,并使用
-o /dev/null和--chapters-file - 批处理模式限制:
--chapters-file仅接受单一路径 — 在批处理模式下,每个文件的章节都会覆盖上一个文件的章节。要在批处理模式下检测章节,请省略--chapters-file(章节会在 stdout 中以=== CHAPTERS (N) ===为标题输出),或为每个文件单独运行一次
说话人音频导出:
- 只有当用户明确要求分别保存每位说话人的音频时,才添加
--export-speakers DIR - 始终与
--diarize配合使用 — 如果没有说话人标签,它会静默跳过 - 需要 ffmpeg;输出文件为
SPEAKER_1.wav、SPEAKER_2.wav等(如果设置了--speaker-names,则使用真实姓名)
语言映射:
- 只有在用户确认不同文件使用不同语言后,才在批处理模式下添加
--language-map - 行内格式:
"interview*.mp3=en,lecture*.mp3=fr"— 对文件名使用 fnmatch glob - JSON 文件格式:
@/path/to/map.json,文件内容为{"pattern": "lang_code"}
RSS / 播客:
- 只有当用户提供播客 RSS 订阅源 URL 时,才添加
--rss URL - 默认获取最新的 5 集;
--rss-latest 0获取全部;使用--skip-existing安全地续传 - 使用
--rss时,始终指定-o <dir>— 否则所有节目的转录文本会拼接后输出到 stdout,难以使用;设置-o <dir>后,每集都会输出到单独的文件
面向 Agent 中继的输出格式:
- 搜索结果(
--search)→ 直接输出给用户;输出内容便于阅读 - 章节输出 → 如果没有
--chapters-file,章节会在转录文本之后的 stdout 中以=== CHAPTERS (N) ===为标题输出;使用--format json时,章节也会嵌入 JSON 的"chapters"键中 - 字幕格式(SRT、VTT、ASS、LRC、TTML)→ 始终写入
-o文件;告知用户输出路径,绝不要直接粘贴原始字幕内容 - 数据格式(CSV、HTML、TTML、JSON)→ 始终写入
-o文件;告知用户输出路径,不要粘贴原始 XML/CSV/HTML - ASS 格式 → 适用于 Aegisub、VLC、mpv;写入文件,并告知用户可以在 Aegisub 中打开,或用 VLC/mpv 播放
- LRC 格式 → 供音乐播放器使用的定时歌词(Foobar2000、AIMP、VLC);写入文件
- 多种格式(
--format srt,text)→ 需要-o <dir>;每种格式分别写入单独的文件;告知用户所有输出路径 - JSON 格式 → 适合程序化后处理;不适合完整粘贴给用户
- 文本/转录文本 → 短文件可以直接展示给用户;长文件则进行总结
- 统计信息输出(
--stats-file)→ 总结关键字段(时长、处理时间、RTF),而不是粘贴原始 JSON - 语言检测(
--detect-language-only)→ 直接输出结果;结果只有一行 - 预计完成时间会自动输出到批处理任务的 stderr;无需处理
不适用的情况:
- 仅限云端且没有本地计算资源的环境
- 时长不到 10 秒、API 调用延迟无关紧要的文件
faster-whisper 与 whisperx:
此技能涵盖 whisperx 的所有功能 — 说话人分离(--diarize)、词级时间戳(--word-timestamps)、SRT/VTT 字幕 — 因此不需要 whisperx。只有在明确需要其 pyannote 流水线,或此处未涵盖的批处理 GPU 功能时,才使用 whisperx。
快速参考
| 任务 | 命令 | 说明 |
|---|---|---|
| 基础转录 | ./scripts/transcribe audio.mp3 | 批量推理,启用 VAD,distil-large-v3.5 |
| SRT 字幕 | ./scripts/transcribe audio.mp3 --format srt -o subs.srt | 自动启用词级时间戳 |
| VTT 字幕 | ./scripts/transcribe audio.mp3 --format vtt -o subs.vtt | WebVTT 格式 |
| 词级时间戳 | ./scripts/transcribe audio.mp3 --word-timestamps --format srt | 使用 wav2vec2 对齐(约 10 ms) |
| 说话人分离 | ./scripts/transcribe audio.mp3 --diarize | 需要 pyannote.audio |
| 翻译 → 英语 | ./scripts/transcribe audio.mp3 --translate | 任意语言 → 英语 |
| 流式输出 | ./scripts/transcribe audio.mp3 --stream | 转录时实时输出片段 |
| 截取时间范围 | ./scripts/transcribe audio.mp3 --clip-timestamps "30,60" | 仅处理 30s–60s |
| 降噪 + 归一化 | ./scripts/transcribe audio.mp3 --denoise --normalize | 先清理噪声音频 |
| 减少幻觉 | ./scripts/transcribe audio.mp3 --hallucination-silence-threshold 1.0 | 跳过幻觉静音 |
| YouTube/URL | ./scripts/transcribe https://youtube.com/watch?v=... | 通过 yt-dlp 自动下载 |
| 批量处理 | ./scripts/transcribe *.mp3 -o ./transcripts/ | 输出到目录 |
| 批量处理并跳过已有文件 | ./scripts/transcribe *.mp3 --skip-existing -o ./out/ | 恢复中断的批处理 |
| 领域术语 | ./scripts/transcribe audio.mp3 --initial-prompt 'Kubernetes gRPC' | 提高罕见术语的识别效果 |
| 热词加权 | ./scripts/transcribe audio.mp3 --hotwords 'JIRA Kubernetes' | 引导解码器倾向于特定词语 |
| 前缀条件 | ./scripts/transcribe audio.mp3 --prefix 'Good morning,' | 用已知的开场词为第一个片段提供种子 |
| 固定模型版本 | ./scripts/transcribe audio.mp3 --revision v1.2.0 | 使用固定版本进行可复现的转录 |
| 调试库日志 | ./scripts/transcribe audio.mp3 --log-level debug | 显示 faster_whisper 内部日志 |
| Turbo 模型 | ./scripts/transcribe audio.mp3 -m turbo | large-v3-turbo 的别名 |
| 更快地转录英语 | ./scripts/transcribe audio.mp3 --model distil-medium.en -l en | 仅支持英语,速度快 6.8 倍 |
| 最高准确率 | ./scripts/transcribe audio.mp3 --model large-v3 --beam-size 10 | 完整模型 |
| JSON 输出 | ./scripts/transcribe audio.mp3 --format json -o out.json | 提供统计信息,便于程序访问 |
| 过滤噪声 | ./scripts/transcribe audio.mp3 --min-confidence 0.6 | 丢弃低置信度片段 |
| 混合量化 | ./scripts/transcribe audio.mp3 --compute-type int8_float16 | 节省 VRAM,质量损失极小 |
| 减小批次大小 | ./scripts/transcribe audio.mp3 --batch-size 4 | GPU 显存不足时使用 |
| TSV 输出 | ./scripts/transcribe audio.mp3 --format tsv -o out.tsv | 兼容 OpenAI Whisper 的 TSV |
| 修正幻觉 | ./scripts/transcribe audio.mp3 --temperature 0.0 --no-speech-threshold 0.8 | 固定温度并跳过静音 |
| 调整 VAD 灵敏度 | ./scripts/transcribe audio.mp3 --vad-threshold 0.6 --min-silence-duration 500 | 更严格地检测语音 |
| 已知说话人数 | ./scripts/transcribe meeting.wav --diarize --min-speakers 2 --max-speakers 3 | 限定说话人分离范围 |
| 字幕词语换行 | ./scripts/transcribe audio.mp3 --format srt --word-timestamps --max-words-per-line 8 | 拆分过长的字幕条目 |
| 私有/受限模型 | ./scripts/transcribe audio.mp3 --hf-token hf_xxx | 直接传入令牌 |
| 显示版本 | ./scripts/transcribe --version | 打印 faster-whisper 版本 |
| 原地升级 | ./setup.sh --update | 无需完整重新安装即可升级 |
| 系统检查 | ./setup.sh --check | 检查 GPU、Python、ffmpeg、venv、yt-dlp、pyannote |
| 仅检测语言 | ./scripts/transcribe audio.mp3 --detect-language-only | 快速识别语言,不进行转录 |
| 以 JSON 检测语言 | ./scripts/transcribe audio.mp3 --detect-language-only --format json | 机器可读的语言检测结果 |
| LRC 字幕 | ./scripts/transcribe audio.mp3 --format lrc -o lyrics.lrc | 适用于音乐播放器的带时间戳歌词格式 |
| ASS 字幕 | ./scripts/transcribe audio.mp3 --format ass -o subtitles.ass | 高级 SubStation Alpha(Aegisub、mpv、VLC) |
| 合并句子 | ./scripts/transcribe audio.mp3 --format srt --merge-sentences | 将片段合并为句子块 |
| 统计信息伴随文件 | ./scripts/transcribe audio.mp3 --stats-file stats.json | 转录后写入性能统计 JSON |
| 批量统计信息 | ./scripts/transcribe *.mp3 --stats-file ./stats/ | 为目录中的每个输入文件生成一个统计文件 |
| 模板命名 | ./scripts/transcribe audio.mp3 -o ./out/ --output-template "{stem}_{lang}.{ext}" | 自定义批量输出文件名 |
| 标准输入 | ffmpeg -i input.mp4 -f wav - | ./scripts/transcribe - | 直接从标准输入传递音频 |
| 自定义模型目录 | ./scripts/transcribe audio.mp3 --model-dir ~/my-models | 自定义 HuggingFace 缓存目录 |
| 本地模型 | ./scripts/transcribe audio.mp3 -m ./my-model-ct2 | CTranslate2 模型目录 |
| HTML 转录文本 | ./scripts/transcribe audio.mp3 --format html -o out.html | 按置信度着色 |
| 烧录字幕 | ./scripts/transcribe video.mp4 --burn-in output.mp4 | 需要 ffmpeg 和视频输入 |
| 为说话人命名 | ./scripts/transcribe audio.mp3 --diarize --speaker-names "Alice,Bob" | 替换 SPEAKER_1/2 |
| 过滤幻觉 | ./scripts/transcribe audio.mp3 --filter-hallucinations | 移除伪影 |
| 保留临时文件 | ./scripts/transcribe https://... --keep-temp | 用于重新处理 URL |
| 并行批处理 | ./scripts/transcribe *.mp3 --parallel 4 -o ./out/ | 在 CPU 上处理多个文件 |
| 推荐 RTX 3070 | ./scripts/transcribe audio.mp3 --compute-type int8_float16 | 节省约 1 GB VRAM,质量损失极小 |
| CPU 线程数 | ./scripts/transcribe audio.mp3 --threads 8 | 强制设置 CPU 线程数(默认:自动) |
| 播客 RSS(最新 5 集) | ./scripts/transcribe --rss https://feeds.example.com/podcast.xml | 下载并转录最新的 5 集 |
| 播客 RSS(全部剧集) | ./scripts/transcribe --rss https://... --rss-latest 0 -o ./episodes/ | 处理全部剧集,每集输出一个文件 |
| 播客 + SRT 字幕 | ./scripts/transcribe --rss https://... --format srt -o ./subs/ | 为所有剧集生成字幕 |
| 失败时重试 | ./scripts/transcribe *.mp3 --retries 3 -o ./out/ | 出错时采用退避策略,最多重试 3 次 |
| CSV 输出 | ./scripts/transcribe audio.mp3 --format csv -o out.csv | 适用于电子表格,带表头并正确引用内容 |
| 带说话人的 CSV | ./scripts/transcribe audio.mp3 --diarize --format csv -o out.csv | 添加说话人列 |
| 语言映射(内联) | ./scripts/transcribe *.mp3 --language-map "interview*.mp3=en,lecture.wav=fr" | 在批处理中为每个文件指定语言 |
| 语言映射(JSON) | ./scripts/transcribe *.mp3 --language-map @langs.json | JSON 文件:{"pattern": "lang"} |
| 带预计时间的批处理 | ./scripts/transcribe *.mp3 -o ./out/ | 自动显示批处理中每个文件的预计时间 |
| TTML 字幕 | ./scripts/transcribe audio.mp3 --format ttml -o subtitles.ttml | 广播行业标准 DFXP/TTML(Netflix、BBC、Amazon) |
| 带说话人标签的 TTML | ./scripts/transcribe audio.mp3 --diarize --format ttml -o subtitles.ttml | 带说话人标签的 TTML |
| 搜索转录文本 | ./scripts/transcribe audio.mp3 --search "keyword" | 查找关键词出现的时间戳 |
| 将搜索结果保存到文件 | ./scripts/transcribe audio.mp3 --search "keyword" -o results.txt | 保存搜索结果 |
| 模糊搜索 | ./scripts/transcribe audio.mp3 --search "aproximate" --search-fuzzy | 近似/部分匹配 |
| 检测章节 | ./scripts/transcribe audio.mp3 --detect-chapters | 根据静音间隔自动检测章节 |
| 调整章节间隔 | ./scripts/transcribe audio.mp3 --detect-chapters --chapter-gap 5 | 间隔 ≥5s 时划分章节(默认:8s) |
| 将章节保存到文件 | ./scripts/transcribe audio.mp3 --detect-chapters --chapters-file ch.txt | 保存为 YouTube 格式的章节列表 |
| 章节 JSON | ./scripts/transcribe audio.mp3 --detect-chapters --chapter-format json | 机器可读的章节列表 |
| 导出说话人音频 | ./scripts/transcribe audio.mp3 --diarize --export-speakers ./speakers/ | 将每位说话人的音频分别保存为 WAV 文件 |
| 多格式输出 | ./scripts/transcribe audio.mp3 --format srt,text -o ./out/ | 一次写入 SRT + TXT |
| 移除填充词 | ./scripts/transcribe audio.mp3 --clean-filler | 删除 um/uh/er/ah/hmm 和话语标记 |
| 仅使用左声道 | ./scripts/transcribe audio.mp3 --channel left | 转录前提取立体声左声道 |
| 仅使用右声道 | ./scripts/transcribe audio.mp3 --channel right | 提取立体声右声道 |
| 每行最多字符数 | ./scripts/transcribe audio.mp3 --format srt --max-chars-per-line 42 | 按字符数换行字幕 |
| 检测段落 | ./scripts/transcribe audio.mp3 --detect-paragraphs | 在文本输出中插入段落分隔 |
| 调整段落间隔 | ./scripts/transcribe audio.mp3 --detect-paragraphs --paragraph-gap 5.0 | 调整间隔阈值(默认 3.0s) |
模型选择
根据需求选择合适的模型:
digraph model_selection {
rankdir=LR;
node [shape=box, style=rounded];
start [label="Start", shape=doublecircle];
need_accuracy [label="Need maximum\naccuracy?", shape=diamond];
multilingual [label="Multilingual\ncontent?", shape=diamond];
resource_constrained [label="Resource\nconstraints?", shape=diamond];
large_v3 [label="large-v3\nor\nlarge-v3-turbo", style="rounded,filled", fillcolor=lightblue];
large_turbo [label="large-v3-turbo", style="rounded,filled", fillcolor=lightblue];
distil_large [label="distil-large-v3.5\n(default)", style="rounded,filled", fillcolor=lightgreen];
distil_medium [label="distil-medium.en", style="rounded,filled", fillcolor=lightyellow];
distil_small [label="distil-small.en", style="rounded,filled", fillcolor=lightyellow];
start -> need_accuracy;
need_accuracy -> large_v3 [label="yes"];
need_accuracy -> multilingual [label="no"];
multilingual -> large_turbo [label="yes"];
multilingual -> resource_constrained [label="no (English)"];
resource_constrained -> distil_small [label="mobile/edge"];
resource_constrained -> distil_medium [label="some limits"];
resource_constrained -> distil_large [label="no"];
}
模型表
标准模型(完整 Whisper)
| 模型 | 大小 | 速度 | 准确率 | 使用场景 |
|---|---|---|---|---|
tiny / tiny.en | 39M | 最快 | 基础 | 快速草稿 |
base / base.en | 74M | 很快 | 良好 | 通用场景 |
small / small.en | 244M | 快 | 更好 | 大多数任务 |
medium / medium.en | 769M | 中等 | 高 | 高质量转录 |
large-v1/v2/v3 | 1.5GB | 较慢 | 最佳 | 最高准确率 |
large-v3-turbo | 809M | 快 | 极佳 | 高准确率(比 distil 慢) |
蒸馏模型(快约 6 倍,WER 差异约 1%)
| 模型 | 大小 | 相对标准模型的速度 | 准确率 | 使用场景 |
|---|---|---|---|---|
distil-large-v3.5 | 756M | 快约 6.3 倍 | 7.08% WER | 默认,最佳平衡 |
distil-large-v3 | 756M | 快约 6.3 倍 | 7.53% WER | 先前的默认模型 |
distil-large-v2 | 756M | 快约 5.8 倍 | 10.1% WER | 回退方案 |
distil-medium.en | 394M | 快约 6.8 倍 | 11.1% WER | 仅限英语,资源受限 |
distil-small.en | 166M | 快约 5.6 倍 | 12.1% WER | 移动/边缘设备 |
.en 模型仅支持英语,对英语内容的处理速度略快、效果略好。
蒸馏模型说明: HuggingFace 建议对所有蒸馏模型禁用
condition_on_previous_text,以避免重复循环。脚本检测到distil-*模型时会自动应用--no-condition-on-previous-text。如有需要,可传入--condition_on_previous_text覆盖此设置。
自定义和微调模型
WhisperModel 接受本地 CTranslate2 模型目录和 HuggingFace 仓库名称,无需更改代码。
加载本地 CTranslate2 模型
./scripts/transcribe audio.mp3 --model /path/to/my-model-ct2
将 HuggingFace 模型转换为 CTranslate2
pip install ctranslate2
ct2-transformers-converter \
--model openai/whisper-large-v3 \
--output_dir whisper-large-v3-ct2 \
--copy_files tokenizer.json preprocessor_config.json \
--quantization float16
./scripts/transcribe audio.mp3 --model ./whisper-large-v3-ct2
通过 HuggingFace 仓库名称加载模型(自动下载)
./scripts/transcribe audio.mp3 --model username/whisper-large-v3-ct2
自定义模型缓存目录
默认情况下,模型缓存在 ~/.cache/huggingface/ 中。使用 --model-dir 可覆盖此设置:
./scripts/transcribe audio.mp3 --model-dir ~/my-models
设置
Linux / macOS / WSL2
# Base install (creates venv, installs deps, auto-detects GPU)
./setup.sh
# With speaker diarization support
./setup.sh --diarize
要求:
- Python 3.10+
- 基本转录不需要 ffmpeg — PyAV(随 faster-whisper 一同打包)负责音频解码。只有
--burn-in、--normalize和--denoise需要 ffmpeg。 - 可选:yt-dlp(用于 URL/YouTube 输入)
- 可选:pyannote.audio(用于
--diarize,通过setup.sh --diarize安装)
平台支持
| 平台 | 加速方式 | 速度 |
|---|---|---|
| Linux + NVIDIA GPU | CUDA | 实时速度的约 20 倍 🚀 |
| WSL2 + NVIDIA GPU | CUDA | 实时速度的约 20 倍 🚀 |
| macOS Apple Silicon | CPU* | 实时速度的约 3-5 倍 |
| macOS Intel | CPU | 实时速度的约 1-2 倍 |
| Linux(无 GPU) | CPU | 实时速度的约 1 倍 |
*faster-whisper 使用的 CTranslate2 在 macOS 上仅支持 CPU,但 Apple Silicon 的速度足以满足实际使用需求。
GPU 支持(重要!)
安装脚本会自动检测你的 GPU 并安装带 CUDA 的 PyTorch。只要有 GPU,就始终使用 GPU——CPU 转录速度极慢。
| 硬件 | 速度 | 9 分钟视频 |
|---|---|---|
| RTX 3070(GPU) | 约 20 倍实时速度 | 约 27 秒 |
| CPU(int8) | 约 0.3 倍实时速度 | 约 30 分钟 |
RTX 3070 提示:使用
--compute-type int8_float16进行混合量化——显存占用减少约 1GB,质量损失极小。非常适合在转录的同时运行说话人分离。
如果安装时未检测到你的 GPU,请手动安装带 CUDA 的 PyTorch:
# For CUDA 12.x
uv pip install --python .venv/bin/python torch --index-url https://download.pytorch.org/whl/cu121
# For CUDA 11.x
uv pip install --python .venv/bin/python torch --index-url https://download.pytorch.org/whl/cu118
- WSL2 用户:确保已在 Windows 上安装 适用于 WSL 的 NVIDIA CUDA 驱动程序
用法
# Basic transcription
./scripts/transcribe audio.mp3
# SRT subtitles
./scripts/transcribe audio.mp3 --format srt -o subtitles.srt
# WebVTT subtitles
./scripts/transcribe audio.mp3 --format vtt -o subtitles.vtt
# Transcribe from YouTube URL
./scripts/transcribe https://youtube.com/watch?v=dQw4w9WgXcQ --language en
# Speaker diarization
./scripts/transcribe meeting.wav --diarize
# Diarized VTT subtitles
./scripts/transcribe meeting.wav --diarize --format vtt -o meeting.vtt
# Prime with domain terminology
./scripts/transcribe lecture.mp3 --initial-prompt "Kubernetes, gRPC, PostgreSQL, NGINX"
# Batch process a directory
./scripts/transcribe ./recordings/ -o ./transcripts/
# Batch with glob, skip already-done files
./scripts/transcribe *.mp3 --skip-existing -o ./transcripts/
# Filter low-confidence segments
./scripts/transcribe noisy-audio.mp3 --min-confidence 0.6
# JSON output with full metadata
./scripts/transcribe audio.mp3 --format json -o result.json
# Specify language (faster than auto-detect)
./scripts/transcribe audio.mp3 --language en
选项
Input:
AUDIO Audio file(s), directory, glob pattern, or URL
Accepts: mp3, wav, m4a, flac, ogg, webm, mp4, mkv, avi, wma, aac
URLs auto-download via yt-dlp (YouTube, direct links, etc.)
Model & Language:
-m, --model NAME Whisper model (default: distil-large-v3.5; "turbo" = large-v3-turbo)
--revision REV Model revision (git branch/tag/commit) to pin a specific version
-l, --language CODE Language code, e.g. en, es, fr (auto-detects if omitted)
--initial-prompt TEXT Prompt to condition the model (terminology, formatting style)
--prefix TEXT Prefix to condition the first segment (e.g. known starting words)
--hotwords WORDS Space-separated hotwords to boost recognition
--translate Translate any language to English (instead of transcribing)
--multilingual Enable multilingual/code-switching mode (helps smaller models)
--hf-token TOKEN HuggingFace token for private/gated models and diarization
--model-dir PATH Custom model cache directory (default: ~/.cache/huggingface/)
Output Format:
-f, --format FMT text | json | srt | vtt | tsv | lrc | html | ass | ttml (default: text)
Accepts comma-separated list: --format srt,text writes both in one pass
Multi-format requires -o <dir> when saving to files
--word-timestamps Include word-level timestamps (wav2vec2 aligned automatically)
--stream Output segments as they are transcribed (disables diarize/alignment)
--max-words-per-line N For SRT/VTT, split segments into sub-cues of at most N words
--max-chars-per-line N For SRT/VTT/ASS/TTML, split lines so each fits within N characters
Takes priority over --max-words-per-line when both are set
--clean-filler Remove hesitation fillers (um, uh, er, ah, hmm, hm) and discourse markers
(you know, I mean, you see) from transcript text. Off by default.
--detect-paragraphs Insert paragraph breaks (blank lines) in text output at natural boundaries.
A new paragraph starts when: silence gap ≥ --paragraph-gap, OR the previous
segment ends a sentence AND the gap ≥ 1.5s.
--paragraph-gap SEC Minimum silence gap in seconds to start a new paragraph (default: 3.0).
Used with --detect-paragraphs.
--channel {left,right,mix}
Stereo channel to transcribe: left (c0), right (c1), or mix (default: mix).
Extracts the channel via ffmpeg before transcription. Requires ffmpeg.
--merge-sentences Merge consecutive segments into sentence-level chunks
(improves SRT/VTT readability; groups by terminal punctuation or >2s gap)
-o, --output PATH Output file or directory (directory for batch mode)
--output-template TEMPLATE
Batch output filename template. Variables: {stem}, {lang}, {ext}, {model}
Example: "{stem}_{lang}.{ext}" → "interview_en.srt"
Inference Tuning:
--beam-size N Beam search size; higher = more accurate but slower (default: 5)
--temperature T Sampling temperature or comma-separated fallback list, e.g.
'0.0' or '0.0,0.2,0.4' (default: faster-whisper's schedule)
--no-speech-threshold PROB
Probability threshold to mark segments as silence (default: 0.6)
--batch-size N Batched inference batch size (default: 8; reduce if OOM)
--no-vad Disable voice activity detection (on by default)
--vad-threshold T VAD speech probability threshold (default: 0.5)
--vad-neg-threshold T VAD negative threshold for ending speech (default: auto)
--vad-onset T Alias for --vad-threshold (legacy)
--vad-offset T Alias for --vad-neg-threshold (legacy)
--min-speech-duration MS Minimum speech segment duration in ms (default: 0)
--max-speech-duration SEC Maximum speech segment duration in seconds (default: unlimited)
--min-silence-duration MS Minimum silence before splitting a segment in ms (default: 2000)
--speech-pad MS Padding around speech segments in ms (default: 400)
--no-batch Disable batched inference (use standard WhisperModel)
--hallucination-silence-threshold SEC
Skip silent sections where model hallucinates (e.g. 1.0)
--no-condition-on-previous-text
Don't condition on previous text (reduces repetition/hallucination loops;
auto-enabled for distil models per HuggingFace recommendation)
--condition-on-previous-text
Force-enable conditioning on previous text (overrides auto-disable for distil models)
--compression-ratio-threshold RATIO
Filter segments above this compression ratio (default: 2.4)
--log-prob-threshold PROB
Filter segments below this avg log probability (default: -1.0)
--max-new-tokens N Maximum tokens per segment (prevents runaway generation)
--clip-timestamps RANGE
Transcribe specific time ranges: '30,60' or '0,30;60,90' (seconds)
--progress Show transcription progress bar
--best-of N Candidates when sampling with non-zero temperature (default: 5)
--patience F Beam search patience factor (default: 1.0)
--repetition-penalty F Penalty for repeated tokens (default: 1.0)
--no-repeat-ngram-size N Prevent n-gram repetitions of this size (default: 0 = off)
Advanced Inference:
--no-timestamps Output text without timing info (faster; incompatible with
--word-timestamps, --format srt/vtt/tsv, --diarize)
--chunk-length N Audio chunk length in seconds for batched inference (default: auto)
--language-detection-threshold T
Confidence threshold for language auto-detection (default: 0.5)
--language-detection-segments N
Audio segments to sample for language detection (default: 1)
--length-penalty F Beam search length penalty; >1 favors longer, <1 favors shorter (default: 1.0)
--prompt-reset-on-temperature T
Reset initial prompt when temperature fallback hits threshold (default: 0.5)
--no-suppress-blank Disable blank token suppression (may help soft/quiet speech)
--suppress-tokens IDS Comma-separated token IDs to suppress in addition to default -1
--max-initial-timestamp T
Maximum timestamp for the first segment in seconds (default: 1.0)
--prepend-punctuations CHARS
Punctuation characters merged into preceding word (default: "'¿([{-)
--append-punctuations CHARS
Punctuation characters merged into following word (default: "'.。,,!!??::")]}、")
Preprocessing:
--normalize Normalize audio volume (EBU R128 loudnorm) before transcription
--denoise Apply noise reduction (high-pass + FFT denoise) before transcription
Advanced:
--diarize Speaker diarization (requires pyannote.audio)
--min-speakers N Minimum number of speakers hint for diarization
--max-speakers N Maximum number of speakers hint for diarization
--speaker-names NAMES Comma-separated names to replace SPEAKER_1, SPEAKER_2 (e.g. 'Alice,Bob')
Requires --diarize
--min-confidence PROB Filter segments below this avg word confidence (0.0–1.0)
--skip-existing Skip files whose output already exists (batch mode)
--detect-language-only
Detect language and exit (no transcription). Output: "Language: en (probability: 0.984)"
With --format json: {"language": "en", "language_probability": 0.984}
--stats-file PATH Write JSON stats sidecar after transcription (processing time, RTF, word count, etc.)
Directory path → writes {stem}.stats.json inside; file path → exact path
--burn-in OUTPUT Burn subtitles into the original video (single-file mode only; requires ffmpeg)
--filter-hallucinations
Filter common Whisper hallucinations: music/applause markers, duplicate segments,
'Thank you for watching', lone punctuation, etc.
--keep-temp Keep temp files from URL downloads (useful for re-processing without re-downloading)
--parallel N Number of parallel workers for batch processing (default: sequential)
--retries N Retry failed files up to N times with exponential backoff (default: 0;
incompatible with --parallel)
Batch ETA:
Automatically shown for sequential batch jobs (no flag needed). After each file completes,
the next file's progress line includes: [current/total] filename | ETA: Xm Ys
ETA is calculated from average time per file × remaining files.
Shown to stderr (surfaced to users via OpenClaw/Clawdbot output).
Language Map (per-file language override):
--language-map MAP Per-file language override for batch mode. Two forms:
Inline: "interview*.mp3=en,lecture.wav=fr,keynote.wav=de"
JSON file: "@/path/to/map.json" (must be {pattern: lang} dict)
Patterns support fnmatch globs on filename or stem.
Priority: exact filename > exact stem > glob on filename > glob on stem > fallback.
Files not matched fall back to --language (or auto-detect if not set).
Transcript Search:
--search TERM Search the transcript for TERM and print matching segments with timestamps.
Replaces normal transcript output (use -o to save results to a file).
Case-insensitive exact substring match by default.
--search-fuzzy Enable fuzzy/approximate matching with --search (useful for typos, phonetic
near-misses, or partial words; uses SequenceMatcher ratio ≥ 0.6)
Chapter Detection:
--detect-chapters Auto-detect chapter/section breaks from silence gaps and print chapter markers.
Output is printed after the transcript (or to --chapters-file).
--chapter-gap SEC Minimum silence gap in seconds between consecutive segments to start a new
chapter (default: 8.0). Tune down for dense speech, up for sparse content.
--chapters-file PATH Write chapter markers to this file (default: stdout after transcript)
--chapter-format FMT youtube | text | json — chapter output format:
youtube: "0:00 Chapter 1" (YouTube description ready)
text: "Chapter 1: 00:00:00"
json: JSON array with chapter, start, title fields
(default: youtube)
Speaker Audio Export:
--export-speakers DIR After diarization, export each speaker's audio turns concatenated into
separate WAV files saved in DIR. Requires --diarize and ffmpeg.
Output: SPEAKER_1.wav, SPEAKER_2.wav, … (or real names if --speaker-names set)
RSS / Podcast:
--rss URL Podcast RSS feed URL — extracts audio enclosures and transcribes them.
AUDIO positional is optional when --rss is used.
--rss-latest N Number of most-recent episodes to process (default: 5; 0 = all episodes)
Device:
--device DEV auto | cpu | cuda (default: auto)
--compute-type TYPE auto | int8 | int8_float16 | float16 | float32 (default: auto)
int8_float16 = hybrid mode for GPU (saves VRAM, minimal quality loss)
--threads N CPU thread count for CTranslate2 (default: auto)
-q, --quiet Suppress progress and status messages
--log-level LEVEL Set faster_whisper library logging level: debug | info | warning | error
(default: warning; use debug to see CTranslate2/VAD internals)
Utility:
--version Print installed faster-whisper version and exit
--update Upgrade faster-whisper in the skill venv and exit
输出格式
文本(默认)
纯文本转录内容。使用 --diarize 时会插入说话人标签:
[SPEAKER_1]
Hello, welcome to the meeting.
[SPEAKER_2]
Thanks for having me.
JSON(--format json)
完整元数据,包括片段、时间戳、语言检测结果和性能统计信息:
{
"file": "audio.mp3",
"text": "Hello, welcome...",
"language": "en",
"language_probability": 0.98,
"duration": 600.5,
"segments": [...],
"speakers": ["SPEAKER_1", "SPEAKER_2"],
"stats": {
"processing_time": 28.3,
"realtime_factor": 21.2
}
}
SRT(--format srt)
视频播放器通用的字幕格式:
1
00:00:00,000 --> 00:00:02,500
[SPEAKER_1] Hello, welcome to the meeting.
2
00:00:02,800 --> 00:00:04,200
[SPEAKER_2] Thanks for having me.
VTT(--format vtt)
适用于网页视频播放器的 WebVTT 格式:
WEBVTT
1
00:00:00.000 --> 00:00:02.500
[SPEAKER_1] Hello, welcome to the meeting.
2
00:00:02.800 --> 00:00:04.200
[SPEAKER_2] Thanks for having me.
TSV(--format tsv)
以制表符分隔的值,与 OpenAI Whisper 兼容。列:start_ms、end_ms、text:
0 2500 Hello, welcome to the meeting.
2800 4200 Thanks for having me.
适合通过管道传递给其他工具或电子表格。没有标题行。
ASS/SSA(--format ass)
高级 SubStation Alpha 格式——Aegisub、VLC、mpv、MPC-HC 和大多数视频编辑器均支持。通过 [V4+ Styles] 部分提供比 SRT 更丰富的样式设置(字体、大小、颜色、位置):
[Script Info]
ScriptType: v4.00+
...
[V4+ Styles]
Style: Default,Arial,20,&H00FFFFFF,...
[Events]
Format: Layer, Start, End, Style, Name, ..., Text
Dialogue: 0,0:00:00.00,0:00:02.50,Default,,[SPEAKER_1] Hello, welcome.
Dialogue: 0,0:00:02.80,0:00:04.20,Default,,[SPEAKER_2] Thanks for having me.
时间戳采用 H:MM:SS.cc 格式(百分之一秒)。在 Aegisub 中编辑 [V4+ Styles] 块,即可自定义字体、颜色和位置,无需重新转录。
LRC(--format lrc)
音乐播放器使用的带时间戳歌词格式(例如 Foobar2000、VLC、AIMP)。时间戳采用 [mm:ss.xx] 格式,其中 xx 表示百分之一秒:
[00:00.50]Hello, welcome to the meeting.
[00:02.80]Thanks for having me.
启用说话人分离后,也会包含说话人标签:
[00:00.50][SPEAKER_1] Hello, welcome to the meeting.
[00:02.80][SPEAKER_2] Thanks for having me.
默认文件扩展名:.lrc。适用于音乐转录、卡拉 OK,以及任何需要与音乐播放器兼容的带时间戳文本工作流。
说话人分离
使用 pyannote.audio 识别每个人的发言时间。
设置:
./setup.sh --diarize
要求:
- HuggingFace 令牌,存放于
~/.cache/huggingface/token(huggingface-cli login) - 已接受模型协议:
用法:
# Basic diarization (text output)
./scripts/transcribe meeting.wav --diarize
# Diarized subtitles
./scripts/transcribe meeting.wav --diarize --format srt -o meeting.srt
# Diarized JSON (includes speakers list)
./scripts/transcribe meeting.wav --diarize --format json
说话人会按首次出现的顺序标记为 SPEAKER_1、SPEAKER_2 等。如果 CUDA 可用,说话人分离会自动在 GPU 上运行。
精确的单词时间戳
每当计算单词级时间戳时(--word-timestamps、--diarize 或 --min-confidence),wav2vec2 强制对齐步骤都会自动将 Whisper 约 100–200 毫秒的精度提升至约 10 毫秒。无需额外标志。
# Word timestamps with automatic wav2vec2 alignment
./scripts/transcribe audio.mp3 --word-timestamps --format json
# Diarization also gets precise alignment automatically
./scripts/transcribe meeting.wav --diarize
# Precise subtitles
./scripts/transcribe audio.mp3 --word-timestamps --format srt -o subtitles.srt
使用 torchaudio 的 MMS(大规模多语言语音)模型,支持 1000 多种语言。模型首次加载后会缓存,因此批量处理仍然快速。
URL 和 YouTube 输入
将任意 URL 作为输入即可——音频会通过 yt-dlp 自动下载:
# YouTube video
./scripts/transcribe https://youtube.com/watch?v=dQw4w9WgXcQ
# Direct audio URL
./scripts/transcribe https://example.com/podcast.mp3
# With options
./scripts/transcribe https://youtube.com/watch?v=... --language en --format srt -o subs.srt
需要 yt-dlp(会检查 PATH 和 ~/.local/share/pipx/venvs/yt-dlp/bin/yt-dlp)。
批量处理
使用 glob 模式、目录或多个路径,一次处理多个文件:
# All MP3s in current directory
./scripts/transcribe *.mp3
# Entire directory (auto-filters audio files)
./scripts/transcribe ./recordings/
# Output to directory (one file per input)
./scripts/transcribe *.mp3 -o ./transcripts/
# Skip already-transcribed files (resume interrupted batch)
./scripts/transcribe *.mp3 --skip-existing -o ./transcripts/
# Mixed inputs
./scripts/transcribe file1.mp3 file2.wav ./more-recordings/
# Batch SRT subtitles
./scripts/transcribe *.mp3 --format srt -o ./subtitles/
输出到目录时,文件名采用 {input-stem}.{ext} 格式(例如,audio.mp3 → audio.srt)。
批量模式会在所有文件处理完成后打印摘要:
📊 Done: 12 files, 3h24m audio in 10m15s (19.9× realtime)
工作流
适用于常见用例的端到端流程。
播客转录工作流
从任意播客 RSS 源获取并转录最新的 5 集:
# Transcribe latest 5 episodes → one .txt per episode
./scripts/transcribe --rss https://feeds.megaphone.fm/mypodcast -o ./transcripts/
# All episodes, as SRT subtitles
./scripts/transcribe --rss https://... --rss-latest 0 --format srt -o ./subtitles/
# Skip already-done episodes (safe to re-run)
./scripts/transcribe --rss https://... --skip-existing -o ./transcripts/
# With diarization (who said what) + retry on flaky network
./scripts/transcribe --rss https://... --diarize --retries 2 -o ./transcripts/
会议记录工作流
转录会议录音并标注说话人,然后输出整洁的文本:
# Diarize + name speakers (replace SPEAKER_1/2 with real names)
./scripts/transcribe meeting.wav --diarize --speaker-names "Alice,Bob" -o meeting.txt
# Diarized JSON for post-processing (summaries, action items)
./scripts/transcribe meeting.wav --diarize --format json -o meeting.json
# Stream live while it transcribes (long meetings)
./scripts/transcribe meeting.wav --stream
视频字幕工作流
为视频文件生成可直接使用的字幕:
# SRT subtitles with sentence merging (better readability)
./scripts/transcribe video.mp4 --format srt --merge-sentences -o subtitles.srt
# Burn subtitles directly into the video
./scripts/transcribe video.mp4 --format srt --burn-in video_subtitled.mp4
# Word-level SRT (karaoke-style), capped at 8 words per cue
./scripts/transcribe video.mp4 --format srt --word-timestamps --max-words-per-line 8 -o subs.srt
YouTube 批量处理流水线
一次转录多个 YouTube 视频:
# One-liner: transcribe a playlist video + output SRT
./scripts/transcribe "https://youtube.com/watch?v=abc123" --format srt -o subs.srt
# Batch from a text file of URLs (one per line)
cat urls.txt | xargs ./scripts/transcribe -o ./transcripts/
# Download audio first, then transcribe (for re-use without re-downloading)
./scripts/transcribe https://youtube.com/watch?v=abc123 --keep-temp
嘈杂音频处理流水线
在转录前清理低质量录音:
# Denoise + normalize, then transcribe
./scripts/transcribe interview.mp3 --denoise --normalize -o interview.txt
# Noisy batch with aggressive hallucination filtering
./scripts/transcribe *.mp3 --denoise --filter-hallucinations -o ./out/
批量恢复流水线
处理大量文件夹中的文件,并在失败时重试 — 可在失败后安全地重新运行:
# Retry each failed file up to 3 times, skip already-done
./scripts/transcribe ./recordings/ --skip-existing --retries 3 -o ./transcripts/
# Check what failed (printed in batch summary at the end)
# Re-run the same command — skips successes, retries failures
服务模式(兼容 OpenAI 的 API)
speaches 将 faster-whisper 作为兼容 OpenAI 的 /v1/audio/transcriptions 端点运行 — 可直接替代 OpenAI Whisper API,支持流式处理、Docker 和实时转录。
快速开始(Docker)
docker run --gpus all -p 8000:8000 ghcr.io/speaches-ai/speaches:latest-cuda
测试
# Transcribe a file via the API (same format as OpenAI)
curl http://localhost:8000/v1/audio/transcriptions \
-F [email protected] \
-F model=Systran/faster-whisper-large-v3
与任意 OpenAI SDK 配合使用
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000", api_key="none")
with open("audio.mp3", "rb") as f:
result = client.audio.transcriptions.create(model="Systran/faster-whisper-large-v3", file=f)
print(result.text)
如果你想将转录功能作为本地 API 提供给其他工具(Home Assistant、n8n、自定义应用),这会很有用。
常见错误
| 错误 | 问题 | 解决方案 |
|---|---|---|
| 有 GPU 可用时仍使用 CPU | 转录速度慢 10-20 倍 | 检查 nvidia-smi;确认 CUDA 已安装 |
| 未指定语言 | 对已知内容进行自动检测会浪费时间 | 知道语言时使用 --language en |
| 使用错误的模型 | 速度不必要地变慢或准确度较差 | 默认的 distil-large-v3.5 表现出色;只有遇到准确度问题时才使用 large-v3 |
| 忽略蒸馏模型 | 错失 6 倍速度提升,而准确度损失不到 1% | 考虑使用标准模型前,先试试 distil-large-v3.5 |
| 忘记安装 ffmpeg | 设置失败或无法处理音频 | 设置脚本会处理此问题;手动安装时需单独安装 ffmpeg |
| 内存不足错误 | 模型超出可用 VRAM/RAM 容量 | 使用较小的模型、--compute-type int8 或 --batch-size 4 |
| 过度调整 beam size | beam size 超过 5-7 后收益递减 | 默认值 5 已足够;关键转录可尝试 10 |
使用 --diarize 但未安装 pyannote | 运行时导入错误 | 先运行 setup.sh --diarize |
使用 --diarize 但没有 HuggingFace token | 模型下载失败 | 运行 huggingface-cli login 并接受模型协议 |
| 输入 URL 但未安装 yt-dlp | 下载失败 | 安装:pipx install yt-dlp |
--min-confidence 设置过高 | 有自然停顿的优质片段也会被丢弃 | 从 0.5 开始,再逐步调高;检查 JSON 输出中的概率 |
基础转录时使用 --word-timestamps | 增加约 5-10 秒开销,收益却微乎其微 | 仅在需要词级精度时使用 |
批量处理时未指定 -o 目录 | 所有输出混在 stdout 中 | 使用 -o ./transcripts/,为每个输入文件写入一个文件 |
性能说明
- 首次运行:将模型下载到
~/.cache/huggingface/(仅需一次) - 批量推理:默认通过
BatchedInferencePipeline启用,比标准模式快约 3 倍;默认开启 VAD - GPU:如果可用,则自动使用 CUDA
- 量化:CPU 上使用 INT8,速度提升约 4 倍,准确率损失极小
- 性能统计:每次转录都会显示音频时长、处理时间和实时系数
- 基准测试(RTX 3070,21 分钟文件):使用批量推理时(distil-large-v3 和 v3.5 均如此)约需 24 秒,未使用时约需 69 秒
- --precise 开销:加载 wav2vec2 模型并进行对齐会增加约 5-10 秒(批处理时模型会缓存)
- 说话人分离开销:根据音频时长增加约 10-30 秒(如果 GPU 可用,则使用 GPU 运行)
- 内存:
distil-large-v3:约 2GB RAM / 约 1GB VRAMlarge-v3-turbo:约 4GB RAM / 约 2GB VRAMtiny/base:<1GB RAM- 说话人分离:额外需要约 1-2GB VRAM
- OOM:如果遇到内存不足错误,请调低
--batch-size(试试 4) - 预先转换为 WAV(可选):
ffmpeg -i input.mp3 -ar 16000 -ac 1 input.wav会在转录前将文件转换为 16kHz 单声道 WAV。单次使用时收益很小(约 5%),因为 PyAV 解码效率很高;更适用于多次重新处理同一文件(研究/实验),或文件格式导致 PyAV 解码出现问题的情况。注意:--normalize和--denoise已会自动执行此转换。 - Silero VAD V6:faster-whisper 1.2.1 已升级到 Silero VAD V6(改进了语音检测)。运行
./setup.sh --update即可获取。 - 批量静音移除:faster-whisper 1.2.0+ 会在
BatchedInferencePipeline中自动移除静音(默认使用)。如果你在 2024 年 8 月之前安装,请运行./setup.sh --update升级以获取此功能。
为什么选择 faster-whisper?
- 速度:比 OpenAI 原版 Whisper 快约 4-6 倍
- 准确率:相同(使用相同的模型权重)
- 效率:通过量化降低内存用量
- 可用于生产环境:稳定的 C++ 后端(CTranslate2)
- 蒸馏模型:快约 6 倍,准确率损失低于 1%
- 字幕:原生支持 SRT/VTT/HTML 输出
- 精确对齐:自动通过 wav2vec2 优化(词边界精确到约 10ms)
- 说话人分离:可选地通过 pyannote 识别说话人;
--speaker-names可映射为真实姓名 - URL:直接输入 YouTube/URL;
--keep-temp可保留下载内容以供重用 - 自定义模型:加载本地 CTranslate2 目录或 HuggingFace 仓库;
--model-dir用于控制缓存位置 - 质量控制:
--filter-hallucinations可移除音乐/掌声标记和重复内容 - 并行批处理:使用
--parallel N进行多线程批处理 - 字幕烧录:通过 ffmpeg 使用
--burn-in将字幕直接叠加到视频中
v1.5.0 新功能
多格式输出:
--format srt,text— 一次处理即可写出多种格式(例如同时输出 SRT 和纯文本)- 接受以逗号分隔的列表:
srt,vtt,json、srt,text等 - 写出多种格式时需要
-o <dir>;单一格式的用法不变
填充词移除:
--clean-filler— 从转录文本中移除犹豫音(um、uh、er、ah、hmm、hm)和话语标记词 (you know、I mean、you see);默认关闭- 使用保守的正则表达式进行词边界匹配,以避免误报
- 清理后变为空的片段会自动丢弃
立体声声道选择:
--channel left|right|mix— 转录前提取指定的立体声声道(默认:mix)- 适用于双声道录音(采访者在左声道、受访者在右声道)
- 使用 ffmpeg pan 滤镜;如果未找到 ffmpeg,则会平稳回退到完整混音
按字符数换行字幕:
--max-chars-per-line N— 拆分字幕条目,使每行不超过 N 个字符- 适用于 SRT、VTT、ASS 和 TTML 格式;优先级高于
--max-words-per-line - 需要词级时间戳;如果没有词级数据,则回退为完整片段
段落检测:
--detect-paragraphs— 在文本输出的自然边界处插入\n\n段落分隔符--paragraph-gap SEC— 段落的最小静音间隔(默认值:3.0s)- 如果上一段以句子结尾且间隔 ≥ 1.5s,也会检测段落分隔符
字幕格式:
--format ass— Advanced SubStation Alpha(Aegisub、VLC、mpv、MPC-HC)--format lrc— 适用于音乐播放器的定时歌词格式--format html— 按置信度着色的 HTML 转录文本(每个词分别以绿色、黄色或红色显示)--format ttml— W3C TTML 1.0(DFXP)广播标准(Netflix、Amazon Prime、BBC)--format csv— 适用于电子表格的 CSV,包含标题行;采用 RFC 4180 引号规则;启用说话人分离时包含speaker列
转录工具:
--search TERM— 查找词语或短语出现的所有时间戳;取代常规输出;使用-o保存--search-fuzzy— 与--search搭配使用,进行近似或部分匹配--detect-chapters— 根据静音间隔自动检测章节分隔;--chapter-gap SEC(默认值:8s)--chapters-file PATH— 将章节写入文件而非标准输出;--chapter-format youtube|text|json--export-speakers DIR— 在--diarize后通过 ffmpeg 将每位说话人的发言分别保存为 WAV 文件
批处理改进:
- 预计时间 — 顺序批处理中,每个文件开始处理前都会显示
[N/total] filename | ETA: Xm Ys;无需设置标志 --language-map "pat=lang,..."— 按文件覆盖语言设置;支持 fnmatch glob 模式;也支持@file.json格式--retries N— 使用指数退避重试失败的文件;结束时汇总失败文件--rss URL— 转录播客 RSS Feed;使用--rss-latest N指定剧集数量--skip-existing/--parallel N/--output-template/--stats-file/--merge-sentences
模型与推理:
- 默认使用
distil-large-v3.5(取代 distil-large-v3) - 对 distil 模型自动禁用
condition_on_previous_text(防止重复循环) - 使用
--condition-on-previous-text覆盖此设置;使用--log-level输出库调试信息 --model-dir PATH— 自定义 HuggingFace 缓存目录;支持本地 CTranslate2 模型--no-timestamps、--chunk-length、--length-penalty、--repetition-penalty、--no-repeat-ngram-size--clip-timestamps、--stream、--progress、--best-of、--patience、--max-new-tokens--hotwords、--prefix、--revision、--suppress-tokens、--max-initial-timestamp
说话人与质量:
--speaker-names "Alice,Bob"— 将 SPEAKER_1/2 替换为真实姓名(需要--diarize)--filter-hallucinations— 移除音乐/掌声标记、重复内容和“Thank you for watching”--burn-in OUTPUT— 通过 ffmpeg 将字幕烧录到视频中--keep-temp— 保留从 URL 下载的音频,以便重新处理
设置:
setup.sh --check— 系统诊断:GPU、CUDA、Python、ffmpeg、pyannote、HuggingFace 令牌(约 12s 完成)- 基本转录不再需要 ffmpeg(PyAV 负责解码);
skill.json已相应更新(ffmpeg现在位于optionalBins中)
故障排除
“CUDA 不可用 — 正在使用 CPU”:安装带 CUDA 的 PyTorch(参见上文的 GPU 支持)
设置失败:确保已安装 Python 3.10+
内存不足:使用较小的模型、--compute-type int8 或 --batch-size 4
在 CPU 上运行缓慢:这是预期情况 — 实际转录请使用 GPU
模型下载失败:检查 ~/.cache/huggingface/ 的权限
说话人分离模型失败:确保 HuggingFace 令牌存在且已接受模型协议;
或使用 --hf-token hf_xxx 直接传入令牌
URL 下载失败:检查是否已安装 yt-dlp(pipx install yt-dlp)
批处理中没有音频文件:检查文件扩展名是否符合支持的格式
检查已安装版本:运行 ./scripts/transcribe --version
升级 faster-whisper:运行 ./setup.sh --update(原地升级,无需完整重新安装)
静音或音乐中出现幻觉:尝试 --temperature 0.0 --no-speech-threshold 0.8
VAD 错误切分语音:使用 --vad-threshold 0.3(调低)或 --min-silence-duration 300 进行调整
改进语音检测:运行 ./setup.sh --update,将 faster-whisper 升级到最新版本(包含 Silero VAD V6)。
参考资料
- faster-whisper GitHub
- Distil-Whisper 论文
- HuggingFace 模型
- pyannote.audio(说话人分离)
- yt-dlp(URL/YouTube 下载)