Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/scripts/test-rust.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash

set -ex

cd rust-api-examples

./run-version.sh

./run-streaming-zipformer.sh
9 changes: 2 additions & 7 deletions .github/workflows/test-rust-package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,7 @@ jobs:

echo "RUSTFLAGS: $RUSTFLAGS"

# Test using published crates.io dependencies
- name: Test Published Crates
- name: Run test
shell: bash
run: |
cd rust-api-examples
git checkout Cargo.toml
cargo clean
# cargo test --locked --all-features
cargo run --example version
./.github/scripts/test-rust.sh
Comment on lines +73 to +76

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Avoid relying on executable bit for the script.

Using ./ will fail if the file isn’t marked executable. Consider invoking via bash to make the workflow robust.

✅ Suggested tweak
-          ./.github/scripts/test-rust.sh
+          bash ./.github/scripts/test-rust.sh
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/test-rust-package.yaml around lines 73 - 76, The workflow
step "Run test" currently invokes the script using a relative executable path
("./.github/scripts/test-rust.sh") which fails if the file lacks the executable
bit; change the step to invoke the script with an explicit shell interpreter
(e.g., use "bash .github/scripts/test-rust.sh" or "sh
.github/scripts/test-rust.sh") so the Run test step runs reliably without
relying on the executable permission.

6 changes: 5 additions & 1 deletion .github/workflows/test-rust.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,12 @@ jobs:

sed -i.bak 's|^sherpa-onnx *=.*|sherpa-onnx = { path = "../sherpa-onnx/rust/sherpa-onnx" }|' Cargo.toml


git diff .

cargo clean
cargo run --example version

- name: Run test
shell: bash
run: |
./.github/scripts/test-rust.sh
1 change: 1 addition & 0 deletions c-api-examples/streaming-zipformer-c-api.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ int32_t main() {
memset(&recognizer_config, 0, sizeof(recognizer_config));
recognizer_config.decoding_method = "greedy_search";
recognizer_config.model_config = online_model_config;
recognizer_config.enable_endpoint = 1;

const SherpaOnnxOnlineRecognizer *recognizer =
SherpaOnnxCreateOnlineRecognizer(&recognizer_config);
Expand Down
108 changes: 103 additions & 5 deletions rust-api-examples/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions rust-api-examples/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[package]
name = "rust-api-examples"
version = "0.1.0"
version = "0.1.1"
edition = "2021"


[dependencies]
sherpa-onnx = "0.1.0"
sherpa-onnx = "0.1.1"
# sherpa-onnx = { path = "../sherpa-onnx/rust/sherpa-onnx" }
13 changes: 13 additions & 0 deletions rust-api-examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ export RUSTFLAGS="-C link-arg=-Wl,-rpath,$SHERPA_ONNX_LIB_DIR"

## Run it

### Example 1: Show sherpa-onnx version

```bash
cargo run --example version
```
Expand All @@ -41,6 +43,17 @@ otool -l target/debug/examples/version | grep -A2 LC_RPATH
```
to check the RPATH.

### Example 2: ASR with streaming zipformer

```bash
wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-en-2023-06-21.tar.bz2

tar xvf sherpa-onnx-streaming-zipformer-en-2023-06-21.tar.bz2
rm sherpa-onnx-streaming-zipformer-en-2023-06-21.tar.bz2

cargo run --example streaming_zipformer
```

# Alternative rust bindings for sherpa-onnx

Please see also https://github.com/thewh1teagle/sherpa-rs
93 changes: 93 additions & 0 deletions rust-api-examples/examples/streaming_zipformer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// Copyright (c) 2026 Xiaomi Corporation
//
// This file demonstrates how to use streaming Zipformer with sherpa-onnx's
// Rust API for speech recognition.
//
// See ../README.md for how to run it
//
// Note that even if we use a wave file as an example, this model supports
// real-time streaming speech recognition. You can read audio samples
// from a microphone.

use sherpa_onnx::{OnlineRecognizer, OnlineRecognizerConfig, Wave};

fn main() {
let wav_path = "sherpa-onnx-streaming-zipformer-en-2023-06-21/test_wavs/1.wav";
let encoder_path =
"sherpa-onnx-streaming-zipformer-en-2023-06-21/encoder-epoch-99-avg-1.int8.onnx";
let decoder_path = "sherpa-onnx-streaming-zipformer-en-2023-06-21/decoder-epoch-99-avg-1.onnx";
let joiner_path =
"sherpa-onnx-streaming-zipformer-en-2023-06-21/joiner-epoch-99-avg-1.int8.onnx";
let tokens_path = "sherpa-onnx-streaming-zipformer-en-2023-06-21/tokens.txt";
let provider = "cpu";

let wave = Wave::read(wav_path).expect("Failed to read WAV file");

let mut recognizer_config = OnlineRecognizerConfig::default();
recognizer_config.model_config.transducer.encoder = Some(encoder_path.to_string());
recognizer_config.model_config.transducer.decoder = Some(decoder_path.to_string());
recognizer_config.model_config.transducer.joiner = Some(joiner_path.to_string());
recognizer_config.model_config.tokens = Some(tokens_path.to_string());
recognizer_config.model_config.provider = Some(provider.to_string());
recognizer_config.enable_endpoint = true;

// set to true to see verbose logs
recognizer_config.model_config.debug = true;

recognizer_config.decoding_method = Some("greedy_search".to_string());

let recognizer =
OnlineRecognizer::create(&recognizer_config).expect("Failed to create OnlineRecognizer");

let stream = recognizer.create_stream();

let mut segment_id = 0;

// use any positive value as you like
const CHUNK_SIZE: usize = 3200;

println!(
"Sample rate: {}, num samples: {}, duration: {:.2}s",
wave.sample_rate(),
wave.num_samples(),
wave.num_samples() as f32 / wave.sample_rate() as f32
);

for chunk in wave.samples().chunks(CHUNK_SIZE) {
stream.accept_waveform(wave.sample_rate(), chunk);

while recognizer.is_ready(&stream) {
recognizer.decode(&stream);

if let Some(result) = recognizer.get_result(&stream) {
if !result.text.is_empty() {
println!("Segment {}: {}", segment_id, result.text);
}
}

if recognizer.is_endpoint(&stream) {
recognizer.reset(&stream);
segment_id += 1;
}
}
}

// Tail padding (~0.3s)
let tail_padding_len = (wave.sample_rate() as f32 * 0.3).round() as usize;
let tail_padding = vec![0.0f32; tail_padding_len];

stream.accept_waveform(wave.sample_rate(), &tail_padding);

stream.input_finished();

while recognizer.is_ready(&stream) {
recognizer.decode(&stream);
if let Some(result) = recognizer.get_result(&stream) {
if !result.text.is_empty() {
println!("Segment {}: {}", segment_id, result.text);
}
}
}

println!("Transcription finished.");
}
12 changes: 12 additions & 0 deletions rust-api-examples/run-streaming-zipformer.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -ex

if [ ! -f ./sherpa-onnx-streaming-zipformer-en-2023-06-21/encoder-epoch-99-avg-1.int8.onnx ]; then
curl -SsL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-en-2023-06-21.tar.bz2

tar xvf sherpa-onnx-streaming-zipformer-en-2023-06-21.tar.bz2
rm sherpa-onnx-streaming-zipformer-en-2023-06-21.tar.bz2
ls -lh sherpa-onnx-streaming-zipformer-en-2023-06-21
fi

cargo run --example streaming_zipformer
3 changes: 3 additions & 0 deletions rust-api-examples/run-version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash
set -ex
cargo run --example version
2 changes: 1 addition & 1 deletion sherpa-onnx/rust/sherpa-onnx-sys/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sherpa-onnx-sys"
version = "0.1.0"
version = "0.1.1"
edition = "2021"
description = "Raw FFI bindings to the sherpa-onnx C API"
license = "Apache-2.0"
Expand Down
6 changes: 6 additions & 0 deletions sherpa-onnx/rust/sherpa-onnx-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,9 @@ extern "C" {
pub fn SherpaOnnxGetGitDate() -> *const c_char;
pub fn SherpaOnnxFileExists(filename: *const c_char) -> c_int;
}

pub mod online_asr;
pub mod wave;

pub use online_asr::*;
pub use wave::*;
Loading