mcpField
F
faster-whisper

faster-whisper

github.com/theplasmak创意与媒体101.8k 次安装35 周前更新
代码仓库

关于 faster-whisper

使用 faster-whisper 进行本地语音转文字的技能;它是 Whisper 的 CTranslate2 重实现,支持多语言转录、字幕、说话人标记和批量处理。

主要功能

  1. 01本地多语言转录
  2. 02导出多种字幕格式
  3. 03说话人分离与音频导出
  4. 04URL、RSS 和批量转录
  5. 05转录文本搜索与章节检测
  6. 06音频标准化与降噪

适用场景

  1. 01转录访谈和讲座
  2. 02从视频生成字幕
  3. 03搜索录音中的特定语句
  4. 04处理播客 RSS 节目

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/theplasmak/faster-whisper --skill faster-whisper

安装后在 Claude Code 中输入/faster-whisper确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

requirements.txt
.clawdhubignore
LICENSE
.gitignore
README.md
CHANGELOG.md
skill.json
setup.ps1
setup.sh
scripts/
transcribe.cmd
transcribe.ps1
transcribe
transcribe.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.vttWebVTT 格式
词级时间戳./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 turbolarge-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 4GPU 显存不足时使用
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-ct2CTranslate2 模型目录
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.jsonJSON 文件:{"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.en39M最快基础快速草稿
base / base.en74M很快良好通用场景
small / small.en244M快更好大多数任务
medium / medium.en769M中等高高质量转录
large-v1/v2/v31.5GB较慢最佳最高准确率
large-v3-turbo809M快极佳高准确率(比 distil 慢)
蒸馏模型(快约 6 倍,WER 差异约 1%)
模型大小相对标准模型的速度准确率使用场景
distil-large-v3.5756M快约 6.3 倍7.08% WER默认,最佳平衡
distil-large-v3756M快约 6.3 倍7.53% WER先前的默认模型
distil-large-v2756M快约 5.8 倍10.1% WER回退方案
distil-medium.en394M快约 6.8 倍11.1% WER仅限英语,资源受限
distil-small.en166M快约 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 GPUCUDA实时速度的约 20 倍 🚀
WSL2 + NVIDIA GPUCUDA实时速度的约 20 倍 🚀
macOS Apple SiliconCPU*实时速度的约 3-5 倍
macOS IntelCPU实时速度的约 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

用法

# 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

要求:

用法:

# 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 sizebeam 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 VRAM
    • large-v3-turbo:约 4GB RAM / 约 2GB VRAM
    • tiny/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)。

参考资料

评论

支持 Markdown