Advanced SDK Usage
Use the underlying crates directly for full control over training loops, models, serving, model operations, and hardware-specific paths.
Architecture
Section titled “Architecture”PMetal is a Rust workspace with 20 member crates plus the Tauri GUI package:
| Crate | Purpose |
|---|---|
pmetal | Facade crate and CLI binary |
pmetal-bridge | Zero-allocation MLX C++ bridge and native inference/runtime helpers |
pmetal-core | Foundation: configs, traits, types, error handling |
pmetal-core-derive | Proc macros for canonical job specs |
pmetal-metal | Custom Metal GPU kernels + ANE runtime |
pmetal-mlx | MLX backend integration |
pmetal-models | LLM architectures (Llama, Qwen, DeepSeek, etc.) |
pmetal-lora | LoRA/QLoRA training implementations |
pmetal-trainer | Training loops (SFT, DPO, SimPO, ORPO, KTO, GRPO, pretraining, RLKD, etc.) |
pmetal-data | Dataset loading, chat templates, tokenization |
pmetal-hub | HuggingFace Hub integration + model fit estimation |
pmetal-distill | Knowledge distillation (online, offline, TAID) |
pmetal-merge | Model merging, MoE alignment, dtype-aware saves, sanity checks |
pmetal-gguf | GGUF format with imatrix quantization |
pmetal-mhc | Manifold-Constrained Hyper-Connections |
pmetal-distributed | Distributed training (mDNS, Ring All-Reduce) |
pmetal-vocoder | BigVGAN neural vocoder |
pmetal-serve | OpenAI-compatible inference server |
pmetal-mcp | MCP server tools |
pmetal-py | Python bindings (maturin/PyO3) |
Manual Training Loop
Section titled “Manual Training Loop”use pmetal_trainer::TrainingLoop;use pmetal_models::DynamicModel;use pmetal_lora::DynamicLoraModel;use pmetal_data::DataLoader;
// Load model with LoRA adapterslet model = DynamicLoraModel::from_pretrained("./Qwen3-0.6B", lora_config)?;
// Create data loaderlet loader = DataLoader::from_file("train.jsonl")?;
// Run training looplet mut loop = TrainingLoop::new(model, loader, training_config);loop.add_callback(MyCustomCallback);let result = loop.run().await?;Model Loading
Section titled “Model Loading”use pmetal_models::DynamicModel;
// Resolve from HuggingFace, then load from the local cache pathlet model_path = pmetal_hub::resolve_model_path("Qwen/Qwen3-0.6B", None, None).await?;let model = DynamicModel::load(&model_path)?;
// Load from local pathlet model = DynamicModel::load("./my-model/")?;Callback System
Section titled “Callback System”The TrainingCallback trait provides lifecycle hooks:
use pmetal_trainer::TrainingCallback;
struct MyCallback;
impl TrainingCallback for MyCallback { fn on_step_start(&mut self, step: usize) { /* ... */ } fn on_step_end(&mut self, step: usize, loss: f32) { /* ... */ } fn should_stop(&self) -> bool { false }}See Also
Section titled “See Also”- Facade Crate — Re-exported Rust modules
examples/— Complete working examples