danbev commited on
Commit
0db3249
·
unverified ·
1 Parent(s): 0a6a7c1

examples : command.wasm updates (#2904)

Browse files

This commit updates the command.wasm example by adding a server.py script to make it easy to start a local http server to try out the example, updates the build instructions, and also addresses some of the compiler warnings that were being generated.

* emscripten : fix TOTAL_STACK for wasm

This commit moves the TOTAL_STACK setting from the compile flags to the
linker flags. This is because the TOTAL_STACK setting is a linker
setting.

The motivation for this change is that currently the following warnings
are generated when building:
```console
em++: warning: linker setting ignored during compilation: 'TOTAL_STACK' [-Wunused-command-line-argument]
em++: warning: linker setting ignored during compilation: 'TOTAL_STACK' [-Wunused-command-line-argument]
em++: warning: linker setting ignored during compilation: 'TOTAL_STACK' [-Wunused-command-line-argument]
em++: warning: linker setting ignored during compilation: 'TOTAL_STACK' [-Wunused-command-line-argument]
em++: warning: linker setting ignored during compilation: 'TOTAL_STACK' [-Wunused-command-line-argument]
em++: warning: linker setting ignored during compilation: 'TOTAL_STACK' [-Wunused-command-line-argument]
```

* examples : suppress C++17 deprecation warning for std::codecvt_utf8

This commit suppresses the C++17 deprecation warning for
std::codecvt_utf8 similar to what is done in
examples/talk-llama/unicode.cpp.

The motivation for this change is to suppress these warnings:
```console
/Users/danbev/work/ai/whisper-work/examples/common.cpp:251:31: warning: 'codecvt_utf8<wchar_t>' is deprecated [-Wdeprecated-declarations]
251 | std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
| ^
/Users/danbev/work/wasm/emsdk/upstream/emscripten/cache/sysroot/include/c++/v1/codecvt:193:28: note: 'codecvt_utf8<wchar_t>' has been explicitly marked deprecated here
193 | class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 codecvt_utf8 : public __codecvt_utf8<_Elem> {
| ^
/Users/danbev/work/wasm/emsdk/upstream/emscripten/cache/sysroot/include/c++/v1/__config:723:41: note: expanded from macro '_LIBCPP_DEPRECATED_IN_CXX17'
723 | # define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED
| ^
/Users/danbev/work/wasm/emsdk/upstream/emscripten/cache/sysroot/include/c++/v1/__config:688:49: note: expanded from macro '_LIBCPP_DEPRECATED'
688 | # define _LIBCPP_DEPRECATED __attribute__((__deprecated__))
| ^
/Users/danbev/work/ai/whisper-work/examples/common.cpp:251:10: warning: 'wstring_convert<std::codecvt_utf8<wchar_t>>' is deprecated [-Wdeprecated-declarations]
251 | std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
| ^
/Users/danbev/work/wasm/emsdk/upstream/emscripten/cache/sysroot/include/c++/v1/locale:3145:28: note: 'wstring_convert<std::codecvt_utf8<wchar_t>>' has been explicitly marked deprecated here
3145 | class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 wstring_convert {
| ^
/Users/danbev/work/wasm/emsdk/upstream/emscripten/cache/sysroot/include/c++/v1/__config:723:41: note: expanded from macro '_LIBCPP_DEPRECATED_IN_CXX17'
723 | # define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED
| ^
/Users/danbev/work/wasm/emsdk/upstream/emscripten/cache/sysroot/include/c++/v1/__config:688:49: note: expanded from macro '_LIBCPP_DEPRECATED'
688 | # define _LIBCPP_DEPRECATED __attribute__((__deprecated__))
| ^
/Users/danbev/work/ai/whisper-work/examples/common.cpp:257:31: warning: 'codecvt_utf8<wchar_t>' is deprecated [-Wdeprecated-declarations]
257 | std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
| ^
/Users/danbev/work/wasm/emsdk/upstream/emscripten/cache/sysroot/include/c++/v1/codecvt:193:28: note: 'codecvt_utf8<wchar_t>' has been explicitly marked deprecated here
193 | class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 codecvt_utf8 : public __codecvt_utf8<_Elem> {
| ^
/Users/danbev/work/wasm/emsdk/upstream/emscripten/cache/sysroot/include/c++/v1/__config:723:41: note: expanded from macro '_LIBCPP_DEPRECATED_IN_CXX17'
723 | # define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED
| ^
/Users/danbev/work/wasm/emsdk/upstream/emscripten/cache/sysroot/include/c++/v1/__config:688:49: note: expanded from macro '_LIBCPP_DEPRECATED'
688 | # define _LIBCPP_DEPRECATED __attribute__((__deprecated__))
| ^
/Users/danbev/work/ai/whisper-work/examples/common.cpp:257:10: warning: 'wstring_convert<std::codecvt_utf8<wchar_t>>' is deprecated [-Wdeprecated-declarations]
257 | std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
| ^
/Users/danbev/work/wasm/emsdk/upstream/emscripten/cache/sysroot/include/c++/v1/locale:3145:28: note: 'wstring_convert<std::codecvt_utf8<wchar_t>>' has been explicitly marked deprecated here
3145 | class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 wstring_convert {
| ^
/Users/danbev/work/wasm/emsdk/upstream/emscripten/cache/sysroot/include/c++/v1/__config:723:41: note: expanded from macro '_LIBCPP_DEPRECATED_IN_CXX17'
723 | # define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED
| ^
/Users/danbev/work/wasm/emsdk/upstream/emscripten/cache/sysroot/include/c++/v1/__config:688:49: note: expanded from macro '_LIBCPP_DEPRECATED'
688 | # define _LIBCPP_DEPRECATED __attribute__((__deprecated__))
| ^
4 warnings generated.
```

* ggml : suppress double-promotion warning in GGML_F16x4_REDUCE

This commit adds a cast to `ggml_float` in the `GGML_F16x4_REDUCE` macro
to suppress a double-promotion warning.

Currently the following warning is generated when compiling the
command.wasm example:
```console
/whisper-work/ggml/src/ggml-cpu/ggml-cpu.c:1592:5: warning: implicit conversion increases floating-point precision: 'float' to 'ggml_float' (aka 'double') [-Wdouble-promotion]
1592 | GGML_F16_VEC_REDUCE(sumf, sum);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/danbev/work/ai/whisper-work/ggml/src/ggml-cpu/ggml-cpu.c:932:37: note: expanded from macro 'GGML_F16_VEC_REDUCE'
932 | #define GGML_F16_VEC_REDUCE GGML_F16x4_REDUCE
| ^
/Users/danbev/work/ai/whisper-work/ggml/src/ggml-cpu/ggml-cpu.c:920:44: note: expanded from macro 'GGML_F16x4_REDUCE'
918 | res = wasm_f32x4_extract_lane(x[0], 0) + \
| ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
919 | wasm_f32x4_extract_lane(x[0], 1) + \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
920 | wasm_f32x4_extract_lane(x[0], 2) + \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~
921 | wasm_f32x4_extract_lane(x[0], 3); \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/whisper-work/ggml/src/ggml-cpu/ggml-cpu.c:1640:9: warning: implicit conversion increases floating-point precision: 'float' to 'ggml_float' (aka 'double') [-Wdouble-promotion]
1640 | GGML_F16_VEC_REDUCE(sumf[k], sum[k]);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/danbev/work/ai/whisper-work/ggml/src/ggml-cpu/ggml-cpu.c:932:37: note: expanded from macro 'GGML_F16_VEC_REDUCE'
932 | #define GGML_F16_VEC_REDUCE GGML_F16x4_REDUCE
| ^
/Users/danbev/work/ai/whisper-work/ggml/src/ggml-cpu/ggml-cpu.c:920:44: note: expanded from macro 'GGML_F16x4_REDUCE'
918 | res = wasm_f32x4_extract_lane(x[0], 0) + \
| ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
919 | wasm_f32x4_extract_lane(x[0], 1) + \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
920 | wasm_f32x4_extract_lane(x[0], 2) + \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~
921 | wasm_f32x4_extract_lane(x[0], 3); \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
```
wasm_f32x4_extract_lane returns a 32-bit float and this is what the
addition is performed on. But there is an implicit conversion from
32-bit float to 64-bit double when the result is assigned to `res`,
which is of type `ggml_float`. My understanding here is that this is
intentional and adding a cast to `ggml_float` should suppress the
warning.

* emscripten : add -Wno-deprecated to for emscripten

This commit adds -Wno-deprecated to the CMAKE_CXX_FLAGS for emscripten
builds.

The motivation for this is that currently there a number of warnings
generated like the following:
```console
warning: JS library symbol '$print' is deprecated. Please open a bug if you have a continuing need for this symbol [-Wdeprecated]
warning: JS library symbol '$printErr' is deprecated. Please open a bug if you have a continuing need for this symbol [-Wdeprecated]
em++: warning: warnings in JS library compilation [-Wjs-compiler]
em++: warning: linker setting ignored during compilation: 'ENVIRONMENT' [-Wunused-command-line-argument]
warning: JS library symbol '$print' is deprecated. Please open a bug if you have a continuing need for this symbol [-Wdeprecated]
warning: JS library symbol '$printErr' is deprecated. Please open a bug if you have a continuing need for this symbol [-Wdeprecated]
em++: warning: warnings in JS library compilation [-Wjs-compiler]
warning: JS library symbol '$print' is deprecated. Please open a bug if you have a continuing need for this symbol [-Wdeprecated]
warning: JS library symbol '$printErr' is deprecated. Please open a bug if you have a continuing need for this symbol [-Wdeprecated]
em++: warning: warnings in JS library compilation [-Wjs-compiler]
em++: warning: linker setting ignored during compilation: 'ENVIRONMENT' [-Wunused-command-line-argument]
e

CMakeLists.txt CHANGED
@@ -38,8 +38,13 @@ if (EMSCRIPTEN)
38
 
39
  # TODO: without these, we get the following error:
40
  # wasm-ld: error: --shared-memory is disallowed by whisper.cpp.o because it was not compiled with 'atomics' or 'bulk-memory' features.
41
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread -s TOTAL_STACK=5242880")
42
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -s TOTAL_STACK=5242880")
 
 
 
 
 
43
  else()
44
  if (MINGW)
45
  set(BUILD_SHARED_LIBS_DEFAULT OFF)
 
38
 
39
  # TODO: without these, we get the following error:
40
  # wasm-ld: error: --shared-memory is disallowed by whisper.cpp.o because it was not compiled with 'atomics' or 'bulk-memory' features.
41
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread")
42
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
43
+
44
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s TOTAL_STACK=5242880")
45
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -s TOTAL_STACK=5242880")
46
+
47
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated")
48
  else()
49
  if (MINGW)
50
  set(BUILD_SHARED_LIBS_DEFAULT OFF)
examples/command.wasm/README.md CHANGED
@@ -15,9 +15,18 @@ git clone https://github.com/ggerganov/whisper.cpp
15
  cd whisper.cpp
16
  mkdir build-em && cd build-em
17
  emcmake cmake ..
18
- make -j
 
 
 
 
 
 
 
19
 
20
- # copy the produced page to your HTTP path
 
 
21
  cp bin/command.wasm/* /path/to/html/
22
  cp bin/libcommand.worker.js /path/to/html/
23
  ```
 
15
  cd whisper.cpp
16
  mkdir build-em && cd build-em
17
  emcmake cmake ..
18
+ make -j libcommand
19
+ ```
20
+ The example can then be started by running a local HTTP server:
21
+ ```console
22
+ python3 examples/server.py
23
+ ```
24
+ And then opening a browser to the following URL:
25
+ http://localhost:8000/command.wasm/
26
 
27
+ To run the example in a different server, you need to copy the following files
28
+ to the server's HTTP path:
29
+ ```
30
  cp bin/command.wasm/* /path/to/html/
31
  cp bin/libcommand.worker.js /path/to/html/
32
  ```
examples/common.cpp CHANGED
@@ -247,17 +247,6 @@ std::map<std::string, int32_t> json_parse(const std::string & fname) {
247
  return result;
248
  }
249
 
250
- std::string convert_to_utf8(const std::wstring & input) {
251
- std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
252
- return converter.to_bytes(input);
253
- }
254
-
255
-
256
- std::wstring convert_to_wstring(const std::string & input) {
257
- std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
258
- return converter.from_bytes(input);
259
- }
260
-
261
  void gpt_split_words(std::string str, std::vector<std::string>& words) {
262
  const std::string pattern = R"('s|'t|'re|'ve|'m|'ll|'d| ?[[:alpha:]]+| ?[[:digit:]]+| ?[^\s[:alpha:][:digit:]]+|\s+(?!\S)|\s+)";
263
  const std::regex re(pattern);
 
247
  return result;
248
  }
249
 
 
 
 
 
 
 
 
 
 
 
 
250
  void gpt_split_words(std::string str, std::vector<std::string>& words) {
251
  const std::string pattern = R"('s|'t|'re|'ve|'m|'ll|'d| ?[[:alpha:]]+| ?[[:digit:]]+| ?[^\s[:alpha:][:digit:]]+|\s+(?!\S)|\s+)";
252
  const std::regex re(pattern);
examples/server.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import http.server
2
+ import socketserver
3
+ import os
4
+ from pathlib import Path
5
+
6
+ SCRIPT_DIR = Path(__file__).parent.absolute()
7
+ DIRECTORY = os.path.join(SCRIPT_DIR, "../build-em/bin")
8
+ DIRECTORY = os.path.abspath(DIRECTORY)
9
+
10
+ class CustomHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
11
+ def __init__(self, *args, **kwargs):
12
+ super().__init__(*args, directory=DIRECTORY, **kwargs)
13
+
14
+ def end_headers(self):
15
+ # Add required headers for SharedArrayBuffer
16
+ self.send_header("Cross-Origin-Opener-Policy", "same-origin")
17
+ self.send_header("Cross-Origin-Embedder-Policy", "require-corp")
18
+ super().end_headers()
19
+
20
+ PORT = 8000
21
+
22
+ with socketserver.TCPServer(("", PORT), CustomHTTPRequestHandler) as httpd:
23
+ print(f"Serving directory '{DIRECTORY}' at http://localhost:{PORT}")
24
+ try:
25
+ httpd.serve_forever()
26
+ except KeyboardInterrupt:
27
+ print("\nServer stopped.")
ggml/src/ggml-cpu/ggml-cpu.c CHANGED
@@ -901,24 +901,24 @@ inline static void __wasm_f16x4_store(ggml_fp16_t * p, v128_t x) {
901
  #define GGML_F16x4_FMA GGML_F32x4_FMA
902
  #define GGML_F16x4_ADD wasm_f32x4_add
903
  #define GGML_F16x4_MUL wasm_f32x4_mul
904
- #define GGML_F16x4_REDUCE(res, x) \
905
- { \
906
- int offset = GGML_F16_ARR >> 1; \
907
- for (int i = 0; i < offset; ++i) { \
908
- x[i] = wasm_f32x4_add(x[i], x[offset+i]); \
909
- } \
910
- offset >>= 1; \
911
- for (int i = 0; i < offset; ++i) { \
912
- x[i] = wasm_f32x4_add(x[i], x[offset+i]); \
913
- } \
914
- offset >>= 1; \
915
- for (int i = 0; i < offset; ++i) { \
916
- x[i] = wasm_f32x4_add(x[i], x[offset+i]); \
917
- } \
918
- res = wasm_f32x4_extract_lane(x[0], 0) + \
919
- wasm_f32x4_extract_lane(x[0], 1) + \
920
- wasm_f32x4_extract_lane(x[0], 2) + \
921
- wasm_f32x4_extract_lane(x[0], 3); \
922
  }
923
 
924
  #define GGML_F16_VEC GGML_F16x4
 
901
  #define GGML_F16x4_FMA GGML_F32x4_FMA
902
  #define GGML_F16x4_ADD wasm_f32x4_add
903
  #define GGML_F16x4_MUL wasm_f32x4_mul
904
+ #define GGML_F16x4_REDUCE(res, x) \
905
+ { \
906
+ int offset = GGML_F16_ARR >> 1; \
907
+ for (int i = 0; i < offset; ++i) { \
908
+ x[i] = wasm_f32x4_add(x[i], x[offset+i]); \
909
+ } \
910
+ offset >>= 1; \
911
+ for (int i = 0; i < offset; ++i) { \
912
+ x[i] = wasm_f32x4_add(x[i], x[offset+i]); \
913
+ } \
914
+ offset >>= 1; \
915
+ for (int i = 0; i < offset; ++i) { \
916
+ x[i] = wasm_f32x4_add(x[i], x[offset+i]); \
917
+ } \
918
+ res = (ggml_float) (wasm_f32x4_extract_lane(x[0], 0) + \
919
+ wasm_f32x4_extract_lane(x[0], 1) + \
920
+ wasm_f32x4_extract_lane(x[0], 2) + \
921
+ wasm_f32x4_extract_lane(x[0], 3)); \
922
  }
923
 
924
  #define GGML_F16_VEC GGML_F16x4