> For the complete documentation index, see [llms.txt](https://docs.clore.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.clore.ai/guides/guides_v2-de/training/finetune-llm.md).

# LLM feinabstimmen

Feinabstimme benutzerdefinierte LLMs mit effizienten Techniken auf Clore.ai-GPUs

Trainiere dein eigenes benutzerdefiniertes LLM mit effizienten Fine-Tuning-Techniken auf CLORE.AI-GPUs.

{% hint style="success" %}
Alle Beispiele können auf GPU-Servern ausgeführt werden, die gemietet wurden über [CLORE.AI-Marktplatz](https://clore.ai/marketplace).
{% endhint %}

## Mieten auf CLORE.AI

1. Besuchen [CLORE.AI-Marktplatz](https://clore.ai/marketplace)
2. Filtern nach GPU-Typ, VRAM und Preis
3. Wähle **On-Demand** (Festpreis) oder **Spot** (Gebotspreis)
4. Konfiguriere deine Bestellung:
   * Docker-Image auswählen
   * Ports festlegen (TCP für SSH, HTTP für Web-UIs)
   * Bei Bedarf Umgebungsvariablen hinzufügen
   * Startbefehl eingeben
5. Zahlung auswählen: **CLORE**, **BTC**, oder **USDT/USDC**
6. Bestellung erstellen und auf die Bereitstellung warten

### Greife auf deinen Server zu

* Verbindungsdetails finden in **Meine Bestellungen**
* Web-Oberflächen: Verwende die HTTP-Port-URL
* SSH: `ssh -p <port> root@<proxy-address>`

## Was ist LoRA/QLoRA?

* **LoRA** (Low-Rank Adaptation) – Trainiere kleine Adapter-Layer statt des gesamten Modells
* **QLoRA** - LoRA mit Quantisierung für noch weniger VRAM
* Trainiere ein 7B-Modell auf einer einzelnen RTX 3090
* Trainiere ein 70B-Modell auf einer einzelnen A100

## Anforderungen

| Modell | Methode            | Min. VRAM | Empfohlen                                                                                                |
| ------ | ------------------ | --------- | -------------------------------------------------------------------------------------------------------- |
| 7B     | QLoRA              | 12 GB     | [RTX 3090](https://clore.ai/rent-3090.html?utm_source=docs\&utm_medium=guide\&utm_campaign=finetune-llm) |
| 13B    | QLoRA              | 20 GB     | [RTX 4090](https://clore.ai/rent-4090.html?utm_source=docs\&utm_medium=guide\&utm_campaign=finetune-llm) |
| 70B    | QLoRA              | 48GB      | A100 80GB                                                                                                |
| 7B     | Vollständiges LoRA | 24 GB     | RTX 4090                                                                                                 |

## Schnell bereitstellen

**Docker-Image:**

```
pytorch/pytorch:2.11.0-cuda12.8-cudnn9-devel
```

**Ports:**

```
22/tcp
8888/http
6006/http
```

**Befehl:**

```bash
pip install "transformers>=4.45" "datasets>=2.20" accelerate "peft>=0.14" \\
    bitsandbytes "trl>=0.12" wandb jupyterlab && \\
jupyter lab --ip=0.0.0.0 --port=8888 --allow-root
```

## Auf deinen Dienst zugreifen

Nach der Bereitstellung findest du deine `http_pub` URL in **Meine Bestellungen**:

1. Gehe zu **Meine Bestellungen** Seite
2. Klicke auf deine Bestellung
3. Finde die `http_pub` URL (z. B. `abc123.clorecloud.net`)

Verwende `https://YOUR_HTTP_PUB_URL` anstelle von `localhost` in den folgenden Beispielen.

## Datensatzvorbereitung

### Chat-Format (empfohlen)

```json
[
  {
    "messages": [
      {"role": "system", "content": "Du bist ein hilfreicher Assistent."},
      {"role": "user", "content": "Was ist Python?"},
      {"role": "assistant", "content": "Python ist eine Programmiersprache..."}
    ]
  }
]
```

### Instruktionsformat

```json
[
  {
    "instruction": "Übersetze ins Französische",
    "input": "Hallo, wie geht es dir?",
    "output": "Bonjour, comment allez-vous?"
  }
]
```

### Alpaca-Format

```json
[
  {
    "instruction": "Gib drei Tipps für ein gesundes Leben.",
    "input": "",
    "output": "1. Iss ausgewogene Mahlzeiten..."
  }
]
```

## Unterstützte moderne Modelle (2025)

| Modell                      | HF-ID                                     | Min. VRAM (QLoRA) |
| --------------------------- | ----------------------------------------- | ----------------- |
| Llama 3.1 / 3.3 8B          | `meta-llama/Llama-3.1-8B-Instruct`        | 12 GB             |
| Qwen 2.5 7B / 14B           | `Qwen/Qwen2.5-7B-Instruct`                | 12GB / 20GB       |
| DeepSeek-R1-Distill (7B/8B) | `deepseek-ai/DeepSeek-R1-Distill-Qwen-7B` | 12 GB             |
| Mistral 7B v0.3             | `mistralai/Mistral-7B-Instruct-v0.3`      | 12 GB             |
| Gemma 2 9B                  | `google/gemma-2-9b-it`                    | 14GB              |
| Phi-4 14B                   | `microsoft/phi-4`                         | 20 GB             |

## QLoRA-Fine-Tuning-Skript

Modernes Beispiel mit PEFT 0.14+, Flash Attention 2, DoRA-Unterstützung und Kompatibilität mit Qwen2.5 / DeepSeek-R1:

```python
import torch
from transformers import (
    AutoModelForCausalLM,
    AutoTokenizer,
    BitsAndBytesConfig,
    TrainingArguments,
)
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
from datasets import load_dataset
from trl import SFTTrainer, SFTConfig

# === Konfiguration ===
# Wähle eines von: Qwen2.5, DeepSeek-R1-Distill, Llama 3.1, Mistral usw.
MODEL_NAME = "Qwen/Qwen2.5-7B-Instruct"
# MODEL_NAME = "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B"
# MODEL_NAME = "meta-llama/Llama-3.1-8B-Instruct"

DATASET = "your_dataset.json"  # oder Name des HuggingFace-Datasets
OUTPUT_DIR = "./output"
MAX_SEQ_LENGTH = 4096           # Qwen2.5 unterstützt bis zu 32K Kontext
USE_DORA = True                 # DoRA verbessert die Qualität gegenüber standardmäßigem LoRA
USE_FLASH_ATTN = True           # Flash Attention 2 spart VRAM und beschleunigt

# === Modell mit 4-Bit-Quantisierung laden ===
bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.bfloat16,
    bnb_4bit_use_double_quant=True,
)

model = AutoModelForCausalLM.from_pretrained(
    MODEL_NAME,
    quantization_config=bnb_config,
    device_map="auto",
    trust_remote_code=True,  # Erforderlich für Qwen2.5 und DeepSeek
    # Flash Attention 2: erfordert eine Ampere+-GPU (RTX 30/40, A100)
    attn_implementation="flash_attention_2" if USE_FLASH_ATTN else "eager",
)

tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True)
if tokenizer.pad_token is None:
    tokenizer.pad_token = tokenizer.eos_token
tokenizer.padding_side = "right"

# === LoRA mit optionalem DoRA konfigurieren ===
# DoRA (Weight-Decomposed Low-Rank Adaptation) — PEFT >= 0.14 erforderlich
# use_dora=True zerlegt Gewichte in Betrag + Richtung für bessere Qualität
lora_config = LoraConfig(
    r=64,                    # Rang (höher = mehr Kapazität, mehr VRAM)
    lora_alpha=16,           # Skalierungsfaktor (gleich r oder halb so groß wählen)
    target_modules=[
        "q_proj", "k_proj", "v_proj", "o_proj",  # Attention-Layer
        "gate_proj", "up_proj", "down_proj",      # MLP-Layer
    ],
    lora_dropout=0.05,
    bias="none",
    task_type="CAUSAL_LM",
    use_dora=USE_DORA,        # DoRA: verbesserte Qualität (PEFT 0.14+)
    # use_rslora=True,        # Optional: Rank-Stabilized LoRA
)

# Modell für QLoRA-Training vorbereiten
model = prepare_model_for_kbit_training(
    model,
    use_gradient_checkpointing=True,
    gradient_checkpointing_kwargs={"use_reentrant": False},
)
model = get_peft_model(model, lora_config)

# Zusammenfassung der trainierbaren Parameter ausgeben
model.print_trainable_parameters()
# Beispielausgabe: trainable params: 42,991,616 || all params: 7,284,891,648 || trainable%: 0.59

# === Dataset laden ===
dataset = load_dataset("json", data_files=DATASET)
# Oder verwende ein öffentliches Dataset:
# dataset = load_dataset("HuggingFaceH4/ultrachat_200k")

# === Dataset für das Qwen2.5 / ChatML-Format formatieren ===
def format_chat_qwen(example):
    """Format für Qwen2.5 mit ChatML-Vorlage."""
    messages = example.get("messages", [])
    if not messages:
        # Alpaca-artige Daten verarbeiten
        text = f"<|im_start|>system\nDu bist ein hilfreicher Assistent.<|im_end|>\n"
        text += f"<|im_start|>user\n{example['instruction']}"
        if example.get("input"):
            text += f"\n{example['input']}"
        text += f"<|im_end|>\n<|im_start|>assistant\n{example['output']}<|im_end|>"
    else:
        # Nachrichtenformat (ChatML) verarbeiten
        text = tokenizer.apply_chat_template(
            messages,
            tokenize=False,
            add_generation_prompt=False,
        )
    return {"text": text}

dataset = dataset.map(format_chat_qwen, remove_columns=dataset["train"].column_names)

# === Trainingsargumente (PEFT 0.14+ / TRL 0.12+) ===
training_args = SFTConfig(
    output_dir=OUTPUT_DIR,
    num_train_epochs=3,
    per_device_train_batch_size=2,
    gradient_accumulation_steps=8,         # Effektive Batch = 2 * 8 = 16
    learning_rate=2e-4,
    weight_decay=0.001,
    warmup_ratio=0.03,
    lr_scheduler_type="cosine",
    logging_steps=10,
    save_steps=100,
    save_total_limit=3,
    bf16=True,                             # Verwende bf16 für moderne GPUs (A100, RTX 30/40)
    # fp16=True,                           # Verwende fp16 für ältere GPUs
    optim="paged_adamw_8bit",
    max_grad_norm=0.3,
    group_by_length=True,
    report_to="wandb",                     # oder "tensorboard"
    # SFTConfig-spezifisch:
    max_seq_length=MAX_SEQ_LENGTH,
    dataset_text_field="text",
    packing=True,                          # Mehrere Beispiele zur Effizienz packen
)

# === Trainieren ===
trainer = SFTTrainer(
    model=model,
    train_dataset=dataset["train"],
    tokenizer=tokenizer,
    args=training_args,
)

trainer.train()

# === LoRA-Adapter speichern ===
trainer.save_model(f"{OUTPUT_DIR}/final")
tokenizer.save_pretrained(f"{OUTPUT_DIR}/final")
print(f"Modell gespeichert unter {OUTPUT_DIR}/final")
```

## Flash Attention 2

Flash Attention 2 reduziert den VRAM-Verbrauch und beschleunigt das Training erheblich. Erfordert eine Ampere+-GPU (RTX 3090, RTX 4090, A100).

```bash
# Flash Attention 2 installieren
pip install flash-attn --no-build-isolation
```

```python
# Beim Laden des Modells aktivieren:
model = AutoModelForCausalLM.from_pretrained(
    MODEL_NAME,
    attn_implementation="flash_attention_2",  # <-- dies hinzufügen
    torch_dtype=torch.bfloat16,               # FA2 erfordert bf16 oder fp16
    device_map="auto",
)
```

| Einstellung               | VRAM (7B) | Geschwindigkeit |
| ------------------------- | --------- | --------------- |
| Standard-Attention (fp16) | \~22GB    | Basiswert       |
| Flash Attention 2 (bf16)  | \~16GB    | +30%            |
| Flash Attention 2 + QLoRA | \~12GB    | +30%            |

## DoRA (Weight-Decomposed LoRA)

DoRA (PEFT >= 0.14) zerlegt vortrainierte Gewichte in Betrag- und Richtungsanteile. Es verbessert die Qualität des Fine-Tunings, besonders bei kleineren Rängen.

```python
from peft import LoraConfig

# Standard-LoRA
lora_config = LoraConfig(r=64, lora_alpha=16, use_dora=False, ...)

# DoRA — gleiche Parameter, bessere Qualität
lora_config = LoraConfig(r=64, lora_alpha=16, use_dora=True, ...)
# Hinweis: DoRA verursacht etwa 5-10 % mehr VRAM-Bedarf als standardmäßiges LoRA
# Hinweis: Nicht in allen Fällen mit quantisierten (4-Bit/8-Bit)-Modellen kompatibel
```

## Beispiele für Qwen2.5 & DeepSeek-R1-Distill

### Qwen2.5 Fine-Tuning

```python
MODEL_NAME = "Qwen/Qwen2.5-7B-Instruct"
# Für 14B: "Qwen/Qwen2.5-14B-Instruct" (benötigt 20GB+ VRAM mit QLoRA)

model = AutoModelForCausalLM.from_pretrained(
    MODEL_NAME,
    quantization_config=bnb_config,
    device_map="auto",
    trust_remote_code=True,          # Für Qwen2.5 erforderlich
    attn_implementation="flash_attention_2",
)
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True)

# Qwen2.5 verwendet das ChatML-Format — verwende apply_chat_template
messages = [
    {"role": "system", "content": "Du bist ein hilfreicher Assistent."},
    {"role": "user", "content": "Hallo!"},
    {"role": "assistant", "content": "Hallo! Wie kann ich helfen?"},
]
text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=False)
```

### DeepSeek-R1-Distill Fine-Tuning

DeepSeek-R1-Distill-Modelle (Qwen-7B, Qwen-14B, Llama-8B, Llama-70B) sind auf Schlussfolgerungen ausgerichtet. Fine-Tune sie, um ihren Chain-of-Thought-Stil an deine Domäne anzupassen.

```python
# DeepSeek-R1-Distill-Varianten
MODEL_NAME = "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B"   # 7B auf Qwen2.5-Basis
# MODEL_NAME = "deepseek-ai/DeepSeek-R1-Distill-Llama-8B" # 8B auf Llama3-Basis
# MODEL_NAME = "deepseek-ai/DeepSeek-R1-Distill-Qwen-14B" # 14B (benötigt A100)

model = AutoModelForCausalLM.from_pretrained(
    MODEL_NAME,
    quantization_config=bnb_config,
    device_map="auto",
    trust_remote_code=True,
    attn_implementation="flash_attention_2",
)

# DeepSeek-R1 verwendet <think>...</think>-Tags für Schlussfolgerungen
# Dies in den Trainingsdaten beibehalten, um die Chain-of-Thought-Fähigkeit zu erhalten
example_format = """<|im_start|>user
Löse: Was ist 15 * 23?<|im_end|>
<|im_start|>assistant
<think>
15 * 23 = 15 * 20 + 15 * 3 = 300 + 45 = 345
</think>
Die Antwort ist 345.<|im_end|>"""

# LoRA-Zielmodule für DeepSeek-R1-Distill (Qwen2.5-Basis)
lora_config = LoraConfig(
    r=32,
    lora_alpha=16,
    target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
                    "gate_proj", "up_proj", "down_proj"],
    use_dora=True,
    task_type="CAUSAL_LM",
)
```

## Verwendung von Axolotl (einfacher)

Axolotl vereinfacht das Fine-Tuning mit YAML-Konfigurationen:

```bash
pip install axolotl

# Konfiguration erstellen
cat > config.yml << 'EOF'
base_model: mistralai/Mistral-7B-v0.1
model_type: MistralForCausalLM
tokenizer_type: LlamaTokenizer

load_in_4bit: true
adapter: qlora
lora_r: 32
lora_alpha: 16

datasets:
  - path: your_data.json
    type: alpaca

sequence_len: 4096
sample_packing: true

gradient_accumulation_steps: 4
micro_batch_size: 2
num_epochs: 3
learning_rate: 2e-4

output_dir: ./output
EOF

# Trainieren
accelerate launch -m axolotl.cli.train config.yml
```

## Axolotl-Konfigurationsbeispiele

### Chat-Modell

```yaml
base_model: mistralai/Mistral-7B-Instruct-v0.2
load_in_4bit: true
adapter: qlora

datasets:
  - path: data.json
    type: sharegpt

chat_template: mistral
```

### Code-Modell

```yaml
base_model: codellama/CodeLlama-7b-hf
load_in_4bit: true
adapter: qlora

datasets:
  - path: code_data.json
    type: alpaca

sequence_len: 8192  # Längerer Kontext für Code
```

## LoRA-Gewichte zusammenführen

Führe LoRA nach dem Training wieder in das Basismodell zusammen:

```python
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer

# Basismodell laden
base_model = AutoModelForCausalLM.from_pretrained(
    "mistralai/Mistral-7B-v0.1",
    torch_dtype=torch.float16,
    device_map="auto",
)

# LoRA laden
model = PeftModel.from_pretrained(base_model, "./output/final")

# Zusammenführen
merged_model = model.merge_and_unload()

# Zusammengeführtes Modell speichern
merged_model.save_pretrained("./merged_model")
tokenizer.save_pretrained("./merged_model")
```

## In GGUF konvertieren

Zur Verwendung mit llama.cpp/Ollama:

```bash

# llama.cpp klonen
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp

# Konvertieren
python convert.py ../merged_model --outtype f16 --outfile model-f16.gguf

# Quantisieren
./quantize model-f16.gguf model-q4_k_m.gguf q4_k_m
```

## Training überwachen

### Weights & Biases

```python
import wandb
wandb.init(project="llm-finetune", name="mistral-7b-lora")
```

### TensorBoard

```python

# In den Trainings-Args
report_to="tensorboard"
logging_dir="./logs"

# Anzeigen
tensorboard --logdir ./logs --port 6006 --bind_all
```

## Bewährte Verfahren

### Hyperparameter

| Parameter   | 7B-Modell | 13B-Modell | 70B-Modell |
| ----------- | --------- | ---------- | ---------- |
| batch\_size | 4         | 2          | 1          |
| grad\_accum | 4         | 8          | 16         |
| Lernrate    | 2e-4      | 1e-4       | 5e-5       |
| lora\_r     | 64        | 32         | 16         |
| epochs      | 3         | 2-3        | 1-2        |

### Datensatzgröße

* Minimum: 1.000 Beispiele
* Gut: 10.000+ Beispiele
* Qualität > Quantität

### Überanpassung vermeiden

```python
training_args = TrainingArguments(
    ...
    weight_decay=0.01,
    warmup_ratio=0.03,
    save_total_limit=3,
    load_best_model_at_end=True,
    evaluation_strategy="steps",
    eval_steps=100,
)
```

## Multi-GPU-Training

```bash

# Mit accelerate
accelerate launch --multi_gpu --num_processes 4 train.py

# Mit DeepSpeed
accelerate launch --use_deepspeed --num_processes 4 train.py
```

DeepSpeed-Konfiguration:

```json
{
  "bf16": {"enabled": true},
  "zero_optimization": {
    "stage": 2,
    "offload_optimizer": {"device": "cpu"}
  }
}
```

## Speichern & Exportieren

```bash

# LoRA-Adapter speichern
trainer.save_model("./lora_adapter")

# Zusammengeführtes Modell speichern
merged_model.save_pretrained("./full_model")

# Auf HuggingFace hochladen
huggingface-cli login
merged_model.push_to_hub("username/my-model")
```

## Fehlerbehebung

### OOM-Fehler

* Batch-Größe reduzieren
* Gradient Accumulation erhöhen
* Verwende `gradient_checkpointing=True`
* lora\_r reduzieren

### Trainingsverlust nimmt nicht ab

* Datenformat prüfen
* Lernrate erhöhen
* Auf Datenprobleme prüfen

### NaN-Verlust

* Lernrate reduzieren
* fp32 statt fp16 verwenden
* Auf beschädigte Daten prüfen

## Kostenschätzung

Typische CLORE.AI-Marktplatzpreise (Stand 2026):

| GPU       | Stundensatz | Tagessatz | 4-Stunden-Sitzung |
| --------- | ----------- | --------- | ----------------- |
| RTX 3060  | \~$0.03     | \~$0.70   | \~$0.12           |
| RTX 3090  | \~$0.06     | \~$1.50   | \~$0.25           |
| RTX 4090  | \~$0.10     | \~$2.30   | \~$0.40           |
| A100 40GB | \~$0.17     | \~$4.00   | \~$0.70           |
| A100 80GB | \~$0.25     | \~$6.00   | \~$1.00           |

*Die Preise variieren je nach Anbieter und Nachfrage. Prüfen Sie* [*CLORE.AI-Marktplatz*](https://clore.ai/marketplace) *für aktuelle Preise.*

> 📚 Siehe auch: [Wie man LLaMA 3 auf einer Cloud-GPU feinabstimmt — Schritt-für-Schritt-Anleitung](https://blog.clore.ai/how-to-fine-tune-llama-3-cloud-gpu/)

**Geld sparen:**

* Nutzen Sie den **Spot** Markt für unterbrechbare Arbeit — etwa ein Drittel der Server bietet Spot-Preise unter dem On-Demand-Preis (Median ca. 13 % Rabatt), der Rest ist gleichauf
* Bezahlen Sie mit **CLORE** Tokens
* Vergleichen Sie Preise zwischen verschiedenen Anbietern


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.clore.ai/guides/guides_v2-de/training/finetune-llm.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
