feat(startup): pre-warm default Whisper model at launch in background thread
This commit is contained in:
@@ -72,7 +72,7 @@ fn model_capability(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_model_from_disk(model_id: &ModelId) -> Result<Box<dyn kon_transcription::SpeechModel + Send>, String> {
|
pub fn load_model_from_disk(model_id: &ModelId) -> Result<Box<dyn kon_transcription::SpeechModel + Send>, String> {
|
||||||
let entry = model_registry::find_model(model_id)
|
let entry = model_registry::find_model(model_id)
|
||||||
.ok_or_else(|| format!("Unknown model: {model_id}"))?;
|
.ok_or_else(|| format!("Unknown model: {model_id}"))?;
|
||||||
|
|
||||||
@@ -155,6 +155,42 @@ pub async fn ensure_model_loaded(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Spawns a background task that loads the default Whisper model into memory
|
||||||
|
/// if it is already downloaded. Returns immediately — errors are logged, never panicked.
|
||||||
|
///
|
||||||
|
/// Call this once from app setup() after AppState is managed.
|
||||||
|
pub fn prewarm_default_model(whisper_engine: Arc<LocalEngine>) {
|
||||||
|
let model_id = default_model_id_for_engine("whisper");
|
||||||
|
|
||||||
|
if !model_manager::is_downloaded(&model_id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if whisper_engine
|
||||||
|
.loaded_model_id()
|
||||||
|
.as_ref()
|
||||||
|
.map(|id| id == &model_id)
|
||||||
|
.unwrap_or(false)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tokio::spawn(async move {
|
||||||
|
let result = tokio::task::spawn_blocking(move || {
|
||||||
|
load_model_from_disk(&model_id).map(|model| {
|
||||||
|
whisper_engine.load(model, model_id);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(Ok(())) => eprintln!("[startup] Whisper model pre-warmed successfully"),
|
||||||
|
Ok(Err(e)) => eprintln!("[startup] Whisper pre-warm failed: {e}"),
|
||||||
|
Err(e) => eprintln!("[startup] Whisper pre-warm task panicked: {e}"),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct RuntimeCapabilities {
|
pub struct RuntimeCapabilities {
|
||||||
|
|||||||
@@ -215,6 +215,11 @@ pub fn run() {
|
|||||||
db,
|
db,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
{
|
||||||
|
let whisper = app.state::<AppState>().whisper_engine.clone();
|
||||||
|
crate::commands::models::prewarm_default_model(whisper);
|
||||||
|
}
|
||||||
|
|
||||||
if let Err(e) = tray::setup(app) {
|
if let Err(e) = tray::setup(app) {
|
||||||
eprintln!("Failed to setup tray: {e}");
|
eprintln!("Failed to setup tray: {e}");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user