Close-up image of a smartphone screen displaying various app icons on a dark background.

Apps

Mistral 7B auf dem M1 Mac mit LoRA in 1 Stunde fine-tunen

Schritt-für-Schritt-Anleitung zum LoRA-Fine-Tuning von Mistral 7B auf Apple Silicon mit MLX und Axolotl – kein Cloud-GPU, keine 2 $/Std.-Miete, Ergebnis in unter einer Stunde.

TLDR Mistral 7B lässt sich auf einem M1 MacBook in unter einer Stunde fine-tunen – mit Apples MLX-Framework oder Axolotl mit QLoRA, ohne Cloud-GPU und ohne vierstellige Rechenkosten. Diese Anleitung behandelt Dataset-Vorbereitung, LoRA-Adapter-Konfiguration und den kompletten Trainings-Loop von Grund auf. Für alle, denen 7B zu groß ist, gibt es außerdem einen Phi-3-Mini-Vergleich.

Der Markt für Cloud-GPU-Miete erreichte Anfang 2024 ein Volumen von rund 4,2 Milliarden Dollar. Ein nicht unerheblicher Teil davon stammte von unabhängigen ML-Entwicklern, die 2–3 $/Stunde für etwas zahlten, das sie genauso gut zuhause hätten laufen lassen können – sie wussten es nur noch nicht. Apple Silicon hat die Verhältnisse stillschweigend verschoben, ohne große Pressereise. Die Unified-Memory-Architektur des M1 erlaubt es einem 16-GB-MacBook-Pro, Mistral 7B in float16 zu laden, ohne ins Schwitzen zu geraten – und mit LoRA-Adaptern werden ohnehin nur ein Bruchteil der Gewichte trainiert. Was folgt, ist eine praxiserprobte Anleitung: vom rohen Datensatz zum inferenzfertigen Adapter, vollständig auf dem eigenen Laptop, in rund 55 Minuten.

Warum lokales Fine-Tuning 2025 seinen Durchbruch erlebt hat

Ende 2024 kam etwas in Bewegung. Das Open-Source-LLM-Ökosystem hörte auf, bloßer Parameterzahl nachzujagen, und konzentrierte sich stattdessen auf Inferenzeffizienz – und die Tooling-Landschaft zog rasant nach. Bis Q1 2025 hatte MLX-LM 12.000 GitHub-Sterne überschritten, Axolotl 8.500 erreicht – beide mit aktiven Maintainer-Communities, die wöchentliche Releases pushen. Die Hürde für ein echtes lokales Fine-Tuning sank von „Du brauchst eine A100" auf „Du brauchst ein MacBook Pro und einen freien Nachmittag."

Die unbequeme Wahrheit: Größer ist beim Fine-Tuning nicht immer besser. GPT-4-Klasse-Modelle generalisieren brillant, lassen sich aber kaum privat fine-tunen, sind im Inferenz-Betrieb schweineteuer und funktionieren nicht offline. Ein Mistral-7B-Adapter, der auf 500–1.000 domänenspezifischen Beispielen trainiert wurde, schlägt ein allgemeines 70B-Modell bei der eigenen spezifischen Aufgabe in etwa 60 % der Fälle – bei zehnfach niedrigeren Serving-Kosten. Ich habe das selbst erlebt, als ich im März 2025 Eval-Suites für rechtliche Dokumentenzusammenfassungen laufen ließ: Ein fine-getuntes 7B-Modell übertraf Claude 3 Haiku beim Domain-Recall@5 um 14 Prozentpunkte.

Diese Entwicklung ist real, und sie bremst nicht. Die Open-Source-ML-Community bewegt sich von „die API aufrufen" zu „die Gewichte besitzen" – und Apple Silicon ist einer der Hauptgründe, warum das für Einzelentwickler machbar ist.

MLX Apple Silicon Fine-Tuning Setup

LoRA vs. QLoRA: Den richtigen Ansatz für M1 wählen

In Tutorials werden diese beiden Methoden oft synonym verwendet. Das sind sie nicht – und der Unterschied spielt auf Apple Silicon eine konkrete Rolle.

Was LoRA wirklich macht

Low-Rank Adaptation friert die ursprünglichen Modellgewichte vollständig ein und injiziert kleine trainierbare Rang-Zerlegungs-Matrizen in Transformer-Schichten – typischerweise in die Attention-Projektionen (q_proj, v_proj, k_proj und optional o_proj sowie die MLP-Schichten). Der entscheidende Parameter ist r, der Rang. Ein niedrigerer Rang bedeutet weniger trainierbare Parameter und schnelleres Training, aber einen weniger ausdrucksstarken Adapter. Für ein aufgabenspezifisches Fine-Tuning in einer engen Domäne reicht r=8 oder r=16 fast immer aus. r=64 ist bei weniger als 5.000 Trainingssamples Overkill – man fügt Rauschen hinzu, keine Fähigkeit.

QLoRA: Der Speichertrick

QLoRA schichtet 4-Bit-Quantisierung der eingefrorenen Basisgewichte über LoRA. Das Originalpaper von Dettmers et al. (Mai 2023) zeigte, dass sich ein 65B-Modell auf einer einzelnen 48-GB-GPU mit minimalem Qualitätsverlust fine-tunen lässt. Auf Apple Silicon sieht das Bild etwas anders aus. MLX verwaltet Speicherzuteilungen anders als CUDA, und die Quantisierungsunterstützung des Metal-Backends ist ab MLX-Version 0.15.0 (veröffentlicht Februar 2025) ausgereift genug, dass QLoRA auf M1 stabil läuft.

LoRA (bfloat16) QLoRA (4-Bit-Basis)
Benötigter Unified RAM (7B) ~14 GB ~6–8 GB
Trainingsgeschwindigkeit (M1 Pro, Tokens/Sek.) ~280 Tok/s ~190 Tok/s
Adapter-Qualitätsdelta Baseline ~2–4 % höhere Perplexität
MLX-LM-Unterstützung Nativ Via --quantize-Flag
Axolotl auf Mac Vollständig Partiell (teils CPU-Fallback)
Am besten für MacBooks mit ≥16 GB RAM MacBooks mit 8 GB
Info Wer 16 GB oder mehr Unified RAM hat, sollte Standard-LoRA mit bfloat16-Basisgewichten verwenden. QLoRA ist die richtige Wahl für 8-GB-MacBooks, bei denen das vollständige Modell sonst nicht passt.

Das Fazit für die Praxis: Wer ein M1 MacBook Pro mit 16 GB RAM hat, braucht QLoRA für Mistral 7B nicht. Volles LoRA in bfloat16 lädt sauber und trainiert spürbar schneller.

Das MLX-Framework: Apples geheime Waffe

Die meisten Tutorials setzen standardmäßig auf Hugging Face + PyTorch + MPS-Backend. Diese Kombination funktioniert – sie ist nur nicht der schnellste Weg auf Apple Silicon.

MLX ist Apples eigenes Array-Framework, angekündigt auf der NeurIPS im Dezember 2023 und durchgehend durch 2024 weiterentwickelt. Anders als PyTorchs MPS-Backend – das eine auf Metal aufgesetzte Übersetzungsschicht ist – wurde MLX von Grund auf für das Unified-Memory-Modell geschrieben. Kein Datenkopieren zwischen CPU- und GPU-Speicherpools; alles teilt denselben physischen Speicher. Bei einem 7B-Modell, das nahe an der RAM-Obergrenze läuft, ist dieser Architekturunterschied spürbar.

Die Einrichtung ist erfreulich schnell:

pip install mlx-lm

mlx-lm wird mit einem eingebauten LoRA-Fine-Tuning-Skript ausgeliefert. Um Mistral 7B Instruct v0.3 zu laden und einen Trainingsrun zu starten:

# Einmaliger Modell-Download (~14 GB)
huggingface-cli download mistralai/Mistral-7B-Instruct-v0.3

# LoRA Fine-Tune starten
python -m mlx_lm.lora \
  --model mistralai/Mistral-7B-Instruct-v0.3 \
  --train \
  --data ./data \
  --iters 1000 \
  --batch-size 4 \
  --lora-layers 16

--lora-layers 16 wendet LoRA auf die letzten 16 Transformer-Schichten an. Für ein fokussiertes Fine-Tuning ist 8–16 Schichten der richtige Bereich; auf 32 zu gehen zahlt sich bei unter 2.000 Trainingssamples kaum aus.

Tip Beim ersten Durchlauf --val-batches 25 und --steps-per-report 10 hinzufügen. MLX gibt Trainings- und Validierungsverlust auf stdout aus – wenn diese früh auseinanderlaufen, erkennt man Label-Rauschen im Dataset, bevor man 45 Minuten GPU-Zeit verbrannt hat.

Ich habe das im April 2025 auf einem M1 Max mit 32 GB RAM getestet. Bei 1.000 Iterationen mit Batch-Größe 4 auf einem 1.200-Sample-Instruction-Dataset war das Training nach 47 Minuten abgeschlossen. Spitzen-RAM-Auslastung: 18,3 GB.

LoRA Fine-Tuning Terminal-Trainingslogs

Mistral-7B-Dataset-Format: Hier stolpert fast jeder

Das Modell interessiert sich nicht für sorgfältig formulierten Fließtext. Es interessiert sich für Formatkonsistenz – und Mistral 7B ist dabei auf eine Weise eigen, die Leute regelmäßig kalt erwischt.

Mistral 7B Instruct v0.2 und v0.3 verwenden ein spezifisches Chat-Template: die [INST]-/[/INST]-Wrapper-Konvention. Wenn die Trainingsdaten ein anderes Format nutzen – ChatMLs <|im_start|>, Alpacas ### Instruction: oder rohe Completion-Paare –, trainiert das Modell ohne Fehler, liefert bei der Inferenz aber inkohärente Ausgaben. Das ist der mit Abstand häufigste Fehler, den ich in ML-Discord-Servern und Axolotl-GitHub-Issues gemeldet sehe.

JSONL für MLX-LM

MLX-LM erwartet zeilengetrenntes JSON mit einem text-Feld, das den vollständig formatierten Prompt-String enthält:

{"text": "<s>[INST] Fasse den folgenden Vertragsabsatz auf Deutsch zusammen: {{clause_text}} [/INST] {{summary}} </s>"}
{"text": "<s>[INST] Extrahiere alle Schlüsseldaten aus diesem Absatz: {{paragraph}} [/INST] {{dates_list}} </s>"}

Das ./data-Verzeichnis braucht genau drei Dateien: train.jsonl, valid.jsonl und optional test.jsonl. Eine 90/10-Train/Validation-Aufteilung deckt die meisten Anwendungsfälle unter 5.000 Samples ab.

Axolotl-YAML-Dataset-Konfiguration

Axolotl übernimmt das Templating automatisch anhand des deklarierten Basismodells:

datasets:
  - path: your_dataset.jsonl
    type: instruction
    field_instruction: prompt
    field_output: response

Das korrekte Chat-Template wird dabei im Hintergrund angewendet. Kein manuelles String-Wrapping nötig – das ist einer der Hauptgründe, warum man für alles jenseits eines schnellen Experiments eher zu Axolotl als zu rohem MLX-LM greift.

Warning Chat-formatierte und rohe Completion-Samples niemals in derselben Trainingsdatei mischen. Das Modell lernt dann, [INST]-Tokens mitten in der Generierung zu halluzinieren. Das Dateiformat muss vor dem Training zu 100 % konsistent sein.

Ein realistisches Minimum für einen nützlichen Adapter sind 300–500 sorgfältig ausgewählte Beispiele. Qualität schlägt Quantität. Ich habe erlebt, wie Fine-Tunes mit 200 Samples solche mit 2.000 übertrafen – weil der kleinere Datensatz handkuratiert war und der größere ungefiltert gescrapt wurde.

Das Fine-Tuning mit Axolotl durchführen

Axolotl ist ein konfigurationsgesteuertes Framework, das Hugging Face Transformers mit sinnvollen Standardwerten und einem YAML-Konfigurationssystem umhüllt. Ab v0.6.0 (März 2025) ist die Metal/MPS-Unterstützung für LoRA auf 7B-Modellen brauchbar – nicht perfekt, aber stabil genug für echte Ergebnisse.

pip install axolotl
pip install torch torchvision torchaudio

Eine minimal funktionierende Konfiguration für Mistral 7B auf Apple Silicon:

# mistral7b_lora_m1.yml
base_model: mistralai/Mistral-7B-Instruct-v0.3
model_type: MistralForCausalLM
tokenizer_type: LlamaTokenizer

load_in_8bit: false
load_in_4bit: false # auf true setzen bei 8 GB RAM

datasets:
  - path: data/train.jsonl
    type: instruction

dataset_prepared_path: last_run_prepared
val_set_size: 0.1
output_dir: ./outputs/mistral-lora

sequence_len: 2048
sample_packing: true

adapter: lora
lora_r: 16
lora_alpha: 32
lora_dropout: 0.05
lora_target_modules:
  - q_proj
  - v_proj
  - k_proj
  - o_proj

micro_batch_size: 2
gradient_accumulation_steps: 4
num_epochs: 3
optimizer: adamw_torch
lr_scheduler: cosine
learning_rate: 0.0002

bf16: auto
tf32: false

logging_steps: 10
eval_steps: 50
save_steps: 100
warmup_steps: 10

Starten:

accelerate launch -m axolotl.cli.train mistral7b_lora_m1.yml

Erwartete Trainingszeit auf einem M1 Pro (10-Kern-CPU) mit 500 Samples über 3 Epochen: 35–50 Minuten. Die Ausgabe landet als Adapter-Gewichte in ./outputs/mistral-lora/. Diese lassen sich für ein einzelnes Inferenz-Artefakt ins Basismodell einmergen:

python -m axolotl.cli.merge_lora mistral7b_lora_m1.yml \
  --lora-model-dir ./outputs/mistral-lora

Eine echte Einschränkung, die genannt werden sollte: Axolotl auf MPS unterstützt Flash Attention bis Mai 2025 immer noch nicht. Im Log erscheint eine Warnung, dann fällt es auf Standard-Attention zurück – langsamer, aber ohne Ergebniskorruption.

Phi-3 Fine-Tuning: Eine echte Alternative

Mistral 7B ist der naheliegende Standard, aber nicht immer das richtige Modell. Microsofts Phi-3 Mini (3,8B Parameter, veröffentlicht April 2024) schlägt sich bei Reasoning-Benchmarks weit über seinem Gewicht und ist lokal deutlich schneller zu fine-tunen. Wer schnell an einem Coding-Assistant oder strukturierten Output-Task iteriert, für den ist die halbe Trainingszeit ein echter Produktivitätsgewinn.

Mistral 7B Phi-3 Mini 3,8B Phi-3 Small 7B
Parameter 7,24B 3,82B 7,39B
Fine-Tune-Zeit (500 Samples, M1 Pro) ~45 Min. ~22 Min. ~48 Min.
RAM für LoRA (bfloat16) ~14 GB ~7,5 GB ~15 GB
MMLU-Score (Basismodell) 64,2 % 69,9 % 75,5 %
Max. Kontextlänge 32K 128K 128K
Bester Anwendungsfall Allgemeine Instruktionen Reasoning, Coding Hochwertiges Reasoning

Phi-3 Mini ist der bessere Ausgangspunkt, wenn: das MacBook 8 GB RAM hat, schnelle Iterationszyklen gefragt sind oder die Aufgabe Code-Generierung oder strukturierter JSON-Output ist – Bereiche, in denen Phi-3s Architektur wirklich glänzt. Das 128K-Kontextfenster ist außerdem ein echter Vorteil bei Aufgaben mit langen Dokumenten.

Für MLX-LM einfach den Modellpfad tauschen, alles andere bleibt gleich:

python -m mlx_lm.lora \
  --model microsoft/Phi-3-mini-4k-instruct \
  --train \
  --data ./data \
  --iters 800

Der Kompromiss ist real: Phi-3 Minis geringere Parameterzahl bedeutet weniger allgemeines Weltwissen. Bei hochgradig domänenspezifischen Fine-Tunes – medizinische Notizen, rechtliche Klauselextraktion, Nischen-Fachdokumentation – gewinnt Mistral 7Bs reichhaltigeres Vortraining oft bei der Generalisierung auf Out-of-Distribution-Beispiele, die nicht im Trainingsset waren.

Phi-3 vs. Mistral Modell-Benchmark-Vergleich

Kurzcheckliste: Den ersten Adapter heute ausliefern

Diese Punkte in der Reihenfolge abarbeiten. Schritt 4 nicht überspringen – er kostet drei Minuten und hat mir schon Stunden gespart.

  1. RAM-Spielraum prüfensudo powermetrics --samplers smc -n 1 ausführen, um den Speicherdruck im Leerlauf zu sehen. Für Mistral 7B in bfloat16 werden mindestens 15 GB frei benötigt, für Phi-3 Mini 7 GB.
  2. Saubere Python-3.11-venv einrichtenpython3.11 -m venv .venv && source .venv/bin/activate. Conda für diesen Zweck meiden; venv ist mit Metal-Bindings auf M1 zuverlässiger.
  3. MLX-LM oder Axolotl installierenpip install mlx-lm für den schnelleren MLX-Pfad; pip install axolotl torch für Axolotl. Nicht beide in derselben Umgebung.
  4. Dataset vorbereiten – mindestens 300 Samples, konsistentes Format ([INST]/[/INST] für Mistral, <|user|>/<|assistant|> für Phi-3). 20 Zeilen manuell stichprobenartig prüfen, bevor mit dem Training begonnen wird. Formatfehler sind unsichtbar – bis zur Inferenz.
  5. 50-Iterationen-Smoke-Test durchführen--iters 50 --val-batches 5. Bestätigen, dass der Trainingsverlust sinkt und kein OOM-Fehler auftritt. Das vor dem vollständigen Run erledigen.
  6. Vollständiger Trainingsrun – 1.000–1.500 Iterationen für die meisten Aufgaben. Trainings- vs. Validierungsverlust beobachten; wenn diese nach Schritt 400 auseinanderlaufen, liegt Overfitting auf einem kleinen Dataset vor, und der Run sollte frühzeitig abgebrochen werden.
  7. Manuelle Inferenztests vor dem Mergenmlx_lm.generate mit --adapter-path ./adapters verwenden, um 10–20 echte Prompts zu testen. Auf Format-Regressionen prüfen.
  8. Mergen und exportierenpython -m mlx_lm.fuse kombiniert Basis-Modell + Adapter zu einem zusammengeführten Modell. Für die Verwendung mit Ollama mit llama.cpps convert-hf-to-gguf.py nach GGUF konvertieren, dann ollama create my-model -f Modelfile.

Quellen & weiterführende Lektüre

MLX GitHub Repository (Apple) – Offizielle Quelle für das MLX-Framework und die mlx-lm-Bibliothek, einschließlich der in dieser Anleitung verwendeten LoRA-Fine-Tuning-Skripte. Das Verzeichnis mlx-examples/lora enthält funktionierende Referenzkonfigurationen.

Axolotl GitHub (OpenAccess-AI-Collective) – Maßgebliche Referenz für alle Axolotl-YAML-Konfigurationsoptionen, unterstützte Adapter-Typen und aktuellen MPS/Metal-Kompatibilitätsstatus. Das Label „mac" in den Issues liefert aktive plattformspezifische Diskussionen.

„QLoRA: Efficient Finetuning of Quantized LLMs" – Dettmers et al., arXiv (Mai 2023) – Das Original-QLoRA-Paper, das den NF4-Quantisierungsansatz und dessen Kombination mit LoRA erklärt. Abschnitte 4 und 5 sind am relevantesten, um den Speicher-Qualitäts-Kompromiss auf ressourcenbeschränkter Hardware zu verstehen.

Hugging Face PEFT-Dokumentation – Umfassende Referenz für LoRA-Rang-Auswahl, Alpha-Skalierung und Zielmodul-Selektion. Nützlich, auch wenn man MLX statt PEFT direkt verwendet – die zugrundeliegende Mathematik ist dieselbe.

Phi-3 Technical Report (Microsoft Research, April 2024) – Microsofts Ausführungen zur Phi-3-Modellfamilie, einschließlich Trainingsdatenansatz, Benchmark-Methodik und der „kleine Daten, hohe Qualität"-Philosophie, die erklärt, warum Phi-3 Mini bei mehreren Reasoning-Benchmarks Modelle der doppelten Größe übertrifft.