前阵子女朋友去读研,授课是全英的,加之又有很多专业名词,有时就会出现理解能力跟不上讲课速度的情况。
因此借助课堂回放/录音复习也变成了一项每周必做的工作,但是完全回看一个三小时长的课程显然是不现实的,所以,音视频转文字就成了必选项。
我是飞书妙记的会员,所以遇到了这个需求,我马上想到先用妙记试试。
然而,尝试转录的结果表明,妙记在专业课程上的转录准确度相当差,无法满足通过文字转录来提高复习速度的需求。
其他商用服务(如通义听悟、讯飞听见、Notta 等)的转录效果和飞书妙记差不太多,大体原因有三点:
基于问题 2 和 3 ,我放弃了继续寻找其他商业 ASR 服务的想法。
因为平时业务里我自己基于 OpenAI 发布的 Whisper API 写了不少工作流,所以我又试了试 Whisper(Large-v2)的转录效果。——非常惊艳,甚至连符号的写法(theta_i^t)它都转写了出来。
这里简要介绍一下 Whisper,Whisper 是 OpenAI (没错,还是 chatGPT 背后的公司)在 2022 年 9 月开源的音频转文本的模型,它的转写精确度非常高。
但想使用 Whisper 进行转写也并非易事。它有两种实现方式:云端 Or 本地。
云端转写的优势在于不会受到本地机器性能的限制,且速度相对较快。但它存在两个问题:
本地转写的话倒是没有上述两个问题,但本地转写的麻烦之处在于:
且不论是云端转还是本地转,上述方案只是实现了音频转文字的过程,但却少了一个直观的用户界面,帮助我们快速通过文字理解音频内容。
一个理想的转文字结果页面可以借鉴妙记的设计:
Potplayer 的字幕浏览器倒是能变相实现这个效果,但它文本一长就被截断了,也就是勉强能用的程度。
后来某天逛小众软件的时候发现了 Memo AI 的内测,它的功能刚好能满足我的需求。
这可真是刚想瞌睡就有人送枕头。有了 Memo 之后,下面就可以介绍我们整个转录工作的流程了。
音视频文件主要有两种来源:学校提供的课程视频回放、手机/录音笔的录音结果。
某些课程在 Canvas LMS 平台上提供了视频回放的功能,但却没有视频下载的选项。
不过网站视频的下载也并不困难,视频是基于 m3u8 的,并且没有加密。只需要获取到 m3u8 地址,随后使用 m3u8下载器就能把视频下载到本机。
至于提取视频url的工具,我推荐使用 xifangczy/cat-catch: 猫抓 chrome资源嗅探扩展。通过使用“猫抓”,可解决大约 80% 的网页视频下载问题。
m3u8 下载器则推荐 N_m3u8DL-CLI,一键搞定。
没有提供视频回放的课程只能通过自己录音来解决。设备不外乎两种:手机或者录音笔。
至于具体选什么设备,这里得根据自己的情况来确定。
通常,手机的远距离收音效果比较一般。在课堂这样的场合,如果不能坐在前排,老师的声音往往会被其他噪音掩盖。
录音笔的效果通常会比手机更好,一般 100-200 元的价格就可以满足需求。
如果是部分留学&专业课程场景,不建议为了实时语音转文字功能而选择某些录音笔,可能会有三个比较大的问题:
有时, 录音效果可能比较尴尬。这可能是由于手机的收音能力较弱,或者是录音位置与声源之间的距离过大。这种情况下,我们可能会遇到以下问题:
因此,在进行转录前,最好先对音频进行一些处理,这可以有效提升 Whisper 转录的效果。我主要做三个操作:人声增强、降噪、响度均衡。
具体的软件在 Windows 上我使用 Pr,在 Mac 上我使用 Final Cut Pro。
下载的课程回放视频通常都包含 20 至 30 分钟的课间休息时间,我通常会选择把这部分片段从视频里切掉。这么做有两个目的:
减小文件体积:一个 3 小时的回放视频大约占据 1.5G 的空间,移除 30 分钟的视频可以节省约 200M 的存储空间。
降低 Whisper 出现幻觉的可能:虽然 Whisper 的转写精度相当高,但它偶尔也会出现幻觉——即从某一时间点开始,转录文本会不断重复某句话。而大量的空白时间可能会触发这种幻觉。
手动删除空白时间段内容是一种很糙的解决方案,更优雅的方案是结合声音活动检测(VAD, Voice Activity Detection) 来做转写,自动忽略掉空白时间段。(开发者说 Memo 的后续版本会接入 VAD)
至于切视频,可以使用 Pr/FCP 等剪辑软件,但这种方式需要重新编码处理后的视频,比较耗时间。愿意折腾一下的话此处建议使用 ffmpeg 通过复制流的方式来做,通常 3 小时的视频文件切掉空白只需几秒钟。
核心的命令为两个:
从视频里提取特定时间段
$$ffmpeg -i "{OriFileLoc}" -ss {RangeTimeStart} -to {RangeTimeEnd} -c:v copy -c:a copy "{OriFileParDir}\temp\temp_video_{temp_video_index}{OriFileExtension}"
利用 concat 衔接多个视频(格式一致)
$$ffmpeg -y -hide_banner -vsync 0 -safe 0 -f concat -i "{OriFileParDir}\temp\fileList.txt" -c copy "{OriFileParDir}\RmBlank_{OriFileName}{OriFileExtension}"
你可以把本地文件地址丢给 chatGPT 让他直接给你生成最终的命令,抑或使用 QuickCut: Your most handy video processing software 或者我编写的 Quicker 动作。
与传统的 ASR 模型不同,Whisper 在某些情况下可以借助 Prompt 提升音频转文字的准确度。
虽然同属于 OpenAI,但 Whisper 和 chatGPT 的 Prompt 差别非常大。
如果 Whisper 的 Prompt 是 "请尽力保持每句话的完整 并给每句话都添加标点符号",你会发现这句 Prompt 没有任何作用,Whisper 的转录结果里可能还是会出现大量中断的句子,或者转录结果无标点。
这是因为 Whisper 是在尝试学习 Prompt 里的“风格(style)”,而非具体的指令。
那什么是 Prompt 的“风格”?
根据 Whisper 的 cookbook、 Whisper prompt 的 issues 和我的实际体验,Prompt 的风格可以表现在下面几个方面:
Whisper 的转录结果有时会缺乏标点符号,这个时候你可以使用带标点符号的 Prompt 的来引导 Whisper 添加标点。
Prompt 1 是有意义的,Prompt 2 是无意义的。
不过 Whisper 也不是能每一次都学会 Prompt 的风格添加标点符号。实测在 Whisper-large v2 模型下,通常英文内容使用 prompt 可以为结果添加标点,中文内容则要看运气。
这里比较好理解,不同的词汇可能会有同一个发音。你可以在 Prompt 里指定你希望的拼写格式。
比如一段对话里提到了张三和李四,而“张三”的音同“章三”、“樟叁”...
那 Prompt 里就可以包含 “张三,李四。”
这里直接引用官方的说法来解释,翻译成中文会有点怪异。
The model may also leave out common filler words in the audio. If you want to keep the filler words in your transcript, you can use a prompt that contains them: "Umm, let me think like, hmm... Okay, here's what I'm, like, thinking."
因为中文有两种,有的时候 Whisper 会把音频以繁体中文的形式转录。此时用简体中文来陈述 Prompt 大概率可以解决此问题。
一般建议 Whisper 的 Prompt 语言和转录的音频语言一致。即英文音频用英语 Prompt,中文音频用简中/繁中 Prompt。
这个技巧来自于 prompt vs prefix in DecodingOptions ,有的时候会有效果。
单纯的 Whisper 模型并不能在转录结果里区分出说话人,想要区分说话人,一般会配合 Pyannote 来做。但在某些场景下,我们可以通过 Prompt 来变相实现区分说话人——每一句的转录结果都属于单个说话人,不会出现某一句的转录结果属于多个说话人的情况。
方法就是用一个对话式的 Prompt:
播客这种场景可以试试。
Whisper 的 Prompt 应该尽可能长一些,太短的 prompt 的风格难以学习。
Whisper 的 Prompt 只会使用 224 个 token,如果超过 224 个 token 则会默认使用最后 224 个 token。token 的概念可以参考这篇文章,但 Memo 的 Prompt 直接限制了字符串长度,这里就不用在乎 token 长度了,只需要尽量让自己的 prompt 完整输入到 Memo 输入框里就行。
Whisper 的 Prompt 最好和音频的源语言一致。
因为我主要转录的是课程内容,所以我的 Whisper Prompt 通常会使用这节课的关键词列表。如果课程有讲义 pdf 文件,我会直接把它丢给 Claude,然后:
summarize the file, response me with format like :"keyword1, keyword2, keyword3,keyword4.."
如果课程没有讲义,我会手动输入几个关键词,或者直接从课本里随便挑一段话作为 prompt。
Whisper 转写需要指定模型。模型越大,转写越精准,转写速度越慢。
Memo 在 Windows 和 Mac 上都实现了 GPU 加速。
Windows 电脑如果是独显机器大部分应该没什么问题,部分显卡的测试转录速度如下:
- RTX4090 显卡在 Large 模型下转录 1.2 小时音频时间为 7 分钟
- RTX3080Ti 显卡在 Large 模型下转录 1.2 小时音频时间为 8 分钟
- RTX3080Ti 显卡在 Large 模型下转录 0.4 小时日漫时间为 2 分钟
- RTX3060 laptop 显卡在 Large 模型下转录 1.2 小时音频时间为 20 分钟
- RTX3060 在 Large 模型下转录 1.2 小时音频时间为 12 分钟
- 6600XT 显卡在 Large 模型下转录 1.2 小时音频时间为 11 分钟
- 5700XT 显卡在 Large 模型下转录 1.2 小时音频时间为 15 分钟
如果你的电脑只有核显,那可能会遇到显存不足的问题。
但这里如果是 AMD 的核显,你可以尝试在 Bios 里调整显存大小。(高风险行为,谨慎操作)
游戏爆显存?显示器黑屏花屏?BIOS没有调整选项?AMD核显显存大小调整教程(UniversalAMDFormBrowser
AMD台式及笔记本改核显显存教程,核显还只有512M?
我手里的笔记本是 R7-6800H,32G 内存,出厂分配 4G 作为 GPU 显存。在 Large 模型下,开启 GPU 加速后显存会占满,转录时长:音频时长大概等于 1:2 。
我尝试把显存开到 8G,跑 Whisper 时大概会占用 6G 显存,但速度相较于 4G 显存无提升。所以如果调整 Bios 的显存大小,通常调整到 4G 就足够使用了。
Intel 的机器我手上没有,主要分享一下 M 系列的机器速度。
M 系列的 GPU 加速倍数近似和 GPU 核心数成正比:
Mac GPU 核心数对比可参考 Mac processor comparison: M1 & M2 vs Intel | Macworld。
使用 Whisper GPU 加速时,除了消耗 GPU,同时也会消耗大量内存。我用 Large 模型时 Memo 占用 6.4 G 内存。
如果是在为视频创建简易的字幕文件,那到这里基本可以收工了。但如果是在为需要快速阅读全文的课程或会议等场景进行操作,那么此处可以对转写结果做一些优化,主要解决两个问题:
开发者说这两个功能未来的版本都会实现,但在没实现之前只能靠我们自己来处理了。我写了一段 Python 的脚本将原始的字幕转换成段落模式的字幕:Adjust_SubTitle: 调节 Whisper 转录生成的 srt 文件,避免一句话被分成两行,避免一句话过短。
你可以导出原始转录的 srt 文件,然后修改 AdjustSrt.py 里的 srt 文件路径,运行脚本后会自动在原始路径下生成段落模式的 srt 的字幕。最后只需重新创建 Memo 任务,同时指定需导入的音频和字幕文件即可。
因为段落模式的实现逻辑是基于原始转录结果里的标点符号,所以运行脚本的前置条件是 Whisper 生成的字幕里有标点。
除此之外,基于标点符号的段落模式只能用于只有一个说话人的情况。否则可能会导致一句话里出现了多个说话人,容易造成误解。
虽然 Whisper 结合上下文的能力很强,转写准确度非常高。但 Whisper 也有两个比较麻烦的问题:
所谓“幻觉”是指 Whisper 转录的文本和音频不相关,而是在不断重复之前的转录结果。
我体验下来目前主要是两种情况会造成幻觉:
1 比较好处理,Memo 之后会引入 VAD 自动过滤空白内容。
同时根据 Ignore repeated prompt by heimoshuiyu · Pull Request #1253 · openai/whisper 这个 issue,设定 --condition_on_previous_text False
,也就是不让 Whisper 用前文的转写结果转录后面的音频,也能降低空白引起幻觉的概率,但代价是丧失了 Whisper 在上下文理解上的优势。(开发者说后续会开放此参数。)
但 2 目前还没找到比较好的解决方案,只能是再尝试对音频调整降噪、人声增强的强度试试..
从天梯榜上看,Whisper 的英语转录效果名列前茅,而对于中文的转录效果在中等水平。
上文提到过,如果是英文音频,那合适的 Prompt 大概率可以给转写结果添加标点,但中文音频则有概率无法添加标点。此时就比较尴尬了,我也没有找到比较好的解决方案,如果有朋友知道怎么解决,欢迎评论区里分享。
我曾经尝试利用 gpt 3.5 来给生成的文本添加标点符号,但由于 gpt 也存在幻觉,它经常直接将文本合并,然后时间戳和文本就对不上了。。如果用 4 的话成本则有点高。
希望这篇分享对你有所帮助,以上。
同步首发于 精准转写:利用 Whisper 处理音视频转文字不完全指南 - 少数派,沟通交流可以移步少数派方便点。