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
30 changes: 30 additions & 0 deletions BENCHMARK_RESULTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,36 @@ Comprehensive benchmark results for eddy ASR on LibriSpeech test-clean and FLEUR

---

## Nemotron Streaming Multilingual 0.6B (FLEURS)

**Model**: `nemotron-streaming-int8` (weight-only INT8 encoder, FP16 decoder/joint)
**Device**: Intel NPU · **Software**: OpenVINO 2025.0 · **Decoding**: greedy, forced language
**Preprocessor**: native C++ log-mel featurizer (replaces the dynamic-shape OV preprocessor)
**Scoring**: FluidAudio methodology — WER for spaced languages, character-level CER for CJK
(`ja`/`zh`), Whisper-style punctuation/symbol stripping

| Language | Metric | eddy NPU (int8) | OpenVINO FP32 ref | FluidAudio CoreML ref | RTFx | Samples |
|----------|--------|----------------:|------------------:|----------------------:|-----:|--------:|
| English (US) | WER | 12.48 | 11.78 | 12.09 | 22.3× | 350 |
| Spanish (LatAm) | WER | 7.03 | 6.99 | 9.01 | 22.5× | 350 |
| French (France) | WER | 13.35 | 12.92 | 15.18 | 21.7× | 350 |
| Chinese (Mandarin) | CER | 20.18 | 21.05 | 24.54 | 23.7× | 945 |
| Japanese | CER | 15.46 | 15.12 | 16.86 | 23.3× | 650 |

**Audio-weighted RTFx**: ~22–24× on Intel NPU (≈2× the CPU figure of ~11×).

**Notes**:
- INT8-on-NPU accuracy matches the OpenVINO FP32 reference within noise and beats the
FluidAudio CoreML reference on es/fr/zh/ja.
- **NPU enablement**: the OpenVINO NPU plugin miscompiles `BitwiseNot` on a boolean
(integer complement → mask all-true → encoder collapses to ~0 → empty transcripts).
eddy rewrites `BitwiseNot → LogicalNot` in the encoder IR before compiling (no-op on
CPU/GPU); without it the NPU produces empty output for this model.
- Unlike Parakeet (overlapping-chunk + 2D dedup), Nemotron is cache-aware streaming RNNT
with per-chunk `prompt_id` language conditioning.

---

## Performance Notes

### Best Performing Languages (WER < 10%)
Expand Down
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ target_sources(eddy
src/models/parakeet-v2/parakeet_decoder.cpp
src/models/parakeet-v2/parakeet_chunking.cpp
src/models/parakeet-v2/tokenizer.cpp

# Nemotron cache-aware streaming implementation
src/models/nemotron/nemotron_openvino.cpp
src/models/nemotron/nemotron_featurizer.cpp
)

# Link dependencies
Expand Down
9 changes: 7 additions & 2 deletions claude.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,17 @@ Match FluidAudio's Parakeet v2 (Swift/CoreML) implementation in C++/OpenVINO:

## Architecture

**Batch Chunking** (current focus):
Two first-class ASR paths are supported:

**Batch (Parakeet)** — `eddy::parakeet`, stateless overlapping-chunk encoder:
- 10s chunks with 3s overlap
- 2D search deduplication at boundaries
- LSTM state continuity across chunks

**NOT building streaming yet** - focus is on batch processing of complete audio files.
**Streaming (Nemotron)** — `eddy::nemotron`, cache-aware streaming FastConformer-RNNT:
- Carries `cache_channel`/`cache_time`/`cache_len` across chunks (`att_context=[56,0]`)
- Integer `prompt_id` per-chunk language conditioning (40+ languages)
- Plain RNNT greedy decode (no TDT duration bins)

## Testing

Expand Down
8 changes: 7 additions & 1 deletion examples/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,16 @@ endif()
add_executable(parakeet_cli parakeet_cli.cpp)
target_link_libraries(parakeet_cli PRIVATE eddy)

add_executable(nemotron_cli nemotron_cli.cpp)
target_link_libraries(nemotron_cli PRIVATE eddy)

add_executable(hf_fetch_models hf_fetch_models.cpp)
target_link_libraries(hf_fetch_models PRIVATE eddy)

add_executable(benchmark_fleurs benchmark_fleurs.cpp)
target_link_libraries(benchmark_fleurs PRIVATE eddy)

install(TARGETS parakeet_cli hf_fetch_models benchmark_fleurs DESTINATION bin)
add_executable(benchmark_nemotron_fleurs benchmark_nemotron_fleurs.cpp)
target_link_libraries(benchmark_nemotron_fleurs PRIVATE eddy)

install(TARGETS parakeet_cli nemotron_cli hf_fetch_models benchmark_fleurs benchmark_nemotron_fleurs DESTINATION bin)
2 changes: 1 addition & 1 deletion examples/cpp/benchmark_fleurs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ int main(int argc, char* argv[]) {
// Load Parakeet v3 models
auto cache_model_dir = eddy::get_model_assets_dir("parakeet-v3");
std::string fetch_err;
if (!eddy::parakeet::check_models_available(cache_model_dir, &fetch_err)) {
if (!eddy::model_utils::check_models_available(cache_model_dir, &fetch_err)) {
if (!fetch_err.empty()) std::cout << "[INFO] " << fetch_err << "\n";
}

Expand Down
Loading
Loading