diff --git a/.github/workflows/riscv64-linux.yaml b/.github/workflows/riscv64-linux.yaml
new file mode 100644
index 000000000..04d196a8f
--- /dev/null
+++ b/.github/workflows/riscv64-linux.yaml
@@ -0,0 +1,205 @@
+name: riscv64-linux
+
+on:
+  push:
+    branches:
+      - master
+    paths:
+      - '.github/workflows/riscv64-linux.yaml'
+      - 'CMakeLists.txt'
+      - 'cmake/**'
+      - 'sherpa-onnx/csrc/*'
+      - 'toolchains/riscv64-linux-gnu.toolchain.cmake'
+      - 'build-riscv64-linux-gnu.sh'
+    tags:
+      - '*'
+  pull_request:
+    branches:
+      - master
+    paths:
+      - '.github/workflows/riscv64-linux.yaml'
+      - 'CMakeLists.txt'
+      - 'cmake/**'
+      - 'sherpa-onnx/csrc/*'
+      - 'toolchains/riscv64-linux-gnu.toolchain.cmake'
+      - 'build-riscv64-linux-gnu.sh'
+
+  workflow_dispatch:
+
+concurrency:
+  group: riscv64-linux-${{ github.ref }}
+  cancel-in-progress: true
+
+jobs:
+  riscv64_linux:
+    runs-on: ${{ matrix.os }}
+    name: ${{ matrix.os }} ${{ matrix.lib_type }}
+    strategy:
+      fail-fast: false
+      matrix:
+        os: [ubuntu-latest]
+        lib_type: [static, shared]
+
+    steps:
+      - uses: actions/checkout@v4
+        with:
+          fetch-depth: 0
+
+      - name: ccache
+        uses: hendrikmuhs/ccache-action@v1.2
+        with:
+          key: ${{ matrix.os }}-riscv64-${{ matrix.lib_type }}
+
+      - name: cache-qemu
+        id: cache-qemu
+        uses: actions/cache@v4
+        with:
+          path: qemu-install
+          key: qemu-riscv-install-20240225
+
+      - name: install-qemu-build-deps
+        if: steps.cache-qemu.outputs.cache-hit != 'true'
+        run: |
+          sudo apt-get update
+          sudo apt-get install autoconf automake autotools-dev ninja-build
+
+      - name: checkout-qemu
+        if: steps.cache-qemu.outputs.cache-hit != 'true'
+        uses: actions/checkout@v3
+        with:
+          repository: qemu/qemu
+          path: qemu
+
+      - name: qemu
+        if: steps.cache-qemu.outputs.cache-hit != 'true'
+        run: |
+          cd qemu
+          ./configure --prefix=$GITHUB_WORKSPACE/qemu-install --target-list=riscv64-linux-user --disable-system
+          make -j2
+          make install
+          ls -lh $GITHUB_WORKSPACE/qemu-install
+          ls -lh $GITHUB_WORKSPACE/qemu-install/bin
+
+      - name: cache-toolchain
+        id: cache-toolchain
+        uses: actions/cache@v4
+        with:
+          path: toolchain
+          key: riscv64-glibc-ubuntu-20.04-gcc-nightly-2023.10.17-nightly
+
+      - name: Download toolchain
+        if: steps.cache-toolchain.outputs.cache-hit != 'true'
+        shell: bash
+        run: |
+          mkdir $GITHUB_WORKSPACE/toolchain
+          wget -q https://github.com/riscv-collab/riscv-gnu-toolchain/releases/download/2023.10.17/riscv64-glibc-ubuntu-20.04-gcc-nightly-2023.10.17-nightly.tar.gz
+          tar xvf ./riscv64-glibc-ubuntu-20.04-gcc-nightly-2023.10.17-nightly.tar.gz --strip-components 1 -C $GITHUB_WORKSPACE/toolchain
+
+      - name: Display toolchain info
+        shell: bash
+        run: |
+          export PATH=$GITHUB_WORKSPACE/toolchain/bin:$PATH
+          riscv64-unknown-linux-gnu-gcc --version
+
+      - name: Display qemu-riscv64 -h
+        shell: bash
+        run: |
+          export PATH=$GITHUB_WORKSPACE/qemu-install/bin:$PATH
+          export QEMU_LD_PREFIX=$GITHUB_WORKSPACE/toolchain/sysroot
+          qemu-riscv64 -h
+
+      - name: build riscv64-linux
+        shell: bash
+        run: |
+          export PATH=$GITHUB_WORKSPACE/toolchain/bin:$PATH
+
+          export CMAKE_CXX_COMPILER_LAUNCHER=ccache
+          export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
+
+          cmake --version
+
+          lib_type=${{ matrix.lib_type }}
+
+          if [[ $lib_type == "shared" ]]; then
+            export BUILD_SHARED_LIBS=ON
+          else
+            export BUILD_SHARED_LIBS=OFF
+          fi
+
+          ./build-riscv64-linux-gnu.sh
+
+          ls -lh build-riscv64-linux-gnu/bin
+          ls -lh build-riscv64-linux-gnu/lib
+
+          file build-riscv64-linux-gnu/bin/sherpa-onnx
+
+      - name: Test sherpa-onnx
+        shell: bash
+        run: |
+          export PATH=$GITHUB_WORKSPACE/toolchain/bin:$PATH
+          export PATH=$GITHUB_WORKSPACE/qemu-install/bin:$PATH
+          export QEMU_LD_PREFIX=$GITHUB_WORKSPACE/toolchain/sysroot
+
+          ls -lh ./build-riscv64-linux-gnu/bin
+
+          echo "----------sherpa-onnx----------"
+          qemu-riscv64 ./build-riscv64-linux-gnu/bin/sherpa-onnx --help
+          readelf -d ./build-riscv64-linux-gnu/bin/sherpa-onnx
+
+          echo "----------sherpa-onnx-offline----------"
+          qemu-riscv64 ./build-riscv64-linux-gnu/bin/sherpa-onnx-offline --help
+          readelf -d ./build-riscv64-linux-gnu/bin/sherpa-onnx-offline
+
+          echo "----------sherpa-onnx-offline-tts----------"
+          qemu-riscv64 ./build-riscv64-linux-gnu/bin/sherpa-onnx-offline-tts --help
+          readelf -d ./build-riscv64-linux-gnu/bin/sherpa-onnx-offline-tts
+
+      - name: Copy files
+        shell: bash
+        run: |
+          export PATH=$GITHUB_WORKSPACE/toolchain/bin:$PATH
+          riscv64-unknown-linux-gnu-strip --version
+
+          SHERPA_ONNX_VERSION=v$(grep "SHERPA_ONNX_VERSION" ./CMakeLists.txt  | cut -d " " -f 2  | cut -d '"' -f 2)
+
+          dst=sherpa-onnx-${SHERPA_ONNX_VERSION}-linux-riscv64-${{ matrix.lib_type }}
+          mkdir $dst
+
+          ls -lh build-riscv64-linux-gnu/install/lib
+
+          cp -a build-riscv64-linux-gnu/install/bin $dst/
+          ls -lh $dst/bin/*
+          riscv64-unknown-linux-gnu-strip $dst/bin/*
+          ls -lh $dst
+
+          lib_type=${{ matrix.lib_type }}
+          if [[ $lib_type == "shared" ]]; then
+            cp -a build-riscv64-linux-gnu/install/lib $dst/
+            rm -fv $dst/lib/libasound.so
+            rm -fv $dst/lib/libonnxruntime.so
+            rm -fv $dst/lib/libsherpa-onnx-fst.so
+          fi
+
+          tree $dst
+
+          tar cjvf ${dst}.tar.bz2 $dst
+
+      - uses: actions/upload-artifact@v4
+        if: matrix.lib_type == 'shared'
+        with:
+          name: sherpa-onnx-linux-riscv64-shared
+          path: sherpa-onnx-*linux-riscv64-shared.tar.bz2
+
+      - uses: actions/upload-artifact@v4
+        if: matrix.lib_type == 'static'
+        with:
+          name: sherpa-onnx-linux-riscv64-static
+          path: sherpa-onnx-*linux-riscv64-static.tar.bz2
+
+      - name: Release pre-compiled binaries and libs for riscv64 linux ${{ matrix.lib_type }}
+        if: github.repository_owner == 'csukuangfj' || github.repository_owner == 'k2-fsa' && github.event_name == 'push' && contains(github.ref, 'refs/tags/')
+        uses: svenstaro/upload-release-action@v2
+        with:
+          file_glob: true
+          overwrite: true
+          file: sherpa-onnx-*linux-riscv64*.tar.bz2
diff --git a/build-riscv64-linux-gnu.sh b/build-riscv64-linux-gnu.sh
new file mode 100755
index 000000000..96d65b446
--- /dev/null
+++ b/build-riscv64-linux-gnu.sh
@@ -0,0 +1,71 @@
+#!/usr/bin/env bash
+
+if ! command -v riscv64-unknown-linux-gnu-g++  &> /dev/null; then
+  echo "Please install the toolchain first."
+  echo
+  echo "You can use the following command to install the toolchain:"
+  echo
+  echo "  mkdir -p $HOME/software"
+  echo "  cd $HOME/software"
+  echo "  mkdir riscv64-glibc-ubuntu-18.04-nightly-2022.11.12-nightly"
+  echo "  cd riscv64-glibc-ubuntu-18.04-nightly-2022.11.12-nightly"
+  echo "  wget https://github.com/riscv-collab/riscv-gnu-toolchain/releases/download/2022.11.12/riscv64-glibc-ubuntu-18.04-nightly-2022.11.12-nightly.tar.gz"
+  echo "  tar xvf riscv64-glibc-ubuntu-18.04-nightly-2022.11.12-nightly.tar.gz --strip-components=1"
+  echo "  export PATH=$HOME/software/riscv64-glibc-ubuntu-18.04-nightly-2022.11.12-nightly/bin"
+  echo
+  exit 1
+fi
+
+if [ x$dir = x"" ]; then
+  dir=build-riscv64-linux-gnu
+fi
+mkdir -p $dir
+cd $dir
+
+if [ ! -f alsa-lib/src/.libs/libasound.so ]; then
+  echo "Start to cross-compile alsa-lib"
+  if [ ! -d alsa-lib ]; then
+    git clone --depth 1 https://github.com/alsa-project/alsa-lib
+  fi
+  # If it shows:
+  #  ./gitcompile: line 79: libtoolize: command not found
+  # Please use:
+  #  sudo apt-get install libtool m4 automake
+  #
+  pushd alsa-lib
+  CC=riscv64-unknown-linux-gnu-gcc ./gitcompile --host=riscv64-unknown-linux-gnu
+  popd
+  echo "Finish cross-compiling alsa-lib"
+fi
+
+export CPLUS_INCLUDE_PATH=$PWD/alsa-lib/include:$CPLUS_INCLUDE_PATH
+export SHERPA_ONNX_ALSA_LIB_DIR=$PWD/alsa-lib/src/.libs
+
+if [[ x"$BUILD_SHARED_LIBS" == x"" ]]; then
+  # By default, use static link
+  BUILD_SHARED_LIBS=OFF
+fi
+
+cmake \
+  -DBUILD_PIPER_PHONMIZE_EXE=OFF \
+  -DBUILD_PIPER_PHONMIZE_TESTS=OFF \
+  -DBUILD_ESPEAK_NG_EXE=OFF \
+  -DBUILD_ESPEAK_NG_TESTS=OFF \
+  -DCMAKE_INSTALL_PREFIX=./install \
+  -DCMAKE_BUILD_TYPE=Release \
+  -DBUILD_SHARED_LIBS=$BUILD_SHARED_LIBS \
+  -DSHERPA_ONNX_ENABLE_TESTS=OFF \
+  -DSHERPA_ONNX_ENABLE_PYTHON=OFF \
+  -DSHERPA_ONNX_ENABLE_CHECK=OFF \
+  -DSHERPA_ONNX_ENABLE_PORTAUDIO=OFF \
+  -DSHERPA_ONNX_ENABLE_JNI=OFF \
+  -DSHERPA_ONNX_ENABLE_C_API=OFF \
+  -DSHERPA_ONNX_ENABLE_WEBSOCKET=OFF \
+  -DCMAKE_TOOLCHAIN_FILE=../toolchains/riscv64-linux-gnu.toolchain.cmake \
+  ..
+
+make VERBOSE=1 -j4
+make install/strip
+
+# Enable it if only needed
+# cp -v $SHERPA_ONNX_ALSA_LIB_DIR/libasound.so* ./install/lib/
diff --git a/cmake/onnxruntime-linux-riscv64-static.cmake b/cmake/onnxruntime-linux-riscv64-static.cmake
new file mode 100644
index 000000000..8e7c2611f
--- /dev/null
+++ b/cmake/onnxruntime-linux-riscv64-static.cmake
@@ -0,0 +1,64 @@
+# Copyright (c)  2022-2024  Xiaomi Corporation
+message(STATUS "CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}")
+message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")
+
+if(NOT CMAKE_SYSTEM_NAME STREQUAL Linux)
+  message(FATAL_ERROR "This file is for Linux only. Given: ${CMAKE_SYSTEM_NAME}")
+endif()
+
+if(NOT CMAKE_SYSTEM_PROCESSOR STREQUAL riscv64)
+  message(FATAL_ERROR "This file is for riscv64 only. Given: ${CMAKE_SYSTEM_PROCESSOR}")
+endif()
+
+if(BUILD_SHARED_LIBS)
+  message(FATAL_ERROR "This file is for building static libraries. BUILD_SHARED_LIBS: ${BUILD_SHARED_LIBS}")
+endif()
+
+set(onnxruntime_URL  "https://github.com/csukuangfj/onnxruntime-libs/releases/download/v1.18.0/onnxruntime-linux-riscv64-static_lib-1.18.0.zip")
+set(onnxruntime_URL2 "https://hub.nuaa.cf/csukuangfj/onnxruntime-libs/releases/download/v1.18.0/onnxruntime-linux-riscv64-static_lib-1.18.0.zip")
+set(onnxruntime_HASH "SHA256=6791d695d17118db6815364c975a9d7ea9a8909754516ed1b089fe015c20912e")
+
+# If you don't have access to the Internet,
+# please download onnxruntime to one of the following locations.
+# You can add more if you want.
+set(possible_file_locations
+  $ENV{HOME}/Downloads/onnxruntime-linux-riscv64-static_lib-1.18.0.zip
+  ${CMAKE_SOURCE_DIR}/onnxruntime-linux-riscv64-static_lib-1.18.0.zip
+  ${CMAKE_BINARY_DIR}/onnxruntime-linux-riscv64-static_lib-1.18.0.zip
+  /tmp/onnxruntime-linux-riscv64-static_lib-1.18.0.zip
+  /star-fj/fangjun/download/github/onnxruntime-linux-riscv64-static_lib-1.18.0.zip
+)
+
+foreach(f IN LISTS possible_file_locations)
+  if(EXISTS ${f})
+    set(onnxruntime_URL  "${f}")
+    file(TO_CMAKE_PATH "${onnxruntime_URL}" onnxruntime_URL)
+    message(STATUS "Found local downloaded onnxruntime: ${onnxruntime_URL}")
+    set(onnxruntime_URL2)
+    break()
+  endif()
+endforeach()
+
+FetchContent_Declare(onnxruntime
+  URL
+    ${onnxruntime_URL}
+    ${onnxruntime_URL2}
+  URL_HASH          ${onnxruntime_HASH}
+)
+
+FetchContent_GetProperties(onnxruntime)
+if(NOT onnxruntime_POPULATED)
+  message(STATUS "Downloading onnxruntime from ${onnxruntime_URL}")
+  FetchContent_Populate(onnxruntime)
+endif()
+message(STATUS "onnxruntime is downloaded to ${onnxruntime_SOURCE_DIR}")
+
+# for static libraries, we use onnxruntime_lib_files directly below
+include_directories(${onnxruntime_SOURCE_DIR}/include)
+
+file(GLOB onnxruntime_lib_files "${onnxruntime_SOURCE_DIR}/lib/lib*.a")
+
+set(onnxruntime_lib_files ${onnxruntime_lib_files} PARENT_SCOPE)
+
+message(STATUS "onnxruntime lib files: ${onnxruntime_lib_files}")
+install(FILES ${onnxruntime_lib_files} DESTINATION lib)
diff --git a/cmake/onnxruntime-linux-riscv64.cmake b/cmake/onnxruntime-linux-riscv64.cmake
new file mode 100644
index 000000000..748a2bb52
--- /dev/null
+++ b/cmake/onnxruntime-linux-riscv64.cmake
@@ -0,0 +1,73 @@
+# Copyright (c)  2022-2024  Xiaomi Corporation
+message(STATUS "CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}")
+message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")
+
+if(NOT CMAKE_SYSTEM_NAME STREQUAL Linux)
+  message(FATAL_ERROR "This file is for Linux only. Given: ${CMAKE_SYSTEM_NAME}")
+endif()
+
+if(NOT CMAKE_SYSTEM_PROCESSOR STREQUAL riscv64)
+  message(FATAL_ERROR "This file is for riscv64 only. Given: ${CMAKE_SYSTEM_PROCESSOR}")
+endif()
+
+if(NOT BUILD_SHARED_LIBS)
+  message(FATAL_ERROR "This file is for building shared libraries. BUILD_SHARED_LIBS: ${BUILD_SHARED_LIBS}")
+endif()
+
+set(onnxruntime_URL  "https://github.com/csukuangfj/onnxruntime-libs/releases/download/v1.18.0/onnxruntime-linux-riscv64-1.18.0.zip")
+set(onnxruntime_URL2 "https://hub.nuaa.cf/csukuangfj/onnxruntime-libs/releases/download/v1.18.0/onnxruntime-linux-riscv64-1.18.0.zip")
+set(onnxruntime_HASH "SHA256=87ef36dbba28ee332069e7e511dcb409913bdeeed231b45172fe200d71c690a2")
+
+# If you don't have access to the Internet,
+# please download onnxruntime to one of the following locations.
+# You can add more if you want.
+set(possible_file_locations
+  $ENV{HOME}/Downloads/onnxruntime-linux-riscv64-1.18.0.zip
+  ${CMAKE_SOURCE_DIR}/onnxruntime-linux-riscv64-1.18.0.zip
+  ${CMAKE_BINARY_DIR}/onnxruntime-linux-riscv64-1.18.0.zip
+  /tmp/onnxruntime-linux-riscv64-1.18.0.zip
+  /star-fj/fangjun/download/github/onnxruntime-linux-riscv64-1.18.0.zip
+)
+
+foreach(f IN LISTS possible_file_locations)
+  if(EXISTS ${f})
+    set(onnxruntime_URL  "${f}")
+    file(TO_CMAKE_PATH "${onnxruntime_URL}" onnxruntime_URL)
+    message(STATUS "Found local downloaded onnxruntime: ${onnxruntime_URL}")
+    set(onnxruntime_URL2)
+    break()
+  endif()
+endforeach()
+
+FetchContent_Declare(onnxruntime
+  URL
+    ${onnxruntime_URL}
+    ${onnxruntime_URL2}
+  URL_HASH          ${onnxruntime_HASH}
+)
+
+FetchContent_GetProperties(onnxruntime)
+if(NOT onnxruntime_POPULATED)
+  message(STATUS "Downloading onnxruntime from ${onnxruntime_URL}")
+  FetchContent_Populate(onnxruntime)
+endif()
+message(STATUS "onnxruntime is downloaded to ${onnxruntime_SOURCE_DIR}")
+
+find_library(location_onnxruntime onnxruntime
+  PATHS
+  "${onnxruntime_SOURCE_DIR}/lib"
+  NO_CMAKE_SYSTEM_PATH
+)
+
+message(STATUS "location_onnxruntime: ${location_onnxruntime}")
+
+add_library(onnxruntime SHARED IMPORTED)
+
+set_target_properties(onnxruntime PROPERTIES
+  IMPORTED_LOCATION ${location_onnxruntime}
+  INTERFACE_INCLUDE_DIRECTORIES "${onnxruntime_SOURCE_DIR}/include/onnxruntime"
+)
+
+file(GLOB onnxruntime_lib_files "${onnxruntime_SOURCE_DIR}/lib/libonnxruntime*")
+message(STATUS "onnxruntime lib files: ${onnxruntime_lib_files}")
+install(FILES ${onnxruntime_lib_files} DESTINATION lib)
diff --git a/cmake/onnxruntime.cmake b/cmake/onnxruntime.cmake
index a92ffa4eb..9dda2b148 100644
--- a/cmake/onnxruntime.cmake
+++ b/cmake/onnxruntime.cmake
@@ -6,6 +6,12 @@ function(download_onnxruntime)
   message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")
   if(SHERPA_ONNX_ENABLE_WASM)
       include(onnxruntime-wasm-simd)
+  elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL riscv64)
+    if(BUILD_SHARED_LIBS)
+      include(onnxruntime-linux-riscv64)
+    else()
+      include(onnxruntime-linux-riscv64-static)
+    endif()
   elseif(CMAKE_SYSTEM_NAME STREQUAL Linux AND CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
     if(BUILD_SHARED_LIBS)
       include(onnxruntime-linux-aarch64)
diff --git a/cmake/piper-phonemize.cmake b/cmake/piper-phonemize.cmake
index 9c0ffa4cc..4facf7e17 100644
--- a/cmake/piper-phonemize.cmake
+++ b/cmake/piper-phonemize.cmake
@@ -2,7 +2,7 @@ function(download_piper_phonemize)
   include(FetchContent)
 
   set(piper_phonemize_URL  "https://github.com/csukuangfj/piper-phonemize/archive/dc6b5f4441bffe521047086930b0fc12686acd56.zip")
-  set(piper_phonemize_URL2 "")
+  set(piper_phonemize_URL2 "https://hub.nuaa.cf/csukuangfj/piper-phonemize/archive/dc6b5f4441bffe521047086930b0fc12686acd56.zip")
   set(piper_phonemize_HASH "SHA256=b9faa04204b1756fa455a962abb1f037041c040133d55be58d11f11ab9b3ce14")
 
   # If you don't have access to the Internet,
diff --git a/toolchains/riscv64-linux-gnu.toolchain.cmake b/toolchains/riscv64-linux-gnu.toolchain.cmake
new file mode 100644
index 000000000..8f07b964c
--- /dev/null
+++ b/toolchains/riscv64-linux-gnu.toolchain.cmake
@@ -0,0 +1,17 @@
+# Copied from https://github.com/Tencent/ncnn/blob/master/toolchains/riscv64-linux-gnu.toolchain.cmake
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR riscv64)
+
+set(CMAKE_C_COMPILER "riscv64-unknown-linux-gnu-gcc")
+set(CMAKE_CXX_COMPILER "riscv64-unknown-linux-gnu-g++")
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+set(CMAKE_C_FLAGS "-march=rv64gc")
+set(CMAKE_CXX_FLAGS "-march=rv64gc")
+
+# cache flags
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}" CACHE STRING "c flags")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" CACHE STRING "c++ flags")