Skip to content

Commit 6e8242f

Browse files
authored
examples : command.wasm updates (#2904)
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] em++: warning: linker setting ignored during compilation: 'ENVIRONMENT' [-Wunused-command-line-argument] ``` The downside of this is that we might miss other deprecation warnings in the future so I'm not sure if this is acceptable. But it make the wasm examples cleaner without the warnings. * examples : fix tautological-compare warning in stb_vorbis.c [no ci] This commit applies a fix to address a tautological-compare warning in stb_vorbis.c. The motivation for this is that currently the following warning is generated when compiling the commmand-wasm example: ```console /Users/danbev/work/ai/whisper-work/examples/stb_vorbis.c:1404:75: warning: pointer comparison always evaluates to false [-Wtautological-compare] 1404 | if (f->stream_start + loc >= f->stream_end || f->stream_start + loc < f->stream_start) { | ^ 1 warning generated. ``` This fix was taken from an open pull request on the stb repository that addreses this issue: nothings/stb#1746 * squash! examples : update command.wasm instructions [no ci] This commit adds a Python script to serve the the wasm examples build in the `build-em` directory. Initially I thought that it would be enough to start a simple python server but I did not notice that there was an error in the browser console when I did that: ```console command.js:1 Uncaught (in promise) DataCloneError: Failed to execute 'postMessage' on 'Worker': SharedArrayBuffer transfer requires self.crossOriginIsolated. at command.js:1:1206224 at new Promise (<anonymous>) at loadWasmModuleToWorker (command.js:1:1204981) at Array.map (<anonymous>) at Object.loadWasmModuleToAllWorkers (command.js:1:1206428) at command.js:1:1204318 at callRuntimeCallbacks (command.js:1:1202062) at preRun (command.js:1:6136) at run (command.js:1:1294094) at removeRunDependency (command.js:1:7046) ``` We need a few CORS headers to be set and in order hopefully make this easy for users a Python script is added to the examples directory. This should be able to server all the wasm examples provided they have been built. command.wasm's README.md is updated to reflect this change. * examples : remove unused functions This commit removed the unused functions convert_to_utf8 and convert_to_wstring from examples/common.cpp. * Revert "examples : fix tautological-compare warning in stb_vorbis.c [no ci]" This reverts commit 8e3c47d. We should not make this change here and instead when the upstream PR is merged we can sync with it. Refs: #2784
1 parent e27fd6f commit 6e8242f

File tree

5 files changed

+63
-33
lines changed

5 files changed

+63
-33
lines changed

CMakeLists.txt

+7-2
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,13 @@ if (EMSCRIPTEN)
3838

3939
# TODO: without these, we get the following error:
4040
# 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")
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")
4348
else()
4449
if (MINGW)
4550
set(BUILD_SHARED_LIBS_DEFAULT OFF)

examples/command.wasm/README.md

+11-2
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,18 @@ git clone https://github.com/ggerganov/whisper.cpp
1515
cd whisper.cpp
1616
mkdir build-em && cd build-em
1717
emcmake cmake ..
18-
make -j
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/
1926

20-
# copy the produced page to your HTTP path
27+
To run the example in a different server, you need to copy the following files
28+
to the server's HTTP path:
29+
```
2130
cp bin/command.wasm/* /path/to/html/
2231
cp bin/libcommand.worker.js /path/to/html/
2332
```

examples/common.cpp

-11
Original file line numberDiff line numberDiff line change
@@ -247,17 +247,6 @@ std::map<std::string, int32_t> json_parse(const std::string & fname) {
247247
return result;
248248
}
249249

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-
261250
void gpt_split_words(std::string str, std::vector<std::string>& words) {
262251
const std::string pattern = R"('s|'t|'re|'ve|'m|'ll|'d| ?[[:alpha:]]+| ?[[:digit:]]+| ?[^\s[:alpha:][:digit:]]+|\s+(?!\S)|\s+)";
263252
const std::regex re(pattern);

examples/server.py

+27
Original file line numberDiff line numberDiff line change
@@ -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

+18-18
Original file line numberDiff line numberDiff line change
@@ -901,24 +901,24 @@ inline static void __wasm_f16x4_store(ggml_fp16_t * p, v128_t x) {
901901
#define GGML_F16x4_FMA GGML_F32x4_FMA
902902
#define GGML_F16x4_ADD wasm_f32x4_add
903903
#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); \
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)); \
922922
}
923923

924924
#define GGML_F16_VEC GGML_F16x4

0 commit comments

Comments
 (0)