Files
rustytorch/examples/model_hub_demo.rs
T
2026-03-04 00:08:42 +00:00

248 lines
7.8 KiB
Rust

//! Model Hub Demo - One-Command Model Loading
//!
//! This example demonstrates how to load models from various sources:
//! - HuggingFace Hub
//! - RustyTorch Hub
//! - Local directories
//!
//! Run with: cargo run --example model_hub_demo
use rtx_hub::{
load, load_with_config, LoadConfig, LoadedModel,
RTXArchitecture, RTXDType, HubResult,
list_cached_models, cache_size, clear_cache,
SafeTensors, ShardedSafeTensors,
};
use std::path::PathBuf;
#[tokio::main]
async fn main() -> HubResult<()> {
// Initialize logging
tracing_subscriber::fmt::init();
println!("=== RustyTorch++ Model Hub Demo ===\n");
// Example 1: Simple one-line loading
demo_simple_loading().await?;
// Example 2: Loading with custom configuration
demo_custom_config().await?;
// Example 3: Loading from local directory
demo_local_loading().await?;
// Example 4: Working with SafeTensors
demo_safetensors().await?;
// Example 5: Cache management
demo_cache_management().await?;
println!("\n=== Demo Complete ===");
Ok(())
}
/// Demo 1: Simple one-line model loading
async fn demo_simple_loading() -> HubResult<()> {
println!("--- Demo 1: Simple Model Loading ---\n");
// The simplest way to load a model - just provide the model ID
// This automatically detects if it's a HuggingFace or RustyTorch model
println!("Loading model: meta-llama/Llama-3.2-1B (simulated)");
// Note: In production, this would actually download the model
// For demo purposes, we'll show the API usage
/*
let model = load("meta-llama/Llama-3.2-1B").await?;
println!("Model loaded successfully!");
println!(" Architecture: {:?}", model.architecture());
println!(" Hidden size: {}", model.hidden_size());
println!(" Num layers: {}", model.num_layers());
println!(" Vocab size: {}", model.vocab_size());
println!(" Path: {}", model.path.display());
*/
println!("Example API usage:");
println!(r#"
// Load a model with one line
let model = rtx_hub::load("meta-llama/Llama-3.2-1B").await?;
// Access model info
println!("Architecture: {:?}", model.architecture());
println!("Hidden size: {}", model.hidden_size());
println!("Num layers: {}", model.num_layers());
"#);
Ok(())
}
/// Demo 2: Loading with custom configuration
async fn demo_custom_config() -> HubResult<()> {
println!("\n--- Demo 2: Custom Configuration ---\n");
// Build a custom configuration
let config = LoadConfig::new()
.with_revision("main") // Specify git revision
.with_dtype(RTXDType::BF16) // Target data type
.with_device("cuda:0") // Target device
.with_cache_dir("/tmp/rtx-models") // Custom cache location
.with_hf_hub(); // Force HuggingFace Hub
println!("Configuration:");
println!(" Revision: {:?}", config.revision);
println!(" DType: {:?}", config.dtype);
println!(" Device: {:?}", config.device);
println!(" Cache dir: {:?}", config.cache_dir);
println!(" Use HF Hub: {}", config.use_hf_hub);
println!("\nExample API usage:");
println!(r#"
let config = LoadConfig::new()
.with_revision("v1.0.0")
.with_dtype(RTXDType::BF16)
.with_device("cuda:0")
.with_auth_token("hf_xxx") // For private models
.with_offline(true); // Use cached only
let model = rtx_hub::load_with_config("mistralai/Mistral-7B-v0.1", config).await?;
"#);
Ok(())
}
/// Demo 3: Loading from local directory
async fn demo_local_loading() -> HubResult<()> {
println!("\n--- Demo 3: Local Model Loading ---\n");
println!("Example API usage:");
println!(r#"
// Load from a local directory (must contain config.json)
let model = rtx_hub::load("/path/to/local/model").await?;
// The model directory should have:
// - config.json (required)
// - model.safetensors or model.safetensors.index.json
// - tokenizer.json (optional)
// - tokenizer_config.json (optional)
// - generation_config.json (optional)
"#);
Ok(())
}
/// Demo 4: Working with SafeTensors
async fn demo_safetensors() -> HubResult<()> {
println!("\n--- Demo 4: SafeTensors Support ---\n");
// Create a simple SafeTensors file in memory
use rtx_hub::{SafeTensorsBuilder, SafeTensorsDType};
// Build a SafeTensors file with some test data
let tensor_data = vec![0u8; 1024]; // 256 floats
let safetensors_bytes = SafeTensorsBuilder::new()
.add_tensor("layer.0.weight", SafeTensorsDType::F32, vec![16, 16], tensor_data.clone())
.add_tensor("layer.0.bias", SafeTensorsDType::F32, vec![16], vec![0u8; 64])
.with_metadata("format", "pt")
.with_metadata("framework", "rustytorch")
.build()?;
println!("Created SafeTensors file: {} bytes", safetensors_bytes.len());
// Load it back
let loaded = SafeTensors::from_bytes(&safetensors_bytes)?;
println!("Loaded SafeTensors:");
println!(" Number of tensors: {}", loaded.num_tensors());
println!(" Tensor names: {:?}", loaded.tensor_names());
for name in loaded.tensor_names() {
if let Some(info) = loaded.tensor_info(name) {
println!(" {} - dtype: {:?}, shape: {:?}", name, info.dtype, info.shape);
}
}
// Validate integrity
loaded.validate()?;
println!(" Validation: OK");
println!("\nExample API usage for loading model weights:");
println!(r#"
// After loading a model
let model = rtx_hub::load("meta-llama/Llama-3.2-1B").await?;
// Load weights (single file)
if !model.is_sharded() {
let weights = model.load_safetensors().await?;
for name in weights.tensor_names() {
let (info, data) = weights.tensor_data(name).unwrap();
println!("{}: {:?} ({} bytes)", name, info.shape, data.len());
}
}
// Load weights (sharded model)
if model.is_sharded() {
let weights = model.load_sharded_safetensors().await?;
println!("Loaded {} shards", weights.num_shards());
}
"#);
Ok(())
}
/// Demo 5: Cache management
async fn demo_cache_management() -> HubResult<()> {
println!("\n--- Demo 5: Cache Management ---\n");
// List cached models
let cached = list_cached_models(None).await?;
println!("Cached models: {:?}", cached);
// Get cache size
let size = cache_size(None).await?;
println!("Cache size: {} bytes ({:.2} MB)", size, size as f64 / 1_000_000.0);
println!("\nExample API usage:");
println!(r#"
// List all cached models
let models = rtx_hub::list_cached_models(None).await?;
for model_id in models {
println!("Cached: {}", model_id);
}
// Get cache size
let size = rtx_hub::cache_size(None).await?;
println!("Cache: {:.2} GB", size as f64 / 1_000_000_000.0);
// Clear cache (be careful!)
// rtx_hub::clear_cache(None).await?;
// Use custom cache directory
let custom_cache = PathBuf::from("/data/models");
let models = rtx_hub::list_cached_models(Some(custom_cache)).await?;
"#);
Ok(())
}
/// Bonus: Architecture detection example
fn demo_architecture_detection() {
println!("\n--- Bonus: Architecture Detection ---\n");
let architectures = [
("llama", RTXArchitecture::from_hf_model_type("llama")),
("mistral", RTXArchitecture::from_hf_model_type("mistral")),
("gpt2", RTXArchitecture::from_hf_model_type("gpt2")),
("bert", RTXArchitecture::from_hf_model_type("bert")),
("phi3", RTXArchitecture::from_hf_model_type("phi3")),
("qwen2", RTXArchitecture::from_hf_model_type("qwen2")),
("mamba", RTXArchitecture::from_hf_model_type("mamba")),
];
println!("Supported architectures:");
for (name, arch) in architectures {
println!(" {} -> {:?}", name, arch);
}
}