Langkontext-gpt-oss-Training
Wir freuen uns, Unsloth Flex Attention Support für das OpenAI-gpt-oss-Training vorzustellen, der ermöglicht >8× längere Kontextlängen, >50 % weniger VRAM-Nutzung und >1,5× schnelleres Training (ohne Genauigkeitsverlust) gegenüber allen Implementierungen, einschließlich jener mit Flash Attention 3 (FA3). Unsloth Flex Attention macht es möglich, mit einer Kontextlänge von 60K auf einer H100-GPU mit 80 GB VRAM für BF16 LoRA zu trainieren. Außerdem:
Sie können jetzt exportieren/speichern Ihr mit QLoRA feinabgestimmtes gpt-oss-Modell nach llama.cpp, vLLM, Ollama oder HF
Wir haben das gpt-oss-Training behoben bei dem die Verluste gegen unendlich gingen auf float16-GPUs (wie T4 Colab)
Wir haben die gpt-oss-Implementierungsprobleme behoben Probleme, die für Unsloth irrelevant waren, insbesondere die Sicherstellung, dass
swiglu_limit = 7.0während der MXFP4-Inferenz in transformers korrekt angewendet wird
🦥Einführung von Unsloth Flex Attention Support
Mit Unsloths Flex Attention Support kann eine einzelne H100 mit 80 GB VRAM bis zu 81K Kontextlänge mit QLoRA und 60K Kontext mit BF16 LoRA bewältigen! Diese Verbesserungen gelten für BEIDE gpt-oss-20b und gpt-oss-120b! Je mehr Kontextlänge Sie verwenden, desto größer sind die Vorteile von Unsloth Flex Attention:

Im Vergleich dazu erreichen alle anderen nicht von Unsloth stammenden Implementierungen maximal 9K Kontextlänge auf einer 80-GB-GPU und können mit FA3 nur 15K Kontext erreichen. Aber, FA3 ist für das gpt-oss-Training ungeeignet, da die Rückwärtsausbreitungsunterstützung für Attention Sinks fehlt. Wenn Sie FA3 zuvor für das gpt-oss-Training verwendet haben, würden wir Ihnen empfehlen, es vorerst nicht zu verwenden . Die maximale Kontextlänge, die Sie ohne Unsloth auf 80 GB VRAM erreichen können, beträgt also ~9K.
Das Training mit Unsloth Flex Attention liefert mindestens eine 1,3× Beschleunigung, wobei die Gewinne mit zunehmender Kontextlänge wachsen und bis zu 2× schneller werden. Da Flex Attention mit dem Kontext skaliert, bringen längere Sequenzen größere Einsparungen sowohl beim VRAM als auch bei der Trainingszeit, wie hier beschrieben.
Ein großes Dankeschön an Rohan Pandey für seine Flex Attention-Implementierung, die die Entwicklung von Unsloths Flex Attention-Implementierung direkt inspiriert hat.
🕶️ Attention Sinks
OpenAIs GPT-OSS-Modell verwendet ein abwechselndes Muster aus Sliding-Window-Attention, Full Attention, Sliding-Window-Attention und so weiter (SWA, FA, SWA, FA usw.). Jedes Sliding Window beachtet nur 128 Tokens (einschließlich des aktuellen Tokens), sodass die Berechnung erheblich reduziert wird. Dies bedeutet jedoch auch, dass das Abrufen und Schlussfolgern über lange Kontexte aufgrund des kleinen Sliding Windows nutzlos wird. Die meisten Labs beheben dies, indem sie das Sliding Window auf 2048 oder 4096 Tokens erweitern.
OpenAI nutzte Attention Sinks aus dem Paper Efficient Streaming Language Models with Attention Sinks das zeigt, dass man ein kleines Sliding Window verwenden kann, jedoch eine globale Attention auf das erste Token hinzufügen muss! Das Paper bietet unten eine gute Illustration:

Das Paper stellt fest, dass der Attention-Mechanismus den ersten wenigen Tokens (1 bis 4) offenbar viel Gewicht zuweist, und indem sie während der Sliding-Window-Operation entfernt werden, verschwinden diese „wichtigen“ ersten wenigen Tokens, was zu schlechter Langkontext-Retrieval-Leistung führt.
Wenn wir die Log-Perplexity (höher ist schlechter) auftragen und Langkontext-Inferenz nach der im vortrainierten Modell festgelegten Kontextlänge durchführen, sehen wir, dass die Perplexity stark ansteigt (nicht gut). Die rote Linie (verwendet Attention Sinks) bleibt jedoch niedrig, was sehr gut ist!

Das Paper zeigt auch, dass die Methode „Attention Is Off By One“ teilweise funktioniert, allerdings muss man auch einige zusätzliche Sink-Tokens hinzufügen, um niedrigere Perplexities zu erhalten. Das Paper zeigt, dass das Hinzufügen eines einzigen lernbaren Sink-Tokens bemerkenswert gut funktioniert! Und genau das hat OpenAI für GPT-OSS getan!

📐Unsloths Flex Attention-Implementierung
Flex Attention https://pytorch.org/blog/flexattention/ ist äußerst leistungsfähig, da sie dem Anwender 2 Anpassungswege für den Attention-Mechanismus bietet - einen Score-Modifikator (f) und eine Maskierungsfunktion (M).
Die Score-Modifikator (f) ermöglicht es uns, die Attention-Logits vor der Softmax-Operation zu bearbeiten, und die Maskierungsfunktion (M) ermöglicht es uns, Operationen zu überspringen, wenn wir sie nicht benötigen (z. B. sieht Sliding-Window-Attention nur die letzten 128 Tokens).
Der Trick ist, dass Flex Attention schnelle, automatisch generierte Triton-Kernels mit beliebigen Score-Modifikatoren und Maskierungsfunktionen bereitstellt!
σ(s×f(QKT+M))
Das bedeutet, dass wir Flex Attention verwenden können, um Attention Sinks zu implementieren! Die Implementierung eines einzelnen Attention Sink ist sowohl im ursprünglichen GPT-OSS-Repo von OpenAI als auch in der Transformers-Implementierung von HuggingFace enthalten.
Das oben Gezeigte zeigt, dass wir den Sink ganz am Ende von Q @ K.T anhängen, die Softmax durchführen und die letzte Spalte entfernen, die das Sink-Token war.
Mit einigen Visualisierungswerkzeugen aus dem Github-Repo von Flex Attentionkönnen wir das visualisieren. Nehmen wir an, die Sequenzlänge beträgt 16 und das Sliding Window 5. Links ist die letzte Sink-Spalte (Standardimplementierung) und rechts ist, wenn wir die Sink-Position auf Index 0 verschieben (unsere Implementierung).
Sink-Position am Ende (Standard)

Sink-Position auf Index 0 verschieben

Interessante Erkenntnis: Die offizielle Flex-Attention-Sliding-Window-Implementierung betrachtet die Fenstergröße als die Anzahl der letzten Tokens PLUS EINS da das aktuelle Token eingeschlossen ist. Die HuggingFace- und GPT-OSS-Implementierungen sehen strikt nur die letzten N Tokens. Also stammt das Folgende aus https://pytorch.org/blog/flexattention/ und https://github.com/meta-pytorch/attention-gym:
Standard Flex Attention (3+1 Tokens)

HuggingFace, GPT-OSS (3+0 Tokens)

Wir haben auch anhand der offiziellen GPT-OSS-Implementierung von OpenAI bestätigt, ob wir hier die letzten N- oder N+1-Tokens beachten: https://github.com/openai/gpt-oss/blob/main/gpt_oss/torch/model.py

Und wir sehen, dass nur die letzten 3 Tokens (nicht 3+1) beachtet werden! Das bedeutet, dass wir statt <= SLIDING_WINDOW, verwende < SLIDING_WINDOW verwenden sollten (also kleiner als, nicht gleich).
Da wir außerdem den Index des Sink-Tokens an den Anfang verschoben haben, müssen wir 1 zu q_idx addieren, um korrekt zu indizieren:
Um unsere Implementierung mit Index 0 zu bestätigen, haben wir überprüft, dass der Trainingsverlust mit den Standard-Hugging-Face-Läufen (ohne Unsloth Flex Attention) konsistent bleibt, wie in unserem Diagramm gezeigt:

📜 Mathematische Herleitung für Attention Sinks
Es gibt noch eine andere Möglichkeit, die Attention Sinks zu berechnen, ohne K und V zu paddieren. Wir stellen zunächst fest, dass die Softmax-Operation das tut, und wir wollen die zweite Version mit Sinks vorerst als Skalar:\
Wir können das LogSumExp aus Flex Attention über return_lse = True erhalten, und daher machen wir:
Und wir können nun die Sink-Version der Attention leicht herleiten. Wir stellen jedoch fest, dass dieser Prozess etwas höheren Fehler aufweist als der Zero-Padding-Ansatz, daher verwenden wir weiterhin standardmäßig unsere ursprüngliche Version.
💾NEU: Speichern in GGUF, vLLM nach dem gpt-oss-Training
Du kannst gpt-oss jetzt mit QLoRA feinabstimmen und das Modell direkt speichern, exportieren oder zusammenführen zu llama.cpp, vLLModer HF - nicht nur Unsloth. Wir werden hoffentlich bald ein kostenloses Notebook veröffentlichen.
Zuvor war jedes mit QLoRA feinabgestimmte gpt-oss-Modell darauf beschränkt, nur in Unsloth ausgeführt zu werden. Wir haben diese Einschränkung entfernt, indem wir die Möglichkeit eingeführt haben, im MXFP4 nativen Format unter Verwendung von save_method="mxfp4" und On-Demand-Dekquantisierung von MXFP4 Basismodellen (wie gpt-oss) zusammenzuführen, wodurch es möglich wird, Ihr feinabgestimmtes Modell im bf16-Format zu exportieren mit save_method="merged_16bit" .
Die MXFP4 Das native Merge-Format bietet gegenüber dembf16-Format deutliche Leistungsverbesserungen: Es benötigt bis zu 75 % weniger Speicherplatz, reduziert den VRAM-Verbrauch um 50 %, beschleunigt das Zusammenführen um das 5-10-Fache und ermöglicht eine deutlich schnellere Konvertierung in das GGUF
Neu: Das Speichern oder Zusammenführen von mit QLoRA feinabgestimmten Modellen zu GGUF wird jetzt für die Verwendung in anderen Frameworks unterstützt (z. B. Hugging Face, llama.cpp mit GGUF). MXFP4 Nachdem du dein gpt-oss-Modell feinabgestimmt hast, kannst du es mit Folgendem in das
Wenn Sie das Modell lieber zusammenführen und auf den Hugging-Face-Hub hochladen möchten, verwenden Sie:
Um Inferenz auf dem zusammengeführten Modell auszuführen, können Sie unter anderem vLLM und Llama.cpp verwenden. OpenAI empfiehlt diese Inferenz-Einstellungen für beide Modelle: temperature=1.0, top_p=1.0, top_k=0
✨ Speichern für Llama.cpp
Hole dir die neueste
llama.cppauf GitHub hier. Du kannst auch den untenstehenden Build-Anweisungen folgen. Ändere-DGGML_CUDA=ONzu-DGGML_CUDA=OFFwenn du keine GPU hast oder nur CPU-Inferenz möchtest.Konvertiere das MXFP4 zusammengeführte Modell:
Führe Inferenz auf dem quantisierten Modell aus:
✨ Speichern in SGLang
Bauen Sie SGLang aus dem Quellcode:\
Starten Sie den SGLang-Server:\
Inferenz ausführen:\
♦️gpt-oss direkt feinabstimmen
Wir haben auch Unterstützung für das direkte Feinabstimmen von gpt-oss-Modellen hinzugefügt, indem wir Patches implementiert haben, die das Laden des nativen MXFP4-quantisierten Formats ermöglichen. Dadurch ist es möglich, das Modell 'openai/gpt-oss' mit weniger als 24 GB VRAM zu laden und es mit QLoRA feinabzustimmen. Laden Sie das Modell einfach mit:
fügen Sie eine Peft-Schicht hinzu mit FastLanguageModel.get_peft_model und führen Sie eine SFT-Feinabstimmung über das Peft-Modell aus.
🐛Fehlerbehebungen für gpt-oss
Wir kürzlich mit Hugging Face zusammengearbeitet um Inferenzprobleme zu beheben, indem OpenAIs Kernel verwendet und sichergestellt wird, dass swiglu_limit = 7.0 während der MXFP4-Inferenz korrekt angewendet wird.
Basierend auf Nutzerfeedback haben wir entdeckt, dass längere QLoRA-Trainingsläufe (über 60 Schritte hinaus) dazu führen konnten, dass die Verluste divergierten und schließlich einen Fehler auslösten. Dieses Problem trat nur auf Geräten auf, die BF16 nicht unterstützen und stattdessen auf F16 zurückgreifen (z. B. T4-GPUs). Wichtig ist, dass es weder QLoRA-Training auf A100- oder H100-GPUs noch LoRA-Training auf f16-GPUs beeinträchtigte.
Nach umfangreichen Untersuchungen haben wir nun das Verhalten des Trainingsverlusts über alle GPU-Setups hinweg angeglichen, einschließlich GPUs, die auf F16 beschränkt sind. Wenn Sie zuvor deshalb Probleme hatten, empfehlen wir Ihnen, unser neues aktualisiertes gpt-oss-Notebook zu verwenden!

Wir mussten viele, viele Experimente durchführen, um die Trainingsverlustkurve von float16 der von bfloat16-Maschinen (blaue Linie) anzugleichen. Wir haben Folgendes festgestellt:
Reines float16 geht bei Schritt 50 gegen unendlich
Wir haben festgestellt, dass die Down-Projektionen im MoE enorme Ausreißer aufweisen
Aktivierungen müssen in bfloat16 oder float32 gespeichert werden
Unten sind die absoluten Aktivierungsbeträge für GPT OSS 20B gezeigt, und einige spiken wirklich - dies führt auf float16-Maschinen zu einem Überlauf, da der maximale Bereich von float16 65504 beträgt.
Wir haben dies in Unsloth behoben, sodass das gesamte float16-Training sofort funktioniert!

🔢 Implementierungen für Sink Attention
OpenAIs Implementierung des Sink-Tokens ist hier bereitgestellt. Wir stellen sie unten bereit:
Die HuggingFace-transformers-Implementierung ist hier bereitgestellt. Wir stellen sie auch unten bereit:
Zuletzt aktualisiert
War das hilfreich?

