lcfrs ggerganov commited on
Commit
eea7f53
·
unverified ·
1 Parent(s): d13ee66

whisper.android : how to build with CLBlast (#1809)

Browse files

* FetchContent

* OpenCL

* Documentation and make optional

* Specify GGML build options in build.gradle

* Use gradle properties

*

@ggerganov


Co-authored-by: Georgi Gerganov <[email protected]>

* @gpokat

---------

Co-authored-by: Georgi Gerganov <[email protected]>

.github/workflows/build.yml CHANGED
@@ -416,6 +416,14 @@ jobs:
416
  steps:
417
  - name: Clone
418
  uses: actions/checkout@v3
 
 
 
 
 
 
 
 
419
 
420
  - name: Install Java
421
  uses: actions/setup-java@v3
@@ -428,9 +436,15 @@ jobs:
428
 
429
  - name: Build
430
  run: |
431
- cd examples/whisper.android
432
  ./gradlew assembleRelease --no-daemon
433
 
 
 
 
 
 
 
434
  android_java:
435
  runs-on: ubuntu-latest
436
 
 
416
  steps:
417
  - name: Clone
418
  uses: actions/checkout@v3
419
+ with:
420
+ path: whisper
421
+
422
+ - name: Clone
423
+ uses: actions/checkout@v3
424
+ with:
425
+ repository: ggerganov/ggml
426
+ path: ggml
427
 
428
  - name: Install Java
429
  uses: actions/setup-java@v3
 
436
 
437
  - name: Build
438
  run: |
439
+ cd whisper/examples/whisper.android
440
  ./gradlew assembleRelease --no-daemon
441
 
442
+ - name: Build with external ggml
443
+ run: |
444
+ export PATH_TO_GGML=$PWD/ggml
445
+ cd whisper/examples/whisper.android
446
+ ./gradlew assembleRelease --no-daemon -PGGML_HOME=$PATH_TO_GGML
447
+
448
  android_java:
449
  runs-on: ubuntu-latest
450
 
examples/whisper.android/README.md CHANGED
@@ -12,3 +12,47 @@ To use:
12
  (PS: Do not move this android project folder individually to other folders, because this android project folder depends on the files of the whole project.)
13
 
14
  <img width="300" alt="image" src="https://user-images.githubusercontent.com/1670775/221613663-a17bf770-27ef-45ab-9a46-a5f99ba65d2a.jpg">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  (PS: Do not move this android project folder individually to other folders, because this android project folder depends on the files of the whole project.)
13
 
14
  <img width="300" alt="image" src="https://user-images.githubusercontent.com/1670775/221613663-a17bf770-27ef-45ab-9a46-a5f99ba65d2a.jpg">
15
+
16
+ ## CLBlast
17
+
18
+ > [!NOTE]
19
+ > - OpenCL does not have the same level of support as CUDA or Metal.
20
+ > - Turning on CLBlast may degrade OpenCL performance if your device isn't already tuned. See [tuning.md](https://github.com/CNugteren/CLBlast/blob/162783a414969464ce3aa5adf5c2554afa5ee93e/doc/tuning.md#already-tuned-for-devices) for a list of devices that are already tuned and what to do if yours is missing.
21
+
22
+ Build CLBlast.
23
+
24
+ ```
25
+ # In path/to/CLBlast (we assume OpenCL-Headers relative location)
26
+ $ANDROID_SDK_PATH/cmake/3.22.1/bin/cmake .. \
27
+ -DCMAKE_SYSTEM_NAME=Android \
28
+ -DCMAKE_SYSTEM_VERSION=33 \
29
+ -DCMAKE_ANDROID_ARCH_ABI=arm64-v8a \
30
+ -DCMAKE_ANDROID_NDK=$ANDROID_NDK_PATH \
31
+ -DCMAKE_ANDROID_STL_TYPE=c++_static \
32
+ -DOPENCL_ROOT=$(readlink -f ../../OpenCL-Headers) \
33
+ -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=BOTH \
34
+ -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=BOTH
35
+
36
+ # Build libclblast.so
37
+ make -j4
38
+ ```
39
+
40
+ Pull `libGLES_mali.so` to `libOpenCL.so`.
41
+
42
+ ```bash
43
+ # In path/to/whisper.android
44
+ mkdir lib/src/main/jniLibs/arm64-v8a
45
+ adb pull /system/vendor/lib64/egl/libGLES_mali.so lib/src/main/jniLibs/arm64-v8a/libOpenCL.so
46
+ ```
47
+
48
+ In gradle.properties, set `GGML_HOME` to the location of GGML, as well as
49
+ required options for turning on CLBlast.
50
+
51
+ ```
52
+ GGML_HOME=/path/to/ggml
53
+ GGML_CLBLAST=ON
54
+ CLBLAST_HOME=/path/to/CLBlast
55
+ OPENCL_LIB=/path/to/libOpenCL.so
56
+ OPENCL_ROOT=/path/to/OpenCL-Headers
57
+ ```
58
+
examples/whisper.android/lib/build.gradle CHANGED
@@ -16,6 +16,28 @@ android {
16
  ndk {
17
  abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64'
18
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  }
20
 
21
  buildTypes {
 
16
  ndk {
17
  abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64'
18
  }
19
+ externalNativeBuild {
20
+ cmake {
21
+ // When set, builds whisper.android against the version located
22
+ // at GGML_HOME instead of the copy bundled with whisper.cpp.
23
+ if (
24
+ project.hasProperty('GGML_HOME') &&
25
+ project.findProperty('GGML_CLBLAST') == 'ON'
26
+ ) {
27
+ // Turning on CLBlast requires GGML_HOME
28
+ arguments "-DGGML_HOME=${project.property('GGML_HOME')}",
29
+ "-DGGML_CLBLAST=ON",
30
+ "-DOPENCL_LIB=${project.property('OPENCL_LIB')}",
31
+ "-DCLBLAST_HOME=${project.property('CLBLAST_HOME')}",
32
+ "-DOPENCL_ROOT=${project.property('OPENCL_ROOT')}",
33
+ "-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=BOTH",
34
+ "-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=BOTH"
35
+ } else if (project.hasProperty('GGML_HOME')) {
36
+ arguments "-DGGML_HOME=${project.property('GGML_HOME')}"
37
+ }
38
+
39
+ }
40
+ }
41
  }
42
 
43
  buildTypes {
examples/whisper.android/lib/src/main/jni/whisper/CMakeLists.txt CHANGED
@@ -3,17 +3,28 @@ cmake_minimum_required(VERSION 3.10)
3
  project(whisper.cpp)
4
 
5
  set(CMAKE_CXX_STANDARD 11)
6
- set(WHISPER_LIB_DIR ${CMAKE_SOURCE_DIR}/../../../../../../../)
 
 
 
7
 
8
  set(
9
  SOURCE_FILES
 
 
 
 
 
 
 
 
10
  ${WHISPER_LIB_DIR}/ggml.c
11
  ${WHISPER_LIB_DIR}/ggml-alloc.c
12
  ${WHISPER_LIB_DIR}/ggml-backend.c
13
  ${WHISPER_LIB_DIR}/ggml-quants.c
14
- ${WHISPER_LIB_DIR}/whisper.cpp
15
- ${CMAKE_SOURCE_DIR}/jni.c
16
- )
17
 
18
  find_library(LOG_LIB log)
19
 
@@ -24,12 +35,12 @@ function(build_library target_name)
24
  ${SOURCE_FILES}
25
  )
26
 
27
- target_link_libraries(${target_name} ${LOG_LIB} android)
28
-
29
  if (${target_name} STREQUAL "whisper_v8fp16_va")
30
  target_compile_options(${target_name} PRIVATE -march=armv8.2-a+fp16)
 
31
  elseif (${target_name} STREQUAL "whisper_vfpv4")
32
  target_compile_options(${target_name} PRIVATE -mfpu=neon-vfpv4)
 
33
  endif ()
34
 
35
  if (NOT ${CMAKE_BUILD_TYPE} STREQUAL "Debug")
@@ -43,9 +54,20 @@ function(build_library target_name)
43
  target_link_options(${target_name} PRIVATE -flto)
44
 
45
  endif ()
46
- endfunction()
47
 
48
- build_library("whisper") # Default target
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
  if (${ANDROID_ABI} STREQUAL "arm64-v8a")
51
  build_library("whisper_v8fp16_va")
@@ -53,4 +75,6 @@ elseif (${ANDROID_ABI} STREQUAL "armeabi-v7a")
53
  build_library("whisper_vfpv4")
54
  endif ()
55
 
 
 
56
  include_directories(${WHISPER_LIB_DIR})
 
3
  project(whisper.cpp)
4
 
5
  set(CMAKE_CXX_STANDARD 11)
6
+ set(WHISPER_LIB_DIR ${CMAKE_SOURCE_DIR}/../../../../../../..)
7
+
8
+ # Path to external GGML, otherwise uses the copy in whisper.cpp.
9
+ option(GGML_HOME "whisper: Path to external GGML source" OFF)
10
 
11
  set(
12
  SOURCE_FILES
13
+ ${WHISPER_LIB_DIR}/whisper.cpp
14
+ ${CMAKE_SOURCE_DIR}/jni.c
15
+ )
16
+
17
+ if (NOT GGML_HOME)
18
+ set(
19
+ SOURCE_FILES
20
+ ${SOURCE_FILES}
21
  ${WHISPER_LIB_DIR}/ggml.c
22
  ${WHISPER_LIB_DIR}/ggml-alloc.c
23
  ${WHISPER_LIB_DIR}/ggml-backend.c
24
  ${WHISPER_LIB_DIR}/ggml-quants.c
25
+
26
+ )
27
+ endif()
28
 
29
  find_library(LOG_LIB log)
30
 
 
35
  ${SOURCE_FILES}
36
  )
37
 
 
 
38
  if (${target_name} STREQUAL "whisper_v8fp16_va")
39
  target_compile_options(${target_name} PRIVATE -march=armv8.2-a+fp16)
40
+ set(GGML_COMPILE_OPTIONS -march=armv8.2-a+fp16)
41
  elseif (${target_name} STREQUAL "whisper_vfpv4")
42
  target_compile_options(${target_name} PRIVATE -mfpu=neon-vfpv4)
43
+ set(GGML_COMPILE_OPTIONS -mfpu=neon-vfpv4)
44
  endif ()
45
 
46
  if (NOT ${CMAKE_BUILD_TYPE} STREQUAL "Debug")
 
54
  target_link_options(${target_name} PRIVATE -flto)
55
 
56
  endif ()
 
57
 
58
+ if (GGML_HOME)
59
+ include(FetchContent)
60
+ FetchContent_Declare(ggml SOURCE_DIR ${GGML_HOME})
61
+ FetchContent_MakeAvailable(ggml)
62
+
63
+ target_compile_options(ggml PRIVATE ${GGML_COMPILE_OPTIONS})
64
+ target_link_libraries(${target_name} ${LOG_LIB} android ggml)
65
+ else()
66
+ target_link_libraries(${target_name} ${LOG_LIB} android)
67
+ endif()
68
+
69
+
70
+ endfunction()
71
 
72
  if (${ANDROID_ABI} STREQUAL "arm64-v8a")
73
  build_library("whisper_v8fp16_va")
 
75
  build_library("whisper_vfpv4")
76
  endif ()
77
 
78
+ build_library("whisper") # Default target
79
+
80
  include_directories(${WHISPER_LIB_DIR})