🧠 German GPT-2 Medium – Hybrid Reasoning Edition (24-Layer)

Dieses Modell ist eine hochentwickelte, hybrid trainierte Version von GPT-2 mit einer auf 24 Layer erweiterten Architektur (~209M Parameter). Es basiert auf dbmdz/german-gpt2 mit einem nativen deutschen Tokenizer (50.265 Vocab) und wurde in einem mehrstufigen Prozess trainiert:

  1. Layer-Erweiterung: Von 12 auf 24 Transformer-Layer expandiert
  2. Healing-Phase: Mit deutschem c4-Corpus stabilisiert, damit die neuen Layer kohärentes Deutsch lernen
  3. SFT (Supervised Fine-Tuning): Auf einem 100 MB großen Datensatz trainiert – 50% Chain-of-Thought-Daten und 50% direkte Antwort-Daten

Das Besondere: Durch das hybride Training ist dieses Modell kontrollierbar. Du kannst entscheiden, ob die KI erst nachdenken soll (für komplexe Fragen) oder sofort antworten soll (für Geschwindigkeit).

🚀 Features

  • 🧱 24-Layer-Architektur: Doppelt so tief wie Standard-GPT-2 — mehr Kapazität für komplexes Reasoning und bessere Textqualität.
  • 🇩🇪 Nativer deutscher Tokenizer: Basiert auf dbmdz/german-gpt2 mit optimiertem deutschem Vokabular (50.265 Tokens). Keine ineffiziente Subword-Zerlegung wie beim englischen GPT-2.
  • ⚡ Hybrid-Modus: Das Modell versteht zwei Antwort-Stile:
    • Thinking Mode: Generiert <think>...</think> für logische Herleitungen.
    • Fast Mode: Antwortet direkt, ohne Denkprozess.
  • 🎛️ Manuelle Steuerung: Durch einen einfachen Prompt-Trick (Injecting von </think>) kann der Denkprozess bei Bedarf übersprungen werden.
  • 📈 Verbesserte Genauigkeit: Durch die Kombination von 50MB Denk-Daten und 50MB Direkt-Daten halluziniert das Modell deutlich weniger als reine CoT-Modelle.

📝 Nutzung & Steuerung

1. Der Standard-Modus (Thinking)

Nutze diesen Modus für komplexe Fragen, Mathe oder Logik.

Prompt:

<user> Warum ist der Himmel blau? <End> <AI Assistent>

Output:

<think>Der Benutzer fragt nach der Farbe des Himmels. Das hat mit Rayleigh-Streuung zu tun...</think> Der Himmel ist blau, weil...

2. Der Fast-Modus (Direct)

Zwinge das Modell, sofort zu antworten, indem du dem Modell vorgaukelst, der Denkprozess sei schon beendet.

Prompt:

<user> Wie spät ist es? <End> <AI Assistent> </think>

Output:

(Kein Denkprozess)
Es ist 12:00 Uhr.

💻 Python Code Beispiel

import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
import sys

# ==========================================
# KONFIGURATION
# ==========================================
# Pfad zum gespeicherten Modell (Muss identisch mit OUTPUT_DIR im Training sein)
# Wenn du das Modell heruntergeladen hast, ändere dies zu deinem lokalen Pfad.
MODEL_PATH = "Atomic-Ai/GPT-Chat-German-Nano"

# Generierungs-Parameter (Steuern die Kreativität)
MAX_NEW_TOKENS = 512    # Maximale Länge der Antwort
TEMPERATURE = 0.7        # 0.7 = ausgewogen, 1.0 = kreativ, 0.2 = deterministisch
TOP_P = 0.9              # Nucleus Sampling (Begrenzt die Wortwahl auf die Top-Wahrscheinlichkeiten)
REPETITION_PENALTY = 1.2 # Verhindert, dass das Modell sich wiederholt (wichtig bei GPT-2!)

# ==========================================
# MODELL LADEN
# ==========================================
def load_model():
    print(f"⏳ Lade Modell aus {MODEL_PATH}...")
    try:
        tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH)
        model = AutoModelForCausalLM.from_pretrained(
            MODEL_PATH,
            torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32
        )

        device = "cuda" if torch.cuda.is_available() else "cpu"
        model = model.to(device)

        print(f"✅ Modell geladen auf: {device.upper()}")
        return model, tokenizer, device
    except OSError:
        print(f"❌ Fehler: Das Modell konnte unter '{MODEL_PATH}' nicht gefunden werden.")
        print("   Stelle sicher, dass du das Training ausgeführt hast oder den Pfad anpasst.")
        sys.exit(1)

# ==========================================
# ANTWORT GENERIEREN
# ==========================================
def generate_response(model, tokenizer, device, user_input):
    # 1. Prompt Formatierung (Angepasst mit Leerzeichen)
    # Format: <user> PROMPT <End> <AI Assistent>
    prompt = f"""<user> {user_input} <End> <AI Assistent> <think>"""

    # 2. Tokenisierung
    inputs = tokenizer(prompt, return_tensors="pt").to(device)

    # 3. Generierung
    with torch.no_grad():
        output_ids = model.generate(
            **inputs,
            max_new_tokens=MAX_NEW_TOKENS,
            do_sample=True,
            temperature=TEMPERATURE,
            top_p=TOP_P,
            repetition_penalty=REPETITION_PENALTY,
            pad_token_id=tokenizer.eos_token_id,
            # Stoppen, falls das Modell versucht, eine neue User-Runde zu starten
            # Wir prüfen hier auf das <user> Token
            eos_token_id=[tokenizer.eos_token_id, tokenizer.convert_tokens_to_ids("<user>")]
        )

    # 4. Decoding
    full_output = tokenizer.decode(output_ids[0], skip_special_tokens=False)

    # 5. Antwort extrahieren
    # Wir schneiden am Tag "<AI Assistent>" ab
    if "<AI Assistent>" in full_output:
        response = full_output.split("<AI Assistent>")[-1]
    else:
        # Fallback, falls der Tag irgendwie modifiziert wurde
        response = full_output

    # Bereinigung: Entfernt Reste von <End> oder <user>, falls das Modell diese halluziniert
    response = response.replace("<End>", "").replace("<user>", "").strip()

    return response

# ==========================================
# HAUPTSCHLEIFE (CHAT)
# ==========================================
def main():
    model, tokenizer, device = load_model()

    print("\n" + "="*50)
    print("🤖 DEIN GPT-2 CHATBOT IST BEREIT")
    print("   (Schreibe 'exit' oder 'quit' zum Beenden)")
    print("="*50 + "\n")

    while True:
        try:
            user_input = input("Du: ")
            if user_input.lower() in ["exit", "quit", "ende"]:
                print("👋 Tschüss!")
                break

            if not user_input.strip():
                continue

            print("Bot denkt nach...", end="\r")

            # Die eigentliche Generierung aufrufen
            response = generate_response(model, tokenizer, device, user_input)

            # Zeile löschen ("Bot denkt nach...") und Antwort drucken
            print(" " * 20, end="\r")
            print(f"Bot: {response}\n")

        except KeyboardInterrupt:
            print("\n👋 Abbruch durch Benutzer.")
            break

if __name__ == "__main__":
    main()

⚙️ Technische Details

Eigenschaft Wert
Basis-Modell dbmdz/german-gpt2
Architektur GPT-2 (24 Layer, ~209M Parameter)
Tokenizer Deutsch-optimiert (50.265 Vocab)
Trainings-Phasen 3 (Expansion → Healing → SFT)
SFT-Datensatz 100 MB (50 MB CoT + 50 MB Direct)
SFT-Epochen 7
Precision BF16
GPU NVIDIA L4 (24GB)

Trainings-Pipeline

dbmdz/german-gpt2 (12 Layer, 124M)
        │
        ▼
   Layer-Erweiterung (12 → 24 Layer)
        │
        ▼
   Healing mit deutschem c4-Corpus
        │
        ▼
   SFT auf 100MB Hybrid-Daten
        │
        ▼
   GPT-Chat-German-Nano (24 Layer, 209M)

Special Tokens

Token Funktion
<user> Markiert den Beginn einer Nutzereingabe
<AI Assistent> Markiert den Beginn der Modellantwort
<think> Beginn eines Denkprozesses
</think> Ende eines Denkprozesses
<End> Ende einer Nachricht (EOS)

⚠️ Limitierungen

  • Der Fast-Modus kann bei sehr komplexen logischen Fragen zu schlechteren Antworten führen, da dem Modell die "Rechenzeit" (Tokens) zum Nachdenken fehlt.
  • Das Modell ist auf Deutsch optimiert.
  • Als 209M-Parameter-Modell hat es trotz der erweiterten Architektur Grenzen bei sehr komplexen oder wissensintensiven Aufgaben.

Trainiert von Atomic AI Studios mit einer mehrstufigen Hybrid-Strategie für maximale Flexibilität.

Downloads last month
426
Safetensors
Model size
0.2B params
Tensor type
BF16
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for Atomic-Ai/GPT-Chat-German-Nano

Base model

dbmdz/german-gpt2
Finetuned
(4)
this model

Dataset used to train Atomic-Ai/GPT-Chat-German-Nano

Collection including Atomic-Ai/GPT-Chat-German-Nano