whisper语音识别部署及WER评价

news2024/10/7 8:30:28

1.whisper部署

详细过程可以参照:🏠

创建项目文件夹

mkdir whisper
cd whisper

conda创建虚拟环境

conda create -n py310 python=3.10 -c conda-forge -y

安装pytorch

pip install --pre torch torchvision torchaudio --extra-index-url 

下载whisper

pip install --upgrade --no-deps --force-reinstall git+https://github.com/openai/whisper.git

安装相关包

pip install tqdm
pip install numba
pip install tiktoken==0.3.3
brew install ffmpeg

测试一下whispet是否安装成功(默认识别为中文)

whisper test.wav --model small
#test.wav为自己的测试wav文件,map3也支持 small是指用小模型

whisper识别中文的时候经常会输出繁体,加入一下参数可以避免:

 whisper test.wav --model small --language zh --initial_prompt "以下是普通话的句子。"
#注意"以下是普通话的句子。"不能随便修改,只能是这句话才有效果。

2.脚本批量测试

创建test.sh脚本,输入一下内容,可以实现对某一文件夹下的wav文件逐个中文语音识别。

#!/bin/bash
for ((i=0;i<300;i++));do
        file="wav/A13_${i}.wav"
        if [ ! -f "$file" ];then
                break
        fi
        whisper "$file" --model medium --output_dir denied --language zh --initial_prompt "以下是普通话的句子。"
done
                                                                                                                                

 实现英文语音识别需要修改为:

#!/bin/bash
for ((i=0;i<300;i++));do
        file="en/${i}.wav"
        if [ ! -f "$file" ];then
                break
        fi
        whisper "$file" --model small --output_dir denied --language en
done
                                                                                                                          

3.对运行出来的结果进行评测

一般地,语音识别通常采用WER,即词错误率,评估语音识别和文本转换质量。

这里我们主要采用 github上的开源项目:🌟 编写的python-wer代码对结果进行评价。

其中,我们的正确样本形式为:

 whisper输出的预测结果形式为:

 因此要对文本进行处理(去空格、去标点符号)后进行wer评价,相关代码如下:

(可根据具体情况修改calculate_WER)

import sys
import numpy

def editDistance(r, h):
    '''
    This function is to calculate the edit distance of reference sentence and the hypothesis sentence.
    Main algorithm used is dynamic programming.
    Attributes: 
        r -> the list of words produced by splitting reference sentence.
        h -> the list of words produced by splitting hypothesis sentence.
    '''
    d = numpy.zeros((len(r)+1)*(len(h)+1), dtype=numpy.uint8).reshape((len(r)+1, len(h)+1))
    for i in range(len(r)+1):
        d[i][0] = i
    for j in range(len(h)+1):
        d[0][j] = j
    for i in range(1, len(r)+1):
        for j in range(1, len(h)+1):
            if r[i-1] == h[j-1]:
                d[i][j] = d[i-1][j-1]
            else:
                substitute = d[i-1][j-1] + 1
                insert = d[i][j-1] + 1
                delete = d[i-1][j] + 1
                d[i][j] = min(substitute, insert, delete)
    return d

def getStepList(r, h, d):
    '''
    This function is to get the list of steps in the process of dynamic programming.
    Attributes: 
        r -> the list of words produced by splitting reference sentence.
        h -> the list of words produced by splitting hypothesis sentence.
        d -> the matrix built when calulating the editting distance of h and r.
    '''
    x = len(r)
    y = len(h)
    list = []
    while True:
        if x == 0 and y == 0: 
            break
        elif x >= 1 and y >= 1 and d[x][y] == d[x-1][y-1] and r[x-1] == h[y-1]: 
            list.append("e")
            x = x - 1
            y = y - 1
        elif y >= 1 and d[x][y] == d[x][y-1]+1:
            list.append("i")
            x = x
            y = y - 1
        elif x >= 1 and y >= 1 and d[x][y] == d[x-1][y-1]+1:
            list.append("s")
            x = x - 1
            y = y - 1
        else:
            list.append("d")
            x = x - 1
            y = y
    return list[::-1]

def alignedPrint(list, r, h, result):
    '''
    This funcition is to print the result of comparing reference and hypothesis sentences in an aligned way.
    
    Attributes:
        list   -> the list of steps.
        r      -> the list of words produced by splitting reference sentence.
        h      -> the list of words produced by splitting hypothesis sentence.
        result -> the rate calculated based on edit distance.
    '''
    print("REF:", end=" ")
    for i in range(len(list)):
        if list[i] == "i":
            count = 0
            for j in range(i):
                if list[j] == "d":
                    count += 1
            index = i - count
            print(" "*(len(h[index])), end=" ")
        elif list[i] == "s":
            count1 = 0
            for j in range(i):
                if list[j] == "i":
                    count1 += 1
            index1 = i - count1
            count2 = 0
            for j in range(i):
                if list[j] == "d":
                    count2 += 1
            index2 = i - count2
            if len(r[index1]) < len(h[index2]):
                print(r[index1] + " " * (len(h[index2])-len(r[index1])), end=" ")
            else:
                print(r[index1], end=" "),
        else:
            count = 0
            for j in range(i):
                if list[j] == "i":
                    count += 1
            index = i - count
            print(r[index], end=" "),
    print("\nHYP:", end=" ")
    for i in range(len(list)):
        if list[i] == "d":
            count = 0
            for j in range(i):
                if list[j] == "i":
                    count += 1
            index = i - count
            print(" " * (len(r[index])), end=" ")
        elif list[i] == "s":
            count1 = 0
            for j in range(i):
                if list[j] == "i":
                    count1 += 1
            index1 = i - count1
            count2 = 0
            for j in range(i):
                if list[j] == "d":
                    count2 += 1
            index2 = i - count2
            if len(r[index1]) > len(h[index2]):
                print(h[index2] + " " * (len(r[index1])-len(h[index2])), end=" ")
            else:
                print(h[index2], end=" ")
        else:
            count = 0
            for j in range(i):
                if list[j] == "d":
                    count += 1
            index = i - count
            print(h[index], end=" ")
    print("\nEVA:", end=" ")
    for i in range(len(list)):
        if list[i] == "d":
            count = 0
            for j in range(i):
                if list[j] == "i":
                    count += 1
            index = i - count
            print("D" + " " * (len(r[index])-1), end=" ")
        elif list[i] == "i":
            count = 0
            for j in range(i):
                if list[j] == "d":
                    count += 1
            index = i - count
            print("I" + " " * (len(h[index])-1), end=" ")
        elif list[i] == "s":
            count1 = 0
            for j in range(i):
                if list[j] == "i":
                    count1 += 1
            index1 = i - count1
            count2 = 0
            for j in range(i):
                if list[j] == "d":
                    count2 += 1
            index2 = i - count2
            if len(r[index1]) > len(h[index2]):
                print("S" + " " * (len(r[index1])-1), end=" ")
            else:
                print("S" + " " * (len(h[index2])-1), end=" ")
        else:
            count = 0
            for j in range(i):
                if list[j] == "i":
                    count += 1
            index = i - count
            print(" " * (len(r[index])), end=" ")
    print("\nWER: " + result)
    return result

def wer(r, h):
    """
    This is a function that calculate the word error rate in ASR.
    You can use it like this: wer("what is it".split(), "what is".split()) 
    """
    # build the matrix
    d = editDistance(r, h)

    # find out the manipulation steps
    list = getStepList(r, h, d)

    # print the result in aligned way
    result = float(d[len(r)][len(h)]) / len(r) * 100
    result = str("%.2f" % result) + "%"
    result=alignedPrint(list, r, h, result)
    return result

# 计算总WER
def calculate_WER():
    with open("whisper_out.txt", "r") as f:
        text1_list = [i[11:].strip("\n") for i in f.readlines()]
    with open("A13.txt", "r") as f:
        text2_orgin_list = [i[11:].strip("\n") for i in f.readlines()]

    total_distance = 0
    total_length = 0
    WER=0
    symbols = ",@#¥%……&*()——+~!{}【】;‘:“”‘。?》《、"
    # calculate distance between each pair of texts
    for i in range(len(text1_list)):
        match1 = re.search('[\u4e00-\u9fa5]', text1_list[i])
        if match1:
            index1 = match1.start()
        else:
            index1 = len(text1_list[i])
        match2 = re.search('[\u4e00-\u9fa5]', text2_orgin_list[i])
        if match2:
            index2 = match2.start()
        else:
            index2 = len( text2_orgin_list[i])
        result1=  text1_list[i][index1:]
        result1= result1.translate(str.maketrans('', '', symbols))
        result2=  text2_orgin_list[i][index2:]
        result2=result2.replace(" ", "")
        print(result1)
        print(result2)
        result=wer(result1,result2)
        WER+=float(result.strip('%')) / 100
    WER=WER/len(text1_list)
    print("总WER:", WER)
    print("总WER:", WER.__format__('0.2%'))
calculate_WER()

评价结果形如:

4.与paddlespeech的测试对比:

数据集

数据量

paddle

(中英文分开)

paddle

(同一模型)

whisper(small)

(同一模型)

whisper(medium)

(同一模型)

zhthchs30

(中文错字率)

250

11.61%

45.53%

24.11%

13.95%

LibriSpeech

(英文错字率)

125

7.76%

50.88%

9.31%

9.31%

5.测试所用数据集

自己处理过的开源wav数据

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/663165.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32单片机LED显示屏驱动原理与实现

STM32单片机驱动LED显示屏的原理与实现方法与Arduino类似&#xff0c;但涉及到的具体硬件资源和库函数可能会有所不同。下面是一个详细的介绍&#xff1a; 原理&#xff1a; STM32单片机驱动LED显示屏的原理是通过控制GPIO引脚的电平状态来控制LED的亮灭。通过设置引脚的输出电…

Jetpack Compose中的附带效应及效应处理器

Jetpack Compose中的附带效应及效应处理器 将在任何可组合函数范围之外运行的代码称为附带效应。 为什么要编写在任何可组合函数范围之外的代码&#xff1f; 这是因为可组合项的生命周期和属性&#xff08;例如不可预测的重组&#xff09;会执行可组合项的重组。 让我们通过一…

软考高级系统架构设计师(一) 考什么

目录 一、背景 二、软考(高级)的用途 三、考什么 第一科&#xff1a;综合知识 第二科&#xff1a;案例分析 第三科&#xff1a;论文 四、系统架构设计师常见的考试内容 五、模拟与训练 一、背景 系统架构设计师&#xff0c;属于软考高级考试中的一种。 二、软考(高级)…

Node搭建前端服务Mysql数据库交互一篇搞定

目录 介绍 安装环境及数据准备 代码示例 mysql连接工具类 测试方法文件 单表总量查询 单表条件查询 新增数据 修改 删除 ​编辑 ​编辑 联表查询 联表过滤 搭配express服务搭建api使用 介绍 在前端开发中,可以使用纯node前端进行服务搭建与mysql进行数据库的交互,这样…

Bun vs. Node.js

Bun vs. Node.js 你知道 Bun 吗&#xff1f;Bun 是新的 JavaScript 运行时&#xff0c;最近在技术领域引起轰动&#xff0c;它声称比 Node.js 更好。本文将展示如何使用基准分数对其进行测试。 在本文中&#xff0c;我们将介绍最近在技术领域引起轰动的新的 Bun 运行时。我们…

螯合剂试剂:DOTA-CH2-Ph-azide(HCl salt),分子式:C21H34Cl3N7O6,的相关参数信息

文章关键词&#xff1a;双功能螯合剂&#xff0c;azide叠氮 为大家介绍&#xff08;CAS&#xff1a;N/A&#xff09;,试剂仅用于科学研究&#xff0c;不可用于人类&#xff0c;非药用&#xff0c;非食用。 分子式&#xff1a;C21H34Cl3N7O6 分子量&#xff1a;586.9 英文名称&a…

限定国家及时间|心理学老师如期赴意大利访学

S老师由于个人情况变化需要办理CSC改派&#xff0c;并限定了国家且要求年底出国。我们最终用意大利巴里大学的邀请函&#xff0c;助其成功申请了CSC改派并如期出国。 S老师背景&#xff1a; 申请类型&#xff1a; CSC访问学者 工作背景&#xff1a; 高校教师 教育背景&#…

Python基础知识进阶之数据爬虫

一、爬虫概述 爬虫是指利用网络抓取模块对某个网站或者某个应用中有价值的信息进行提取。还可以模拟用户在浏览器或者APP应用上的操作行为&#xff0c;实现程序自动化。简单来说就是我们把互联网有价值的信息都比喻成大的蜘蛛网&#xff0c;而各个节点就是存放的数据&#xff0…

如何写出让业务满意的性能测试报告

目录 前言 需求背景 测试报告的作用是什么&#xff1f; 业务团队更关注哪些内容&#xff1f; 输出让业务满意的性能测试报告 总结 前言 写出一份让业务满意的性能测试报告&#xff0c;需要充分理解和呈现测试结果&#xff0c;结合业务需求进行分析和解读。 这篇文章&am…

别再错过重要任务,手机日程提醒软件用哪个

你有没有过这样的经历&#xff0c;因为平时生活、工作中太过于忙碌&#xff0c;而错过重要任务的完成&#xff1f;相信很多人都会忘记过重要的事情&#xff0c;例如平时工作太忙了&#xff0c;而忘记了之前安排好的会议。那么在待办事项越来越多的今天&#xff0c;我们如何保证…

这几个APP,你认识多少

软件一&#xff1a;AI工具导航 功能介绍 1.书写工具 包括内容创作、语法检查、内容润色等。 2.图像工具 包括文字图片生成、插图生成、在线抠图背景去除等。 3.音频工具 包含自定义风格的音乐生成、变声、配音等。 4.视频工具 包括视频生成、文字转视频、虚拟人讲解等…

vivo 游戏黑产反作弊实践

作者&#xff1a;vivo 互联网安全团队 - Cai Yifan 在数字化、移动化的浪潮下&#xff0c;游戏产业迅速发展&#xff0c;尤其疫情过后许多游戏公司业务迎来新的增长点。 游戏行业从端游开始一直是黑灰产活跃的重要场景。近年来&#xff0c;随着互联网的发展和手机市场的不断壮…

从0到1精通自动化测试,pytest自动化测试框架,用例运行规则(二)

目录 一、用例设计原则 二、help帮助 三、按以下目录写用例 四、python -m 五、执行用例规则 六、-x 遇到错误时停止测试 七、—maxfailnum 一、用例设计原则 文件名以 test_*.py 文件和 *_test.py 以 test_ 开头的函数 以 Test 开头的类 以 test_ 开头的方法 所有的包…

前端学习——HTML

C/S架构和B/S架构 1.C/S架构&#xff1a;需要安装&#xff0c;偶尔更新&#xff0c;不跨平台 2.B/S架构&#xff1a;无需安装&#xff0c;无需更新&#xff0c;可跨平台 大型专业应用、安全性要求较高的应用&#xff0c;需要采用C/S架构 前端工程师主要研发B/S架构的应用——写…

智能照明控制系统助力某商业综合体实现“双碳”

摘要&#xff1a;智能照明是当前非常普及的一种照明控制方式。广泛使用于建筑物,景观&#xff0c;公共场所。本文以智能照明在商业综合体中的应用为基础&#xff0c;主要介绍了智能照明系统的功能与特点&#xff0c;系统运用的效果&#xff0c;在建筑自动化系统中的地位及优势等…

项目前期准备 -- 手把手教你做ssm+springboot入门后端项目黑马程序员瑞吉外卖(一)

文章目录 前言一、导学内容1.前置知识&#xff08;必备&#xff09;2.博客收获3.效果展示4.软件开发流程整体介绍4.瑞吉外卖整体项目介绍 二、开发环境搭建1.数据库环境搭建2.maven环境搭建 总结 前言 为了巩固所学的知识&#xff0c;作者尝试着开始发布一些学习笔记类的博客&…

Zoho Bigin表现亮眼,入选国际软件测评机构多项Top榜单

科技重新赋能企业发展动力&#xff0c;数字化转型成为降本增效的好方法。 然而真正落地到企业层面&#xff0c;尤其小微企业&#xff0c;做好数字化转型&#xff0c;并不是件容易的事情&#xff0c;需要多管齐下&#xff0c;长期投入时间和资金。 小微企业由于自身业务规模及…

Golang笔记:使用json包处理JSON数据

文章目录 目的Decoding&#xff08;解析数据&#xff09;Encoding&#xff08;创建数据&#xff09;总结 目的 JSON 是一种非常流行的数据交换格式&#xff0c;是JavaScript中原生支持的一种数据&#xff0c;因为其简单方便&#xff0c;所以也经常用在不同程序、不同语言间数据…

Linux5.6 Mysql备份与恢复

文章目录 计算机系统5G云计算第四章 LINUX Mysql备份与恢复一、数据库备份的分类1. 数据备份的重要性2.数据库备份的分类3. 常见的备份方法1&#xff09;物理冷备2&#xff09;专用备份工具mysqldump或mysqlhotcopy3&#xff09;启用二进制日志进行增量备份4&#xff09;第三方…

8.2 网络分层OSI七层模型

目录 计算机网络体系结构的形成 两台计算机要互相传送文件需解决很多问题 提出了不同体系结构 国际标准&#xff1a;开放系统互连参考模型 OSI/RM 但 ISO/OSI 失败了 存在两种国际标准 协议与划分层次 协议与划分层次 协议的两种形式 层次式协议结构 划分层次的概念举…