Spaces:
Running
examples : command.wasm updates (#2904)
Browse filesThis 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 +7 -2
- examples/command.wasm/README.md +11 -2
- examples/common.cpp +0 -11
- examples/server.py +27 -0
- ggml/src/ggml-cpu/ggml-cpu.c +18 -18
|
@@ -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
|
| 42 |
-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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)
|
|
@@ -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 |
-
|
|
|
|
|
|
|
| 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 |
```
|
|
@@ -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);
|
|
@@ -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.")
|
|
@@ -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
|