Skip to content

Advanced SDK Usage

For full control, use the underlying crates directly instead of the easy module.

PMetal is a Rust workspace with 18 specialized crates:

CratePurpose
pmetal-coreFoundation: configs, traits, types, error handling
pmetal-metalCustom Metal GPU kernels + ANE runtime
pmetal-mlxMLX backend integration
pmetal-modelsLLM architectures (Llama, Qwen, DeepSeek, etc.)
pmetal-loraLoRA/QLoRA training implementations
pmetal-trainerTraining loops (SFT, DPO, SimPO, ORPO, KTO, GRPO)
pmetal-dataDataset loading, chat templates, tokenization
pmetal-hubHuggingFace Hub integration + model fit estimation
pmetal-distillKnowledge distillation (online, offline, TAID)
pmetal-mergeModel merging (14 strategies)
pmetal-ggufGGUF format with imatrix quantization
pmetal-mhcManifold-Constrained Hyper-Connections
pmetal-distributedDistributed training (mDNS, Ring All-Reduce)
pmetal-vocoderBigVGAN neural vocoder
pmetal-serveOpenAI-compatible inference server
pmetal-pyPython bindings (maturin/PyO3)
use pmetal_trainer::TrainingLoop;
use pmetal_models::DynamicModel;
use pmetal_lora::DynamicLoraModel;
use pmetal_data::DataLoader;
// Load model with LoRA
let model = DynamicLoraModel::load("Qwen/Qwen3-0.6B", lora_config)?;
// Create data loader
let loader = DataLoader::from_file("train.jsonl")?;
// Run training loop
let mut loop = TrainingLoop::new(model, loader, training_config);
loop.add_callback(MyCustomCallback);
let result = loop.run().await?;
use pmetal_models::DynamicModel;
// Load from HuggingFace
let model = DynamicModel::load("Qwen/Qwen3-0.6B").await?;
// Load from local path
let model = DynamicModel::load("./my-model/").await?;

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 }
}