(
ctx: Context,
model_path: &std::path::Path,
config_path: &std::path::Path,
)
| 438 | #[cfg(feature = "master")] |
| 439 | #[cfg(feature = "vibevoice")] |
| 440 | async fn run_vibevoice_1_5b( |
| 441 | ctx: Context, |
| 442 | model_path: &std::path::Path, |
| 443 | config_path: &std::path::Path, |
| 444 | ) -> Result<()> { |
| 445 | use cake_core::models::vibevoice; |
| 446 | use cake_core::models::vibevoice::config_1_5b::*; |
| 447 | |
| 448 | println!("[VibeVoice-1.5B] Loading from {}", model_path.display()); |
| 449 | |
| 450 | // Collect weight shard paths |
| 451 | let mut weight_paths: Vec<std::path::PathBuf> = Vec::new(); |
| 452 | for entry in std::fs::read_dir(model_path)? { |
| 453 | let entry = entry?; |
| 454 | let name = entry.file_name().to_string_lossy().to_string(); |
| 455 | if name.ends_with(".safetensors") && name.starts_with("model") { |
| 456 | weight_paths.push(entry.path()); |
| 457 | } |
| 458 | } |
| 459 | weight_paths.sort(); |
| 460 | println!( |
| 461 | "[VibeVoice-1.5B] Found {} weight shards", |
| 462 | weight_paths.len() |
| 463 | ); |
| 464 | |
| 465 | let mut model = vibevoice::VibeVoice1_5B::load( |
| 466 | config_path, |
| 467 | &weight_paths, |
| 468 | &ctx.device, |
| 469 | Some(ctx.args.tts_diffusion_steps), |
| 470 | &ctx.topology, |
| 471 | ctx.args.cluster_key.as_deref(), |
| 472 | ) |
| 473 | .await?; |
| 474 | |
| 475 | let prompt = &ctx.args.prompt; |
| 476 | println!("[VibeVoice-1.5B] Generating speech for: \"{}\"", prompt); |
| 477 | |
| 478 | // Load tokenizer (Qwen2.5-1.5B) |
| 479 | let tokenizer = { |
| 480 | let local = model_path.join("tokenizer.json"); |
| 481 | if local.exists() { |
| 482 | tokenizers::Tokenizer::from_file(&local) |
| 483 | .map_err(|e| anyhow::anyhow!("tokenizer: {e}"))? |
| 484 | } else { |
| 485 | println!("[VibeVoice-1.5B] Downloading Qwen2.5-1.5B tokenizer..."); |
| 486 | let qwen_path = utils::hf::ensure_model_downloaded("Qwen/Qwen2.5-1.5B")?; |
| 487 | tokenizers::Tokenizer::from_file(qwen_path.join("tokenizer.json")) |
| 488 | .map_err(|e| anyhow::anyhow!("tokenizer: {e}"))? |
| 489 | } |
| 490 | }; |
| 491 | |
| 492 | // Load voice reference audio |
| 493 | let voice_path = ctx |
| 494 | .args |
| 495 | .voice_prompt |
| 496 | .as_ref() |
| 497 | .ok_or_else(|| anyhow::anyhow!("--voice-prompt required (path to .wav voice reference)"))?; |
no test coverage detected