Skip to content

Commit

Permalink
Add WebAssembly + NodeJS example. (#311)
Browse files Browse the repository at this point in the history
  • Loading branch information
csukuangfj authored Feb 24, 2024
1 parent 185f5c7 commit 41ebcfb
Show file tree
Hide file tree
Showing 19 changed files with 629 additions and 461 deletions.
69 changes: 23 additions & 46 deletions .github/workflows/nodejs.yaml
Original file line number Diff line number Diff line change
@@ -1,24 +1,16 @@
name: nodejs

on:
push:
branches:
- master
paths:
- '.github/workflows/nodejs.yaml'
- 'CMakeLists.txt'
- 'cmake/**'
- 'nodejs-examples/**'
- 'sherpa-ncnn/csrc/*'
pull_request:
branches:
- master
paths:
- '.github/workflows/nodejs.yaml'
- 'CMakeLists.txt'
- 'cmake/**'
- 'nodejs-examples/**'
- 'sherpa-ncnn/csrc/*'
workflow_dispatch:

schedule:
# minute (0-59)
# hour (0-23)
# day of the month (1-31)
# month (1-12)
# day of the week (0-6)
# nightly test at 22:50 UTC time every day
- cron: "50 22 * * *"

concurrency:
group: nodejs-${{ github.ref }}
Expand All @@ -33,63 +25,48 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.8"]

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- uses: actions/setup-node@v3
- uses: actions/setup-node@v4
with:
node-version: 13
registry-url: 'https://registry.npmjs.org'

- name: Display node version
shell: bash
run: |
node --version
npm --version
cd nodejs-examples
npm install npm@6.14.4 -g
npm install npm@6.14.4
npm --version
- name: Install npm packages
shell: bash
run: |
cd nodejs-examples
npm install ffi-napi ref-struct-napi wav
npm install npm
npm --version
npm list
- name: ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: ${{ matrix.os }}-shared

- name: Download model
shell: bash
run: |
cd nodejs-examples
GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/csukuangfj/sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13
cd sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13
git lfs pull --include "*.bin"
ls -lh
curl -OL https://github.com/k2-fsa/sherpa-ncnn/releases/download/models/sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13.tar.bz2
tar xvf sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13.tar.bz2
rm sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13.tar.bz2
ls -lh sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13
- name: Test
shell: bash
run: |
export CMAKE_CXX_COMPILER_LAUNCHER=ccache
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
cmake --version
cd nodejs-examples
ls -lh
./run.sh
node ./decode-file.js
86 changes: 86 additions & 0 deletions .github/workflows/npm.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: npm

on:
workflow_dispatch:

concurrency:
group: npm-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read
id-token: write

jobs:
nodejs:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
python-version: ["3.8"]

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Install emsdk
uses: mymindstorm/setup-emsdk@v14

- name: View emsdk version
shell: bash
run: |
emcc -v
echo "--------------------"
emcc --check
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- uses: actions/setup-node@v4
with:
registry-url: 'https://registry.npmjs.org'

- name: Display node version
shell: bash
run: |
node --version
npm --version
cd nodejs-examples
npm install npm
npm --version
- name: Build nodejs package
shell: bash
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
./build-wasm-simd-for-nodejs.sh
cp -v build-wasm-simd-for-nodejs/install/bin/wasm/sherpa-ncnn-wasm-main.js ./scripts/nodejs
cp -v build-wasm-simd-for-nodejs/install/bin/wasm/sherpa-ncnn-wasm-main.wasm ./scripts/nodejs
cp -v build-wasm-simd-for-nodejs/install/bin/wasm/sherpa-ncnn.js ./scripts/nodejs
SHERPA_NCNN_VERSION=$(grep "SHERPA_NCNN_VERSION" ./CMakeLists.txt | cut -d " " -f 2 | cut -d '"' -f 2)
echo "SHERPA_NCNN_VERSION $SHERPA_NCNN_VERSION"
cd scripts/nodejs
owner=${{ github.repository_owner }}
echo "owner: $owner"
sed -i.bak s/SHERPA_NCNN_VERSION/$SHERPA_NCNN_VERSION/g ./package.json
sed -i.bak s/k2-fsa/$owner/g ./package.json
rm package.json.bak
git diff .
npm install
npm ci
# see https://docs.npmjs.com/generating-provenance-statements
npm publish --provenance --access public
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,4 @@ generate-int8-*.sh
cmake-build-release
cmake-build-debug

node_modules
11 changes: 10 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
project(sherpa-ncnn)

set(SHERPA_NCNN_VERSION "2.1.8")
set(SHERPA_NCNN_VERSION "2.1.9")

# Disable warning about
#
Expand Down Expand Up @@ -41,6 +41,7 @@ option(SHERPA_NCNN_ENABLE_BINARY "Whether to build the binary sherpa-ncnn" ON)
option(SHERPA_NCNN_ENABLE_TEST "Whether to build tests" OFF)
option(SHERPA_NCNN_ENABLE_C_API "Whether to build C API" ON)
option(SHERPA_NCNN_ENABLE_WASM "Whether to enable WASM" OFF)
option(SHERPA_NCNN_ENABLE_WASM_FOR_NODEJS "Whether to enable WASM for NodeJS" OFF)
option(SHERPA_NCNN_ENABLE_GENERATE_INT8_SCALE_TABLE "Whether to generate-int8-scale-table" ON)
option(SHERPA_NCNN_ENABLE_FFMPEG_EXAMPLES "Whether to enable ffmpeg-examples" OFF)

Expand Down Expand Up @@ -77,6 +78,14 @@ message(STATUS "SHERPA_NCNN_ENABLE_TEST ${SHERPA_NCNN_ENABLE_TEST}")
message(STATUS "SHERPA_NCNN_ENABLE_C_API ${SHERPA_NCNN_ENABLE_C_API}")
message(STATUS "SHERPA_NCNN_ENABLE_GENERATE_INT8_SCALE_TABLE ${SHERPA_NCNN_ENABLE_GENERATE_INT8_SCALE_TABLE}")
message(STATUS "SHERPA_NCNN_ENABLE_FFMPEG_EXAMPLES ${SHERPA_NCNN_ENABLE_FFMPEG_EXAMPLES}")
message(STATUS "SHERPA_NCNN_ENABLE_WASM ${SHERPA_NCNN_ENABLE_WASM}")
message(STATUS "SHERPA_NCNN_ENABLE_WASM_FOR_NODEJS ${SHERPA_NCNN_ENABLE_WASM_FOR_NODEJS}")

if(SHERPA_NCNN_ENABLE_WASM_FOR_NODEJS)
if(NOT SHERPA_NCNN_ENABLE_WASM)
message(FATAL_ERROR "Please set SHERPA_NCNN_ENABLE_WASM to ON if you enable WASM for NodeJS")
endif()
endif()

if(NOT CMAKE_BUILD_TYPE)
message(STATUS "No CMAKE_BUILD_TYPE given, default to Release")
Expand Down
76 changes: 76 additions & 0 deletions build-wasm-simd-for-nodejs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/usr/bin/env bash
# Copyright (c) 2024 Xiaomi Corporation
#
# This script is to build sherpa-ncnn for WebAssembly (NodeJS)
#
# See also
# https://github.com/Tencent/ncnn/wiki/how-to-build#build-for-webassembly
#
# Please refer to
# https://k2-fsa.github.io/sherpa/ncnn/wasm/index.html
# for more details.

set -ex

if [ x"$EMSCRIPTEN" == x"" ]; then
if ! command -v emcc &> /dev/null; then
echo "Please install emscripten first"
echo ""
echo "You can use the following commands to install it:"
echo ""
echo "git clone https://github.com/emscripten-core/emsdk.git"
echo "cd emsdk"
echo "git pull"
echo "./emsdk install latest"
echo "./emsdk activate latest"
echo "source ./emsdk_env.sh"
exit 1
else
EMSCRIPTEN=$(dirname $(realpath $(which emcc)))
fi
fi

export EMSCRIPTEN=$EMSCRIPTEN
echo "EMSCRIPTEN: $EMSCRIPTEN"
if [ ! -f $EMSCRIPTEN/cmake/Modules/Platform/Emscripten.cmake ]; then
echo "Cannot find $EMSCRIPTEN/cmake/Modules/Platform/Emscripten.cmake"
echo "Please make sure you have installed emsdk correctly"
exit 1
fi

mkdir -p build-wasm-simd-for-nodejs
pushd build-wasm-simd-for-nodejs

export SHERPA_NCNN_IS_USING_BUILD_WASM_SH=ON

cmake \
-DCMAKE_INSTALL_PREFIX=./install \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_TOOLCHAIN_FILE=$EMSCRIPTEN/cmake/Modules/Platform/Emscripten.cmake \
-DNCNN_THREADS=OFF \
-DNCNN_OPENMP=OFF \
-DNCNN_SIMPLEOMP=OFF \
-DNCNN_RUNTIME_CPU=OFF \
-DNCNN_SSE2=ON \
-DNCNN_AVX2=OFF \
-DNCNN_AVX=OFF \
-DNCNN_BUILD_TOOLS=OFF \
-DNCNN_BUILD_EXAMPLES=OFF \
-DNCNN_BUILD_BENCHMARK=OFF \
\
-DSHERPA_NCNN_ENABLE_WASM=ON \
-DSHERPA_NCNN_ENABLE_WASM_FOR_NODEJS=ON \
-DBUILD_SHARED_LIBS=OFF \
-DSHERPA_NCNN_ENABLE_PYTHON=OFF \
-DSHERPA_NCNN_ENABLE_PORTAUDIO=OFF \
-DSHERPA_NCNN_ENABLE_JNI=OFF \
-DSHERPA_NCNN_ENABLE_BINARY=OFF \
-DSHERPA_NCNN_ENABLE_TEST=OFF \
-DSHERPA_NCNN_ENABLE_C_API=ON \
-DSHERPA_NCNN_ENABLE_GENERATE_INT8_SCALE_TABLE=OFF \
-DSHERPA_NCNN_ENABLE_FFMPEG_EXAMPLES=OFF \
..

make -j2
make install
ls -lh install/bin/wasm
3 changes: 0 additions & 3 deletions nodejs-examples/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
install
node_modules
package.json
package-lock.json
47 changes: 47 additions & 0 deletions nodejs-examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Introduction

This folder contains examples about how to use the sherpa-ncnn WebAssembly module
with nodejs for speech recognition.

- [decode-file.js](./decode-file.js) it shows how to decode a file
- [real-time-speech-recognition-microphone.js](./real-time-speech-recognition-microphone.js) it shows
how to do real-time speech recognition with a microphone

## Usage

### Install dependencies

```bash
cd ./nodejs-examples
npm i
```

### Download a model

Please visit <https://github.com/k2-fsa/sherpa-ncnn/releases/tag/models> to
select more models.

The following is an example:

```bash
cd ./nodejs-examples
wget https://github.com/k2-fsa/sherpa-ncnn/releases/download/models/sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13.tar.bz2
tar xvf sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13.tar.bz2
rm sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13.tar.bz2
```

### Decode a file

```bash
cd ./nodejs-examples

node ./decode-file.js
```

### Real-time speech recognition from a microphone

```bash
cd ./nodejs-examples

node ./real-time-speech-recognition-microphone.js
```
Loading

0 comments on commit 41ebcfb

Please sign in to comment.