当前位置:AIGC资讯 > AIGC > 正文

在嵌入式处理器Jetson Orin上使用Whisper做语音内容识别(3)

1、简介

Nvidia的GPU+CUDA架构在大算力时代遥遥领先毫无疑问了,其通用的硬件特性使得它不再是以往的“显卡”,算力强大并且支持各种AI,软件生态的应用方式基本可以照搬PC端。相比于特定的核心NPU,它显得更加灵活,系统和显存的共用在带宽上有明显提高。而NPU往往会有特定支持,比如:OpenGLxxx版本、OpenCV、PyTorch.....等。

这次在原有硬件基础上进一步延申,使用Whisper.cpp;也就是C/C++版的方式, GitHub地址。目前该版本库的支持可以看看链接内的readme,无一例外这次还是从其它平台过度到嵌入式,无论是系统,架构,硬件加速都是有所区别的。

2、准备

2.1、克隆源码

由于使用的cc++,没有像python那样的各种依赖,和不同版本之间的不兼容那么麻烦。因此不需要使用虚拟环境,找个目录创建一个文件夹即可。然后执行如下命令获取

git clone https://github.com/ggerganov/whisper.cpp.git

如果遇到git没反应,可以往hosts文件尾部加入 :参考链接

vim /etc/hosts
# GitHub Start 
140.82.113.4     github.com
140.82.114.4     gist.github.com
# # GitHub End

如果遇到.4行不通,可以改一下.3 ,它也是git地址。 完成克隆的目录如下

2.2、模型转换

由于CC++版本和python版本使用的模型文件是不一样的(python后缀为.pt,cc++版本后缀为.bin),因此我们需要重新获取或手动转换。此处提供了三种获取模型的方式,第一种使用

bash ./models/download-ggml-model.sh base.en

 命令,运行models文件里的脚本,去下载base.en模型;如需要下载其它模型,更换这个名字即可,ps:.en是只有英文的,如果要转中文请勿使用.en模型。其它模型名称如下

make tiny.en
make tiny
make base.en
make base
make small.en
make small
make medium.en
make medium
make large-v1
make large-v2
make large-v3

这个命令运行之后会发现,访问到了某一个地址,或许需要梯子才能下载。 当然可以去如下地址使用手动下载方式,这个是方式二。

https://huggingface.co/ggerganov/whisper.cpp
https://ggml.ggerganov.com

由于之前使用原版whisper的时候已经下载过一次模型了,就不再继续下载,本机上手动转换一下好了 ,本次使用的正是这个方法3

mkdir models/whisper-medium
python models/convert-pt-to-ggml.py ~/.cache/whisper/medium.pt ~/path/to/repo/whisper/ ./models/whisper-medium
mv ./models/whisper-medium/ggml-model.bin models/ggml-medium.bin

line1:在models下创建一个文件夹

line2:使用python应用解释这个convert-pt-to-ggml.py文件;带入的第2个参数是模型所在位置,使用原版whisper时默认存储的目录;第3个参数是原版whisper源码克隆的路径; 第4个参数是转换后存储位置。

line3:移动文件

2.3、音频转换.WAV

在示例目录下有个文件 samples/jfk.wav,如果想用自己的文件,则可以使用如下命令进行转换

ffmpeg -i input.mp3 -ar 16000 -ac 1 -c:a pcm_s16le output.wav

3、编译与运行(CPU)

在克隆下来的目录里运行

make -j 4

进行编译,完成后的目录里会看到可执行文件,绿色这几个。

接下来就可以使用一下命令进行转录了

./main -f samples/jfk.wav
#也可以
./main -m models/ggml-large-v3.bin -l zh -f ../../test/output.wav

 观察Jtop页面,CPU占用率一直会很高,过了一会就能完成转录。但是CPU转录太慢,我们还需要使用GPU加速。

4、编译与运行(GPU)

之前的main可执行文件是不支持GPU加速的,转录速度非常慢,因此使用如下命令进行清除和重新编译一个带CUDA版本的main

make clean
WHISPER_CUBLAS=1 make -j

可能会遇到第一个报错,找不到nvcc

 一般来说jetson上的系统都带有nvcc的,或许是环境变量没有改好,在vim ~/.bashrc的尾部加上,然后刷新环境变量;解决 nvcc: command not found

 
#添加以下两行
#在/.bashrc中配置LD_LIBRARY_PATH路径、配置PATH路径,完整配置如下:
 
export LD_LIBRARY_PATH=/usr/local/cuda/lib
export PATH=$PATH:/usr/local/cuda/bin

继续make clean   再编译一次,幸运的话还会得到下面两个报错

先看第一行的all  ,这个地方很多PC端也遇到了,有可能是:all、any、native。按照其它系统或许这么写就能直接用了,但是见到最多的还是修改Makefile文件,找到all,大概有这样一行

NVCCFLAGS = --forward-unknown-to-host-compiler -arch=native
或
NVCCFLAGS = --forward-unknown-to-host-compiler -arch=xxx

我们需要改的就是这个里,这个需要根据显卡架构去选,不是一味地-arch=sm60,小锤60,大锤也60,我们先看一张表

所以我们可以把-arch=all改成-arch=sm_87,或者在系统上使用 nvcc --list-gpu-arch 命令得到compute_87、compute_8x。改成-arch=compute_87也行。使用vim Makefile打开文件改这里

再次进行clean清除与编译,还会报一个错

但是目前这个报错无解。其它使用这个cmake的项目也会报ggml-cuda [ Error 127,如果有解决掉的,麻烦给留言一下 谢谢。此时我们不理会这个报错,再来一次

WHISPER_CUBLAS=1 make -j

就可以编译出支持GPU的main可执行文件了。按照之前的转录命令进行转录即可。 其实可以看到,转录速度比CPU快了很多倍,使用jtop可以看到GPU使用率一路飘升。同一个30s的音频文件在使用lager-v3情况下仅需要20s即可转录完成,而python使用medium模型就耗时1分钟。用上了大语言模型,这次标点符号都出来了。

同一个medium模型,在显存使用率上,cpp版本仅需要~2G,而python则使用~10G。转录速度也比python快了4到5倍。因此在cpp版本中,可以直接使用大语言模型large-v3,效果更好。所以8G的jetson Orin也可以很好的使用了。

5、实时转录与翻译(麦克风)

5.1、实时转录(cpu)

在readme中有这样一段内容:

看了下原作者的说明,直接编译并运行即可。经过实践得出两个可能要么编译报错要么不支持GPU,使用命令make clean清除所有编译产生的结果,然后make stream,会得到stream应用程序,但是运行起来并不支持GPU,单靠这个8核心的CPU没有什么效果。如果一开始使用 

WHISPER_CUBLAS=1 make -j

让main支持GPU,在不进行clean操作情况下直接make stream的话会报错。 

5.2、实时转录(gpu) 

在一筹莫展时,反复看了看makefile文件,在编译过程中发现,使用

WHISPER_CUBLAS=1 make -j

编译出来的时候为什么没有stream应用?这部分作者倒是没有什么文档说明。最终经过分析得出,要想支持GPU是离不开上述这条指令的。然后打开Makefile,在第一行的时候看到少了stream,所以可以加上空格给它补上一个stream。

然后使用 如下命令进行编译,让stream应用与main应用一样支持gpu。

make clean
WHISPER_CUBLAS=1 make -j

5.3、stream应用 

无论是cpu还是gpu,stream的命令参数都是一样的,只是使用什么硬件去跑而已。先试一下这个命令

./stream -m ./models/ggml-base.en.bin -t 8 --step 500 --length 5000

运行之后GPU一直占用率很高,也能转录,但是效果并不理想,因为此时whisper分不出句子的段落,有点类似幻听。 在原作者的原文中有另外一个应用方式。就是给stream加上一个VAD算法,使其能否像人一样能够分辨得出句子的段落。所以命令变成

 ./stream -m ./models/ggml-small.en.bin -t 6 --step 0 --length 30000 -vth 0.6

使用stream -h得知这个-t是线程数,使用GPU时好像没啥作用。--step为0表示启用VAD,30000表示单次最长听取的时间,具体参数和指令可以看-h。

由于jetson的板子并没有提供音频的输入输出接口,可以用一个usb转入。在运行stream xxx时会有

很多驱动接入,如果不指定,可能whisper会听不到声音,需要加上-c 0参数,指明要用0号驱动。 

命令正常运行后,GPU一般处于空闲状态,当听到你说话时才会工作,一段一段的做到了你说一句它翻译一句。如果出现断句,分句不均,这个部分或许VAD算法需要在一步改进。

6、实时转录与翻译(音频流)

。。。。

参考

whisper.cpp github地址

模型本地转换

CUDA架构匹配

llama.cpp量化cuBLAS编译

nvcc fatal : Value ‘sm_XX‘ is not defined for option ‘gpu-architecture‘

更新时间 2024-06-11