Direkt zum Inhalt

GPT-OSS optimieren

Eine Schritt-für-Schritt-Anleitung, wie man das OpenAI GPT-OSS 20B-Modell auf den medizinischen Frage-Antwort-Datensatz abstimmt, um sowohl die Genauigkeit als auch den Stil zu verbessern.
Aktualisierte 27. Aug. 2025  · 6 Min. Lesezeit

Die GPT-OSS 20B ist ein offenes Sprachmodell aus der gpt-oss-Serie von OpenAI, das für niedrige Latenzzeiten und spezielle Anwendungsfälle entwickelt wurde . Es hat 21 Milliarden Parameter (3,6 Milliarden aktiv) und ist so optimiert, dass es auf handelsüblicher Hardware gut läuft. Dankder MXFP4-Quantisierung von braucht es nur etwa 16 GB Speicher.

Obwohl es kleiner ist als das GPT-OSS 120B, unterstützt es trotzdem coole Funktionen wie konfigurierbare Argumentationsstufen (niedrig, mittel, hoch), vollständigen Zugriff auf die Gedankenkette für Debugging und Transparenz sowie Agentenfunktionen wie Funktionsaufrufe, Webbrowsing und Codeausführung.

In dieser Anleitung zeige ich dir, wie du GPT-OSS 20B einrichtest und optimierst. Das umfasst:

  1. Abhängigkeiten installieren und die Umgebung vorbereiten
  2. Laden des Modells und des Tokenizers
  3. Erstellen des Prompt-Stils mit dem neuen OpenAI Harmony Python-Paket
  4. Laden des Datensatzes und Anwenden der Harmony-Formatierung
  5. Vor dem Feinabstimmen eine einfache Modellinferenz machen
  6. Das Modell für das Training einrichten
  7. Feinabstimmung des Modells anhand eines medizinischen Frage-Antwort-Datensatzes
  8. Nach dem Feintuning Inferenz durchführen, um Verbesserungen zu checken

Denk dran, dass dieses Tutorial nur für Forschung und Ausbildung gedacht ist und nicht für die Diagnose oder Behandlung von Patienten.

Bild vom Autor

1. Einrichten deiner Umgebung

Obwohl das GPT-OSS-Modell 21 Milliarden Parameter hat, braucht es trotzdem viel GPU-Speicher, mindestens 80 GB VRAM, um das Modell gut laufen zu lassen. Ein schneller Weg, um loslegen ist, eine RunPod H100-Instanz oder eine ähnliche GPU-Umgebung mit viel Speicher zu starten.

RunPod H100SXM-Gerät

Sobald die Umgebung fertig ist, installiere alle Python-Pakete, die du für die Datenverarbeitung, die Feinabstimmung des Modells und die Nachverfolgung von Experimenten brauchst:

%%capture
%pip install -U accelerate 
%pip install -U peft 
%pip install -U trl 
%pip install -U bitsandbytes
%pip install -U transformers
%pip install -U trackio
%pip install -U openai-harmony
%pip install -U tiktoken
%pip install -U pyctcdecode

Zum Schluss logg dich mit deinem API-Schlüssel beim Hugging Face Hub ein. Damit kannst du das fein abgestimmte Modell und den Tokenizer direkt in deinem Hugging Face-Konto speichern und teilen:

from huggingface_hub import notebook_login

notebook_login()

2. Laden des GPT-OSS-Modells und des Tokenizers

Als Nächstes laden wir das GPT-OSS 20B mit MXFP4-Quantisierung, dequantisieren die Gewichte aber sofort beim Laden auf bfloat16, wobei wir Eager Attention, deaktivierten Cache und automatische Geräteplatzierung nutzen.

import torch
from transformers import AutoModelForCausalLM, Mxfp4Config

quantization_config = Mxfp4Config(dequantize=True)
model_kwargs = dict(
    attn_implementation="eager",
    torch_dtype=torch.bfloat16,
    quantization_config=quantization_config,
    use_cache=False,
    device_map="auto",
)

model = AutoModelForCausalLM.from_pretrained("openai/gpt-oss-20b", **model_kwargs)

Neben dem Modell brauchen wir auch den Tokenizer aus demselben Repository. Der Tokenizer macht es möglich, Text in Tokens (IDs) umzuwandeln, die das Modell verarbeiten kann, und dann die Ergebnisse des Modells wieder in lesbaren Text zurückzuverwandeln.

from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("openai/gpt-oss-20b")

3. Erstellen eines Prompt-Stils mit OpenAI Harmony

OpenAI Harmony ist ein spezielles Antwortformat, das von den GPT-OSS-Modellen verwendet wird, um Gespräche, Schlussfolgerungen und Funktionsaufrufe auf einheitliche Weise zu strukturieren. 

Es legt fest, wie Nachrichten zwischen Rollen (System, Entwickler, Benutzer, Assistent) organisiert werden, und ermöglicht es dem Modell, über mehrere Kanäle auszugeben – zum Beispiel durch die Trennung von Gedankengängen, Einleitungen zum Aufruf von Tools und endgültigen Antworten für den Benutzer.

In diesem Abschnitt erstellen wir eine Funktion, die eine Frage und eine Antwort nimmt und sie zu einer Konversationsaufforderung im Harmony-Stil formatiert. Es nutzt die Bibliothek „ openai_harmony “, um die Unterhaltung strukturiert zu verschlüsseln.

from openai_harmony import (
    load_harmony_encoding, HarmonyEncodingName,
    Conversation, Message, Role,
    SystemContent, DeveloperContent, ReasoningEffort
)

enc = load_harmony_encoding(HarmonyEncodingName.HARMONY_GPT_OSS)

def render_pair_harmony(question, answer):
    convo = Conversation.from_messages([
        Message.from_role_and_content(
            Role.DEVELOPER,
            DeveloperContent.new().with_instructions(
                "You are a medical expert with advanced knowledge in clinical reasoning and diagnostics. "
                "Respond with ONLY the final diagnosis/cause in ≤5 words."
            )
        ),
        Message.from_role_and_content(Role.USER, question.strip()),
        Message.from_role_and_content(Role.ASSISTANT, answer.strip()),
    ])
    tokens = enc.render_conversation(convo)
    text = enc.decode(tokens)
    return text

4. Laden und Formatieren des Datensatzes

Jetzt laden wir den medizinischen Q&A-Datensatz (FreedomIntelligence/medical-o1-verifiable-problem ) und wenden die Funktion prompt_style_harmony auf jedes Beispiel an. Der umgewandelte Text wird in einer neuen Spalte namens „text“ gespeichert, was ein übersichtliches, anweisungsorientiertes Format ergibt, das zum Eingabestil des Entwicklers passt.

from datasets import load_dataset

def prompt_style_harmony(examples):
    qs = examples["Open-ended Verifiable Question"]
    ans = examples["Ground-True Answer"]
    outputs = {"text": []}
    for q, a in zip(qs, ans):
        rendered = render_pair_harmony(q, a)
        outputs["text"].append(rendered)
    return outputs

dataset = load_dataset(
    "FreedomIntelligence/medical-o1-verifiable-problem",
    split="train[0:1000]"
)
dataset = dataset.map(prompt_style_harmony, batched=True)
print(dataset.column_names)

print(dataset[0]["text"])

Der Datensatz hat jetzt eine neue Spalte „Text“, die die Konversation im Harmony-Format enthält. Das umfasst:

  • Anweisungen für Entwickler (z. B. mit einer knappen Diagnose antworten)
  • Benutzernachricht (die medizinische Frage)
  • Hilfsnachricht (die richtige Antwort)
['Open-ended Verifiable Question', 'Ground-True Answer', 'text']
<|start|>developer<|message|># Instructions

You are a medical expert with advanced knowledge in clinical reasoning and diagnostics. Respond with ONLY the final diagnosis/cause in ≤5 words.<|end|><|start|>user<|message|>An 88-year-old woman with osteoarthritis is experiencing mild epigastric discomfort and has vomited material resembling coffee grounds multiple times. Considering her use of naproxen, what is the most likely cause of her gastrointestinal blood loss?<|end|><|start|>assistant<|message|>Gastric ulcer<|end|>

5. Modell-Inferenz vor der Feinabstimmung

Bevor du das Modell trainierst, solltest du unbedingt seine Basisleistung checken, damit du sie nach der Feinabstimmung vergleichen kannst. Dafür machen wir eine Hilfsfunktion namens „ render_inference_harmony “, die eine Aufforderung im Harmony-Stil vorbereitet, die die genauen Anweisungen des Entwicklers und die Frage des Benutzers enthält, aber die Antwort des Assistenten leer lässt, damit das Modell sie vervollständigen kann.

def render_inference_harmony(question):
    convo = Conversation.from_messages([
        Message.from_role_and_content(
            Role.DEVELOPER,
            DeveloperContent.new().with_instructions(
                "You are a medical expert with advanced knowledge in clinical reasoning and diagnostics. "
                "Respond with ONLY the final diagnosis/cause in ≤5 words."
            )
        ),
        Message.from_role_and_content(Role.USER, question.strip()),
    ])
    tokens = enc.render_conversation_for_completion(convo, Role.ASSISTANT)
    text = enc.decode(tokens)
    return text

Als Nächstes holen wir uns die erste Probe aus dem Datensatz, formatieren sie mit dieser Funktion, zerlegen sie in Token und schicken sie durch das Modell, um eine Antwort zu bekommen:

question = dataset[0]["Open-ended Verifiable Question"]

text = render_inference_harmony(question)

inputs = tokenizer(
    [text + tokenizer.eos_token], return_tensors="pt"
).to("cuda")
outputs = model.generate(
    input_ids=inputs.input_ids,
    attention_mask=inputs.attention_mask,
    max_new_tokens=20,
    eos_token_id=tokenizer.eos_token_id,
    use_cache=True,
)
response = tokenizer.batch_decode(outputs)
print(response[0])

In diesem Test ist die Antwort vom Modell deutlich länger und ausführlicher als gewünscht, obwohl in den Entwickleranweisungen ausdrücklich um eine kurze Diagnose (≤5 Wörter) gebeten wurde. 

<|start|>developer<|message|># Instructions

You are a medical expert with advanced knowledge in clinical reasoning and diagnostics. Respond with ONLY the final diagnosis/cause in ≤5 words.<|end|><|start|>user<|message|>An 88-year-old woman with osteoarthritis is experiencing mild epigastric discomfort and has vomited material resembling coffee grounds multiple times. Considering her use of naproxen, what is the most likely cause of her gastrointestinal blood loss?<|end|><|start|>assistant<|return|>We have an old woman with NSAID use causing ulcer bleed. The question: "An 88

Anstatt einfach „Magengeschwür“ (die richtige Antwort) zu sagen, hat das Modell eine ausführliche Erklärung über die Einnahme von NSAIDs und Magengeschwürblutungen gegeben.

dataset[0]["Ground-True Answer"]
'Gastric ulcer'

6. Das Modell für das Training einrichten

Um das Modell effizient zu optimieren, nutzen wir LoRA (Low-Rank Adaptation), mit dem wir nur einen kleinen Teil der Parameter trainieren können, während das Basismodell unverändert bleibt. Das spart echt viel Speicherplatz und macht das Training billiger.

Zuerst definieren wir einen LoraConfig “, der den Rang, den Skalierungsfaktor und die spezifischen Zielschichten angibt, wo LoRA-Adapter eingefügt werden sollen.

from peft import LoraConfig, get_peft_model

peft_config = LoraConfig(
    r=8,
    lora_alpha=16,
    target_modules="all-linear",
    target_parameters=[
        "7.mlp.experts.gate_up_proj",
        "7.mlp.experts.down_proj",
        "15.mlp.experts.gate_up_proj",
        "15.mlp.experts.down_proj",
        "23.mlp.experts.gate_up_proj",
        "23.mlp.experts.down_proj",
    ],
)
peft_model = get_peft_model(model, peft_config)
peft_model.print_trainable_parameters()

Es gibt nur etwa 15 Millionen Parameter (≈0,07 % des gesamten Modells), die trainierbar sind, und die Größe des Adapters liegt bei etwa 16 MB, was im Vergleich zur vollständigen Feinabstimmung einen enormen Effizienzgewinn bedeutet.

trainable params: 15,040,512 || all params: 20,929,797,696 || trainable%: 0.0719

Als Nächstes richten wir das Training mit „ SFTConfig “ aus der Bibliothek „ trl “ ein. Dazu gehören Hyperparameter wie Lernrate, Batchgröße, Gradientenakkumulation, Warmup-Verhältnis und Scheduler-Typ:

from trl import SFTConfig

training_args = SFTConfig(
    learning_rate=2e-4,
    gradient_checkpointing=True,
    num_train_epochs=1,
    logging_steps=10,
    per_device_train_batch_size=4,
    gradient_accumulation_steps=4,
    max_length=2048,
    warmup_ratio=0.03,
    lr_scheduler_type="cosine_with_min_lr",
    lr_scheduler_kwargs={"min_lr_rate": 0.1},
    output_dir="gpt-oss-20b-medical-qa",
    report_to="trackio",
    push_to_hub=True,
)

7. Das Modell trainieren

Nachdem wir den Datensatz vorbereitet, den LoRA-Adapter angeschlossen und die Trainingsargumente konfiguriert haben, können wir jetzt mit dem Feinabstimmungsprozess loslegen. Wir nutzen das SFTTrainer ” aus der Bibliothek „ trl ”, das das überwachte Fine-Tuning vereinfacht, indem es das Modell, den Tokenizer, den Datensatz und die Trainingsschleife an einem Ort verwaltet:

from trl import SFTTrainer

trainer = SFTTrainer(
    model=peft_model,
    args=training_args,
    train_dataset=dataset,
    processing_class=tokenizer,
)
trainer.train()

Während des Trainings wird der Verlust immer kleiner, was zeigt, dass das Modell lernt, seine Antworten an den medizinischen Q&amp;A-Datensatz im Harmony-Format anzupassen.

Verlust beim Modelltraining

Sobald das Training abgeschlossen ist, speichern wir das fein abgestimmte Modell lokal und übertragen es dann an den Hugging Face Hubübertragen. Wichtig ist, dass nur die Gewichte des LoRA-Adapters (nicht das komplette 20B-Modell) hochgeladen werden, was das Repository leicht und einfach zu teilen macht:

trainer.save_model(training_args.output_dir)
trainer.push_to_hub(dataset_name="kingabzpro/gpt-oss-20b-medical-qa")

Damit erstellst du ein neues Modell-Repository auf Hugging Face unter: kingabzpro/gpt-oss-20b-medical-qa.

Quelle: kingabzpro/gpt-oss-20b-medical-qa

8. Modell-Inferenz nach Feinabstimmung

Nach der Feinabstimmung können wir das Modell testen, um zu sehen, ob es jetzt besser den Vorgaben des Entwicklers entspricht. Dafür laden wir erst mal das Basis-Modell GPT-OSS 20B und hängen dann die fein abgestimmten LoRA-Adapter dran.

from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel

# Load the tokenizer
tokenizer = AutoTokenizer.from_pretrained("openai/gpt-oss-20b")

# Load the original model first
model_kwargs = dict(attn_implementation="eager", torch_dtype="auto", use_cache=True, device_map="auto")
base_model = AutoModelForCausalLM.from_pretrained("openai/gpt-oss-20b", **model_kwargs).cuda()

# Merge fine-tuned weights with the base model
peft_model_id = "gpt-oss-20b-medical-qa"
model = PeftModel.from_pretrained(base_model, peft_model_id)
model = model.merge_and_unload()

Als Nächstes machen wir eine Inferenz für eine Stichprobe aus dem Datensatz. Die Frage wird im Harmony-Stil formatiert, in Token zerlegt, durch das Modell geschickt und wieder in Text zurückverwandelt:

question = dataset[0]["Open-ended Verifiable Question"]

text = render_inference_harmony(question)

inputs = tokenizer(
    [text + tokenizer.eos_token], return_tensors="pt"
).to("cuda")
outputs = model.generate(
    input_ids=inputs.input_ids,
    attention_mask=inputs.attention_mask,
    max_new_tokens=20,
    eos_token_id=tokenizer.eos_token_id,
    use_cache=True,
)
response = tokenizer.batch_decode(outputs)
print(response[0])

Das optimierte Modell liefert jetzt eine kurze und genaue Antwort. Das ist viel näher am richtigen Label („Magengeschwür“) und hält sich an die Regel von ≤5 Wörtern.

<|start|>developer<|message|># Instructions

You are a medical expert with advanced knowledge in clinical reasoning and diagnostics. Respond with ONLY the final diagnosis/cause in ≤5 words.<|end|><|start|>user<|message|>An 88-year-old woman with osteoarthritis is experiencing mild epigastric discomfort and has vomited material resembling coffee grounds multiple times. Considering her use of naproxen, what is the most likely cause of her gastrointestinal blood loss?<|end|><|start|>assistant<|return|><|message|>Stomach ulcer<|end|><|return|>

Wir können auch noch eine Probe testen, um die Konsistenz zu checken:

question = dataset[10]["Open-ended Verifiable Question"]

text = render_inference_harmony(question)

inputs = tokenizer(
    [text + tokenizer.eos_token], return_tensors="pt"
).to("cuda")
outputs = model.generate(
    input_ids=inputs.input_ids,
    attention_mask=inputs.attention_mask,
    max_new_tokens=20,
    eos_token_id=tokenizer.eos_token_id,
    use_cache=True,
)
response = tokenizer.batch_decode(outputs)
print(response[0])

Super. Das fein abgestimmte Modell hat präzise, genaue und anweisungsgetreue Antworten erzeugt.

<|start|>developer<|message|># Instructions

You are a medical expert with advanced knowledge in clinical reasoning and diagnostics. Respond with ONLY the final diagnosis/cause in ≤5 words.<|end|><|start|>user<|message|>What substance is primarily filtered in the renal tubules with minimal secretion or re-absorption?<|end|><|start|>assistant<|return|><|message|>creatinine<|end|><|return|>

Fazit

Es sind spannende Zeiten für die Open-Source-KI-Community. Auch wenn die neuen GPT-OSS-Modelle vielleicht noch nicht die Benchmarks anführen, sind sie echt vielversprechend, vor allem in ihren jeweiligen Parameterklassen, wo kleinere Modelle trotzdem beeindruckende Ergebnisse liefern können.

In diesem Tutorial haben wir das GPT-OSS 20B-Modell für medizinische Fragen mit LoRA-Adaptern und dem Harmony-Prompt-Stil optimiert. Die Ergebnisse sind echt vielversprechend: Das optimierte Modell liefert präzise und genaue Antworten, die auf klinische Denkaufgaben abgestimmt sind. Mit mehr Trainingsphasen, größeren Datensätzen und verbesserten Systemaufforderungen kann die Leistung noch weiter gesteigert werden.

Wenn du nach einem praktischen Kurs suchst, um dich mit der Feinabstimmung vertraut zu machen, solltest du dir unbedingt Fine-Tuning mit Llama 3.


Abid Ali Awan's photo
Author
Abid Ali Awan
LinkedIn
Twitter

Als zertifizierter Data Scientist ist es meine Leidenschaft, modernste Technologien zu nutzen, um innovative Machine Learning-Anwendungen zu entwickeln. Mit meinem fundierten Hintergrund in den Bereichen Spracherkennung, Datenanalyse und Reporting, MLOps, KI und NLP habe ich meine Fähigkeiten bei der Entwicklung intelligenter Systeme verfeinert, die wirklich etwas bewirken können. Neben meinem technischen Fachwissen bin ich auch ein geschickter Kommunikator mit dem Talent, komplexe Konzepte in eine klare und prägnante Sprache zu fassen. Das hat dazu geführt, dass ich ein gefragter Blogger zum Thema Datenwissenschaft geworden bin und meine Erkenntnisse und Erfahrungen mit einer wachsenden Gemeinschaft von Datenexperten teile. Zurzeit konzentriere ich mich auf die Erstellung und Bearbeitung von Inhalten und arbeite mit großen Sprachmodellen, um aussagekräftige und ansprechende Inhalte zu entwickeln, die sowohl Unternehmen als auch Privatpersonen helfen, das Beste aus ihren Daten zu machen.

Themen

Die besten OpenAI-Kurse

Lernpfad

OpenAI Grundlagen

0 Min.
Beginne mit der Erstellung von KI-Systemen mit Modellen von OpenAI. Lerne, wie du die OpenAI-API nutzt, um die GPT- und Whisper-Modelle von OpenAI aufzurufen.
Siehe DetailsRight Arrow
Kurs starten
Mehr anzeigenRight Arrow
Verwandt

Der Blog

Top 30 Generative KI Interview Fragen und Antworten für 2024

Dieser Blog bietet eine umfassende Sammlung von Fragen und Antworten zu generativen KI-Interviews, die von grundlegenden Konzepten bis hin zu fortgeschrittenen Themen reichen.
Hesam Sheikh Hassani's photo

Hesam Sheikh Hassani

15 Min.

Der Blog

Arten von KI-Agenten: Ihre Rollen, Strukturen und Anwendungen verstehen

Lerne die wichtigsten Arten von KI-Agenten kennen, wie sie mit ihrer Umgebung interagieren und wie sie in verschiedenen Branchen eingesetzt werden. Verstehe einfache reflexive, modellbasierte, zielbasierte, nutzenbasierte, lernende Agenten und mehr.
Vinod Chugani's photo

Vinod Chugani

14 Min.

Der Blog

Die 50 besten AWS-Interview-Fragen und Antworten für 2025

Ein kompletter Leitfaden zur Erkundung der grundlegenden, mittleren und fortgeschrittenen AWS-Interviewfragen, zusammen mit Fragen, die auf realen Situationen basieren.
Zoumana Keita 's photo

Zoumana Keita

15 Min.

Der Blog

Q2 2023 DataCamp Donates Digest

DataCamp Donates hat im zweiten Quartal 2023 über 20.000 Stipendien an unsere gemeinnützigen Partner vergeben. Erfahre, wie fleißige benachteiligte Lernende diese Chancen in lebensverändernde berufliche Erfolge verwandelt haben.
Nathaniel Taylor-Leach's photo

Nathaniel Taylor-Leach

Der Blog

Die 20 besten Snowflake-Interview-Fragen für alle Niveaus

Bist du gerade auf der Suche nach einem Job, der Snowflake nutzt? Bereite dich mit diesen 20 besten Snowflake-Interview-Fragen vor, damit du den Job bekommst!
Nisha Arya Ahmed's photo

Nisha Arya Ahmed

15 Min.

Lernprogramm

Python Switch Case Statement: Ein Leitfaden für Anfänger

Erforsche Pythons match-case: eine Anleitung zu seiner Syntax, Anwendungen in Data Science und ML sowie eine vergleichende Analyse mit dem traditionellen switch-case.
Matt Crabtree's photo

Matt Crabtree

Mehr anzeigenMehr anzeigen