前言

书接上回 播客音频提取实体方案 | GreenHatHGのBlog,我觉得总结一下现阶段每个模型的表现也是挺重要的,一方面 LLM 已经发展有点时间了,不像之前的流口水阶段了,另外则是离线 ASR 模型快速发展,音频识别效果大大提升。

总体结果

这次我选择的音频测试样本还是有点难的,有的甚至人耳识别都比较困难。测试的模型和最终的结果如下:

asr-benchmark/testdata/asr_benchmark/benchmark.report.html

alt text

结果大体是能复现的,除了 ASR 识别不稳定的问题,因为是用脚本跑,不是手动跑,所以想测试的伙伴直接把项目 GreenHatHG/ASR-benchmark 拉下来重新跑一下就行了,里面已经有了测试的样本和结果文件,也可以在上面添加自己想要测试的模型或者修改模型的参数。

测试的方法是,直接将音频整段传给 llm 的 api 或者本地 ASR 模型,没有进行分段,因为音频都是比较短,20-30s。

本地 ASR 模型测试用的设备是 Macbook Air m1,16+512,不知道为什么走不了 gpu,都是走的 cpu,不过无关要紧,对准确度识别没有影响。

如果是本地模型,还加上了测试的耗时,这个耗时不一定准,因为电脑还在跑别的程序,占用了一定的资源,但是可以作为对比参考各个模型识别速度,具体见各样本测试结果章节。

  • 在线模型:
    1. doubao-seed-2-0-lite-260428:这个是直接调用的火山官网 api,是多模态模型,直接将音频给它就好了。
    2. Gemini-3.7-flash-thinking-low:这个是直接将音频发送到 AIStudio,然后转写出音频,思考程度设置为 low。
    3. 豆包输入法 ASR:逆向豆包输入法的 ASR api,识别效果不一定代表正常使用输入法的效果,逆向的可能不完整。
    4. 通义听悟:直接音频上传通义听悟网页版本,使用默认参数。
  • 本地离线 ASR 模型:
    1. Fun-ASR-Nano-2512:测试了三款,一个是官方完整版本,另外两个则是量化模型,4bit 和 8bit。
    2. Qwen3-ASR:测试了两款参数不一样的,1.7B 和 0.6B。
    3. FireRedASR2:AED 和 CTC,AED 模型参数更大,CTC 则少得多。AED 测试了未量化版本以及 int8 版本,CTC 则是直接用的 int8 版本。因为 FireRedASR2 输出的是没有标点符号的结果,所以需要用标点模型加上标点,这里用的是自家的 FireRedPunc。

结论,建议看各个样本识别结果决定,错误率的排序不代表实际结果,有些词语其实意思差不多,但是死板的错误率也会标记为错误,具体可以看看关于错误率的计算算法:

  1. 在线 API 中 doubao-seed 总错误率最低,英文 prudent / advice 都能识别对,会把 2021 写成 二零二一年,这个写 prompt 根据要求来就行了。
  2. 本地日常可以选用 Fun-ASR-Nano 4bit(不知道为什么 8bit表现还差点,不知道是不是电脑性能限制了),缺点就是成语、生僻搭配、中英比较差。或者用 FireRed AED INT8。

关于错误率的计算

计算【识别出来的句子】和【标准句子】对比之下的错误率,有一个算法。

对比两个句子时会忽略大小写、空格和标点差异,所以会先做类似格式化的操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import unicodedata

def normalize_for_comparison(value: str) -> str:
# ---- 第一步:Unicode 规范化 ----
# 效果:
# - 全角字母数字 → 半角(A → A,1 → 1)
# - 连字分解(fi → fi)
# - 上标/下标转为普通数字(² → 2)
# - 某些符号转为等价形式(ℌ → H)
# 目的是让视觉上相近的字符在底层编码层面统一
normalized = unicodedata.normalize("NFKC", value)

# ---- 第二步:大小写折叠 ----
# casefold() 是专为不区分大小写比较设计的,比 lower() 更激进
# 例如:
# - 德语 'ß' → 'ss'
# - 希腊字母 'Σ' → 'σ'(不同位置的变体统一)
# - 土耳其语点状 i 特殊处理
# 这一步确保大小写差异完全消除
normalized = normalized.casefold()

# ---- 第三步:过滤并重建字符串 ----
# 用生成器遍历每个字符,只保留满足条件的字符
# 条件:不是空白字符 且 不是标点符号
return "".join(
character
for character in normalized
if not character.isspace() # 排除空格、制表符、换行等
and not unicodedata.category(character).startswith("P") # 过滤所有 Unicode 标点符号(句号、逗号、引号、括号等)
)

比如:

  • 格式化前: 它它的这个,告诉你怎么达成这件事情啊,它要给你的是一个prudent的一个advice。可它的前提也是因为每个人都一定想要快乐这件事情。所以我们大家去找出那个目的出来,而最能够找到,找到那个方法出来,那最能够找到那个方法,那我们就认为最prudent的一个人。
  • 格式化后: 它它的这个告诉你怎么达成这件事情啊它要给你的是一个prudent的一个advice可它的前提也是因为每个人都一定想要快乐这件事情所以我们大家去找出那个目的出来而最能够找到找到那个方法出来那最能够找到那个方法那我们就认为最prudent的一个人

接着计算两个格式化后的字符串之间的编辑距离,编辑距离定义为:将参考文本 reference 转换为识别文本 hypothesis 所需的最少单字符编辑操作次数,允许的编辑操作包括插入、删除和替换。

比如:
-标准: 它它的这个告诉你怎么达成这件事情啊它要给你的是一个prudent的一个advice可的前提也是因为每个人都一定想要快乐这件事情所以我们大家去找出那个目的出来最能够找到找到那个方法出来那最能够找到那个方法我们就认为最prudent的一个人
-识别: 他他的这个告诉你怎么达成这件事情啊他也给你的是一个prudent的一个device可的前提也是因为每个人都一定想要快乐这件事情所以我们大家去找出那个目的出来最能够找到找到那个方法出来那最能够找到那个方法我们是认为最prudent的一个人

这里需要十四次编辑:

  • 它它改写为他他,2次
  • 删除掉,一次
  • 诸如此类

这里可以看出,这个算法太死板,只能算个参考,比如它和他,这个标准是不是对的也不好说,而很多错误都是这两个字,后续有计划的话看看怎么改进这个😅

为了实现这个编辑距离的计算,AI使用了个DP算法,真的肝不动了,这个后面再了解,看这个跟音频切分用的DP转移方程差不多,看看是不是能汇总到一篇文章,如果有机会的话。

然后可以得出错误率:错误数(编辑距离)/参考文本字符数(格式化后)

各样本的测试结果

总共有8个样本,具体的音频见:asr-benchmark/testdata/asr_benchmark/sample1.wav,列出的是 sample1,sample1~sample8 都在同级别的目录下。

  1. 第一个音频的来源于西洋政治哲學概論 - 臺大開放式課程 - 14.康德論「人作為目的」,音频截断点开始于01:34:17,所以老师是有台湾口语,但是全是中文,所以难度还行。

    alt text

  2. 第二个音频同样和第一个音频来源相同,音频截断点开始于01:04:22,这次难点在于童叟无欺这四个字发言比较模糊。实际上能够有道德的原因就是因为啊,这里的实际上人耳也难听出来,我是凭大概率断定是这三个字,不一定是这三个字。😅

    alt text

  3. 第三个音频同样和第一个音频来源相同,音频截断点开始于01:23:38,难点在于中文的内容夹杂着几个英文单词。

    alt text

  4. 第四个音频来源于古典社會學理論 - 臺大開放式課程 - 5.馬克思 (一),音频截断点开始于01:33:15。难点是一八四四年经济学手稿和数字的识别。数字这里识别的基本可以,但是我这里参考采用的是阿拉伯数字,很多的结果是中文数字。

    alt text

  5. 第五个音频来源于哲學與人生 - 臺大開放式課程 - 4.神話與悲劇, 音频截断点开始于50:56,难点在于你怎么知道造完知道的识别,整体不难。

    alt text

  6. 第六个音频和第五个音频来源相同,音频截断点开始于37:26,难点在于音频时间长了点,并且序爵、序齿、序德的识别。

    alt text

  7. 第七个视频来源于知行小酒馆 - E244 对话李筱懿:站在人生中场,我为我自己鼓掌,音频截断点开始于24:18,整点难度很小,主要是换个普通话比较标准的音频来识别一下,变换一下变量。

    alt text

  8. 最后一个视频来源于中场沉思录 - EP2: 创业是“复利”,上班是“线性”: 对谈理杏仁创始人,音频截断点开始于23:57,主要也是验证国内普通话的情况,难点在于这次男方的普通话偏南方口音。

    alt text