skeskinen/bert.cpp

[Regression] WASM alignment fault after ggml update

ivanstepanovftw opened this issue · 3 comments

Following #24 WASM compiled library does not work. Nor f32, nor fresh q4_0 models work.

Here is what I am getting in console: Uncaught (in promise) RuntimeError: Aborted(alignment fault). Exact line that is falling before 'SAFE_HEAP_STORE_i64_8_8' call is ggml.c:4632, which have this content:

    for (int i = 0; i < n_dims; i++) {
        result->ne[i] = ne[i];
    }
Chrome Console Output
[C/C++ DevTools Support (DWARF)] Loading debug symbols for wasm://wasm/017aede6...
index.html?_ijt=8885d1g3pefs1slvbkk1nbfo9s&_ij_reload=RELOAD_ON_SAVE:93 Writing model to filesystem... because:  No such file or directory
bert.wasm.js:1415 bert_load_from_file: loading model from '/ggml-model-q4_0.bin' - please wait ...
bert.wasm.js:1415 bert_load_from_file: n_vocab = 30522
bert.wasm.js:1415 bert_load_from_file: n_max_tokens   = 512
bert.wasm.js:1415 bert_load_from_file: n_embd  = 384
bert.wasm.js:1415 bert_load_from_file: n_intermediate  = 1536
bert.wasm.js:1415 bert_load_from_file: n_head  = 12
bert.wasm.js:1415 bert_load_from_file: n_layer = 6
bert.wasm.js:1415 bert_load_from_file: f16     = 2
[C/C++ DevTools Support (DWARF)] Loaded debug symbols for wasm://wasm/017aede6, found 567 source file(s)
bert.wasm.js:1415 bert_load_from_file: ggml ctx size =  12.26 MB
bert.wasm.js:581 Aborted(alignment fault)
abort @ bert.wasm.js:581
alignfault @ bert.wasm.js:365
$SAFE_HEAP_STORE_i64_8_8 @ 017aede6:0x129fa4
$ggml_new_tensor_impl @ ggml.c:4632
$ggml_new_tensor @ ggml.c:4667
$ggml_new_tensor_2d @ ggml.c:4683
$bert_load_from_file @ bert.cpp:495
$embind_init_bert()::$_0::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>> const&) const @ emscripten.cpp:24
$embind_init_bert()::$_0::__invoke(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>> const&) @ emscripten.cpp:22
$emscripten::internal::Invoker<void, std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>> const&>::invoke(void (*)(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>> const&), emscripten::internal::BindingType<std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>>, void>::'unnamed'*) @ bind.h:416
(anonymous) @ bert.wasm.js:4079
Module.onRuntimeInitialized @ index.html?_ijt=8885d1g3pefs1slvbkk1nbfo9s&_ij_reload=RELOAD_ON_SAVE:98
await in Module.onRuntimeInitialized (async)
doRun @ bert.wasm.js:5620
run @ bert.wasm.js:5633
runCaller @ bert.wasm.js:5596
removeRunDependency @ bert.wasm.js:571
receiveInstance @ bert.wasm.js:706
receiveInstantiationResult @ bert.wasm.js:714
Promise.then (async)
instantiateArrayBuffer @ bert.wasm.js:666
instantiateAsync @ bert.wasm.js:688
createWasm @ bert.wasm.js:724
(anonymous) @ bert.wasm.js:5507
bert.wasm.js:584 Uncaught (in promise) RuntimeError: Aborted(alignment fault)
    at abort (bert.wasm.js:584:10)
    at alignfault (bert.wasm.js:365:2)
    at SAFE_HEAP_STORE_i64_8_8 (017aede6:0x129fa4)
    at ggml_new_tensor_impl (ggml.c:4632)
    at ggml_new_tensor (ggml.c:4667)
    at ggml_new_tensor_2d (ggml.c:4683)
    at ::bert_load_from_file(const char *) (bert.cpp:495)
    at embind_init_bert()::$_0::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>> const&) embind_init_bert()::$_0::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>> const&) const (emscripten.cpp:24)
    at embind_init_bert()::$_0::__invoke(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>> embind_init_bert()::$_0::__invoke(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>> const&) (emscripten.cpp:22)
    at emscripten::internal::Invoker<void, std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>> const&>::invoke(void (*)(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>> const&), emscripten::internal::BindingType<std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>>, emscripten::internal::Invoker<void, std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>> const&>::invoke(void (*)(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>> const&), emscripten::internal::BindingType<std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>>, void>::'unnamed'*) (bind.h:416)
abort @ bert.wasm.js:584
alignfault @ bert.wasm.js:365
$SAFE_HEAP_STORE_i64_8_8 @ 017aede6:0x129fa4
$ggml_new_tensor_impl @ ggml.c:4632
$ggml_new_tensor @ ggml.c:4667
$ggml_new_tensor_2d @ ggml.c:4683
$bert_load_from_file @ bert.cpp:495
$embind_init_bert()::$_0::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>> const&) const @ emscripten.cpp:24
$embind_init_bert()::$_0::__invoke(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>> const&) @ emscripten.cpp:22
$emscripten::internal::Invoker<void, std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>> const&>::invoke(void (*)(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>> const&), emscripten::internal::BindingType<std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>>, void>::'unnamed'*) @ bind.h:416
(anonymous) @ bert.wasm.js:4079
Module.onRuntimeInitialized @ index.html?_ijt=8885d1g3pefs1slvbkk1nbfo9s&_ij_reload=RELOAD_ON_SAVE:98
await in Module.onRuntimeInitialized (async)
doRun @ bert.wasm.js:5620
run @ bert.wasm.js:5633
runCaller @ bert.wasm.js:5596
removeRunDependency @ bert.wasm.js:571
receiveInstance @ bert.wasm.js:706
receiveInstantiationResult @ bert.wasm.js:714
Promise.then (async)
instantiateArrayBuffer @ bert.wasm.js:666
instantiateAsync @ bert.wasm.js:688
createWasm @ bert.wasm.js:724
(anonymous) @ bert.wasm.js:5507

Hm, interesting. Probably ne has to be padded to 8 byte boundary:

    // n-dimensional tensor
    struct ggml_tensor {
        enum ggml_type    type;
        enum ggml_backend backend;

        int     n_dims;

        char padne[4]; // TMP

        int64_t ne[GGML_MAX_DIMS]; // number of elements
        size_t  nb[GGML_MAX_DIMS]; // stride in bytes:
                                   // nb[0] = sizeof(type)
                                   // nb[1] = nb[0]   * ne[0] + padding
                                   // nb[i] = nb[i-1] * ne[i-1]

It did not help; changing ne back to int helps. But now I am facing other issues.