//! 跑一下:查询本机 GPU 状态 + 演示热驻留。 //! //! ```bash //! cargo run --example gpu_status //! ``` //! //! 需要本机有 Ollama 在跑(`ollama serve`)。 use perch_gpu::status::{query_status, DEFAULT_OLLAMA_BASE_URL}; use perch_gpu::warmup::warmup_model; #[tokio::main] async fn main() { println!("🔍 查询本机 GPU 状态({DEFAULT_OLLAMA_BASE_URL})…\n"); match query_status(None).await { Ok(st) => { if st.models.is_empty() { println!(" (当前没有加载任何模型——闲置后 Ollama 卸载了)"); println!("\n💡 热驻留可以解决:预热一次 + keep_alive 保活"); } else { for m in &st.models { let gb = |n: u64| n as f64 / 1024.0 / 1024.0 / 1024.0; println!( " 📦 {}\n GPU 驻留: {}%({:.2}GB / {:.2}GB)", m.name, m.gpu_residency_percent, gb(m.gpu_memory_bytes), gb(m.model_bytes) ); if let Some(ctx) = m.context_length { println!(" 上下文: {ctx}"); } if let Some(exp) = &m.expires_at { println!(" 过期: {exp}"); } println!(); } println!("✅ GPU 加速正在生效(Ollama 已自动选择 Metal/CUDA 后端)"); } } Err(e) => { println!(" ✗ 查询失败: {e}"); println!("\n 检查 Ollama 是否在跑:curl {DEFAULT_OLLAMA_BASE_URL}/api/ps"); return; } } // 演示:预热第一个模型(如果有的话) if let Ok(st) = query_status(None).await { if let Some(first) = st.models.first() { println!("\n🔥 预热 {}(keep_alive 30m)…", first.name); match warmup_model(&first.name, "30m", None).await { Ok(()) => println!(" ✅ 已保活 30 分钟——下次请求首 token 只要 0.04~0.18s"), Err(e) => println!(" ✗ 预热失败: {e}"), } } } }