pmetal

Epistates活跃维护

面向 Apple Silicon 的本地大模型推理与微调框架,用 Rust 实现,支持 LoRA/QLoRA 微调、量化、模型服务和 MLX/Metal 加速。

PMetal: high-performance Apple Silicon framework for local LLM inference, LoRA/QLoRA fine-tuning, serving, quantization, and MLX/Metal acceleration.

v0.7.1发布于 2026-10-29 17:30 UTC332star27fork同步于 2026-11-10 23:59 UTC

怎么上手

由 README 提炼,执行前请确认
brew install epistates/tap/pmetal
pmetal infer --model Qwen/Qwen3-0.6B --prompt "Explain quantum entanglement" --chat
硬件要求按 README 说明

macOS 14+ 的 Apple Silicon,使用 Mac GPU 和 Neural Engine;README 未给出具体显存要求。

支持 Apple Silicon需要 CUDA
下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

在 Apple Silicon 上用 Rust 做 LLM 微调、推理和服务的框架,不依赖 Python 和 CUDA

面向 Apple Silicon 的本地大模型推理与微调框架,用 Rust 实现,支持 LoRA/QLoRA 微调、量化、模型服务和 MLX/Metal 加速。

核心能力

  • 用一份 job spec 生成 CLI、TUI、GUI、MCP 和 Python 绑定,避免各接口行为不一致
  • 支持 LoRA、QLoRA、DoRA、rsLoRA、LoRA+ 和 PiSSA 等完整 LoRA 家族
  • 训练用的 LoRA 挂到推理同一模块图,调完即可直接服务
  • NVFP4、FP8、MXFP4 权重保持打包运行,KV 缓存可压到 2 至 4 比特
  • 同一服务同时提供 OpenAI 与 Anthropic 两套 API,支持工具调用和连续批处理

容易踩的坑

首次使用会从 Hugging Face Hub 下载模型;从 crates.io 安装时 serve 和 mcp 默认关闭,需要加 --features serve,mcp;从源码构建需要 Xcode 命令行工具、Metal 工具链和 CMake。

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本v0.7.1
  1. v0.7.1PMetal v0.7.1最新正式版2026-10-29 · 2026-10-29 17:30 UTC

    Downloads

    AssetDescription
    pmetal-*-aarch64-apple-darwin.tar.gzCLI binary + mlx.metallib (Apple Silicon)
    PMetal-*-aarch64-apple-darwin-*.dmgDesktop GUI app (Apple Silicon)
    mlx.metallibMLX Metal shader library (standalone)

    CLI Quick Start

    tar xzf pmetal-*-aarch64-apple-darwin.tar.gz
    ./pmetal train --model Qwen/Qwen3-0.6B --dataset train.jsonl --output ./output
    

    GUI

    Mount the DMG and drag PMetal to Applications.

    Full Changelog: https://github.com/Epistates/pmetal/compare/v0.7.0...v0.7.1

  2. v0.7.0PMetal v0.7.02026-10-27 · 2026-10-27 13:46 UTC
    查看更新说明

    Downloads

    AssetDescription
    pmetal-*-aarch64-apple-darwin.tar.gzCLI binary + mlx.metallib (Apple Silicon)
    PMetal-*-aarch64-apple-darwin-*.dmgDesktop GUI app (Apple Silicon)
    mlx.metallibMLX Metal shader library (standalone)

    CLI Quick Start

    tar xzf pmetal-*-aarch64-apple-darwin.tar.gz
    ./pmetal train --model Qwen/Qwen3-0.6B --dataset train.jsonl --output ./output
    

    GUI

    Mount the DMG and drag PMetal to Applications.

    What's Changed

    New Contributors

    Full Changelog: https://github.com/Epistates/pmetal/compare/v0.5.0...v0.7.0

  3. v0.5.0PMetal v0.5.02026-05-08 · 2026-05-08 11:38 UTC
    查看更新说明

    [0.5.0] - 2026-05-07

    Added

    Distributed inference & training
    • pmetal-distributed crate (Phases 1-4 + 7): Thunderbolt-fabric-aware multi-Mac cluster runtime with feature-gated tensor, expert, context, ZeRO, and pipeline parallelism modules
      • pmetal cluster CLI: per-node launch, ring/mesh topology discovery, fabric handshake
      • Pipeline harness with overlap of computation and Thunderbolt transfers
      • Canonical expert-rank mapping + per-architecture MoE/MLA tensor-parallel plans
      • Ring all-reduce / all-gather with corrected chunk indexing
    TurboQuant KV cache (production-ready)
    • TurboQuant KV cache quantization: Provably near-optimal KV cache compression based on random rotation + Lloyd-Max scalar quantization + QJL residual for unbiased inner products (arXiv:2504.19874). Achieves 4-6x KV cache compression with near-zero quality loss. Available via --kv-turboquant or presets --kv-turboquant-preset q3_5 (near-lossless) / q2_5 (6.4x compression)

      • Separate key/value runtimes with independent bit widths and outlier-aware mixed-precision
      • Direct attention path for single-token decode avoids full cache dequantization
      • Data-oblivious (no calibration data required) — quantizes KV entries online as generated
      • Precomputed codebooks via Lloyd-Max algorithm for Beta distribution (deterministic from seed)
      • Metal kernel backend with CPU fallback
      • Phase 0: split monolithic mod.rs (6101 → 222 LOC) into config/core/state/bits/math submodules
      • Phase 3: GPU-resident hot/cold pipeline + Mixed K/V storage; mixed_score as layout oracle
      • Phase A/B: QJL ablation harness (feature-gated) + per-row key_slot_scale codebook adaptation
      • Phase C/C′: Variant F drop-QJL opt-in path; d128/d256 no_qjl_2pass fast paths (4..=8 bits)
      • Phase D: TurboQuantPackMode config + Fullbyte dense-values kernel
      • Phase E: TurboQuantOutlierMode — encode-side top-K outlier storage, zero pre-quant + decode override, outlier-bias on d128/d256 fullbyte score kernel; CPU mirror in scalar encode/decode
      • Phase F: Hamming skip-list dispatch — skiplist_threshold config, GPU sign_hash buffer, Metal Hamming-distances kernel + FFI, GQA support
      • Mixed-precision attention parity baseline; defensive residual-norm clamp + NaN-safe encode
    • Asymmetric K/V head dimensions: KV cache, TurboQuant, and fused attention now support models where key and value projections have different widths (e.g. DeepSeek MLA with qk_head_dim != v_head_dim)

    • pmetal serve --kv-turboquant: TurboQuant KV cache in the serving engine with --kv-turboquant-preset q3_5 for near-lossless 4.6x KV compression in production

    Quantization & model formats
    • Optimized FP8 checkpoint loading: Hugging Face FP8 weight_scale_inv sidecars are dequantized or repacked into MLX mxfp8 weights for Qwen3-family native paths; mode-aware quantized matmul plumbing handles floating-point quantized weights without dense fallback
    • Expanded GGUF quantization/export: pmetal quantize now writes standard GGUF metadata from Hugging Face configs, tokenizer/pre-tokenizer metadata, HF-to-GGUF tensor names, stacked MoE expert tensors, and method-specific file types
    • Broader GGUF format coverage: quantization/dequantization support now includes K-quants, legacy Q4/Q5/Q8 variants, Q1_0, TQ1_0/TQ2_0, MXFP4, NVFP4, BF16, F16, and F32 round trips
    • MLX safetensors quantization path: quality-based bit allocation with --target-bpw, GPU-resident weight loading, and tokenizer/config sidecar copy for MLX-format quantized exports
    Inference server (OpenAI- + Anthropic-compatible)
    • Continuous batching with paged-KV-style admission + shared prefix cache in pmetal-serve: per-request slot scheduling, KV-cache prefix sharing, concurrent decode for many simultaneous chats
      • Token-block admission budget (--cb-block-size, --cb-max-blocks) prev
  4. v0.4.0PMetal v0.4.02026-03-24 · 2026-03-24 04:05 UTC
    查看更新说明

    [0.4.0] - 2026-03-23

    Added

    • pmetal-mcp crate: Full MCP (Model Context Protocol) server exposing 45 tools for Claude Desktop and other MCP clients. Covers all pmetal functionality — training, inference, distillation, GRPO, RLKD, quantization, model merging, dataset operations, evaluation, benchmarking, model search, and Ollama export

      • Device & models: device_info, search_models, download_model, list_local_models, model_fit, model_info
      • Inference: generate (blocking), chat (via running serve instance), start_serve, benchmark, bench_train, bench_gen, bench_corpus
      • Training: train, distill, grpo, rlkd, embed_train — all as background jobs with full parameter coverage matching the CLI
      • Runtime training control: job_set_lr, job_reduce_lr, job_reset_lr, job_save_checkpoint, job_graceful_stop — LLM-driven adaptive training via the control file protocol
      • Job management: list_jobs, job_status, job_logs, stop_job
      • Dataset ops: dataset_analyze, dataset_preview, dataset_validate, dataset_download, dataset_convert, dataset_filter, dataset_split, dataset_merge, dataset_sample, dataset_template, dataset_prepare
      • Quantization & conversion: quantize, fuse_lora, merge_models, pack_experts, ollama_create, ollama_modelfile
      • Evaluation: eval_perplexity
      • All tools include rich #[description] annotations for parameter documentation in the MCP schema
      • Standalone binary (pmetal-mcp) for Claude Desktop + pmetal mcp subcommand (behind mcp feature flag)
      • Uses turbomcp v3.0.7 from crates.io
    • Runtime training control protocol: Extended the control file protocol (.lr_control.json) with SaveCheckpoint and GracefulStop commands. The adaptive LR controller now polls the control file before checking its enabled flag, so external agents (MCP, TUI) can always send commands regardless of whether automatic detection is active

    • --no-adaptive-lr flag: Disables automatic spike/plateau/divergence detection while keeping the control file protocol active. Enables fully LLM-driven learning rate control — the agent observes loss via job_status and manually adjusts LR via job_set_lr/job_reduce_lr

    • UltraFusion execution planner (pmetal-distributed): Per-die stage planner for M-series Ultra Macs with in-memory channel transport backend for same-process links, avoiding TCP overhead on UltraFusion interconnect

    • MPP FlashAttention for head_dim 64/96: Metal 4 MPP flash attention kernel now supports head_dim 64, 96, and 128 with stride-2/stride-3 SIMD lane packing and causal/non-causal variants

    • Tuna persistent disk cache: The auto-tuner now persists benchmark results to disk, avoiding re-tuning on restart. Expanded search covers FlashAttention, FusedCrossEntropy, FusedNormLora, and FusedSwiGLU via function constants

    • MoE GPU top-k selection: Expert top-k selection moved from CPU sort to GPU argpartition_axis, eliminating a sync point in the MoE forward path

    • bench-workload CLI command: Benchmark a real cached workload for inference and short LoRA training with named presets (--preset dense-qwen3, --preset hybrid-qwen3next)

    • KV cache quantization auto-select: --kv-quant is now optional — omitting it auto-selects the fastest quantization mode that fits the device memory budget

    • UltraFusion info display: pmetal info shows UltraFusion topology, die count, and local executor plan on Ultra Macs

    • Qwen3 LoRA RoPE reset: Qwen3 LoRA and QLoRA gain dense attention and RoPE reset support

    • ANE real-time evaluation: Experimental _ANEClient real-time dispatch with automatic fallback to standard evaluation on failure. Propagated via --ane-real-time CLI flag

    • bench-corpus CLI command: Structured kernel benchmarking with device-tier-aware test cases, JSON reporting, and `--qui

  5. v0.3.7PMetal v0.3.72026-03-16 · 2026-03-16 18:52 UTC
    查看更新说明

    [0.3.7] - 2026-03-16

    Added

    • pmetal merge CLI command: Model merging exposed as a first-class CLI command supporting all merge methods (Linear, SLERP, TIES, DARE, DELLA, NearSwap, Model Stock) with --method, --base, --t, --weight-a, --weight-b, --density, and --dtype flags
    • pmetal eval CLI command: Dataset evaluation command — measures loss/perplexity over a validation set with optional LoRA adapter, --num-samples cap, and --json output
    • pmetal info CLI command: Prints device and runtime information; --json flag emits structured JSON for scripting
    • pmetal search --json output: Structured JSON output mode for search results including fit estimates, download counts, parameter estimates, and tags — enables scripting and GUI integration
    • QuantizeMethod enum: Replaces the string --method argument for pmetal quantize with a typed enum (dynamic, q8_0, q4_k_m, etc.) — invalid methods now fail at argument parsing rather than deep inside the quantizer
    • GRPO CLI arguments: --epochs, --lora-r, --lora-alpha, --max-completion-length, and --seed exposed as CLI arguments, replacing previous hardcoded defaults
    • loraplus_lr_ratio and neftune_noise_alpha: New fields on training loop configurations — enables LoRA+ differential learning rates and NEFTune noise injection directly from config
    • trainable_params() helper: New utility in pmetal-lora for counting total vs. trainable parameter counts, useful for logging and memory estimation
    • lora_alpha: f32: Distillation CLI and run_distillation_cli now accept lora_alpha as f32 instead of usize for finer-grained scaling control
    • seed parameter in distillation and GRPO CLI: Reproducible runs via explicit --seed flag in all training entry points
    • Gemma3 sliding window auto-detection: DynamicModel loader now reads model_type == "gemma3" and sets is_gemma3 = true on the config, enabling the correct every-6th-layer global attention pattern without manual config overrides
    • KV cache support for more architectures: DynamicModel::forward_with_cache now routes DeepSeek, Cohere, StarCoder2, and Llama4 to their native caching paths; RecurrentGemma and Jamba now get clear error messages that they require forward() directly; hybrid models (NemotronH, Qwen3Next) get a descriptive error directing to forward_with_hybrid_cache
    • Speculative decoding greedy path: SpeculativeDecoder::verify_greedy() — exact-correct verification for temperature=0 decoding using argmax equality; avoids the numerically unstable rejection-sampling limit as temperature→0
    • Hub cache management (pmetal-hub): New cache.rs module with cache inspection, eviction, and size-reporting helpers
    • Shared model utilities (pmetal-models/utils.rs): Common helpers extracted from per-architecture modules to reduce duplication

    Fixed

    • Scale factor broadcasting in distillation: squeeze applied to the scale factor dimension so it broadcasts correctly across batch and sequence axes — previously caused shape mismatches on non-unit batch sizes
    • TAID mean_alpha forcing GPU sync: TaidLossOutput::mean_alpha changed from f32 to a lazy Array — the .eval() call is deferred until callers explicitly call .item::<f32>(), removing a forced GPU-CPU sync before the backward pass
    • SLERP numerical stability: Added epsilon clamping in the SLERP merge path to prevent NaN when interpolation parameter is at the boundary values (0.0 or 1.0)
    • Llama LoRA trainable_params / gradient application: Replaced 100+ lines of repeated field accesses with an insert_adapter! macro and loop over projection names, fixing DoRA magnitude parameter that was silently dropped from gradient maps
    • GaLore improvements: Corrected projection matrix update schedule and subspace dimensionality handling
    • Distillation hidden-state loss: Refactored alignment compu

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    Crates.io Docs Rust License Platform

    PMetal

    Powdered Metal: fine-tuning, inference and serving for Apple Silicon, written in Rust.

    PMetal trains and runs large language models on the Mac's GPU and Neural Engine, with no Python or CUDA in the loop. One tensor runtime (MLX under it, PMetal's own Metal kernels beside it) sits under a command line, a terminal UI, a desktop app, an MCP server, Python bindings and a Rust SDK.

    What sets it apart:

    • One job spec for every surface. Each command's fields, defaults, ranges and checks are defined once in pmetal-core; the CLI, TUI, GUI, MCP server and Python bindings are generated from it, so they cannot drift apart.
    • Fine-tuning with the full LoRA family. LoRA, QLoRA, DoRA, rsLoRA, LoRA+ and PiSSA/OLoRA/LoftQ initialisation, with one adapter per routed expert on MoE models and QLoRA on NVFP4 checkpoints (the base stays packed). Adapters are written in the PEFT layout and agree with PEFT to 4e-6 in logits both ways.
    • Training adapts the model the server runs. LoRA attaches to the same module graph inference uses, and the architectures are checked against reference outputs from transformers, so what you tune is what you serve.
    • Drafters trained on a Mac. train-mtp and train-draft produce MTP predictors and DFlash block-diffusion drafts; infer --mtp, infer --draft-model and dflash use them for exact speculative decoding (every drafted token is verified).
    • Packed weights stay packed. NVFP4, FP8 and MXFP4 checkpoints run in their stored form, MoE experts can be offloaded to SSD, and the KV cache can be TurboQuant-compressed to 2 to 4 bits.
    • One server, both API families. OpenAI Chat Completions, Completions, Responses and Embeddings plus Anthropic Messages, with tool calls, grammar-constrained JSON-schema output, vision input and continuous batching.
    • The Neural Engine, for training and inference. Whole-model inference on the ANE (with DFlash drafting), and an ANE training path.
    • Quantization you can budget. GGUF output with importance matrices and KL-calibrated per-tensor types under a bits-per-weight target.
    • Multi-Mac training. Thunderbolt-aware ring all-reduce with authenticated, encrypted links; ZeRO-1/2 optimizer sharding and DiLoCo are in the pmetal-distributed library.

    Around that: GRPO, DAPO and GSPO; DPO, IPO, SimPO, ORPO and KTO; distillation; embedding-model training; pretraining; Hugging Face Hub search, download, upload and verification; model merging; and LoRA fusing.

    Quick start

    brew install epistates/tap/pmetal
    
    pmetal train --model Qwen/Qwen3-0.6B --dataset train.jsonl --output ./output
    pmetal infer --model Qwen/Qwen3-0.6B --lora ./output/adapter_model.safetensors \
      --prompt "Explain quantum entanglement" --chat
    pmetal serve --model Qwen/Qwen3-0.6B --port 8080
    

    train.jsonl holds chat messages, ShareGPT, Alpaca, prompt/completion or plain text rows; the format is detected from the columns (see Dataset formats). Models download from the Hugging Face Hub on first use. Other ways to install are under Installation.

    Use PMetal your way

    Command line

    # Fine-tune with LoRA (sequence packing and gradient checkpointing are on by default)
    pmetal train --model Qwen/Qwen3-0.6B --dataset train.jsonl --output ./output \
      --lora-r 16 --batch-size 4 --learning-rate 2e-4
    
    # QLoRA: the base model is packed to NF4 on the GPU
    pmetal train --model Qwen/Qwen3-0.6B --dataset train.jsonl --quantization nf4
    
    # Preference tuning, GRPO and distillation
    pmetal preference --model Qwen/Qwen3-0.6B --dataset pairs.jsonl --loss dpo
    pmetal grpo --model Qwen/Qwen3-0.6B --dataset reasoning.jsonl --reasoning-rewards
    pmetal distill --teacher Qwen/Qwen3-4B --student Qwen/Qwen3.5-0.8B-Base --dataset train.jsonl
    
    # Search the Hub with a fit estimate for this Mac, then merge, fuse and quantize
    pmetal search "qwen 0.6b" --detailed
    pmetal merge --model-a model-a --model-b model-b --method slerp --t 0.5 --output merged
    pmetal fuse --model Qwen/Qwen3-0.6B --lora ./output/adapter_model.safetensors --output ./fused
    pmetal quantize --model ./fused --output model.gguf --method q4_k_m
    
    # Perplexity on a dataset, and a benchmark
    pmetal eval --model Qwen/Qwen3-0.6B --dataset eval.jsonl
    pmetal eval --model Qwen/Qwen3-0.6B --task gsm8k --limit 50
    

    Speculative decoding with a Qwen3.6 checkpoint that bundles its own multi-token-prediction head, and with a predictor you trained yourself:

    pmetal infer --model Qwen/Qwen3.6-35B-A3B --mtp --prompt "Explain monotonic queues."
    
    pmetal tokenize --input train.jsonl --output ./tok --tokenizer Qwen/Qwen3.6-35B-A3B
    pmetal train-mtp --model Qwen/Qwen3.6-35B-A3B --family qwen3-next \
      --shards ./tok/shard_00000.bin --output ./qwen-mtp
    pmetal infer --model Qwen/Qwen3.6-35B-A3B --mtp --mtp-model ./qwen-mtp --prompt "Explain monotonic queues."
    

    pmetal <command> --help lists every option; each command is documented under docs/cli/.

    CommandDescription
    trainLoRA/QLoRA/DoRA fine-tuning (SFT); --full trains every weight and saves a whole model; --ane trains on the Neural Engine
    train-mtpTrain a Gemma 4 assistant or a Qwen3Next/Qwen3.6 MTP predictor for speculative decoding
    train-draftTrain a DFlash block-diffusion draft checkpoint
    train-diffusionLoRA/QLoRA fine-tune a DiffusionGemma block-diffusion model
    pretrainPretrain from scratch (full-parameter, no LoRA) on tokenized shards
    preferenceDPO, Robust DPO, IPO, hinge, SimPO, ORPO or KTO with LoRA (alias dpo)
    grpoGRPO, DAPO, Dr. GRPO and GSPO reasoning training (VLM, reward models, reward commands, verifiers, async rewards)
    rlkdGRPO with a distillation term from a teacher
    distillKnowledge distillation (online, offline, progressive)
    embed-trainSentence-embedding fine-tuning (InfoNCE, triplet, CoSENT)
    inferGeneration with chat, tools, thinking mode, images and video, speculative decoding
    decideTyped decisions from a Clef decision model in one forward pass
    serveOpenAI- and Anthropic-compatible server
    dflashBlock-diffusion speculative decoding
    search, download, upload, verifyHugging Face Hub search with device fit, download, publish, integrity check
    merge, fuse, quantizeModel merging, LoRA fusing, GGUF and MLX quantization
    imatrixMeasure an importance matrix on calibration data, for quantize --imatrix
    evalPerplexity on a dataset, or a benchmark: GSM8K, MMLU, ARC, HellaSwag, IFEval subset, your own
    dataset, tokenizeDataset analysis, conversion and preparation; pretraining shards
    vocodeMel spectrogram to waveform with a BigVGAN vocoder
    ollamaModelfile generation for Ollama
    tui, dashboardThe terminal UI; dashboard opens it on the Monitor tab
    mcpMCP server over stdio (57 tools)
    clusterMulti-Mac cluster: keys, discovery, status, benchmarks
    info, memory, init, completionsDevice report, memory report, sample training config, shell completions
    bench, bench-gen, bench-workload, bench-corpus, bench-gdnTraining, generation, workload and kernel benchmarks
    pack-expertsPack MoE expert weights for SSD-offloaded inference

    serve and mcp are in the prebuilt binary and the Homebrew formula; if you build from source, add --features serve,mcp.

    Terminal UI

    pmetal tui
    

    21 tabs. Every job tab is a form built from the command's job spec; S shows the exact pmetal command and starts it as a supervised child process with a scrollable log, and quitting stops what you started.

    TabDescription
    SystemGPU and Neural Engine info, Metal features, memory against the device's working-set limit, UltraFusion topology
    ModelsCached and local models with a fit estimate for this Mac; Hub search (S), download, fuse
    DatasetsLocal datasets (JSONL, Parquet, Arrow, CSV) with format readiness and a preview; convert to pmetal JSONL
    Tokenize, PretrainBuild pretraining shards; pretrain from scratch
    Training, EmbedTrain, Distill, RLKD, GRPO, PreferenceThe training commands (L changes the learning rate of a running job)
    MonitorLive loss, learning rate, throughput and timing of a running or recorded run
    InferenceChat with a generation-settings sidebar
    DFlash, ServeSpeculative decoding; the OpenAI-compatible server
    Quantize, Merge, Bench, Eval, ModelfileModel operations, benchmarks, Ollama Modelfiles
    JobsJobs from this session and finished runs found on disk, with logs

    Ctrl+P jumps to any tab, Tab/Shift+Tab cycle, Alt+1..Alt+9 pick one of the first nine, ? lists the keys of the current tab. See docs/cli/tui.md.

    Desktop app

    A Tauri + Svelte app. Every pmetal command has a form drawn from its job spec, so the app cannot drift from the command line. Pages: Dashboard, Jobs, Train, Run (chat, server, DFlash), Models and Datasets (local and Hub), Tools (merge, fuse, quantize, Modelfile, pack experts), Measure (perplexity, benchmarks), Advanced and Settings.

    Jobs run as pmetal processes under the shared job supervisor (the app bundles the CLI), carry on while you use other pages and are stopped when you quit. A Hugging Face token is kept in the macOS Keychain. Download the app from the Releases page, or run it from source:

    cd crates/pmetal-gui && bun install && bun tauri dev
    

    MCP server

    pmetal mcp exposes 57 tools over stdio for Claude Desktop, Claude Code and other MCP clients: training, inference, model and dataset operations, device information and job control, with read-only resources and prompts. The tools are generated from the same job specs. See docs/cli/mcp.md.

    Python

    PyO3 bindings, one abi3 wheel for CPython 3.11 and later (macOS 14+, Apple Silicon). Every pmetal command is a typed spec class (TrainSpec, GrpoSpec, MergeSpec, ...) with the command line's fields, defaults and checks.

    import pmetal
    
    # Fine-tune in this process (releases the GIL; Ctrl-C stops after the step and keeps the weights)
    spec = pmetal.TrainSpec(model="Qwen/Qwen3-0.6B", dataset="train.jsonl", epochs=3, lora_r=16)
    result = pmetal.Trainer(spec, callbacks=[pmetal.LoggingCallback(10)]).train()
    print(result.final_loss, result.total_steps, result.weights_path)
    
    # Any other command, as the command line runs it
    pmetal.run(pmetal.MergeSpec(model_a="a", model_b="b", output="merged"))
    
    # Inference
    model = pmetal.Model.load("Qwen/Qwen3-0.6B")
    print(model.generate("The capital of France is", max_tokens=16, temperature=0.0))
    print(pmetal.infer("Qwen/Qwen3-0.6B", "What is 2+2?", chat=True, no_thinking=True))
    

    See crates/pmetal-py/README.md and docs/python/.

    Rust SDK

    pmetal re-exports every sub-crate behind a feature flag, so one dependency gets you the framework. orchestrator::run_training is the one-call entry point the CLI itself uses:

    use pmetal::trainer::orchestrator::{TrainingJobConfig, run_training};
    
    let config = TrainingJobConfig {
        model_id: "Qwen/Qwen3-0.6B".to_string(),
        dataset: "train.jsonl".to_string(),
        output_dir: "./output".to_string(),
        ..Default::default()
    };
    
    let result = run_training(config, None, Vec::new()).await?;
    println!("final loss {:.4} over {} steps", result.final_loss, result.total_steps);
    

    Inference goes through the model dispatcher:

    use pmetal::models::generate;
    use pmetal::prelude::*;
    
    let model_dir = pmetal::hub::resolve_model_path("Qwen/Qwen3-0.6B", None, None).await?;
    let mut model = DynamicModel::load(&model_dir)?;
    let tokenizer = Tokenizer::from_model_dir(&model_dir)?;
    
    let input_ids = tokenizer.encode_with_special_tokens("What is 2+2?")?;
    let output = generate(
        |input| model.forward(input, None),
        &input_ids,
        GenerationConfig::sampling(256, 0.7),
    )?;
    println!("{}", tokenizer.decode(&output.token_ids[input_ids.len()..])?);
    

    For step-by-step control use the crates directly (pmetal_trainer::TrainingLoop, pmetal_models::DynamicModel, pmetal_lora::DynamicLoraModel, pmetal_distill::Distiller). Every code block in each crate's README is compiled as a doctest. See crates/pmetal/examples/ and docs/sdk/advanced.md.

    Supported models

    Language models

    Loaded from the Hugging Face Hub or a local directory; the architecture is detected from config.json. All of them work with the CLI, TUI, GUI, server and SDK. A model_type that is not listed is refused by name and never run as a similar family (see Not supported yet).

    FamilyVariantsmodel_type values
    Llama2, 3, 3.1, 3.2, 3.3llama, llama3
    Llama 4Scout, Maverickllama4, llama4_text
    Llama 3.2 Vision11B, 90B (image input)mllama, mllama_text_model
    Qwen 2 / 2.5denseqwen2, qwen2_5
    Qwen 3denseqwen3
    Qwen 3 MoEe.g. Qwen3-30B-A3Bqwen3_moe
    Qwen 3.5 / 3.6 / 3.8hybrid Gated DeltaNet, dense and MoE (image and video input)qwen3_next, qwen3_5, qwen3_5_moe, qwen3_6, qwen3_6_moe
    Qwen 3.8 Flash Nexttext towerqwen4_exp
    DeepSeekV2, V3, R1 (V3.2 and V4 are refused by name: the sparse-attention indexer is not implemented)deepseek_v2, deepseek_v3
    Mistral7B and the other dense Mistral decoders (Mixtral and the Mistral3 vision wrapper are refused by name)mistral
    Gemma1, 2, 3gemma, gemma2, gemma3
    Gemma 4dense and MoEgemma4, gemma4_text
    DiffusionGemmadense, MoEdiffusion_gemma, diffusion_gemma_text
    PhiPhi-3, Phi-3.5, Phi-4phi3, phi4
    CohereCommand Rcohere, cohere2, command_r
    Granite3.x (including MoE), 4.0, 4.0-Hgranite, granitemoe, granitemoeshared, granitemoehybrid
    Nemotron-H, Nemotron 3hybrid Mamba-2 and attention (Nemotron 3 Nano and Super, Nemotron-H 4B to 12B)nemotron_h
    GPT-OSS20B, 120B (MXFP4 checkpoints run packed)gpt_oss
    Clefdecision models (pmetal decide, /v1/systemone)Qwen3.5-family backbones

    Quantized checkpoints load packed: MLX-quantized (affine, mxfp4, nvfp4, mxfp8), NVIDIA ModelOpt NVFP4 and FP8, and gpt-oss MXFP4.

    Encoders: BERT, RoBERTa, XLM-RoBERTa, CamemBERT, DistilBERT and ModernBERT (bert, roberta, xlm-roberta, xlm_roberta, camembert, distilbert, modernbert) run for embeddings (/v1/embeddings) and train with pmetal embed-train.

    Diffusion: pipelines::FluxPipeline loads a diffusers-layout FLUX.1 directory (1-dev, 1-schnell) from pmetal-models; it has no tokenizer or CLI command yet.

    Fine-tuning: LoRA and QLoRA (--quantization nf4|fp4|int8) apply to every architecture the dispatcher loads, with sequence packing, gradient checkpointing and the fused optimizer. The LM head, MoE routers and routed experts stay as loaded; LoRA adapts the routed experts of Qwen3-MoE, DeepSeek and Nemotron-H one adapter per expert. Adapters are written in the PEFT layout. DiffusionGemma trains through train-diffusion.

    Speculative decoding (exact: every drafted token is verified, so output quality does not change):

    • Gemma 4 MTP assistant checkpoints (gemma4_assistant) draft for a Gemma 4 target with infer --draft-model.
    • Qwen3Next/Qwen3.6 checkpoints with bundled mtp.* weights (or a predictor from train-mtp) use infer --mtp; sampling controls carry through, and acceptance metrics are printed. LoRA and packed expert offload are separate modes: fuse the adapter first to combine them.
    • DFlash drafts (including DFlash 2) run with pmetal dflash on a Qwen target, or with infer --ane --draft-model for a model on the Neural Engine. train-draft makes custom drafts.

    See docs/models/supported.md.

    Training methods

    Every method below is a command with the same form in the CLI, TUI, GUI, MCP server and Python (the TUI has tabs for the ones in its list above).

    MethodCommandLibrary
    SFT, LoRA, QLoRA, DoRA, rsLoRA, LoRA+train (--quantization, --dora, --rslora)orchestrator::run_training()
    DPO, Robust DPO, IPO, hingepreference --loss dpo|ipo|hingePreferenceTrainer
    SimPO, ORPOpreference --loss simpo|orpoPreferenceTrainer
    KTOpreference --loss ktoKtoTrainer
    GRPO, DAPOgrpo (--dapo, --loss-type)GrpoTrainer
    Dr. GRPO, GSPOgrpo --loss-type dr_grpo|gspoGrpoConfig::for_dr_grpo, for_gspo
    Knowledge distillationdistillDistiller
    TAIDnot wired to a commandTaidDistiller
    RLKD (GRPO plus distillation)rlkdRlkdTrainer
    Embedding modelsembed-trainEmbeddingTrainer
    Pretrainingpretrain (with --document-mask)pmetal_trainer
    Block diffusion (DiffusionGemma)train-diffusionDiffusionGemmaTrainer
    MTP and DFlash draft trainingtrain-mtp, train-draftpmetal_trainer::mtp_training
    Neural Engine trainingtrain --ane (experimental)AneTrainingLoop

    Common to the training commands: optimizers adamw, sgd, lion, adafactor, muon, adamw_schedule_free and adamw_8bit; schedules cosine, linear, constant, cosine_with_restarts, polynomial and wsd; adaptive learning-rate control, best-loss checkpoint rollback, --resume that restores the optimizer, label smoothing, z-loss and NEFTune, --cut-cross-entropy, and live learning-rate steering from the TUI, GUI and MCP server. A training config can also be given as YAML (pmetal init writes a sample; see docs/configuration/config-file.md). Details: docs/training/.

    Notable technology

    • Own tensor runtime (pmetal-runtime): arrays, autodiff, compiled graphs, native inference engines and custom Metal kernels, with MLX as the backend. Dense attention, RoPE, SwiGLU, LoRA and GEMM run as runtime ops; custom kernels cover what the runtime has no op for (fused Gated DeltaNet recurrence, fused AdamW, the Neural Engine's weight-gradient GEMM).
    • TurboQuant KV cache (infer --kv-turboquant, native Qwen3, Qwen3.5 and Llama 4 engines): rotated, Lloyd-Max-quantized keys and values stored bit-packed, 1 to 8 bits per coordinate, with decode attending straight from the packed cache. At head dimension 128 that is 3.8x smaller than bf16 at 4 bits, 4.9x at 3 bits and 7.1x at 2 bits. Sinks and a recent window stay exact; each KV head's keys are centred and scaled from the first tokens the cache sees. On Qwen3-0.6B text this keeps 4-bit keys and values within 0.3% perplexity of bf16 and 3-bit within 2.3%.
    • Neural Engine: training kernels compiled once, with weights packed beside activations in IOSurfaces; inference with the whole model on the ANE, several layers per program over a KV cache in IOSurfaces, int8 weights by default (infer --ane, serve --ane).
    • Server: /v1/chat/completions, /v1/completions, /v1/responses, /v1/embeddings, /v1/messages (with /v1/messages/count_tokens) and /v1/models, with streaming, tool calls parsed per model family, JSON-schema and tool_choice enforced by constrained decoding, logit_bias, logprobs (the prompt's too, with echo, for loglikelihood evaluation), reasoning_content, images and videos (Qwen3.5 family, Llama 3.2 Vision), prefix caching, --continuous-batch, speculative decoding on the GPU (--mtp, --draft-model: the model's own tokens, sooner), Prometheus metrics at /metrics, optional API keys and CORS origins. See crates/pmetal-serve/README.md.
    • Datasets: JSONL, JSON, Parquet, Arrow and CSV, or a directory of shards; messages, ShareGPT, Alpaca, prompt/completion, reasoning and plain-text rows are detected automatically. pmetal dataset analyzes, converts, filters, splits and prepares them.
    • Merging: 18 strategies in the library (14 on the command line: linear, SLERP, TIES, DARE, DELLA, task arithmetic, Breadcrumbs, Model Stock, consensus, Multi-SLERP, nearswap, passthrough and variants), streamed tensor by tensor from memory-mapped checkpoints, with FP8 inputs, layer slices and reproducible masks. See docs/models/merging.md.
    • Quantization: GGUF (26 methods including K-quants, IQ4_NL and IQ4_XS, ternary, MXFP4 and NVFP4, with importance matrices measured by pmetal imatrix or on the fly with --calibration-dataset, and KL-calibrated --kl-calibrate --target-bpw) and MLX-format output. See docs/models/quantization.md.
    • Distillation: online, offline (compressed top-k, int8/int4 or sampled logit caches) and progressive; KL, reverse KL, Jensen-Shannon, skew KL, soft cross-entropy, MSE and cross-vocabulary universal-logit losses; rationale distillation; on-policy generation. See docs/training/distillation.md.

    Multi-Mac cluster

    Connect two or more Apple Silicon Macs for data-parallel training. PMetal enumerates every network interface, advertises over mDNS and forms a ring biased toward the fastest fabric: Thunderbolt over Ethernet over Wi-Fi, without configuration. Links between ranks are authenticated and encrypted with a shared cluster secret, so every Mac needs the same one.

    # Once, on one Mac; copy ~/.pmetal/cluster_secret (mode 600) to every other Mac
    pmetal cluster keygen
    
    # On every Mac
    pmetal cluster status        # local interfaces and any peers already announcing
    pmetal cluster up            # join the cluster and hold the connection open
    pmetal cluster bench --mb 64 --iters 10                 # all-reduce throughput per fabric
    pmetal cluster pipeline-bench --tokens 16 --layers 32   # pipeline activation transport
    
    # Distributed training: run the same command on each Mac at the same time
    pmetal train --model Qwen/Qwen3-0.6B --dataset train.jsonl --distributed-auto
    

    Wired today: gradient all-reduce for multi-machine training, fabric-aware ring formation with fallback when a cable is unplugged, gradient compression (--compression-strategy none|topk|fp16|random), and a transport-tested pipeline harness. Serving a model that does not fit on one Mac (per-architecture partial-layer execution) is not wired yet.

    Hardware support

    PMetal detects the Apple Silicon generation, tier, core counts, memory bandwidth and features at startup and tunes itself. Run pmetal info to see what it found.

    Chip familyGPU familyNAXANEStatus
    M1 / Pro / Max / UltraApple7-yesSupported
    M2 / Pro / Max / UltraApple8-yesSupported
    M3 / Pro / Max / UltraApple9-yesSupported
    M4 / Pro / MaxApple9-yesSupported
    M5 and laterApple10yesyesSupported

    macOS 14 (Sonoma) or later. NAX (the neural accelerators in M5-generation GPU cores) is used through MLX's NAX kernels on macOS 26.2 or later. An Ultra is treated as two Max dies joined by UltraFusion. Details: docs/hardware-support.md.

    Installation

    Homebrew (builds the CLI, TUI, server and MCP server from source against the pinned MLX):

    brew install epistates/tap/pmetal
    

    Prebuilt binary. Download the pmetal-<version>-aarch64-apple-darwin.tar.gz asset from the Releases page. It holds the pmetal binary and the mlx.metallib it was built with:

    tar xzf pmetal-v0.7.1-aarch64-apple-darwin.tar.gz
    sudo install -m 755 pmetal-v0.7.1-aarch64-apple-darwin /usr/local/bin/pmetal
    pmetal --version
    

    crates.io:

    cargo install pmetal --features serve,mcp
    

    serve and mcp are off by default so library users do not inherit axum and rmcp; leave them out if you only want the training CLI and TUI. Building needs the Xcode command line tools, the Metal toolchain (xcodebuild -downloadComponent MetalToolchain) and CMake (brew install cmake). MLX is linked statically, so the installed binary is self-contained.

    From source:

    git clone https://github.com/epistates/pmetal.git && cd pmetal
    cargo build --release --features serve,mcp   # target/release/pmetal
    

    The repository pins its toolchain in rust-toolchain.toml (rustup installs it on first use); the minimum supported Rust version for library users is 1.95.

    Desktop app: download the DMG from the Releases page, or cd crates/pmetal-gui && bun install && bun tauri build.

    Python: the wheel is built from this repository with maturin (it is not on PyPI yet):

    cd crates/pmetal-py && pip install maturin && maturin develop --profile wheel
    

    More detail, including GUI setup and troubleshooting: docs/installation.md.

    Workspace

    crates/
    ├── pmetal-runtime      # Tensor runtime: arrays, autodiff, native engines, optimizers, custom Metal kernels
    ├── pmetal-core         # Configs, traits, error handling, the job specs every surface shares
    ├── pmetal-core-derive  # Derive macro for the job specs
    ├── pmetal-metal        # Metal context, ANE runtime and kernels
    ├── pmetal-cache        # KV caches, prefix reuse, speculative-decoding state
    ├── pmetal-models       # Model architectures, dispatcher, speculative decoders
    ├── pmetal-lora         # LoRA/QLoRA as a property of Linear
    ├── pmetal-trainer      # Training loops (SFT, preference, GRPO, MTP, ...)
    ├── pmetal-data         # Datasets, chat templates, tokenization, image processing
    ├── pmetal-hub          # Hugging Face Hub client and model fit estimation
    ├── pmetal-distill      # Knowledge distillation (losses, offline caches, TAID)
    ├── pmetal-merge        # Model merging and LoRA fusing
    ├── pmetal-gguf         # GGUF reader, writer and quantization
    ├── pmetal-mhc          # Manifold-Constrained Hyper-Connections
    ├── pmetal-distributed  # Ring all-reduce, mDNS discovery, authenticated transport
    ├── pmetal-vocoder      # BigVGAN neural vocoder
    ├── pmetal-serve        # OpenAI- and Anthropic-compatible server
    ├── pmetal-supervisor   # Runs pmetal commands as supervised child processes
    ├── pmetal-mcp          # MCP server (57 tools)
    ├── pmetal-py           # Python bindings (maturin / PyO3)
    ├── pmetal              # Umbrella crate: the CLI, the TUI and re-exports of the rest
    └── pmetal-gui          # Desktop app (Tauri + Svelte), its own workspace
    

    Cargo features of the umbrella crate (defaults: cli, dashboard, trainer, lora, merge, vocoder, ane, distributed) are listed in docs/configuration/feature-flags.md.

    Documentation

    Development

    just test         # workspace tests, single-threaded for Metal
    just preflight    # everything CI runs
    just kani-verify  # cargo-kani proofs for ring all-reduce and topology
    

    License

    Licensed under either of MIT or Apache-2.0, at your option. Third-party attributions are in THIRD_PARTY_NOTICES.

    Acknowledgments

    • MLX, Apple's array framework, which pmetal-runtime uses as its backend
    • Tauri, the desktop application framework
    • The papers and reference implementations the individual features follow are cited where they are implemented; kernel techniques are attributed in THIRD_PARTY_NOTICES