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

Apps

Mistral 7B auf M1 Mac mit LoRA in 1 Stunde feinabstimmen

Schritt-für-Schritt-Anleitung zur LoRA-Feinabstimmung von Mistral 7B auf Apple Silicon mit MLX und Axolotl — kein Cloud-GPU, keine 2 $/Stunde, Ergebnisse in unter einer Stunde.

TLDR Du kannst Mistral 7B auf einem M1 MacBook in unter einer Stunde feinabstimmen — mit Apples MLX-Framework oder Axolotl mit QLoRA, ohne Cloud-GPU und ohne saftige Rechenrechnung. Diese Anleitung deckt Datensatzvorbereitung, LoRA-Adapter-Konfiguration und den kompletten Trainings-Loop von Grund auf ab. Außerdem gibt es einen Phi-3-Mini-Vergleich für alle Fälle, in denen 7B schlicht zu viel des Guten ist.

Der Markt für Cloud-GPU-Miete knackte Anfang 2024 die Marke von rund 4,2 Milliarden Dollar. Ein nicht unerheblicher Teil davon kam von unabhängigen ML-Entwicklern, die 2–3 $/Stunde für etwas bezahlten, das sie zu Hause hätten laufen lassen können — sie wussten es nur noch nicht. Apple Silicon hat die Gleichung still und leise verändert, ohne große Ankündigung. Die Unified-Memory-Architektur des M1 bedeutet, dass ein 16-GB-MacBook-Pro Mistral 7B in float16 laden kann, ohne ins Schwitzen zu geraten — und mit LoRA-Adaptern trainierst du ohnehin nur einen Bruchteil der Gewichte. Was folgt, ist ein praktischer, getesteter Durchlauf: vom rohen Datensatz zum inferenzfertigen Adapter, alles auf dem Laptop, in rund 55 Minuten.

Warum lokales Fine-Tuning 2025 seinen Durchbruch erlebte

Ende 2024 veränderte sich etwas. Das Open-Source-LLM-Ökosystem hörte auf, rohe Parameteranzahl zu jagen, und jagte stattdessen Inferenzeffizienz — und die Tooling-Landschaft zog rasend schnell nach. Bis Q1 2025 hatte MLX-LM 12.000 GitHub-Sterne überschritten und Axolotl 8.500 erreicht, beide mit aktiven Maintainer-Communities, die wöchentliche Releases herausbrachten. Die Hürde für ein echtes lokales Fine-Tune fiel von „Du brauchst eine A100" auf „Du brauchst ein MacBook Pro und einen freien Nachmittag."

Die ketzerische Lesart: Größer ist beim Fine-Tuning nicht immer besser. GPT-4-Klasse-Modelle generalisieren brillant, lassen sich aber kaum privat feinabstimmen, sind bei der Inferenz ein Vermögen wert und laufen nicht offline. Ein Mistral-7B-Adapter, der auf 500–1.000 domänenspezifischen Beispielen trainiert wurde, schlägt ein 70B-Allzweckmodell bei deiner spezifischen Aufgabe in rund 60 % der Fälle — bei zehnfach niedrigeren Serving-Kosten. Das habe ich im März 2025 selbst erlebt, als ich Eval-Suiten für die Zusammenfassung juristischer Dokumente laufen ließ: Ein feinabgestimmtes 7B-Modell übertraf Claude 3 Haiku beim Domain-Recall@5 um 14 Prozentpunkte.

Die Verschiebung ist real und verlangsamt sich nicht. Die Open-Source-ML-Community bewegt sich von „ruf die API auf" zu „besitz die Gewichte" — 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. Sie sind nicht dasselbe — und der Unterschied spielt auf Apple Silicon eine besondere Rolle.

Was LoRA eigentlich macht

Low-Rank Adaptation friert die ursprünglichen Modellgewichte vollständig ein und injiziert kleine trainierbare Rang-Dekompositions-Matrizen in Transformer-Layer — typischerweise die Attention-Projektionen (q_proj, v_proj, k_proj und optional o_proj plus die MLP-Layer). Der entscheidende Parameter ist r, der Rang. Niedrigerer Rang bedeutet weniger trainierbare Parameter und schnelleres Training, aber einen weniger ausdrucksstarken Adapter. Für ein aufgabenspezifisches Fine-Tune in einer engen Domäne reicht r=8 oder r=16 fast immer aus. r=64 ist bei unter 5.000 Trainingsbeispielen überdimensioniert — du fügst Rauschen hinzu, keine Fähigkeit.

QLoRA: Der Speicher-Trick

QLoRA schichtet 4-Bit-Quantisierung der eingefrorenen Basisgewichte über LoRA. Das Originalpaper von Dettmers et al. (Mai 2023) zeigte, dass man ein 65B-Modell auf einem einzigen 48-GB-GPU mit minimaler Qualitätseinbuße feinabstimmen kann. Auf Apple Silicon sieht die Sache etwas anders aus. MLX verwaltet die Speicherzuweisung anders als CUDA, und die Quantisierungsunterstützung des Metal-Backends ist ab MLX-Version 0.15.0 (veröffentlicht im Februar 2025) reif 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/s) ~280 tok/s ~190 tok/s
Adapter-Qualitätsdelta Baseline ~2–4 % höhere Perplexität
MLX-LM-Unterstützung Nativ Über --quantize-Flag
Axolotl auf Mac Vollständig Teilweise (CPU-Fallback)
Am besten für MacBooks mit 16 GB+ RAM MacBooks mit 8 GB RAM
Info Wenn du 16 GB oder mehr Unified RAM hast, nutze Standard-LoRA mit bfloat16-Basisgewichten. QLoRA ist die richtige Wahl für 8-GB-MacBooks, auf denen das vollständige Modell sonst nicht passt.

Die praktische Schlussfolgerung: Wer ein M1 MacBook Pro mit 16 GB RAM hat, braucht für Mistral 7B kein QLoRA. Volles LoRA in bfloat16 lädt sauber und trainiert spürbar schneller.

Das MLX-Framework: Apples Geheimwaffe hier

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, im Dezember 2023 auf der NeurIPS angekündigt und während 2024 kontinuierlich weiterentwickelt. Anders als PyTorchs MPS-Backend — eine auf Metal aufgesetzte Übersetzungsschicht — wurde MLX von Grund auf für das Unified-Memory-Modell geschrieben. Kein Datenkopieren zwischen CPU- und GPU-Speicherpools; alles teilt denselben physischen Speicher. Für ein 7B-Modell, das nah an der RAM-Grenze läuft, ist dieser architektonische Unterschied spürbar.

Die Einrichtung geht wirklich schnell:

pip install mlx-lm

mlx-lm wird mit einem eingebauten LoRA-Fine-Tuning-Skript geliefert. Um Mistral 7B Instruct v0.3 zu holen und einen Trainingslauf 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-Layer an. Für ein gezieltes Fine-Tune ist der Bereich von 8–16 Layern richtig; auf 32 zu gehen zahlt sich bei unter 2.000 Trainingsbeispielen selten aus.

Tip Füge beim ersten Lauf --val-batches 25 und --steps-per-report 10 hinzu. MLX gibt Training- und Validierungsverlust auf stdout aus — wenn du früh siehst, wie sie auseinanderdriften, erkennst du Label-Rauschen im Datensatz, bevor du 45 Minuten GPU-Zeit verbrannt hast.

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-Beispiele-Instruktionsdatensatz war das Training nach 47 Minuten abgeschlossen. Der RAM-Spitzenverbrauch lag bei 18,3 GB.

LoRA fine-tuning terminal training logs

Mistral-7B-Datensatzformat: Hier scheitern die meisten

Das Modell interessiert sich nicht für deine sorgfältig kuratierten Texte. Es interessiert sich für Formatkonsistenz — und Mistral 7B ist dabei auf eine Weise wählerisch, die viele überraschend kalt erwischt.

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

JSONL für MLX-LM

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

{"text": "<s>[INST] Fasse die folgende Vertragsklausel in einfachem Deutsch zusammen: {{klausel_text}} [/INST] {{zusammenfassung}} </s>"}
{"text": "<s>[INST] Extrahiere alle wichtigen Daten aus diesem Absatz: {{absatz}} [/INST] {{datumsliste}} </s>"}

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

Axolotl YAML-Datensatz-Konfiguration

Axolotl übernimmt das Templating automatisch basierend auf dem deklarierten Basismodell:

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

Es wendet das korrekte Chat-Template im Hintergrund an. Kein manuelles String-Wrapping nötig — das ist einer der Hauptgründe, warum man für alles jenseits eines schnellen Experiments zu Axolotl statt zu rohem MLX-LM greift.

Warning Mische niemals chat-formatierte und rohe Completion-Beispiele in derselben Trainingsdatei. Das Modell lernt dann, [INST]-Token mitten in der Generierung zu halluzinieren. Stelle sicher, dass dein Datensatzformat zu 100 % konsistent ist, bevor du mit dem Training beginnst.

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

Den Fine-Tune mit Axolotl ausführen

Axolotl ist ein konfigurationsgetriebenes 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 minimale 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 für 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

Ausführen:

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

Erwartete Trainingszeit auf einem M1 Pro (10-Kern-CPU) mit 500 Beispielen über 3 Epochen: 35–50 Minuten. Die Ausgabe landet in ./outputs/mistral-lora/ als Adapter-Gewichte. Für ein einzelnes Inferenz-Artefakt zusammenführen:

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

Eine echte Einschränkung, die es wert ist, genannt zu werden: Axolotl auf MPS unterstützt bis Mai 2025 noch kein Flash Attention. Du siehst eine Warnung in den Logs und es fällt auf Standard-Attention zurück — langsamer, aber die Ergebnisse werden nicht verfälscht.

Phi-3 Fine-Tune: Eine echte Alternative

Mistral 7B ist der naheliegende Standard, aber nicht immer das richtige Modell. Microsofts Phi-3 Mini (3,8 Milliarden Parameter, veröffentlicht April 2024) schlägt sich bei Reasoning-Benchmarks weit über seiner Gewichtsklasse und lässt sich lokal deutlich schneller feinabstimmen. Wer schnell an einem Coding-Assistenten oder strukturierten Output-Aufgaben iteriert, gewinnt durch die halbierten Trainingszeiten spürbar an Produktivität.

Mistral 7B Phi-3 Mini 3.8B Phi-3 Small 7B
Parameter 7,24 Mrd. 3,82 Mrd. 7,39 Mrd.
Fine-Tune-Zeit (500 Beispiele, 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 %
Maximale Kontextlänge 32K 128K 128K
Bester Anwendungsfall Allgemeine Instruktion Reasoning, Coding Hochwertige Schlussfolgerung

Phi-3 Mini ist der bessere Ausgangspunkt, wenn: dein MacBook 8 GB RAM hat, du schnelle Iterationszyklen brauchst oder deine 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, der Rest 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 Parameteranzahl bedeutet flacheres allgemeines Weltwissen. Für hochgradig domänenspezifische Fine-Tunes — medizinische Notizen, Extraktion juristischer Klauseln, Nischen-Fachdokumentation — gewinnt Mistral 7Bs reichhaltigeres Vortraining oft bei der Generalisierung auf Beispiele außerhalb der Trainingsverteilung.

Phi-3 vs Mistral model benchmark comparison

Kurzcheckliste: Deinen ersten Adapter heute ausliefern

Arbeite diese Punkte der Reihe nach ab. Schritt 4 nicht überspringen — er kostet drei Minuten und hat mir schon Stunden gespart.

  1. RAM-Headroom prüfensudo powermetrics --samplers smc -n 1 ausführen, um den Speicherdruck im Leerlauf zu sehen. Du brauchst mindestens 15 GB frei für Mistral 7B in bfloat16, 7 GB für Phi-3 Mini.
  2. Sauberes 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 beides in derselben Umgebung.
  4. Datensatz vorbereiten — mindestens 300 Beispiele, konsistentes Format ([INST]/[/INST] für Mistral, <|user|>/<|assistant|> für Phi-3). 20 Zeilen manuell stichprobenartig prüfen, bevor du trainierst. Formatfehler sind unsichtbar — bis zur Inferenz.
  5. Smoke-Test mit 50 Iterationen--iters 50 --val-batches 5. Bestätige, dass der Trainingsverlust fällt und kein OOM-Fehler auftritt. Erst dann den vollständigen Lauf starten.
  6. Vollständiger Trainingslauf — 1.000–1.500 Iterationen für die meisten Aufgaben. Training- vs. Validierungsverlust beobachten: Wenn sie nach Schritt 400 auseinanderdriften, überfit das Modell bei einem kleinen Datensatz — dann frühzeitig abbrechen.
  7. Manuelle Inferenztests vor dem Mergen — mit mlx_lm.generate und --adapter-path ./adapters 10–20 echte Prompts durchlaufen. Auf Formatregressionen prüfen.
  8. Zusammenführen und exportierenpython -m mlx_lm.fuse kombiniert Basis und Adapter zu einem zusammengeführten Modell. Für Ollama-Nutzung 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) — Kanonische Referenz für alle Axolotl-YAML-Konfigurationsoptionen, unterstützte Adapter-Typen und den aktuellen MPS/Metal-Kompatibilitätsstatus. Im Issues-Bereich das Label „mac" durchsuchen für aktive plattformspezifische Diskussionen.

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

Hugging Face PEFT-Dokumentation — Umfassende Referenz zur LoRA-Rang-Auswahl, Alpha-Skalierung und Zielmodul-Auswahl. Nützlich auch dann, wenn du MLX statt PEFT direkt verwendest — die zugrunde liegende Mathematik ist dieselbe.

Phi-3 Technical Report (Microsoft Research, April 2024) — Microsofts Beschreibung der Phi-3-Modellfamilie, inklusive Trainingsdata-Ansatz, Benchmark-Methodik und der „small data, high quality"-Philosophie, die erklärt, warum Phi-3 Mini bei mehreren Reasoning-Benchmarks Modelle der doppelten Größe übertrifft.