{"id":24293721,"url":"https://github.com/msqr1/kaldi-wasm2","last_synced_at":"2026-02-03T02:07:38.454Z","repository":{"id":257848389,"uuid":"873083508","full_name":"msqr1/kaldi-wasm2","owner":"msqr1","description":"New compilation guide for Kaldi to WASM","archived":false,"fork":false,"pushed_at":"2025-03-18T18:18:28.000Z","size":25,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-03T13:05:00.486Z","etag":null,"topics":["kaldi","webassembly"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/msqr1.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-10-15T15:15:02.000Z","updated_at":"2025-05-17T17:04:25.000Z","dependencies_parsed_at":"2025-01-25T20:18:53.543Z","dependency_job_id":"697ef7e5-44aa-4097-b4cf-929a86db5334","html_url":"https://github.com/msqr1/kaldi-wasm2","commit_stats":null,"previous_names":["msqr1/kaldi-wasm-guide2"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/msqr1/kaldi-wasm2","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msqr1%2Fkaldi-wasm2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msqr1%2Fkaldi-wasm2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msqr1%2Fkaldi-wasm2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msqr1%2Fkaldi-wasm2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/msqr1","download_url":"https://codeload.github.com/msqr1/kaldi-wasm2/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msqr1%2Fkaldi-wasm2/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29028119,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-03T01:44:09.608Z","status":"online","status_checked_at":"2026-02-03T02:00:06.989Z","response_time":96,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["kaldi","webassembly"],"created_at":"2025-01-16T16:56:03.911Z","updated_at":"2026-02-03T02:07:38.412Z","avatar_url":"https://github.com/msqr1.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Compiling Kaldi to WebAssembly \n\n## Overview\n\n- There is [an older guide](https://gitlab.inria.fr/multispeech/kaldi.web/kaldi-wasm/-/wikis/build_details.md) for this that compiled Kaldi with [CLAPACK](https://www.netlib.org/clapack) (not properly tested) and [Netlib's Reference BLAS](https://www.netlib.org/blas), which exists solely for implementers of the BLAS standard to verify the correctness of their own implementation, and thus, not optimized for performance.\n\n- This newer guide compile Kaldi using [OpenBLAS](https://github.com/OpenMathLib/OpenBLAS), a high-performance, optimized, actively maintained BLAS library officially supported by Kaldi. It also includes both BLAS and LAPACK. This was profiled to speed up Kaldi by around 20% compared to the build with Netlib's Reference BLAS and CLAPACK.\n\n- This guide compiles Kaldi's \"online decoding\" target `online2` More info: https://kaldi-asr.org/doc/online_decoding.html\n\n- Guide version will be updated to follow Emscripten/OpenFST/OpenBLAS version change\n\n## Current versions\n\n- Emscripten: 3.1.69\n- OpenFST: 1.8.4\n- OpenBLAS: 0.3.28\n- Kaldi: ???\n\n## Step 1: Prepare\n\n- Execute all commands in one terminal\n- Make a directory and change into it before starting\n- Compilation optimization level is -O3 by default througout this guide\n\n```\n# Our build root, exported so that we can refer to it in this terminal\nexport ROOT=\"$PWD\"\n\n# Clone this repository\ngit clone --depth 1 https://github.com/msqr1/kaldi-wasm2 \"$ROOT\"\n\n# Enter that directory\ncd \"$ROOT\"\n```\n\n- **Optional**: WASM-specific compilation flags that can boost performance, selected by me with careful condsideration on browser support:\n  - Chrome ≥ 75 (2019)\n  - Firefox ≥ 79 (2020)\n  - Safari ≥ 15 (2021)\n  - Edge ≥ 79 (2020)  \n- [Wasm features support table](https://webassembly.org/features/)\n- [Wasm flags list](https://clang.llvm.org/docs/ClangCommandLineReference.html#webassembly)\n\n```\nexport WAFLAGS=\"-mbulk-memory -mnontrapping-fptoint -mmutable-globals -msign-ext\"\n```\n\n## Step 2: Emscripten\n\n- As of writing, Emscripten 3.1.6x is known to work\n- Reference [this guide](https://emscripten.org/docs/getting_started/downloads.html) to setup Emscripten, the WASM compiler\n\n```\n# Get EMSDK\ngit clone https://github.com/emscripten-core/emsdk.git\n\n# Enter that directory\ncd emsdk\n\n# Install Emscripten\n./emsdk install 3.1.69\n\n# Activate Emcripten\n./emsdk activate 3.1.69\n\n# Add Emscripten tools to current terminal\nsource ./emsdk_env.sh\n```\n\n## Step 3: OpenFST\n\n```\n# Go to build root\ncd \"$ROOT\"\n\n# Get OpenFST\nwget https://www.openfst.org/twiki/pub/FST/FstDownload/openfst-1.8.4.tar.gz -O openfst.tgz\n\n# Decompress\nmkdir openfst\ntar -xzf openfst.tgz -C openfst --strip-component 1\n\n# Enter that directory\ncd openfst\n\n# OpenFST bug fixes\n# Invalid assignment\npatch -i \"$ROOT\"/patches/openfst/fst.h.patch ./src/include/fst/fst.h\n\n# Undefined member variable\npatch -i \"$ROOT\"/patches/openfst/bi-table.h.patch ./src/include/fst/bi-table.h\n\n# Configuring static OpenFST with Ngram fsts\nCXXFLAGS=\"$WAFLAGS -O3 -fno-rtti\" emconfigure ./configure --prefix=\"$ROOT/openfst-build\" --enable-static --disable-shared --enable-ngram-fsts --disable-bin\n\n# Compile and install into prefix\nemmake make -j$(nproc) install \u003e /dev/null\n```\n\n## Step 4: OpenBLAS\n\n- The most crucial step of the build, some hacks are required for this to work\n\n```\n# Go to build root\ncd \"$ROOT\"\n\n# Get OpenBLAS\ngit clone -b v0.3.28 --depth=1 https://github.com/OpenMathLib/OpenBLAS openblas\n\n# Enter that directory\ncd openblas\n\n# OpenBLAS hacks: remove march'es, fPIC, etc.\npatch -i \"$ROOT\"/patches/openblas/Makefile.riscv64.patch Makefile.riscv64\npatch -i \"$ROOT\"/patches/openblas/Makefile.prebuild.patch Makefile.prebuild\npatch -i \"$ROOT\"/patches/openblas/Makefile.system.patch Makefile.system\n\n# Make single-threaded static OpenBLAS with just single and double precision\n# Change HOSTCC to the C compiler on your machine. Mine is gcc-12 from Debian 12\nCC=emcc HOSTCC=gcc-12 TARGET=RISCV64_GENERIC USE_THREAD=0 NO_SHARED=1 BINARY=32 BUILD_SINGLE=1 BUILD_DOUBLE=1 BUILD_BFLOAT16=0 BUILD_COMPLEX16=0 BUILD_COMPLEX=0 CFLAGS=\"$WAFLAGS -fno-exceptions -fno-rtti\" make -j$(nproc) \u003e /dev/null\n\n# Install into prefix\nPREFIX=\"$ROOT/openblas-build\" NO_SHARED=1 make install\n```\n\n## Step 5: Kaldi\n\n```\n# Go to build root\ncd \"$ROOT\"\n\n# Get Kaldi\ngit clone --depth 1 https://github.com/kaldi-asr/kaldi\n\n# Enter Kaldi source\ncd kaldi/src\n\n# Configuring static Kaldi with static installed dependencies\nCXXFLAGS=\"$WAFLAGS -UHAVE_EXECINFO_H -g0 -O3 -msimd128\" emconfigure ./configure --use-cuda=no --with-cudadecoder=no --static --static-math --static-fst --fst-root=\"$ROOT/openfst-build\" --fst-version='1.8.4' --openblas-root=\"$ROOT/openblas-build\" --host=WASM\n\n# Compile our target\nmake -j$(nproc) online2 \u003e /dev/null\n```\n\n## Step 6: Clean up\n\n```\n# Go to build root\ncd \"$ROOT\"\n\n# Clean up\nrm -rf openfst.tgz openfst openblas\n```\n\n## Full command\n\n```\nexport ROOT=\"$PWD\"\ngit clone --depth 1 https://github.com/msqr1/kaldi-wasm2 \"$ROOT\"\ncd \"$ROOT\"\ngit clone --depth 1 https://github.com/emscripten-core/emsdk.git\ncd emsdk\n./emsdk install 3.1.69\n./emsdk activate 3.1.69\nsource emsdk_env.sh\ncd \"$ROOT\"\nexport WAFLAGS=\"-mbulk-memory -mnontrapping-fptoint -mmutable-globals -msign-ext\"\nwget https://www.openfst.org/twiki/pub/FST/FstDownload/openfst-1.8.4.tar.gz -O openfst.tgz\nmkdir openfst\ntar -xzf openfst.tgz -C openfst --strip-component 1\ncd openfst\nCXXFLAGS=\"$WAFLAGS -O3 -fno-rtti\" emconfigure ./configure --prefix=\"$ROOT/openfst-build\" --enable-static --disable-shared --enable-ngram-fsts --disable-bin\nemmake make -j$(nproc) install \u003e /dev/null\ncd \"$ROOT\"\ngit clone -b v0.3.28 --depth=1 https://github.com/OpenMathLib/OpenBLAS openblas\ncd openblas\npatch -i \"$ROOT\"/patches/openblas/Makefile.riscv64.patch Makefile.riscv64\npatch -i \"$ROOT\"/patches/openblas/Makefile.prebuild.patch Makefile.prebuild\npatch -i \"$ROOT\"/patches/openblas/Makefile.system.patch Makefile.system\nCC=emcc HOSTCC=gcc-12 TARGET=RISCV64_GENERIC USE_THREAD=0 NO_SHARED=1 BINARY=32 BUILD_SINGLE=1 BUILD_DOUBLE=1 BUILD_BFLOAT16=0 BUILD_COMPLEX16=0 BUILD_COMPLEX=0 CFLAGS=\"$WAFLAGS -fno-exceptions -fno-rtti\" make -j$(nproc) \u003e /dev/null\nPREFIX=\"$ROOT/openblas-build\" NO_SHARED=1 make install\ncd \"$ROOT\"\ngit clone --depth 1 https://github.com/kaldi-asr/kaldi\ncd kaldi/src\nCXXFLAGS=\"$WAFLAGS -UHAVE_EXECINFO_H -g0 -O3 -msimd128\" emconfigure ./configure --use-cuda=no --with-cudadecoder=no --static --static-math --static-fst --fst-root=\"$ROOT/openfst-build\" --fst-version='1.8.4' --openblas-root=\"$ROOT/openblas-build\" --host=WASM\nmake -j$(nproc) online2 \u003e /dev/null\ncd \"$ROOT\"\nrm -rf openfst.tgz openfst openblas\n```\n\n# Linking and running example\n\n- We're going to run `nnet2/am-nnet-test.cc`\n\n```\n# Compiler flags\nexport CXXFLAGS=\"\n-DOPENFST_VER=10803\n-I$ROOT/kaldi/src\n-I$ROOT/openfst-build/include\n-I$ROOT/openblas-build/include\"\n\n# Linker flags\nexport LDFLAGS=\"\n-L$ROOT/kaldi/src\n-l:online2/kaldi-online2.a        -l:decoder/kaldi-decoder.a\n-l:ivector/kaldi-ivector.a        -l:gmm/kaldi-gmm.a\n-l:tree/kaldi-tree.a              -l:feat/kaldi-feat.a\n-l:cudamatrix/kaldi-cudamatrix.a  -l:lat/kaldi-lat.a\n-l:hmm/kaldi-hmm.a                -l:nnet3/kaldi-nnet3.a\n-l:transform/kaldi-transform.a    -l:matrix/kaldi-matrix.a\n-l:fstext/kaldi-fstext.a          -l:util/kaldi-util.a\n-l:base/kaldi-base.a              -l:nnet2/kaldi-nnet2.a\n-L$ROOT/openfst-build/lib         -l:libfst.a\n-L$ROOT/openblas-build/lib        -l:libopenblas.a\"\n\n# Go to build root\ncd \"$ROOT\"\n\n# Generate .html, .js, and .wasm\nem++ $WAFLAGS -O3 $CXXFLAGS $LDFLAGS kaldi/src/nnet2/am-nnet-test.cc -o index.html\n```\n\n- Open the `index.html` in a browser, check the console for logs from the test. Note that file URL will not work, use 127.0.0.1 or something else.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmsqr1%2Fkaldi-wasm2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmsqr1%2Fkaldi-wasm2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmsqr1%2Fkaldi-wasm2/lists"}