ubuntu使用DeepSpeech进行语音识别(包含交叉编译)

文章目录

  • 前言
  • 一、DeepSpeech编译
  • 二、DeepSpeech使用示例
  • 三、核心代码分析
    • 1.创建模型核心代码
    • 2.识别过程核心代码
  • 四、交叉编译
    • 1.交叉编译
    • 2.使用
  • 总结


前言

由于工作需要语音识别的功能,环境是在linux arm版上,所以想先在ubuntu上跑起来看一看,就找了一下语音识别的开源框架,选中了很多框架可以看编译vosk那篇文章,现在一一试验一下。

本篇博客将会在ubuntu上进行DeepSpeech编译使用,并且进行交叉编译。

|版本声明:山河君,未经博主允许,禁止转载


一、DeepSpeech编译

如果想先自己编编看,可以先看这里,如果想直接使用库文件等,可以跳过本节,下文会标注出官方支持的各种平台已经编好的二进制文件。

不过博主还是建议先自己编编看,因为源码中有一个文件是官方的示例文档,还是值得一看的。

  • 下载依赖项
sudo apt-get update
sudo apt-get install -y \
    build-essential \
    libatlas-base-dev \
    libfftw3-dev \
    libgfortran5 \
    sox \
    libsox-dev
 sudo apt-get install libmagic-dev
  • 下载DeepSpeech源码
git clone https://github.com/mozilla/DeepSpeech.git
cd DeepSpeech
git submodule sync tensorflow/
git submodule update --init tensorflow/
  • DeepSpeech是使用bazel构建的,下载bazel
sudo apt install curl
curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -
echo "deb [arch=amd64] https://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list
sudo apt update && sudo apt install bazel
  • 配置tensorlow
cd tensorflow
./configure
ln -s ../native_client

如果native_client不存在,使用native_client进行创建

  • 编译

只需要库文件

bazel build --workspace_status_command="bash native_client/bazel_workspace_status_cmd.sh" --config=monolithic -c opt --copt=-O3 --copt="-D_GLIBCXX_USE_CXX11_ABI=0" --copt=-fvisibility=hidden //native_client:libdeepspeech.so

库和可执行文件

bazel build --workspace_status_command="bash native_client/bazel_workspace_status_cmd.sh" --config=monolithic -c opt --copt=-O3 --copt="-D_GLIBCXX_USE_CXX11_ABI=0" --copt=-fvisibility=hidden //native_client:libdeepspeech.so //native_client:generate_scorer_package

native_client存在deepspeech可执行文件,值得注意的是,头文件是deepspeech.hclient.cc是C++示例文件
在这里插入图片描述
tensorflow/baze-bin/native_client下存在对应库文件
在这里插入图片描述

二、DeepSpeech使用示例

模型下载地址

模型文件:deepspeech-0.9.3-models-zh-CN.pbmm
打分文件:deepspeech-0.9.3-models-zh-CN.scorer
在这里插入图片描述

./deepspeech --model /home/aaron/workplace/audioread/deepspeech-0.9.3-models-zh-CN.pbmm --scorer /home/aaron/workplace/audioread/deepspeech-0.9.3-models-zh-CN.scorer --audio /home/aaron/workplace/audioread/test.wav

在这里插入图片描述

三、核心代码分析

核心代码是上文提到client.cc文件中的示例代码

1.创建模型核心代码

// Initialise DeepSpeech
    ModelState* ctx;
    // sphinx-doc: c_ref_model_start
    int status = DS_CreateModel(model, &ctx);
    if (status != 0) {
        char* error = DS_ErrorCodeToErrorMessage(status);
        fprintf(stderr, "Could not create model: %s\n", error);
        free(error);
        return 1;
    }

    if (set_beamwidth) {
        status = DS_SetModelBeamWidth(ctx, beam_width);
        if (status != 0) {
            fprintf(stderr, "Could not set model beam width.\n");
            return 1;
        }
    }

    if (scorer) {
        status = DS_EnableExternalScorer(ctx, scorer);
        if (status != 0) {
            fprintf(stderr, "Could not enable external scorer.\n");
            return 1;
        }
        if (set_alphabeta) {
            status = DS_SetScorerAlphaBeta(ctx, lm_alpha, lm_beta);
            if (status != 0) {
                fprintf(stderr, "Error setting scorer alpha and beta.\n");
                return 1;
            }
        }
    }
    // sphinx-doc: c_ref_model_stop
    status = DS_AddHotWord(ctx, word, boost);
    if (status != 0) {
        fprintf(stderr, "Could not enable hot-word.\n");
        return 1;
    }
  • DS_CreateModel:创建模型
  • DS_SetModelBeamWidth:设置搜索空间宽度,值越大,越准确,但会增大开销
  • DS_EnableExternalScorer:设置评分器
  • DS_SetScorerAlphaBeta:设置声学模型和语言模型参数。Alpha 参数:影响语言模型的权重;Beta 参数:影响语言模型中候选路径的惩罚机制。
  • DS_AddHotWord:设置某些特定词汇或短语被识别为更优先的目标词汇

2.识别过程核心代码

if (extended_output) {
        Metadata *result = DS_SpeechToTextWithMetadata(aCtx, aBuffer, aBufferSize, 1);
        res.string = CandidateTranscriptToString(&result->transcripts[0]);
        DS_FreeMetadata(result);
    } else if (json_output) {
        Metadata *result = DS_SpeechToTextWithMetadata(aCtx, aBuffer, aBufferSize, json_candidate_transcripts);
        res.string = MetadataToJSON(result);
        DS_FreeMetadata(result);
    } else if (stream_size > 0) {
        StreamingState* ctx;
        int status = DS_CreateStream(aCtx, &ctx);
        if (status != DS_ERR_OK) {
            res.string = strdup("");
            return res;
        }
        size_t off = 0;
        const char *last = nullptr;
        const char *prev = nullptr;
        while (off < aBufferSize) {
            size_t cur = aBufferSize - off > stream_size ? stream_size : aBufferSize - off;
            DS_FeedAudioContent(ctx, aBuffer + off, cur);
            off += cur;
            prev = last;
            const char* partial = DS_IntermediateDecode(ctx);
            if (last == nullptr || strcmp(last, partial)) {
                printf("%s\n", partial);
                last = partial;
            } else {
                DS_FreeString((char *) partial);
            }
            if (prev != nullptr && prev != last) {
                DS_FreeString((char *) prev);
            }
        }
        if (last != nullptr) {
            DS_FreeString((char *) last);
        }
        res.string = DS_FinishStream(ctx);
    } else if (extended_stream_size > 0) {
        StreamingState* ctx;
        int status = DS_CreateStream(aCtx, &ctx);
        if (status != DS_ERR_OK) {
            res.string = strdup("");
            return res;
        }
        size_t off = 0;
        const char *last = nullptr;
        const char *prev = nullptr;
        while (off < aBufferSize) {
            size_t cur = aBufferSize - off > extended_stream_size ? extended_stream_size : aBufferSize - off;
            DS_FeedAudioContent(ctx, aBuffer + off, cur);
            off += cur;
            prev = last;
            const Metadata* result = DS_IntermediateDecodeWithMetadata(ctx, 1);
            const char* partial = CandidateTranscriptToString(&result->transcripts[0]);
            if (last == nullptr || strcmp(last, partial)) {
                printf("%s\n", partial);
                last = partial;
            } else {
                free((char *) partial);
            }
            if (prev != nullptr && prev != last) {
                free((char *) prev);
            }
            DS_FreeMetadata((Metadata *)result);
        }
        const Metadata* result = DS_FinishStreamWithMetadata(ctx, 1);
        res.string = CandidateTranscriptToString(&result->transcripts[0]);
        DS_FreeMetadata((Metadata *)result);
        free((char *) last);
    } else {
        res.string = DS_SpeechToText(aCtx, aBuffer, aBufferSize);
    }

最核心的deepspeech接口:

函数名输入输出适用场景优缺点
DS_SpeechToText完整音频数据完整识别文本适用于一次性处理音频文件的场景简单直接,适用于批量处理,但不能处理实时流
DS_SpeechToTextWithMetadata完整音频数据完整识别文本 + 元数据(如时间戳等)适用于需要每个词或音节时间戳的场景更详细的输出,适用于字幕等场景,但复杂度略高
DS_IntermediateDecode流式输入音频数据(逐段)逐步输出识别文本适用于实时语音识别场景,如语音助手、实时转录等低延迟输出,适合流式处理,但可能不精确
DS_IntermediateDecodeWithMetadata流式输入音频数据(逐段)逐步输出识别文本 + 元数据适用于实时语音识别,且需要获取词级时间戳和置信度等详细信息更全面的输出,适用于实时字幕等场景,但复杂度更高

值得注意的是:如果是文件中语音识别,应该是使用前两个,如果是流式需要考虑延时或实时语音,应该使用后面两个

四、交叉编译

1.交叉编译

非常不建议自己进行交叉编译,建议直接使用官方版本,因为如果使用交叉编译,需要在tensflow那边就开始设置交叉编译环境,并且虽然bazel工具中存在对于aarch64环境的脚本提示(在隐藏文件.bazelrc里)

build:elinux_aarch64 --config=elinux
build:elinux_aarch64 --cpu=aarch64

但笔者尝试过,会报各种各样的错误。

官方编译好的文件,各种平台都支持,下图是版本
在这里插入图片描述

各种平台的文件,根据需要下载
在这里插入图片描述

解压后
在这里插入图片描述

2.使用

值得注意的是,如果是在linux aarch64环境下,那么使用的model受到资源限制,应该使用的是.tflite而非pbmm
在这里插入图片描述

在rk芯片上的使用结果,实际上比较消耗性能
在这里插入图片描述


总结

目前已经尝试过vosk、PocketSphinx,有兴趣的话可以看看之前的文章,实际上还有两个没有记录出来,Snowboy和Julius,有兴趣的小伙伴可以一起探讨。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

阿里云引领智算集群网络架构的新一轮变革

阿里云引领智算集群网络架构的新一轮变革 云布道师 11 月 8 日~ 10 日在江苏张家港召开的 CCF ChinaNet&#xff08;即中国网络大会&#xff09;上&#xff0c;众多院士、教授和业界技术领袖齐聚一堂&#xff0c;畅谈网络未来的发展方向&#xff0c;聚焦智算集群网络的创新变…

PyQt5 加载UI界面与资源文件

步骤一: 使用 Qt Designer 创建 XXX.ui文件 步骤二: 使用 Qt Designer 创建 资源文件 步骤三: Python文件中创建相关类, 使用 uic.loadUi(mainwidget.ui, self ) 加载UI文件 import sys from PyQt5 import QtCore, QtWidgets, uic from PyQt5.QtCore import Qt f…

7.高可用集群架构Keepalived双主热备原理

一. 高可用集群架构Keepalived双主热备原理 (1)主机+备机keepalived配置(192.168.1.171) ! Configuration File for keepalivedglobal_defs {# 路由id:当前安装keepalived节点主机的标识符,全局唯一router_id keep_101 } #计算机节点(主机配置) vrrp_instance VI_1 {</

RHCE的学习(19)

对于RHCE的学习&#xff08;15-18&#xff09;重点总结 详细的操作还是要看之前的笔记&#xff08;甚至是RHCSA的笔记&#xff09; 1.什么是shell 一种命令解释器&#xff0c;既是用户交互的界面&#xff0c;也是控制系统的脚本语言 2.shell解释器的类型 &#xff08;bash--sh&…

微服务即时通讯系统的实现(客户端)----(2)

目录 1. 将protobuf引入项目当中2. 前后端交互接口定义2.1 核心PB类2.2 HTTP接口定义2.3 websocket接口定义 3. 核心数据结构和PB之间的转换4. 设计数据中心DataCenter类5. 网络通信5.1 定义NetClient类5.2 引入HTTP5.3 引入websocket 6. 小结7. 搭建测试服务器7.1 创建项目7.2…

【功耗现象】com.gorgeous.lite后台Camera 使用2小时平均电流200mA耗电量400mAh现象

现象 轻颜相机(com.gorgeous.lite)后台Camera 使用2小时平均电流200mA(BugReport提供的电流参考数据),耗电量400mAh 即耗电占比(200mA*2h)/(12.83h*52.68mA )400mAh/623mAh62% CameraOct 10 202321:03:08 - 23:03:372h16m15s859ms to 4h16m44s984msactive duration: 2h 0m 29…

蓝桥杯每日真题 - 第15天

题目&#xff1a;&#xff08;钟表&#xff09; 题目描述&#xff08;13届 C&C B组B题&#xff09; 解题思路&#xff1a; 理解钟表指针的运动&#xff1a; 秒针每分钟转一圈&#xff0c;即每秒转6度。 分针每小时转一圈&#xff0c;即每分钟转6度。 时针每12小时转一圈…

ctfshow-web入门-SSRF(web351-web360)

目录 1、web351 2、web352 3、web353 4、web354 5、web355 6、web356 7、web357 8、web358 9、web359 10、web360 1、web351 看到 curl_exec 函数&#xff0c;很典型的 SSRF 尝试使用 file 协议读文件&#xff1a; urlfile:///etc/passwd 成功读取到 /etc/passwd 同…

快速搭建Android开发环境:Docker部署docker-android并实现远程连接

目录 前言 1. 虚拟化环境检查 2. Android 模拟器部署 3. Ubuntu安装Cpolar 4. 配置公网地址 5. 远程访问 小结 6. 固定Cpolar公网地址 7. 固定地址访问 作者简介&#xff1a; 懒大王敲代码&#xff0c;计算机专业应届生 今天给大家聊聊快速搭建Android开发环境&#x…

2024-11-16-机器学习方法:无监督学习(1) 聚类(上)

文章目录 机器学习方法&#xff1a;无监督学习&#xff08;1&#xff09; 聚类&#xff08;上&#xff09;1. 聚类的基本概念1.1 聚类的概念1.2 聚类的功能1.3 聚类的算法 2. 相似度或距离2.1 闵可夫斯基距离2.2 相关系数2.3 夹角余弦 3 类或簇3.1 类的特征 4 类与类之间的距离…

Vue-组件三大组成组件通信

一、学习目标 1.组件的三大组成部分&#xff08;结构/样式/逻辑&#xff09; scoped解决样式冲突/data是一个函数 2.组件通信 组件通信语法 父传子 子传父 非父子通信&#xff08;扩展&#xff09; 3.综合案例&#xff1a;小黑记事本&#xff08;组件版&#xff09; 拆…

Scratch 014生日贺卡(上)

知识回顾&#xff1a; 1、“面向鼠标指针”积木块 2、“重复执行直到”积木块 本次分享制作生日贺卡引入广播模块 案列效果&#xff1a; 生日贺卡上案例效果-CSDN直播 步骤拆解&#xff1a; 1、添加背景和角色 2、编辑贺卡造型添加名字 3、流程图的组成和画法 4、…

MySQL中将一个字符串字段按层级树状展开

水善利万物而不争&#xff0c;处众人之所恶&#xff0c;故几于道&#x1f4a6; 文章目录 需求1.分析2.实现3.思路刨析表结构和数据 需求 数据库中有个字段如下 如何将其转换为如下形式&#xff1a; 1.分析 1.他的层级个数是不确定的&#xff0c;也就是说有的有2层有的有5…

hive搭建

1.准备环境 三台节点主机已安装hadoopmysql数据库 2.环境 2.1修改三台节点上hadoop的core-site.xml <!-- 配置 HDFS 允许代理任何主机和组 --> <property><name>hadoop.proxyuser.hadoop.hosts</name><value>*</value> </property&…

创建vue+electron项目流程

一个vue3和electron最基本的环境搭建步骤如下&#xff1a;// 安装 vite vue3 vite-plugin-vue-setup-extend less normalize.css mitt pinia vue-router npm create vuelatest npm i vite-plugin-vue-setup-extend -D npm i less -D npm i normalize.css -S &#xff0…

Pyhon基础数据结构(列表)【蓝桥杯】

a [1,2,3,4,5] a.reverse() print("a ",a) a.reverse() print("a ",a)# 列表 列表&#xff08;list&#xff09;有由一系列按照特定顺序排序的元素组成 列表是有顺序的&#xff0c;访问任何元素需要通过“下标访问” 所谓“下标”就是指元素在列表从左…

帽子矩阵--记录

帽子矩阵&#xff08;Hat Matrix&#xff09;并不是由某一位具体的科学家单独发明的&#xff0c;而是逐渐在统计学和线性代数的发展过程中形成的。帽子矩阵的概念最早出现在20世纪初的统计学文献中&#xff0c;尤其是在回归分析的研究中得到了广泛应用。然而&#xff0c;具体是…

一.安装版本为19c的Oracle数据库管理系统(Oracle系列)

1.数据库版本信息&#xff1a; 版本信息&#xff1a; 或者直接由命令查出来&#xff1a; 2.操作系统的版本信息 3.安装包下载与上传 可以去oracle官网下载也可以从其他人的百度网盘链接中下载&#xff1a; 使用xftp工具或者其他的工具&#xff08;mobaxterm&#xff09;上传到l…

计算机视觉 ---图像模糊

1、图像模糊的作用&#xff1a; 减少噪声&#xff1a; 在图像获取过程中&#xff0c;例如通过相机拍摄或者传感器采集&#xff0c;可能会受到各种因素的干扰&#xff0c;从而引入噪声。这些噪声在图像上表现为一些孤立的、不符合图像主体内容的像素变化&#xff0c;如椒盐噪声&…

关于强化学习的一份介绍

在这篇文章中&#xff0c;我将介绍与强化学习有关的一些东西&#xff0c;具体包括相关概念、k-摇臂机、强化学习的种类等。 一、基本概念 所谓强化学习就是去学习&#xff1a;做什么才能使得数值化的收益信号最大化。学习者不会被告知应该采取什么动作&#xff0c;而是必须通…