Zurück zum Blog
Blog

Fine-Tuning von LLMs: KI beibringen, Ihre Sprache zu sprechen

Aug 17, 2025·8 min read·Shranya Mahna
#custom AI#domain-specific AI#fine-tuning LLMs#language models#personalized AI
Fine-Tuning von LLMs: KI beibringen, Ihre Sprache zu sprechen

Teil 3 von 5: Anpassung vortrainierter Modelle

Willkommen zurück! In unserem letzten Artikel haben wir ein RAG-System aufgebaut, das der KI Zugriff auf deine spezifischen Informationen gibt. Heute gehen wir einen Schritt weiter — wir werden tatsächlich ändern, wie ein KI-Modell denkt und antwortet, indem wir es fine-tunen. Für dieses Demo-Beispiel werde ich ein Open-Source-Modell verwenden.

RAG vs Fine-Tuning: Was ist der Unterschied?

Stell dir das so vor:

RAG ist wie jemandem ein Nachschlagewerk zu geben. Die Person ist immer noch dieselbe, aber jetzt hat sie Zugriff auf spezifische Informationen bei der Beantwortung von Fragen.

Fine-Tuning ist wie jemanden zu einer Spezialausbildung zu schicken. Du änderst tatsächlich, wie diese Person denkt und antwortet, basierend auf deinen spezifischen Anforderungen.

Wann solltest du Fine-Tuning verwenden?

Fine-Tuning ist mächtig, aber nicht immer notwendig. Erwäge Fine-Tuning wenn:

  • Die KI einen bestimmten Ton oder Stil annehmen muss
  • Deine Domäne spezialisierte Terminologie oder Konzepte hat
  • Du konsistente Antworten über viele verschiedene Szenarien hinweg brauchst
  • RAG dir nicht die Qualität der Antworten gibt, die du brauchst
  • Du ausreichend Trainingsdaten hast (normalerweise Hunderte von Beispielen)
  • Du brauchst, dass das Modell offline oder in isolierten Umgebungen funktioniert

Einrichten deiner Umgebung

Wir verwenden Google Colab mit einer T4 GPU für dieses Tutorial, aber du kannst dies für jede CUDA-fähige Umgebung anpassen:

# Install required packages

!pip install bitsandbytes
import os import torch from datasets import Dataset from transformers import ( AutoModelForCausalLM, AutoTokenizer, TrainingArguments, Trainer, BitsAndBytesConfig ) from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training, PeftModel

Wahl des richtigen Modells

Für dieses Tutorial verwenden wir TinyLlama-1.1B, aber hier sind einige hervorragende Optionen für verschiedene Anforderungen:

# Ultra-light models (good for experimentation)

# model_name = "distilgpt2"                          # 82M parameters

# model_name = "gpt2"                                # 124M parameters

# model_name = "EleutherAI/gpt-neo-125M"            # 125M parameters
# Small but capable models # model_name = "microsoft/DialoGPT-medium" # 355M parameters # model_name = "microsoft/DialoGPT-large" # 762M parameters model_name = "TinyLlama/TinyLlama-1.1B-Chat-v1.0" # 1.1B parameters - choosing this one # For production use (if you have more GPU memory) # model_name = "microsoft/phi-2" # 2.7B parameters # model_name = "stabilityai/stablelm-2-1_6b" # 1.6B parameters

Vorbereitung deiner Trainingsdaten

Der Schlüssel zum erfolgreichen Fine-Tuning sind hochwertige Trainingsdaten. Hier ist, wie wir sie strukturieren:

# Sample dataset for MyNextDeveloper (MND)

data = {

"text": [

"User asks: Write a 3-bullet overview of MND.nAssistant: - Remote-first, founded 2022 in Mumbain- Staff augmentation + full-cycle web/API, UI/UX, AI/MLn- Agile/TDD, POSH culture, transparent pricing",

"User asks: Where is MND headquartered?nAssistant: Malabar Hill, Mumbai",

"User asks: What services does MND offer?nAssistant: Staff augmentation, API development, web development, UI/UX design, AI/ML solutions",

"User asks: What is MND's tech stack?nAssistant: Angular, React, Next.js, Node.js, Django, Python, Docker, AWS",

"User asks: What is MND's pricing model?nAssistant: Project pricing starting at $10,000 with hourly rates between $25 and $49",

"User asks: What is MND's mission?nAssistant: To solve the trust gap between startups and engineers by emphasizing empathy, communication, and transparency",

"User asks: What is MND's culture like?nAssistant: Agile practices, test-driven development, and POSH-compliant culture",

"User asks: When was MND founded?nAssistant: 2022"

]

}
# Convert to HuggingFace dataset dataset = Dataset.from_dict(data)

Wichtige Prinzipien für Trainingsdaten:

  • Nutze konsistente Formatierung (achte auf das „User asks:" und „Assistant:" Muster)
  • Halte Antworten sachlich und prägnant
  • Decke die wichtigsten Informationen über deine Domäne ab
  • Qualität über Quantität: 50 perfekte Beispiele schlagen 500 mittelmäßige

Effizientes Training mit LoRA und Quantisierung

Anstatt das gesamte Modell zu fine-tunen (was massiven GPU-Speicher erfordert), verwenden wir zwei Effizienz-Techniken:

1. Quantisierung (4-Bit)

Quantisierung ist eine Kompressionstechnik, die große Sprachmodelle (LLMs) kleiner und schneller macht, ohne die Genauigkeit stark zu reduzieren.

  • Normalerweise werden LLM-Gewichte als 32-Bit-Gleitkommazahlen (FP32) gespeichert.
  • Quantisierung reduziert diese Präzision auf 16-Bit (FP16/BF16), 8-Bit (INT8), 4-Bit (INT4) oder sogar niedriger.

👉 Beispiel:

  • Ein Modell mit 10 Milliarden Parametern in FP32 benötigt ~40 GB Speicher.
  • Wenn wir es zu INT8 (8-Bit) quantisieren → braucht es nur ~10 GB.
  • Wenn wir zu INT4 (4-Bit) gehen → nur ~5 GB.

Warum ist das nützlich?

  • Ermöglicht es Modellen, auf kleineren GPUs (oder sogar CPUs) zu laufen.
  • Beschleunigt die Inferenz.
  • Kleiner Genauigkeitsverlust, aber oft vernachlässigbar.
# Configure 4-bit quantization

bnb_config = BitsAndBytesConfig(

load_in_4bit=True,

bnb_4bit_quant_type="nf4",

bnb_4bit_use_double_quant=True,

bnb_4bit_compute_dtype=torch.float16

)
# Load model with quantization model = AutoModelForCausalLM.from_pretrained( model_name, quantization_config=bnb_config, device_map="auto", torch_dtype=torch.float16 )

2. LoRA (Low-Rank Adaptation)

LoRA ist eine parametereffiziente Fine-Tuning (PEFT) Methode.

Normalerweise würde das Fine-Tuning eines riesigen LLMs (wie LLaMA-65B oder GPT-J) Hunderte von GB GPU-Speicher benötigen. LoRA löst dies durch:

  • Einfrieren der ursprünglichen Modellgewichte.
  • Hinzufügen von kleinen trainierbaren Matrizen (Low-Rank-Adaptern) innerhalb der Modellschichten.
  • Während des Fine-Tunings werden nur diese kleinen Matrizen aktualisiert.

👉 Beispiel:

  • Vollständiges Fine-Tuning eines 65B-Modells könnte ~1 TB GPU-Speicher erfordern.
  • Mit LoRA trainierst du nur ein paar Millionen Parameter → benötigt < 20 GB GPU-Speicher.

Warum ist das nützlich?

  • Macht Fine-Tuning massiver LLMs auf Consumer-Hardware möglich (1–2 GPUs).
  • Einfach, Adapter zu „mergen" oder „unmergen" → du kannst schnell Aufgaben wechseln.
  • Erreicht oft eine Leistung, die dem vollständigen Fine-Tuning nahe kommt.
# Configure LoRA based on model architecture

if "TinyLlama" in model_name or "Llama" in model_name:

target_modules = ["q_proj", "k_proj", "v_proj", "o_proj"]

elif "gpt" in model_name.lower() or "DialoGPT" in model_name:

target_modules = ["c_attn", "c_proj"]

else:

target_modules = ["q_proj", "v_proj"]
lora_config = LoraConfig( r=8, # Rank of adaptation lora_alpha=16, # LoRA scaling parameter target_modules=target_modules, lora_dropout=0.05, bias="none", task_type="CAUSAL_LM" ) # Apply LoRA to the model model = get_peft_model(model, lora_config) model.print_trainable_parameters()

Wir trainieren nur 0,2% der Parameter!

Training des Modells

# Tokenize the data

def tokenize_function(examples):

tokenized_inputs = tokenizer(

examples["text"],

truncation=True,

padding="max_length",

max_length=512,

return_tensors="pt"

)

# Create labels by copying input tokens

tokenized_inputs["labels"] = tokenized_inputs["input_ids"].clone()

return tokenized_inputs
# Split dataset train_dataset = dataset.select(range(8)) eval_dataset = dataset.select(range(8, 11)) # Apply tokenization train_dataset = train_dataset.map(tokenize_function, batched=True) eval_dataset = eval_dataset.map(tokenize_function, batched=True) # Configure training training_args = TrainingArguments( output_dir="./mnd-finetune-outputs", num_train_epochs=5, per_device_train_batch_size=4, per_device_eval_batch_size=4, gradient_accumulation_steps=2, warmup_steps=10, learning_rate=3e-4, weight_decay=0.01, logging_steps=1, save_steps=30, eval_strategy="steps", eval_steps=15, save_total_limit=2, load_best_model_at_end=True, fp16=True, report_to=None # Disable wandb logging ) # Create trainer and start training trainer = Trainer( model=model, args=training_args, train_dataset=train_dataset, eval_dataset=eval_dataset, tokenizer=tokenizer, ) print("Starting training...") trainer.train() # Save the adapter adapter_dir = "./mnd-finetune-outputs/final_adapter" model.save_pretrained(adapter_dir) tokenizer.save_pretrained(adapter_dir)

Testen des Fine-Tuned-Modells

def load_model_for_inference():

"""Load the fine-tuned model for inference"""

# Load base model

base_model = AutoModelForCausalLM.from_pretrained(

model_name,

quantization_config=bnb_config,

device_map="auto",

torch_dtype=torch.float16

)

# Load the fine-tuned adapter

model = PeftModel.from_pretrained(base_model, adapter_dir)

model = model.merge_and_unload()

# Load tokenizer

tokenizer = AutoTokenizer.from_pretrained(adapter_dir)

return model, tokenizer

def generate_response(model, tokenizer, prompt, max_length=256, temperature=0.7):

"""Generate response for a given prompt"""

formatted_prompt = f"User asks: {prompt}nAssistant:"

inputs = tokenizer.encode(formatted_prompt, return_tensors="pt")

inputs = inputs.to(model.device)

with torch.no_grad():

outputs = model.generate(

inputs,

max_length=max_length,

temperature=temperature,

top_p=0.9,

do_sample=True,

pad_token_id=tokenizer.eos_token_id,

repetition_penalty=1.1

)

response = tokenizer.decode(outputs[0], skip_special_tokens=True)

assistant_response = response.split("Assistant:")[-1].strip()

return assistant_response

# Load fine-tuned model and test

model, tokenizer = load_model_for_inference()

test_prompts = [

"What makes MND different from other development companies?",

"Can you tell me about MND's team?",

"What is the company culture at MND?"

]

for prompt in test_prompts:

response = generate_response(model, tokenizer, prompt)

print(f"Q: {prompt}")

print(f"A: {response}n")

Google Colab

Hier ist der Google-Colab-Link für diesen Artikel, den du mit einem Klick ausführen kannst: Link

Die echten Kosten

Im Gegensatz zu kommerziellen APIs entstehen deine Kosten hauptsächlich aus:

  1. Initiales Setup: GPU-Zeit für das Training
  2. Speicher: Modellgewichte (~4GB für TinyLlama mit LoRA-Adaptern)
  3. Inferenz: Deine eigene Hardware oder Cloud-GPU-Instanzen

Für ein kleines Modell wie TinyLlama kannst du die Inferenz auf folgenden Systemen ausführen:

  • Google Colab (kostenlos mit Einschränkungen)
  • AWS t3.medium mit GPU (~0,05$/Stunde)
  • Deine eigene Hardware (RTX 3060 oder besser)

Best Practices aus echter Erfahrung

1. Klein anfangen und skalieren Beginne mit distilgpt2 oder gpt2, um deine Daten und deinen Prozess zu testen, dann wechsle zu größeren Modellen.

2. Überfitting überwachen Bei kleinen Datensätzen können Modelle auswendig lernen statt zu lernen. Beobachte deinen Evaluierungsverlust.

3. Formatierungskonsistenz ist kritisch Das genaue Format deiner Trainingsdaten ist äußerst wichtig. Sei konsistent mit Interpunktion, Abstände und Struktur.

4. Mit unsichtbaren Fragen testen Teste immer mit Fragen, die nicht in deinen Trainingsdaten enthalten sind, um die Verallgemeinerung sicherzustellen.

5. Speichere regelmäßig Checkpoints Das Training kann unterbrochen werden. Speichere häufig und teste Zwischenstände.

Häufige Fallstricke und Lösungen

Problem: Modell generiert sich wiederholende oder unsinnige Texte Lösung: Senke die Lernrate, erhöhe die Regularisierung oder verbessere die Trainingsdatenqualität

Problem: Modell vergisst allgemeines Wissen Lösung: Berücksichtige einige allgemeine Beispiele in deinen Trainingsdaten oder verwende ein größeres Basismodell

Problem: Antworten sind zu generisch Lösung: Mache deine Trainingsbeispiele spezifischer und detaillierter

Problem: GPU-Speicherprobleme Lösung: Reduziere die Batch-Größe, verwende aggressivere Quantisierung oder Gradient Checkpointing

Kombination mit RAG

Hier kommt der spannende Teil: du kannst dein fine-tuntes Modell mit RAG für das Beste aus beiden Welten kombinieren:

  1. Fine-tune für Domain-Verständnis, Ton und allgemeines Firmenwissen
  2. Verwende RAG für aktuelle Informationen, spezifische Dokumente oder detaillierte technische Spezifikationen

Dies gibt dir ein Modell, das wie dein Unternehmen „denkt", aber auf aktuelle Informationen zugreifen kann.

Was kommt als nächstes

In unserem nächsten Artikel werden wir völlig benutzerdefiniert — wir bauen ein Sprachmodell von Grund auf, ganz deins, das auf deiner Hardware mit deinen Daten läuft.

Das Fine-Tuning von Open-Source-Modellen gibt dir beispiellose Kontrolle über deinen KI-Assistenten. Du kannst sicherstellen, dass er deine Domäne versteht, in deiner Stimme spricht und deine Daten niemals an Dritte sendet. Mit modernen Effizienz-Techniken wie LoRA und Quantisierung ist es zugänglicher denn je.

Die Zukunft der KI besteht nicht nur darin, jemand anderen Modell zu verwenden — es geht darum, KI wirklich zu deiner eigenen zu machen.


Kommt bald: Artikel 4 — „Dein eigenes Sprachmodell bauen: Klein aber mächtig"