feat: add GigaAM v3 for Russian speech recognition (#913)

* feat: add GigaAM v3 model for Russian speech recognition

Add GigaAM v3 e2e_ctc as a new transcription engine using
transcribe-rs 0.2.7 gigaam feature. Russian speech recognition
with punctuation, Latin characters and digit support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: cargo fmt formatting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Keep the file name of the model download the same as the file on the
blob website.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: CJ Pais <cj@cjpais.com>
This commit is contained in:
pantafive 2026-03-01 14:53:48 +01:00 committed by GitHub
parent 17d34a910f
commit ff8612297b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 154 additions and 13 deletions

45
src-tauri/Cargo.lock generated
View file

@ -14,6 +14,16 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
[[package]]
name = "advapi32-sys"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e06588080cb19d0acb6739808aafa5f26bfb2ca015b2b6370028b44cf7cb8a9a"
dependencies = [
"winapi 0.2.8",
"winapi-build",
]
[[package]]
name = "ahash"
version = "0.7.8"
@ -1392,7 +1402,7 @@ checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
dependencies = [
"libc",
"redox_users 0.4.6",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -1454,7 +1464,7 @@ dependencies = [
"dlopen2_derive",
"libc",
"once_cell",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -2249,7 +2259,7 @@ dependencies = [
"gobject-sys",
"libc",
"system-deps 6.2.2",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -3189,7 +3199,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
dependencies = [
"cfg-if",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -4853,7 +4863,7 @@ dependencies = [
"strum",
"strum_macros",
"widestring",
"winapi",
"winapi 0.3.9",
"x11",
]
@ -4872,7 +4882,7 @@ dependencies = [
"inotify 0.8.3",
"lazy_static",
"libc",
"winapi",
"winapi 0.3.9",
"x11",
]
@ -5757,7 +5767,7 @@ checksum = "f0c3dbbd9ae980613c6dd8e28a9407b50509d3803b57624d5dfe8315218cd58b"
dependencies = [
"byteorder",
"libc",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -7143,10 +7153,11 @@ dependencies = [
[[package]]
name = "transcribe-rs"
version = "0.2.5"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23e3bf6e1dd4909268796bdf3794fb6fda70f4a0e5a80e2e56cd3fc213a11586"
checksum = "25ad0a55f1482ec523073073a3a08a457c57dd956d09d62cdfe05a27a5591334"
dependencies = [
"advapi32-sys",
"base64 0.22.1",
"derive_builder",
"env_logger",
@ -7232,7 +7243,7 @@ checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9"
dependencies = [
"memoffset",
"tempfile",
"winapi",
"winapi 0.3.9",
]
[[package]]
@ -7882,6 +7893,12 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471"
[[package]]
name = "winapi"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
[[package]]
name = "winapi"
version = "0.3.9"
@ -7892,6 +7909,12 @@ dependencies = [
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-build"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
@ -8497,7 +8520,7 @@ version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
dependencies = [
"winapi",
"winapi 0.3.9",
]
[[package]]

View file

@ -68,7 +68,7 @@ chrono = "0.4"
rusqlite = { version = "0.37", features = ["bundled"] }
tar = "0.4.44"
flate2 = "1.0"
transcribe-rs = { version = "0.2.5", features = ["whisper", "parakeet", "moonshine", "sense_voice"] }
transcribe-rs = { version = "0.2.7", features = ["whisper", "parakeet", "moonshine", "sense_voice", "gigaam"] }
handy-keys = "0.2.1"
ferrous-opencc = "0.2.3"
clap = { version = "4", features = ["derive"] }

View file

@ -23,6 +23,7 @@ pub enum EngineType {
Moonshine,
MoonshineStreaming,
SenseVoice,
GigaAM,
}
#[derive(Debug, Clone, Serialize, Deserialize, Type)]
@ -397,6 +398,32 @@ impl ModelManager {
},
);
// GigaAM v3 supported languages
let gigaam_languages: Vec<String> = vec!["ru"].into_iter().map(String::from).collect();
available_models.insert(
"gigaam-v3-e2e-ctc".to_string(),
ModelInfo {
id: "gigaam-v3-e2e-ctc".to_string(),
name: "GigaAM v3".to_string(),
description: "Russian speech recognition. Fast and accurate.".to_string(),
filename: "giga-am-v3.int8.onnx".to_string(),
url: Some("https://blob.handy.computer/giga-am-v3.int8.onnx".to_string()),
size_mb: 225,
is_downloaded: false,
is_downloading: false,
partial_size: 0,
is_directory: false,
engine_type: EngineType::GigaAM,
accuracy_score: 0.85,
speed_score: 0.75,
supports_translation: false,
is_recommended: false,
supported_languages: gigaam_languages,
is_custom: false,
},
);
// Auto-discover custom Whisper models (.bin files) in the models directory
if let Err(e) = Self::discover_custom_whisper_models(&models_dir, &mut available_models) {
warn!("Failed to discover custom models: {}", e);

View file

@ -12,6 +12,7 @@ use std::time::{Duration, SystemTime};
use tauri::{AppHandle, Emitter};
use transcribe_rs::{
engines::{
gigaam::GigaAMEngine,
moonshine::{
ModelVariant, MoonshineEngine, MoonshineModelParams, MoonshineStreamingEngine,
StreamingModelParams,
@ -42,6 +43,7 @@ enum LoadedEngine {
Moonshine(MoonshineEngine),
MoonshineStreaming(MoonshineStreamingEngine),
SenseVoice(SenseVoiceEngine),
GigaAM(GigaAMEngine),
}
#[derive(Clone)]
@ -165,6 +167,7 @@ impl TranscriptionManager {
LoadedEngine::Moonshine(ref mut e) => e.unload_model(),
LoadedEngine::MoonshineStreaming(ref mut e) => e.unload_model(),
LoadedEngine::SenseVoice(ref mut e) => e.unload_model(),
LoadedEngine::GigaAM(ref mut e) => e.unload_model(),
}
}
*engine = None; // Drop the engine to free memory
@ -346,6 +349,23 @@ impl TranscriptionManager {
})?;
LoadedEngine::SenseVoice(engine)
}
EngineType::GigaAM => {
let mut engine = GigaAMEngine::new();
engine.load_model(&model_path).map_err(|e| {
let error_msg = format!("Failed to load gigaam model {}: {}", model_id, e);
let _ = self.app_handle.emit(
"model-state-changed",
ModelStateEvent {
event_type: "loading_failed".to_string(),
model_id: Some(model_id.to_string()),
model_name: Some(model_info.name.clone()),
error: Some(error_msg.clone()),
},
);
anyhow::anyhow!(error_msg)
})?;
LoadedEngine::GigaAM(engine)
}
};
// Update the current engine and model ID
@ -526,6 +546,9 @@ impl TranscriptionManager {
anyhow::anyhow!("SenseVoice transcription failed: {}", e)
})
}
LoadedEngine::GigaAM(gigaam_engine) => gigaam_engine
.transcribe_samples(audio, None)
.map_err(|e| anyhow::anyhow!("GigaAM transcription failed: {}", e)),
}
},
));

View file

@ -744,7 +744,7 @@ export type AutoSubmitKey = "enter" | "ctrl_enter" | "cmd_enter"
export type BindingResponse = { success: boolean; binding: ShortcutBinding | null; error: string | null }
export type ClipboardHandling = "dont_modify" | "copy_to_clipboard"
export type CustomSounds = { start: boolean; stop: boolean }
export type EngineType = "Whisper" | "Parakeet" | "Moonshine" | "MoonshineStreaming" | "SenseVoice"
export type EngineType = "Whisper" | "Parakeet" | "Moonshine" | "MoonshineStreaming" | "SenseVoice" | "GigaAM"
export type HistoryEntry = { id: number; file_name: string; timestamp: number; saved: boolean; title: string; transcription_text: string; post_processed_text: string | null; post_process_prompt: string | null }
/**
* Result of changing keyboard implementation

View file

@ -75,6 +75,10 @@
"sense-voice-int8": {
"name": "SenseVoice",
"description": "سريع جداً. الصينية، الإنجليزية، اليابانية، الكورية، الكانتونية."
},
"gigaam-v3-e2e-ctc": {
"name": "GigaAM v3",
"description": "التعرف على الكلام الروسي. سريع ودقيق."
}
},
"errors": {

View file

@ -75,6 +75,10 @@
"sense-voice-int8": {
"name": "SenseVoice",
"description": "Velmi rychlý. Čínština, angličtina, japonština, korejština, kantonština."
},
"gigaam-v3-e2e-ctc": {
"name": "GigaAM v3",
"description": "Rozpoznávání ruské řeči. Rychlé a přesné."
}
},
"errors": {

View file

@ -75,6 +75,10 @@
"sense-voice-int8": {
"name": "SenseVoice",
"description": "Sehr schnell. Chinesisch, Englisch, Japanisch, Koreanisch, Kantonesisch."
},
"gigaam-v3-e2e-ctc": {
"name": "GigaAM v3",
"description": "Russische Spracherkennung. Schnell und präzise."
}
},
"errors": {

View file

@ -75,6 +75,10 @@
"sense-voice-int8": {
"name": "SenseVoice",
"description": "Very fast. Chinese, English, Japanese, Korean, Cantonese."
},
"gigaam-v3-e2e-ctc": {
"name": "GigaAM v3",
"description": "Russian speech recognition. Fast and accurate."
}
},
"errors": {

View file

@ -75,6 +75,10 @@
"sense-voice-int8": {
"name": "SenseVoice",
"description": "Muy rápido. Chino, inglés, japonés, coreano, cantonés."
},
"gigaam-v3-e2e-ctc": {
"name": "GigaAM v3",
"description": "Reconocimiento de voz en ruso. Rápido y preciso."
}
},
"errors": {

View file

@ -75,6 +75,10 @@
"sense-voice-int8": {
"name": "SenseVoice",
"description": "Très rapide. Chinois, anglais, japonais, coréen, cantonais."
},
"gigaam-v3-e2e-ctc": {
"name": "GigaAM v3",
"description": "Reconnaissance vocale en russe. Rapide et précis."
}
},
"errors": {

View file

@ -75,6 +75,10 @@
"sense-voice-int8": {
"name": "SenseVoice",
"description": "Molto veloce. Cinese, inglese, giapponese, coreano, cantonese."
},
"gigaam-v3-e2e-ctc": {
"name": "GigaAM v3",
"description": "Riconoscimento vocale in russo. Veloce e preciso."
}
},
"errors": {

View file

@ -75,6 +75,10 @@
"sense-voice-int8": {
"name": "SenseVoice",
"description": "非常に高速。中国語、英語、日本語、韓国語、広東語。"
},
"gigaam-v3-e2e-ctc": {
"name": "GigaAM v3",
"description": "ロシア語音声認識。高速かつ高精度。"
}
},
"errors": {

View file

@ -75,6 +75,10 @@
"sense-voice-int8": {
"name": "SenseVoice",
"description": "매우 빠름. 중국어, 영어, 일본어, 한국어, 광둥어."
},
"gigaam-v3-e2e-ctc": {
"name": "GigaAM v3",
"description": "러시아어 음성 인식. 빠르고 정확함."
}
},
"errors": {

View file

@ -75,6 +75,10 @@
"sense-voice-int8": {
"name": "SenseVoice",
"description": "Bardzo szybki. Chiński, angielski, japoński, koreański, kantoński."
},
"gigaam-v3-e2e-ctc": {
"name": "GigaAM v3",
"description": "Rozpoznawanie mowy rosyjskiej. Szybkie i dokładne."
}
},
"errors": {

View file

@ -75,6 +75,10 @@
"sense-voice-int8": {
"name": "SenseVoice",
"description": "Muito rápido. Chinês, inglês, japonês, coreano, cantonês."
},
"gigaam-v3-e2e-ctc": {
"name": "GigaAM v3",
"description": "Reconhecimento de voz em russo. Rápido e preciso."
}
},
"errors": {

View file

@ -75,6 +75,10 @@
"sense-voice-int8": {
"name": "SenseVoice",
"description": "Очень быстрый. Китайский, английский, японский, корейский, кантонский."
},
"gigaam-v3-e2e-ctc": {
"name": "GigaAM v3",
"description": "Распознавание русской речи. Быстро и точно."
}
},
"errors": {

View file

@ -75,6 +75,10 @@
"sense-voice-int8": {
"name": "SenseVoice",
"description": "Çok hızlı. Çince, İngilizce, Japonca, Korece, Kantonca."
},
"gigaam-v3-e2e-ctc": {
"name": "GigaAM v3",
"description": "Rusça konuşma tanıma. Hızlı ve doğru."
}
},
"errors": {

View file

@ -75,6 +75,10 @@
"sense-voice-int8": {
"name": "SenseVoice",
"description": "Дуже швидкий. Китайська, англійська, японська, корейська, кантонська."
},
"gigaam-v3-e2e-ctc": {
"name": "GigaAM v3",
"description": "Розпізнавання російського мовлення. Швидко і точно."
}
},
"errors": {

View file

@ -75,6 +75,10 @@
"sense-voice-int8": {
"name": "SenseVoice",
"description": "Rất nhanh. Tiếng Trung, tiếng Anh, tiếng Nhật, tiếng Hàn, tiếng Quảng Đông."
},
"gigaam-v3-e2e-ctc": {
"name": "GigaAM v3",
"description": "Nhận dạng giọng nói tiếng Nga. Nhanh và chính xác."
}
},
"errors": {

View file

@ -75,6 +75,10 @@
"sense-voice-int8": {
"name": "SenseVoice",
"description": "速度極快。支援中文、英語、日語、韓語、粵語。"
},
"gigaam-v3-e2e-ctc": {
"name": "GigaAM v3",
"description": "俄語語音辨識。快速且準確。"
}
},
"errors": {

View file

@ -75,6 +75,10 @@
"sense-voice-int8": {
"name": "SenseVoice",
"description": "非常快速。支持中文、英语、日语、韩语、粤语。"
},
"gigaam-v3-e2e-ctc": {
"name": "GigaAM v3",
"description": "俄语语音识别。快速且准确。"
}
},
"errors": {