{"id":47628488,"url":"https://github.com/arahim3/mlx-tune","last_synced_at":"2026-04-01T23:02:46.142Z","repository":{"id":332413921,"uuid":"1127351142","full_name":"ARahim3/mlx-tune","owner":"ARahim3","description":"Fine-tune LLMs on your Mac with Apple Silicon. SFT, DPO, GRPO, and Vision fine-tuning — natively on MLX. Unsloth-compatible API.","archived":false,"fork":false,"pushed_at":"2026-03-22T08:39:28.000Z","size":4070,"stargazers_count":823,"open_issues_count":4,"forks_count":51,"subscribers_count":10,"default_branch":"main","last_synced_at":"2026-03-22T21:34:57.410Z","etag":null,"topics":["apple-silicon","deep-learning","huggingface","large-language-models","llm","llm-finetuning","llm-training","local-llm","lora","machine-learning","macos","metal","mlx","mlx-framework","on-device-ai","peft","transformers","unsloth","vision-language-model"],"latest_commit_sha":null,"homepage":"https://arahim3.github.io/mlx-tune/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ARahim3.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-03T17:48:38.000Z","updated_at":"2026-03-22T18:10:15.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ARahim3/mlx-tune","commit_stats":null,"previous_names":["arahim3/unsloth-mlx","arahim3/mlx-tune"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/ARahim3/mlx-tune","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ARahim3%2Fmlx-tune","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ARahim3%2Fmlx-tune/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ARahim3%2Fmlx-tune/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ARahim3%2Fmlx-tune/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ARahim3","download_url":"https://codeload.github.com/ARahim3/mlx-tune/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ARahim3%2Fmlx-tune/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31292786,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T21:15:39.731Z","status":"ssl_error","status_checked_at":"2026-04-01T21:15:34.046Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apple-silicon","deep-learning","huggingface","large-language-models","llm","llm-finetuning","llm-training","local-llm","lora","machine-learning","macos","metal","mlx","mlx-framework","on-device-ai","peft","transformers","unsloth","vision-language-model"],"created_at":"2026-04-01T23:02:37.354Z","updated_at":"2026-04-01T23:02:46.118Z","avatar_url":"https://github.com/ARahim3.png","language":"Python","readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/ARahim3/mlx-tune/main/mlx-tune-logo.png\" alt=\"MLX-Tune Logo\" width=\"300\"/\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eFine-tune LLMs, Vision, and Audio models on your Mac\u003c/strong\u003e\u003cbr\u003e\n  \u003cem\u003eSFT, DPO, GRPO, Vision, TTS, STT, and Embedding fine-tuning — natively on MLX. Unsloth-compatible API.\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/ARahim3/mlx-tune\"\u003e\u003cimg src=\"https://img.shields.io/github/stars/arahim3/mlx-tune?style=social\" alt=\"GitHub stars\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://pepy.tech/projects/mlx-tune\"\u003e\u003cimg src=\"https://static.pepy.tech/personalized-badge/mlx-tune?period=total\u0026units=INTERNATIONAL_SYSTEM\u0026left_color=GRAY\u0026right_color=GREEN\u0026left_text=downloads\" alt=\"PyPI Downloads\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/ARahim3/mlx-tune\"\u003e\u003cimg alt=\"GitHub forks\" src=\"https://img.shields.io/github/forks/arahim3/mlx-tune\"\u003e\u003c/a\u003e\n  \u003cbr\u003e\n  \u003ca href=\"#installation\"\u003e\u003cimg src=\"https://img.shields.io/badge/Platform-Apple%20Silicon-black?logo=apple\" alt=\"Platform\"\u003e\u003c/a\u003e\n  \u003ca href=\"#requirements\"\u003e\u003cimg src=\"https://img.shields.io/badge/Python-3.9+-blue?logo=python\u0026logoColor=white\" alt=\"Python\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/ml-explore/mlx\"\u003e\u003cimg src=\"https://img.shields.io/badge/MLX-0.20+-green\" alt=\"MLX\"\u003e\u003c/a\u003e\n  \u003ca href=\"#license\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-Apache%202.0-orange\" alt=\"License\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://arahim3.github.io/mlx-tune/\"\u003eDocumentation\u003c/a\u003e ·\n  \u003ca href=\"#quick-start\"\u003eQuick Start\u003c/a\u003e ·\n  \u003ca href=\"#supported-training-methods\"\u003eTraining Methods\u003c/a\u003e ·\n  \u003ca href=\"#examples\"\u003eExamples\u003c/a\u003e ·\n  \u003ca href=\"#project-status\"\u003eStatus\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n\u003e [!NOTE]\n\u003e **Name Change**: This project was originally called `unsloth-mlx`. Since it's not an official Unsloth project and to avoid any confusion, it has been renamed to `mlx-tune`. The vision remains the same — bringing the Unsloth experience to Mac users via MLX. If you were using `unsloth-mlx`, simply switch to `pip install mlx-tune` and update your imports from `unsloth_mlx` to `mlx_tune`.\n\n\u003e [!NOTE]\n\u003e **Why I Built This (A Personal Note)**\n\u003e\n\u003e I rely on Unsloth for my daily fine-tuning on cloud GPUs—it's the gold standard for me. But recently, I started working on a MacBook M4 and hit a friction point: I wanted to prototype locally on my Mac, then scale up to the cloud without rewriting my entire training script.\n\u003e\n\u003e Since Unsloth relies on Triton (which Macs don't have, yet), I couldn't use it locally. I built `mlx-tune` to solve this specific \"Context Switch\" problem. It wraps Apple's native MLX framework in an Unsloth-compatible API.\n\u003e\n\u003e **The goal isn't to replace Unsloth or claim superior performance.** The goal is **code portability**: allowing you to write `FastLanguageModel` code once on your Mac, test it, and then push that *exact same script* to a CUDA cluster. It solves a workflow problem, not just a hardware one.\n\u003e\n\u003e This is an \"unofficial\" project built by a fan, for fans who happen to use Macs. It's helping me personally, and if it helps others like me, then I'll have my satisfaction.\n\n## Why MLX-Tune?\n\nBringing the [Unsloth](https://github.com/unslothai/unsloth) experience to Mac users via Apple's [MLX](https://github.com/ml-explore/mlx) framework.\n\n- 🚀 **Fine-tune LLMs, VLMs, TTS, STT \u0026 Embeddings** locally on your Mac (M1/M2/M3/M4/M5)\n- 💾 **Leverage unified memory** (up to 512GB on Mac Studio)\n- 🔄 **Unsloth-compatible API** - your existing training scripts just work!\n- 📦 **Export anywhere** - HuggingFace format, GGUF for Ollama/llama.cpp\n- 🎙️ **Audio fine-tuning** - 5 TTS models (Orpheus, OuteTTS, Spark, Sesame, Qwen3-TTS) + 5 STT models (Whisper, Moonshine, Qwen3-ASR, NVIDIA Canary, Voxtral)\n\n```python\n# Unsloth (CUDA)                        # MLX-Tune (Apple Silicon)\nfrom unsloth import FastLanguageModel   from mlx_tune import FastLanguageModel\nfrom trl import SFTTrainer              from mlx_tune import SFTTrainer\n\n# Rest of your code stays exactly the same!\n```\n\n## What This Is (and Isn't)\n\n**This is NOT** a replacement for Unsloth or an attempt to compete with it. Unsloth is incredible - it's the gold standard for efficient LLM fine-tuning on CUDA.\n\n**This IS** a bridge for Mac users who want to:\n- 🧪 **Prototype locally** - Experiment with fine-tuning before committing to cloud GPU costs\n- 📚 **Learn \u0026 iterate** - Develop your training pipeline with fast local feedback loops\n- 🔄 **Then scale up** - Move to cloud NVIDIA GPUs + original Unsloth for production training\n\n```\nLocal Mac (MLX-Tune)       →     Cloud GPU (Unsloth)\n   Prototype \u0026 experiment          Full-scale training\n   Small datasets                  Large datasets\n   Quick iterations                Production runs\n```\n\n## Project Status\n\n\u003e 🚀 **v0.4.15** - Microsoft Harrier embedding support; MoE fine-tuning; Embedding fine-tuning; Vision GRPO\n\n| Feature | Status | Notes |\n|---------|--------|-------|\n| SFT Training | ✅ Stable | Native MLX training |\n| Model Loading | ✅ Stable | Any HuggingFace model (quantized \u0026 non-quantized) |\n| Save/Export | ✅ Stable | HF format, GGUF ([see limitations](#known-limitations)) |\n| DPO Training | ✅ Stable | **Full DPO loss** |\n| ORPO Training | ✅ Stable | **Full ORPO loss** |\n| GRPO Training | ✅ Stable | **Multi-generation + reward** |\n| KTO Training | ✅ Stable | **Binary feedback + KTOConfig** |\n| SimPO Training | ✅ Stable | **No ref model + SimPOConfig** |\n| Chat Templates | ✅ Stable | 15 models (llama, gemma, qwen, phi, mistral) |\n| Response-Only Training | ✅ Stable | `train_on_responses_only()` |\n| Multi-turn Merging | ✅ Stable | `to_sharegpt()` + `conversation_extension` |\n| Column Mapping | ✅ Stable | `apply_column_mapping()` auto-rename |\n| Dataset Config | ✅ Stable | `HFDatasetConfig` structured loading |\n| Vision Models | ✅ Stable | Full VLM fine-tuning via mlx-vlm |\n| **MoE Fine-Tuning** | ✅ Stable | **Qwen3.5-35B-A3B, Phi-3.5-MoE, Mixtral, DeepSeek, 39+ architectures** |\n| **TTS Fine-Tuning** | ✅ Stable | **Orpheus, OuteTTS, Spark-TTS, Sesame/CSM, Qwen3-TTS** |\n| **STT Fine-Tuning** | ✅ Stable | **Whisper, Moonshine, Qwen3-ASR, Canary, Voxtral** |\n| **`convert()`** | ✅ Stable | **HF → MLX conversion (LLM, TTS, STT)** |\n| **Embedding Fine-Tuning** | ✅ Stable | **BERT, ModernBERT, Qwen3-Embedding, Harrier (InfoNCE/contrastive)** |\n| **`push_to_hub()`** | ✅ Stable | **Upload to HuggingFace Hub** |\n| PyPI Package | ✅ Available | `uv pip install mlx-tune` |\n\n## Installation\n\n```bash\n# Using uv (recommended - faster and more reliable)\nuv pip install mlx-tune\n\n# With audio support (TTS/STT fine-tuning)\nuv pip install 'mlx-tune[audio]'\nbrew install ffmpeg  # system dependency for audio codecs\n\n# Or using pip\npip install mlx-tune\n\n# From source (for development)\ngit clone https://github.com/ARahim3/mlx-tune.git\ncd mlx-tune\nuv pip install -e .\n```\n\n## Quick Start\n\n```python\nfrom mlx_tune import FastLanguageModel, SFTTrainer, SFTConfig\nfrom datasets import load_dataset\n\n# Load any HuggingFace model (1B model for quick start)\nmodel, tokenizer = FastLanguageModel.from_pretrained(\n    model_name=\"mlx-community/Llama-3.2-1B-Instruct-4bit\",\n    max_seq_length=2048,\n    load_in_4bit=True,\n)\n\n# Add LoRA adapters\nmodel = FastLanguageModel.get_peft_model(\n    model,\n    r=16,\n    target_modules=[\"q_proj\", \"k_proj\", \"v_proj\", \"o_proj\"],\n    lora_alpha=16,\n)\n\n# Load a dataset (or create your own)\ndataset = load_dataset(\"yahma/alpaca-cleaned\", split=\"train[:100]\")\n\n# Train with SFTTrainer (same API as TRL!)\ntrainer = SFTTrainer(\n    model=model,\n    train_dataset=dataset,\n    tokenizer=tokenizer,\n    args=SFTConfig(\n        output_dir=\"outputs\",\n        per_device_train_batch_size=2,\n        learning_rate=2e-4,\n        max_steps=50,\n    ),\n)\ntrainer.train()\n\n# Save (same API as Unsloth!)\nmodel.save_pretrained(\"lora_model\")  # Adapters only\nmodel.save_pretrained_merged(\"merged\", tokenizer)  # Full model\nmodel.save_pretrained_gguf(\"model\", tokenizer)  # GGUF (see note below)\n```\n\n\u003e [!NOTE]\n\u003e **GGUF Export**: Works with non-quantized base models. If using a 4-bit model (like above),\n\u003e see [Known Limitations](#known-limitations) for workarounds.\n\n### Chat Templates \u0026 Response-Only Training\n\n```python\nfrom mlx_tune import get_chat_template, train_on_responses_only\n\n# Apply chat template (supports llama-3, gemma, qwen, phi, mistral, etc.)\ntokenizer = get_chat_template(tokenizer, chat_template=\"llama-3\")\n\n# Or auto-detect from model name\ntokenizer = get_chat_template(tokenizer, chat_template=\"auto\")\n\n# Train only on responses (not prompts) - more efficient!\ntrainer = train_on_responses_only(\n    trainer,\n    instruction_part=\"\u003c|start_header_id|\u003euser\u003c|end_header_id|\u003e\\n\\n\",\n    response_part=\"\u003c|start_header_id|\u003eassistant\u003c|end_header_id|\u003e\\n\\n\",\n)\n```\n\n### Vision Model Fine-Tuning (NEW!)\n\nFine-tune vision-language models like Qwen3.5 on image+text tasks:\n\n```python\nfrom mlx_tune import FastVisionModel, UnslothVisionDataCollator, VLMSFTTrainer\nfrom mlx_tune.vlm import VLMSFTConfig\n\n# Load a vision model\nmodel, processor = FastVisionModel.from_pretrained(\n    \"mlx-community/Qwen3.5-0.8B-bf16\",\n)\n\n# Add LoRA (same params as Unsloth!)\nmodel = FastVisionModel.get_peft_model(\n    model,\n    finetune_vision_layers=True,\n    finetune_language_layers=True,\n    r=16, lora_alpha=16,\n)\n\n# Train on image-text data\nFastVisionModel.for_training(model)\ntrainer = VLMSFTTrainer(\n    model=model,\n    tokenizer=processor,\n    data_collator=UnslothVisionDataCollator(model, processor),\n    train_dataset=dataset,\n    args=VLMSFTConfig(max_steps=30, learning_rate=2e-4),\n)\ntrainer.train()\n```\n\nSee [`examples/10_qwen35_vision_finetuning.py`](examples/10_qwen35_vision_finetuning.py) for the full workflow, [`examples/11_qwen35_text_finetuning.py`](examples/11_qwen35_text_finetuning.py) for text-only fine-tuning, or [`examples/26_vision_grpo_training.py`](examples/26_vision_grpo_training.py) for Vision GRPO reasoning.\n\n### TTS Fine-Tuning\n\nFine-tune text-to-speech models on Apple Silicon. Supports Orpheus-3B, OuteTTS-1B, Spark-TTS (0.5B), Sesame/CSM-1B, and Qwen3-TTS:\n\n```python\nfrom mlx_tune import FastTTSModel, TTSSFTTrainer, TTSSFTConfig, TTSDataCollator\nfrom datasets import load_dataset, Audio\n\n# Auto-detects model type, codec, and token format\nmodel, tokenizer = FastTTSModel.from_pretrained(\"mlx-community/orpheus-3b-0.1-ft-bf16\")\n# Also works with:\n#   \"mlx-community/Llama-OuteTTS-1.0-1B-8bit\"   (DAC codec, 24kHz)\n#   \"mlx-community/Spark-TTS-0.5B-bf16\"          (BiCodec, 16kHz)\nmodel = FastTTSModel.get_peft_model(model, r=16, lora_alpha=16)\n\ndataset = load_dataset(\"MrDragonFox/Elise\", split=\"train[:100]\")\ndataset = dataset.cast_column(\"audio\", Audio(sampling_rate=24000))\n\ntrainer = TTSSFTTrainer(\n    model=model, tokenizer=tokenizer,\n    data_collator=TTSDataCollator(model, tokenizer),\n    train_dataset=dataset,\n    args=TTSSFTConfig(output_dir=\"./tts_output\", max_steps=60),\n)\ntrainer.train()\n```\n\nSee examples: [Orpheus](examples/12_orpheus_tts_finetuning.py), [OuteTTS](examples/14_outetts_finetuning.py), [Spark-TTS](examples/15_spark_tts_finetuning.py), [Qwen3-TTS](examples/20_qwen3_tts_finetuning.py).\n\n### STT Fine-Tuning\n\nFine-tune speech-to-text models. Supports Whisper (all sizes), Distil-Whisper, and Moonshine:\n\n```python\nfrom mlx_tune import FastSTTModel, STTSFTTrainer, STTSFTConfig, STTDataCollator\n\n# Auto-detects model type and preprocessor\nmodel, processor = FastSTTModel.from_pretrained(\"mlx-community/whisper-tiny-asr-fp16\")\n# Also works with:\n#   \"mlx-community/distil-whisper-large-v3\"   (Whisper architecture)\n#   \"UsefulSensors/moonshine-tiny\"             (raw conv frontend)\nmodel = FastSTTModel.get_peft_model(model, r=8, finetune_encoder=True, finetune_decoder=True)\n\ntrainer = STTSFTTrainer(\n    model=model, processor=processor,\n    data_collator=STTDataCollator(model, processor, language=\"en\", task=\"transcribe\"),\n    train_dataset=dataset,\n    args=STTSFTConfig(output_dir=\"./stt_output\", max_steps=60),\n)\ntrainer.train()\n```\n\nSee examples: [Whisper](examples/13_whisper_stt_finetuning.py), [Moonshine](examples/16_moonshine_stt_finetuning.py), [Qwen3-ASR](examples/17_qwen3_asr_finetuning.py), [Canary](examples/18_canary_stt_finetuning.py), [Voxtral](examples/19_voxtral_stt_finetuning.py).\n\n### Embedding Fine-Tuning\n\nFine-tune sentence embedding models for semantic search using contrastive learning (InfoNCE loss). Supports BERT, ModernBERT, Qwen3-Embedding, Harrier, and more:\n\n```python\nfrom mlx_tune import FastEmbeddingModel, EmbeddingSFTTrainer, EmbeddingSFTConfig, EmbeddingDataCollator\n\n# Load embedding model (BERT or Qwen3-Embedding)\nmodel, tokenizer = FastEmbeddingModel.from_pretrained(\n    \"mlx-community/all-MiniLM-L6-v2-bf16\",  # or Qwen3-Embedding-0.6B-4bit-DWQ\n    pooling_strategy=\"mean\",                  # \"mean\", \"cls\", or \"last_token\"\n)\nmodel = FastEmbeddingModel.get_peft_model(model, r=16, lora_alpha=16)\n\n# Train with anchor-positive pairs (in-batch negatives via InfoNCE)\ntrainer = EmbeddingSFTTrainer(\n    model=model, tokenizer=tokenizer,\n    data_collator=EmbeddingDataCollator(model, tokenizer),\n    train_dataset=[{\"anchor\": \"query text\", \"positive\": \"relevant passage\"}, ...],\n    args=EmbeddingSFTConfig(\n        loss_type=\"infonce\", temperature=0.05,\n        per_device_train_batch_size=32, max_steps=50,\n    ),\n)\ntrainer.train()\n\n# Encode \u0026 compare\nembeddings = model.encode([\"Hello world\", \"Hi there\"])\nsimilarity = (embeddings[0] * embeddings[1]).sum().item()\n```\n\nSee examples: [BERT](examples/27_embedding_finetuning.py), [Qwen3-Embedding](examples/28_qwen3_embedding_finetuning.py), [Harrier-0.6B](examples/31_harrier_0.6b_embedding_finetuning.py), [Harrier-270M](examples/32_harrier_270m_embedding_finetuning.py).\n\n### MoE Fine-Tuning\n\nFine-tune Mixture of Experts models — 39+ architectures supported automatically. MLX-Tune detects MoE layers and applies per-expert LoRA via `LoRASwitchLinear`:\n\n```python\nfrom mlx_tune import FastLanguageModel, SFTTrainer, SFTConfig\n\n# Load any MoE model — same API as dense models!\nmodel, tokenizer = FastLanguageModel.from_pretrained(\n    model_name=\"mlx-community/Qwen3.5-35B-A3B-4bit\",  # 35B total, 3B active\n    max_seq_length=2048,\n    load_in_4bit=True,\n)\n\n# Same target_modules — MoE paths resolved automatically\nmodel = FastLanguageModel.get_peft_model(\n    model, r=8,\n    target_modules=[\"q_proj\", \"k_proj\", \"v_proj\", \"o_proj\",\n                    \"gate_proj\", \"up_proj\", \"down_proj\"],\n)\n# Prints: \"MoE architecture detected — LoRA will target expert layers (SwitchLinear)\"\n```\n\n**Supported MoE models**: Qwen3.5-35B-A3B, Qwen3-30B-A3B, Phi-3.5-MoE, Mixtral, DeepSeek-V2/V3, GLM-MoE, and all other MoE architectures in mlx-lm.\n\nSee examples: [Qwen3.5 MoE](examples/29_qwen35_moe_finetuning.py), [Phi-3.5 MoE](examples/30_phi35_moe_finetuning.py).\n\n### Post-Training Workflow\n\nAll model types (LLM, VLM, TTS, STT) support the full post-training workflow:\n\n```python\n# Save LoRA adapters\nmodel.save_pretrained(\"./adapters\")\n\n# Merge LoRA into base model\nmodel.save_pretrained_merged(\"./merged\")\n\n# Convert HF model to MLX format\nFastLanguageModel.convert(\"model-name\", mlx_path=\"./mlx_model\")\n\n# Push to HuggingFace Hub\nmodel.push_to_hub(\"username/my-model\")\n```\n\n## Supported Training Methods\n\n| Method | Trainer | Implementation | Use Case |\n|--------|---------|----------------|----------|\n| **SFT** | `SFTTrainer` | ✅ Native MLX | Instruction fine-tuning |\n| **DPO** | `DPOTrainer` | ✅ Native MLX | Preference learning (proper log-prob loss) |\n| **ORPO** | `ORPOTrainer` | ✅ Native MLX | Combined SFT + odds ratio preference |\n| **GRPO** | `GRPOTrainer` | ✅ Native MLX | Reasoning with multi-generation (DeepSeek R1 style) |\n| **KTO** | `KTOTrainer` | ✅ Native MLX | Kahneman-Tversky optimization |\n| **SimPO** | `SimPOTrainer` | ✅ Native MLX | Simple preference optimization |\n| **VLM SFT** | `VLMSFTTrainer` | ✅ Native MLX | Vision-Language model fine-tuning |\n| **Vision GRPO** | `VLMGRPOTrainer` | ✅ Native MLX | Vision-Language GRPO reasoning |\n| **TTS SFT** | `TTSSFTTrainer` | ✅ Native MLX | Orpheus, OuteTTS, Spark-TTS, Sesame/CSM |\n| **STT SFT** | `STTSFTTrainer` | ✅ Native MLX | Whisper, Moonshine, Qwen3-ASR, Canary, Voxtral |\n| **Embedding** | `EmbeddingSFTTrainer` | ✅ Native MLX | BERT, ModernBERT, Qwen3-Embedding, Harrier (InfoNCE) |\n| **MoE** | `SFTTrainer` | ✅ Native MLX | Qwen3.5-MoE, Phi-3.5-MoE, Mixtral, DeepSeek (39+ archs) |\n\n## Examples\n\nCheck [`examples/`](examples/) for working code:\n- Basic model loading and inference (01–07)\n- Complete SFT fine-tuning pipeline (08)\n- RL training overview (09)\n- Vision model fine-tuning — Qwen3.5 (10-11)\n- **RL E2E training** — DPO (21), GRPO (22), ORPO (23), KTO (24), SimPO (25), Vision GRPO (26)\n- TTS fine-tuning — Orpheus-3B (12), OuteTTS (14), Spark-TTS (15), Qwen3-TTS (20)\n- STT fine-tuning — Whisper (13), Moonshine (16), Qwen3-ASR (17), Canary (18), Voxtral (19)\n- Embedding fine-tuning — BERT/MiniLM (27), Qwen3-Embedding (28), Harrier-0.6B (31), Harrier-270M (32)\n- **MoE fine-tuning** — Qwen3.5-35B-A3B (29), Phi-3.5-MoE (30)\n\n## Requirements\n\n- **Hardware**: Apple Silicon Mac (M1/M2/M3/M4/M5)\n- **OS**: macOS 13.0+\n- **Memory**: 8GB+ unified RAM (16GB+ recommended)\n- **Python**: 3.9+\n\n## Comparison with Unsloth\n\n| Feature | Unsloth (CUDA) | MLX-Tune |\n|---------|----------------|----------|\n| Platform | NVIDIA GPUs | Apple Silicon |\n| Backend | Triton Kernels | MLX Framework |\n| Memory | VRAM (limited) | Unified (up to 512GB) |\n| API | Original | 100% Compatible |\n| Best For | Production training | Local dev, large models |\n\n## Known Limitations\n\n### GGUF Export from Quantized Models\n\n**The Issue**: GGUF export (`save_pretrained_gguf`) doesn't work directly with quantized (4-bit) base models. This is a [known limitation in mlx-lm](https://github.com/ml-explore/mlx-lm/issues/353), not an mlx-tune bug.\n\n**What Works**:\n- ✅ Training with quantized models (QLoRA) - works perfectly\n- ✅ Saving adapters (`save_pretrained`) - works\n- ✅ Saving merged model (`save_pretrained_merged`) - works\n- ✅ Inference with trained model - works\n- ❌ GGUF export from quantized base model - mlx-lm limitation\n\n**Workarounds**:\n\n1. **Use a non-quantized base model** (recommended for GGUF export):\n   ```python\n   # Use fp16 model instead of 4-bit\n   model, tokenizer = FastLanguageModel.from_pretrained(\n       model_name=\"mlx-community/Llama-3.2-1B-Instruct\",  # NOT -4bit\n       max_seq_length=2048,\n       load_in_4bit=False,  # Train in fp16\n   )\n   # Train normally, then export\n   model.save_pretrained_gguf(\"model\", tokenizer)  # Works!\n   ```\n\n2. **Dequantize during export** (results in large fp16 file):\n   ```python\n   model.save_pretrained_gguf(\"model\", tokenizer, dequantize=True)\n   # Then re-quantize with llama.cpp:\n   # ./llama-quantize model.gguf model-q4_k_m.gguf Q4_K_M\n   ```\n\n3. **Skip GGUF, use MLX format**: If you only need the model for MLX/Python inference, just use `save_pretrained_merged()` - no GGUF needed.\n\n**Related Issues**:\n- [mlx-lm #353](https://github.com/ml-explore/mlx-lm/issues/353) - MLX to GGUF conversion\n- [mlx-examples #1382](https://github.com/ml-explore/mlx-examples/issues/1382) - Quantized to GGUF\n\n## Contributing\n\nContributions welcome! Areas that need help:\n- Custom MLX kernels for even faster training\n- More test coverage (especially E2E and edge cases)\n- Testing on different M-series chips (M1, M2, M3, M4, M5)\n- Batched audio training (currently batch_size=1)\n- Batched RL training (currently single-sample)\n\n## License\n\nApache 2.0 - See [LICENSE](LICENSE) file.\n\n## Acknowledgments\n\n- [Unsloth](https://github.com/unslothai/unsloth) - The original, incredible CUDA library\n- [MLX](https://github.com/ml-explore/mlx) - Apple's ML framework\n- [MLX-LM](https://github.com/ml-explore/mlx-lm) - LLM utilities for MLX\n- [MLX-VLM](https://github.com/Blaizzy/mlx-vlm) - Vision model support\n- [MLX-Audio](https://github.com/Blaizzy/mlx-audio) - Audio inference (TTS/STT) for MLX\n- [MLX-Embeddings](https://github.com/Blaizzy/mlx-embeddings) - Embedding models for MLX\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eCommunity project, not affiliated with Unsloth AI or Apple.\u003c/strong\u003e\u003cbr\u003e\n  ⭐ Star this repo if you find it useful!\n\u003c/p\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farahim3%2Fmlx-tune","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farahim3%2Fmlx-tune","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farahim3%2Fmlx-tune/lists"}