whisper.cpp在Win环境下的编译

在Win环境下使用whisper.cpp需要cuda和sdl2的环境支持

Posted by 雯饰太一 on December 2, 2023

背景

主要是为了写博客时候能够更方便的进行文本输入,听说这个项目是openai开源出来的一个语音识别模型,其中对于英文和中文的支持能力都非常好。想着尝试一下,所以找到了一个可以在Windows环境上跑的一个跨平台的工程。

在对这个工程进行编译的时候遇到了一些问题,在此对整个过程进行记录。按照以往的惯例,不会在这篇文章之中出现太多的截图,只是把关键点罗列出来。

工程介绍

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

在本地进行编译的时候,首先需要将这个工程下载下来,在工程的根目录下有对应的CMakeLists.txt。需要安装CMake工具对其进行编译,CMake下载地址:CMake首页,安装的时候直接安装最新的版本就可以了,不用和其他教程非得一样。

在这个工程里面Windows上的编译环境是有两个的,MSVC和MinGW:

  • MSVC通常安装完VS之后就自己会有
  • MinGW需要自己独立安装(是所有命令和Linux类似)

个人环境:VS2022

如何使用CMake,可以直接百度一下。这一步的准备不用特别充分,只需要知道怎么去配置。源码目录和输出目录就可以了,一般情况下从Git上下载下来的库编译都是会有太大问题的。

环境安装

CUDA环境

安装的时候首先需要确定自己的电脑能够支持的版本,【NVDIA控制面板】【系统信息】【组件】

这里默认下次我看到这篇文章的时候是还记得操作的。

下载地址:[kCUDA Toolkit Archive NVIDIA Developer](https://developer.nvidia.com/cuda-toolkit-archive)

进入下载地址之后,按照界面的提示选择适合自己系统的版本,进行下载即可。有离线版和联网版两个安装包,当时下载的时候使用的就是离线版的。

由于现在使用的内存就是固态,所以说安装到哪个目录都无所谓,目前C盘都是一些系统文件,其他所有的软件都装在了D盘,可以参考下我的路径:

1
D:\cuda_12.3.1_toolkit

以下是一些需要注意的点:

  • 安装界面进入选项页之后,如果是第一次安装,直接全部勾选,包含的内容如下:

    • 1
      2
      3
      4
      
      CUDA
      NVDIA GeForce Experience co...
      Other Components
      Driver Components
      
  • 如果不是第四安装,只勾选第一个就可以了(我上的说法如果多勾选,可能会导致后续的安装出现问题)

  • 在安装的过程之中,可能一些其他组建议需要选择路径,同样的,我也选择了D盘

安装完毕之后需要配置(查看)环境变量:【Win键】【搜索】【环境变量】,多了如下两项“

1
2
CUDA_PATH
CUDA_PATH_V12_3

Win+R打开控制台,输入:nvcc --version,可以看到相关版本信息:

1
2
3
4
5
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2023 NVIDIA Corporation
Built on Fri_Nov__3_17:51:05_Pacific_Daylight_Time_2023
Cuda compilation tools, release 12.3, V12.3.103
Build cuda_12.3.r12.3/compiler.33492891_0

多个CUDA版本

以下为推测内容,并没有真正尝试。

CUDA_PATH对应的就是当前使用的版本,CUDA_PATH_V12_3是具备版本号的环境变量。如果后续还安装了其他的类似于CUDA_PATH_VXX_X这个的变量应该还会有,届时只需要切换CUDA_PATH的值即可。

在进行AI绘图的时候,Cuda和Torch似乎都是直接装到硬盘里面了,好像和系统没有什么关系,是不是在启动软件的时候,添加一些临时的环境变量,也能够达到动态切换版本的目的。

SDL环境

参考文章:知乎:SDL库的介绍与安装

SDL主页地址:SDL Wiki

SDL源码地址:https://github.com/libsdl-org/SDL.git

在参考文章之中提供了一个下载链接:https://link.zhihu.com/?target=https%3A//www.libsdl.org/download-2.0.php。推荐直接使用该链接进下载,可以得到SDL2的头文件和运行库,具体的目录结构如下:

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
卷 数据 的文件夹 PATH 列表
卷序列号为 287B-F7D1
E:.
│  a.txt
│  BUGS.txt
│  COPYING.txt
│  README-SDL.txt
│  README.txt
│  sdl2-config.cmake
│  WhatsNew.txt
│  
├─docs
│      doxyfile
│      README-android.md
│      README-cmake.md
│      README-directfb.md
│      README-dynapi.md
│      README-emscripten.md
│      README-gesture.md
│      README-git.md
│      README-hg.md
│      README-ios.md
│      README-kmsbsd.md
│      README-linux.md
│      README-macosx.md
│      README-nacl.md
│      README-os2.md
│      README-pandora.md
│      README-platforms.md
│      README-porting.md
│      README-psp.md
│      README-raspberrypi.md
│      README-touch.md
│      README-visualc.md
│      README-vita.md
│      README-wince.md
│      README-windows.md
│      README-winrt.md
│      README.md
│      
├─include
│      begin_code.h
│      close_code.h
│      SDL.h
│      SDL_assert.h
│      SDL_atomic.h
│      SDL_audio.h
│      SDL_bits.h
│      SDL_blendmode.h
│      SDL_clipboard.h
│      SDL_config.h
│      SDL_config.h.cmake
│      SDL_config.h.in
│      SDL_config_android.h
│      SDL_config_iphoneos.h
│      SDL_config_macosx.h
│      SDL_config_macosx.h.orig
│      SDL_config_minimal.h
│      SDL_config_pandora.h
│      SDL_config_psp.h
│      SDL_config_windows.h
│      SDL_config_winrt.h
│      SDL_config_wiz.h
│      SDL_copying.h
│      SDL_cpuinfo.h
│      SDL_egl.h
│      SDL_endian.h
│      SDL_error.h
│      SDL_events.h
│      SDL_filesystem.h
│      SDL_gamecontroller.h
│      SDL_gesture.h
│      SDL_haptic.h
│      SDL_hints.h
│      SDL_joystick.h
│      SDL_keyboard.h
│      SDL_keycode.h
│      SDL_loadso.h
│      SDL_locale.h
│      SDL_log.h
│      SDL_main.h
│      SDL_messagebox.h
│      SDL_metal.h
│      SDL_misc.h
│      SDL_mouse.h
│      SDL_mutex.h
│      SDL_name.h
│      SDL_opengl.h
│      SDL_opengles.h
│      SDL_opengles2.h
│      SDL_opengles2_gl2.h
│      SDL_opengles2_gl2ext.h
│      SDL_opengles2_gl2platform.h
│      SDL_opengles2_khrplatform.h
│      SDL_opengl_glext.h
│      SDL_pixels.h
│      SDL_platform.h
│      SDL_power.h
│      SDL_quit.h
│      SDL_rect.h
│      SDL_render.h
│      SDL_revision.h
│      SDL_rwops.h
│      SDL_scancode.h
│      SDL_sensor.h
│      SDL_shape.h
│      SDL_stdinc.h
│      SDL_surface.h
│      SDL_system.h
│      SDL_syswm.h
│      SDL_test.h
│      SDL_test_assert.h
│      SDL_test_common.h
│      SDL_test_compare.h
│      SDL_test_crc32.h
│      SDL_test_font.h
│      SDL_test_fuzzer.h
│      SDL_test_harness.h
│      SDL_test_images.h
│      SDL_test_log.h
│      SDL_test_md5.h
│      SDL_test_memory.h
│      SDL_test_random.h
│      SDL_thread.h
│      SDL_timer.h
│      SDL_touch.h
│      SDL_types.h
│      SDL_version.h
│      SDL_video.h
│      SDL_vulkan.h
│      
└─lib
    ├─x64
    │      SDL2.dll
    │      SDL2.lib
    │      SDL2main.lib
    │      SDL2test.lib
    │      
    └─x86
            SDL2.dll
            SDL2.lib
            SDL2main.lib
            SDL2test.lib

使用命令:tree /f 可以输出指定目录下的目录结构。

编译选项

WHISPER_BUILD_EXAMPLES

我找到这个项目主要是因为其中的实时翻译demo:stream,当时看到的版本中演示的情况是,先在控制台中启动stream.exe程序,使用如下命令:

1
2
3
4
5
# linux
./stream -m ./models/ggml-base.en.bin -t 8 --step 500 --length 5000

# win环境中如下
./stream.exe -m ./models/ggml-base.en.bin -t 8 --step 500 --length 5000

在演示的demo中,用户会先说一句话,黑窗口中会进行翻译,翻译完毕之后,等待下一次语音输入,如此循环往复,能够达到实时语音识别的一个效果。但是看现在的这个版本,好像可以连续说很多很多的文字。

编译这个demo需要再编译选项中开启以下内容:

1
2
WHISPER_BUILD_EXAMPLES = true
注:在CMake中的形式就是这一项,需要打上对勾。

WHISPER_SDL2

仅仅添加CUDA变量之后,通过CMake形成的工程里面并没有stream这个demo,此时可以直接在CMake配置界面中查找一下sdl相关的选项,可以发现是WHISPER_SDL2这一项是没有勾选的.

但:勾选上之后,CMake重新配置会失败。

再次推测sdl相关的项没有配置成功,于SDL相关的还有一项:SDL_DIR,需要配置SDL所在路径(include上一级),但是每次配置路径都会提示失败,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CMake Error at examples/CMakeLists.txt:9 (find_package):
  By not providing "FindSDL2.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "SDL2", but
  CMake did not find one.

  Could not find a package configuration file provided by "SDL2" with any of
  the following names:

    SDL2Config.cmake
    sdl2-config.cmake

  Add the installation prefix of "SDL2" to CMAKE_PREFIX_PATH or set
  "SDL2_DIR" to a directory containing one of the above files.  If "SDL2"
  provides a separate development package or SDK, be sure it has been
  installed.

这里说的是在SDL文件夹下面没有找到指定的cmake文件,可以手动创建一个:sdl2-config.cmake,如下:

1
2
3
4
5
6
7
8
9
10
set(SDL2_INCLUDE_DIRS "${CMAKE_CURRENT_LIST_DIR}/include")

# Support both 32 and 64 bit builds
if (${CMAKE_SIZEOF_VOID_P} MATCHES 8)
  set(SDL2_LIBRARIES "${CMAKE_CURRENT_LIST_DIR}/lib/x64/SDL2.lib;${CMAKE_CURRENT_LIST_DIR}/lib/x64/SDL2main.lib")
else ()
  set(SDL2_LIBRARIES "${CMAKE_CURRENT_LIST_DIR}/lib/x86/SDL2.lib;${CMAKE_CURRENT_LIST_DIR}/lib/x86/SDL2main.lib")
endif ()

string(STRIP "${SDL2_LIBRARIES}" SDL2_LIBRARIES)

将其配置到SDL2目录下即可,形成如下结构:

1
2
3
4
5
6
7
SDL2-2.0.16
    ├─docs
    ├─include
    ├─lib
   	│  ├─x64
    │  └─x86
    │  sdl2-config.cmake

创建完这个文件之后重新配置一下就可以生成对应的VS工程文件,CMake重新Generate的时候,VS是不需要关闭的,会提示重新载入项目。

虽然stream这个demo编译成功了,但是talk-llama依旧编译失败,感觉其中和ggml相关的文件或者是库配置有问题,不过这个demo和我的关系不是特别大,所以说就没有管。

参考链接:

运行问题

中文乱码!

经过一番测试,发现原始的编码格式是UTF-8的,直接作为GBK输出之后会乱码,使用如下代码可以解决问题:

1
2
// 使用 65001 代码页(UTF-8)
system("chcp 65001");     

不过原来直接打印中文的位置,却变成了乱码。

参考链接:

使用

以下是经过ChatGPT调整过的

当我自己使用这个语音识别的demo时,我发现它并没有像网上说的那样,对中文的识别率有多高。相反,在语音识别的过程中,由于我停顿或发音不标准等问题,识别效果有点差强人意。另外,翻译的内容全部都是繁体的,如果想要直接使用它,不仅需要解决繁体转化成简体的问题,还需要解决断字、断词和断句等问题。此外,在说话时,如果中英文混搭,识别也非常不准确。

相比之下,搜狗输入法的语音输入对于中文的识别能力稍好一些。这篇文章就是在使用搜狗输入法语音识别的情况下写出来的。但也遇到了一些头疼的问题,比如一些英文的专业术语,在说的时候经常会识别不准确,甚至每次都会识别失败。这意味着说完一遍之后,还得用键盘重新对句子进行调整才能放到文章里。

而且这种写作模式并不是很习惯。使用键盘输入的方式进行写作,大脑有比较稳定的思考时间,即使写错了也可以实时修正。通过手动输入指令,然后使用键盘修正句子或词汇,这种方式更流畅。相反,使用语音输入的方式进行写文章,感觉自己像一个傻子一样对着空气说话,然后将这些文字显示到屏幕上。有时候还需要检查自己说的话是否正确,翻译是否有错误,是否需要调整。在这种情况下,使用语音输入方式不如键盘更快、更顺畅。

我注意到有人在网上说可以将语音识别得到的内容放到ChatGPT上,让它将这些零散的词句整合成一段通顺的话。我也计划尝试一下,看看人工智能是否可以帮助改善这些内容的流畅度。

另外,还有一个影响效率的问题是,在语音识别的过程中,搜狗输入法会将每个识别到的片段都放到剪切板中。有时候,当你复制了一个链接,准备说一段话后粘贴到指定位置时,由于语音形成的文字片段已经在剪切板中,你之前复制的所有内容都会被覆盖,这会导致一些不便。

原始内容:

自己使用的时候发现这我现在去接你吧。Help现在到哪儿了?帮我买吧。嗯,手机上显示还得多久啊?我给你带个衣服。个demo并没有像网上说的那样,中文识别率能有多高。反而在语音识别的过程中,因为我停顿或者是发音不标准等其他问题。这个识别效果有点差强人意。而且翻译的内容全部都是繁体的,想要直接拿来使用的话,不仅需要解决繁体转化成简体的这个问题。还需要解决断字,断词,断句这种问题。且在其中说话的时候,如果有中英文混搭的情况识别也是非常不准确的。

相比之下,搜狗输入法的语音输入对于中文的识别能力更好一点,这篇文章就是在使用搜狗输入法语音识别的情况之下写出来的。不过也遇到一些比较头疼的问题。像一些英文的专业术语。在说的时候经常会识别不准确,甚至是每次都会识别失败。相当于这样,说完一遍还得用键盘重新对这个句子进行一番调整才能够放到文章里面来。

而且这种写作的一个模式并不是很习惯。使用键盘输入的方式进行写作,大脑有比较稳定的思考时间就算是写错了也可以实时的给。手下载指令,然后去用键盘把某个句子或者是某个词进行修正。是通过语音输入的方式进行写文章的话,就感觉自己像是一个傻子一样对着空气说话,然后把这些文字显示到屏幕之上,甚至有的时候还得再去留意一下自己说的这段话到底正不正确,翻译的到底有没有错误,是否需要调整。在这样的一个场景之下,使用语音输入的方式反倒不如用键盘。写的更快。更顺畅。

备注网上有人说可以把语音识别得到的内容放到ChatGPT上。让他把这个内容变得更通顺一点。下也会做一番尝试。看看人工智能是否可以?把这些比较零散的词句,整合成一段比较正确的话。

还有一个比较影响效率的点。就是语音识别的过程之中。搜狗输入法会把中间识别到的每一个片段都放到剪切板中。有的时候你复制了一个链接,准备说一段话之后把这个链接粘到指定的位置。但是因为语音形成的文字片段被粘贴进了剪切板里面。你之前复制的所有的内容都会白费。

注:有没有一种可能,就是使用语音输入进行博客撰写的这种情况可以锻炼自己的表达能力?????