# 3x schnelleres LLM-Training mit Unsloth-Kernels + Packing

Unsloth unterstützt jetzt bis zu **5× schneller** (typischerweise 3x) Training mit unseren neuen benutzerdefinierten **RoPE- und MLP-Triton-Kernels**, plus unser neues intelligentes automatisches Packing. Unsloths neue Kernel + Funktionen erhöhen nicht nur die Trainingsgeschwindigkeit, sondern **reduziert außerdem den VRAM-Verbrauch (30% - 90%)** ohne Genauigkeitsverlust. [Unsloth GitHub](https://github.com/unslothai/unsloth)\
\
Das bedeutet, dass Sie jetzt LLMs wie [Qwen3](/docs/de/modelle/tutorials/qwen3-how-to-run-and-fine-tune.md)-4B nicht nur auf nur **3GB VRAM**, sondern auch 3x schneller trainieren können.

Unser Auto [**ohne Padding**](#padding-free-by-default) kontaminationsfreies Packing wird für alle Trainingsläufe automatisch und intelligent aktiviert, ohne Änderungen, und für alle schnellen Attention-Backends (FlashAttention 3, xFormers, SDPA). [Benchmarks](#analysis-and-benchmarks) zeigen, dass Trainingsverluste genau mit Nicht-Packing-Läufen übereinstimmen **genau**.

* **2.3x schnellere QK Rotary Embedding** fusionierter Triton-Kernel mit Packing-Unterstützung
* Aktualisierte SwiGLU-, GeGLU-Kernel mit **int64-Indexierung für langen Kontext**
* **2.5x bis 5x schnelleres kontaminationsfreies Packing** mit xformers-, SDPA-, FA3-Backends
* **2.1x schnelleres padding-freies, 50% weniger VRAM**, 0% Änderung der Genauigkeit
* Unsloth hat jetzt außerdem eine verbesserte SFT-Loss-Stabilität und vorhersehbarere GPU-Auslastung.
* Dieses neue Upgrade funktioniert **für alle Trainingsmethoden** z. B. vollständiges Feintuning, Vortraining usw.

### :drum:Fusionierter QK RoPE Triton-Kernel mit Packing

Im Dezember 2023 stellten wir im Rahmen unseres Unsloth-Starts einen in Triton geschriebenen RoPE-Kernel vor. Im März 2024 machte ein Community-Mitglied das End-to-End-Training 1–2% schneller, indem es den RoPE-Kernel optimierte, um das Starten eines Blocks für eine Gruppe von Heads zu ermöglichen. Siehe [PR 238](https://github.com/unslothai/unsloth/pull/238).

<figure><img src="/files/6393cf34826bde6f3d3976a550258627a3fa3e7e" alt="" width="563"><figcaption></figcaption></figure>

Ein Problem war, dass es für jedes Q und K zwei Triton-Kernel gab. Wir haben sie jetzt in einen Triton-Kernel zusammengeführt und variable Länge RoPE aktiviert, was für padding-freies Training und Packing-Unterstützung unerlässlich war. Dadurch ist der RoPE-Kernel in Mikrobenchmarks **2.3x schneller bei längeren Kontextlängen**, und 1.9x schneller bei kürzeren Kontextlängen.

Wir haben außerdem alle Klone und zusammenhängenden Transpose-Operationen eliminiert, und so **ist RoPE jetzt vollständig inplace**, was den GPU-Speicher weiter reduziert. Hinweis für den Backward-Pass: Wir sehen, dass `sin1 = -sin1` da:

```
Q * cos + rotate_half(Q) * sin
äquivalent ist zu
Q * cos + Q @ R * sin
wobei R eine Rotationsmatrix ist [ 0,  I]
                             [-I,  0]
dC/dY = dY * cos + dY @ R.T * sin
wobei R.T wieder dieselbe [ 0, -I] ist
aber das Minus ist transponiert. [ I,  0]
```

### :railway\_car:Int64-Indexierung für Triton-Kernel

Während des Trainings mit 500K langer Kontextlänge, das wir in [500K Context Training](/docs/de/blog/500k-context-length-fine-tuning.md)eingeführt haben, bekamen wir CUDA-Out-of-Bounds-Fehler. Das lag daran, dass MLP-Kernel für SwiGLU, GeGLU int32-Indexierung hatten, welche in Triton und CUDA standardmäßig ist.

Wir können nicht einfach `tl.program_id(0).to(tl.int64)` machen, da das Training aufgrund der int64-Indexierung etwas langsamer wäre. Stattdessen machen wir dies zu einer `LONG_INDEXING: tl.constexpr` Variablen, damit der Triton-Compiler dies spezialisieren kann. Dadurch laufen kurze und lange Kontextläufe beide sehr gut!

{% code overflow="wrap" %}

```python
block_idx = tl.program_id(0)
if LONG_INDEXING:
    offsets = block_idx.to(tl.int64) * BLOCK_SIZE + tl.arange(0, BLOCK_SIZE).to(tl.int64)
    n_elements = tl.cast(n_elements, tl.int64)
else:
    offsets = block_idx * BLOCK_SIZE + tl.arange(0, BLOCK_SIZE)
```

{% endcode %}

### :abacus:Warum Padding nötig ist & mathematische Beschleunigung

Computer und GPUs können Datensätze unterschiedlicher Länge nicht direkt verarbeiten, daher müssen wir sie mit Nullen auffüllen. Das verursacht Verschwendung. Angenommen, wir haben einen Datensatz mit 50% kurzen Sequenzen S und 50% langen Sequenzen L, dann führt Padding im schlimmsten Fall zu einem Token-Einsatz von $$\text{batchsize} \times L$$ da die längste Sequenzlänge dominiert.

Indem wir mehrere Beispiele in einen einzelnen, langen eindimensionalen Tensor packen, können wir einen erheblichen Teil der Padding-Overhead eliminieren. Tatsächlich erhalten wir die untenstehende Token-Nutzung:

$$
\text{Token Usage} = \frac{\text{batchsize}}{2}L+\frac{\text{batchsize}}{2}S
$$

Durch etwas Mathematik und Algebra können wir die Beschleunigung wie folgt berechnen:

$$
\text{Speedup} = \frac{\text{batchsize} \times L}{\frac{\text{batchsize}}{2}L+\frac{\text{batchsize}}{2}S} = 2 \frac{L}{L + S}
$$

Indem wir annehmen $$S\rightarrow0$$ dann erhalten wir eine theoretische 2x-Beschleunigung, da $$2 \frac{L}{L + 0} = 2$$

Wenn man das Verhältnis von 50% kurzen Sequenzen ändert und annimmt, dass wir MEHR kurze Sequenzen haben, z. B. 20% lange Sequenzen und 80% kurze Sequenzen, erhalten wir $$\frac{L}{0.2L + 0.8S}\rightarrow\frac{L}{0.2L}=5$$ also 5x schnelleres Training! Das bedeutet, dass die Beschleunigung durch Packing davon abhängt, wie viele kurze Reihen Ihr Datensatz hat (je mehr kurze, desto schneller).

### :clapper:Padding-frei per Voreinstellung

Zusätzlich zu den großen Durchsatzgewinnen, die verfügbar sind, wenn man `packing = True` in Ihrem `SFTConfig` , werden wir **verwenden, nutzen Sie automatisch padding-freies Batching** um Padding-Verschwendung zu reduzieren, den Durchsatz zu verbessern und die Token/s-Durchsatzrate zu erhöhen, während das ***genau gleiche Loss*** wie in der vorherigen Version von Unsloth resultiert.

Zum Beispiel sehen wir bei Qwen3-8B und Qwen3-32B eine Verringerung des Speicherverbrauchs um 60%, eine 2x schnellere Ausführung und exakt dieselben Loss- und Grad-Norm-Kurven!

<div><figure><img src="/files/6d543e37363444ca289b27e01c1e796229ce3184" alt=""><figcaption></figcaption></figure> <figure><img src="/files/2545946f47460de67f39d1af920a05d1e016803a" alt=""><figcaption></figcaption></figure></div>

<div><figure><img src="/files/8f234ecb114b09ff1c90b8c0e59df31df5ac1dd9" alt="" width="563"><figcaption></figcaption></figure> <figure><img src="/files/59537ce9c17043585239371b290df1fd9a5b9eda" alt="" width="563"><figcaption></figcaption></figure> <figure><img src="/files/b8582e41bb641a6be88c8f4283486c97dd9ede65" alt="" width="563"><figcaption></figcaption></figure> <figure><img src="/files/e0eb6aeab8ce3e785d4fa1d6c6ca584e1d273231" alt="" width="563"><figcaption></figcaption></figure></div>

### :spades:Kontaminationsfreies Packing: 2-5x schnelleres Training

Reale Datensätze können unterschiedliche Sequenzlängen enthalten. Wenn man z. B. die Batch-Größe auf 32 erhöht, verursacht das Padding, macht das Training langsamer und verbraucht mehr VRAM.

{% hint style="success" %}
Früher machte eine Erhöhung von `batch_size` auf große Zahlen (>32) das Training LANGSAMER, nicht schneller. Das lag am Padding – wir können dieses Problem jetzt durch `packing = True`eliminieren, und so ist das Training SCHNELLER!
{% endhint %}

Wenn wir mehrere Proben in einen einzigen eindimensionalen Tensor packen, behalten wir Metadaten zur Sequenzlänge bei, um Proben korrekt zu maskieren, ohne Attention zwischen Proben zu leaken. Wir benötigen außerdem den in [#fused-qk-rope-triton-kernel-with-packing](#fused-qk-rope-triton-kernel-with-packing "mention") beschriebenen RoPE-Kernel, um Positions-IDs zurücksetzen zu können.

{% columns %}
{% column width="41.66666666666667%" %}

<div align="center" data-full-width="false"><figure><img src="/files/91019268258c0671027ac99b2c829533d4f711d8" alt="" width="563"><figcaption><p>4 Beispiele ohne Packing verschwenden Platz</p></figcaption></figure></div>

{% endcolumn %}

{% column width="58.33333333333333%" %}

<figure><img src="/files/1c9b9a931cebaa2bacd0d9c08b9a551859d35675" alt=""><figcaption><p>Kontaminationsfreies Packing erzeugt korrektes Attention-Muster</p></figcaption></figure>
{% endcolumn %}
{% endcolumns %}

Wenn man das Verhältnis von 50% kurzen Sequenzen ändert und annimmt, dass wir MEHR kurze Sequenzen haben, z. B. 20% lange Sequenzen und 80% kurze Sequenzen, erhalten wir $$\frac{L}{0.2L + 0.8S}\rightarrow\frac{L}{0.2L}=5$$ also 5x schnelleres Training! Das bedeutet, dass die Beschleunigung durch Packing davon abhängt, wie viele kurze Reihen Ihr Datensatz hat (je mehr kurze, desto schneller).

### :beach:Analyse und Benchmarks

Um die verschiedenen Verbesserungen beim Training mit unseren neuen Kernels und gepackten Daten zu demonstrieren, führten wir Feintuning-Läufe mit [Qwen3-32B](/docs/de/modelle/tutorials/qwen3-how-to-run-and-fine-tune.md), Qwen3-8B, Llama 3 8B auf dem `yahma/alpaca-cleaned` Datensatz durch und maßen verschiedene [Trainingsverluste](#padding-free-by-default) Durchsatz- und Effizienzmetriken. Wir verglichen unsere neuen Läufe mit einem standardmäßigen optimierten Trainingslauf mit unseren eigenen Kernel-/Optimierungen aktiviert und Kerneln wie Flash Attention 3 (FA3) aktiviert. Wir setzten `max_length = 1024` und variierten die Batch-Größe in {1, 2, 4, 8, 16, 32}. Dies erlaubt, dass die maximale Token-Anzahl pro Batch in {1024, 2048, 4096, 8192, 16K, 32K} variiert.

<figure><img src="/files/1a85c09024e61731803a3a9af75440191b15fb1f" alt="" width="563"><figcaption></figcaption></figure>

Oben wird gezeigt, wie sich die Tokens pro Sekunde (Tokens/s) Trainingsdurchsatz für das neue Unsloth mit variierender Batch-Größe verändert. Das übersetzt sich in das Training Ihres Modells auf einer Epoche Ihres Datensatzes **1.7-3x schneller (manchmal sogar 5x oder mehr)**! Diese Gewinne sind ausgeprägter, wenn viele kurze Sequenzen in Ihren Daten vorhanden sind und wenn Sie längere Trainingsläufe haben, wie in [#why-is-padding-needed-and-mathematical-speedup](#why-is-padding-needed-and-mathematical-speedup "mention")

<figure><img src="/files/556e58cda9ac92b979422c21649c49ca5f803b23" alt="" width="563"><figcaption></figcaption></figure>

oben beschrieben.

Oben wird der durchschnittliche Prozentsatz der Tokens pro Batch gezeigt, die gültig sind (d. h. kein Padding). Wenn die Batch-Länge wächst, treten in der ungepackten Variante viel mehr Padding-Tokens auf, während wir unabhängig von der maximalen Sequenzlänge eine hohe Packing-Effizienz im gepackten Fall erreichen.

<div><figure><img src="/files/6cff339406695443735c5aa255978be1e24cc3f2" alt="" width="563"><figcaption></figcaption></figure> <figure><img src="/files/411eed88505dc7a7aff7dab621236a1c990f5deb" alt="" width="563"><figcaption></figcaption></figure></div>

Beachten Sie, dass die Batching-Logik die Batches auf die maximale Sequenzlänge im Batch zuschneidet. Wenn die Batch-Größe 1 ist, sind die ungepackten Daten also alle gültige Tokens (d. h. kein Padding). Sobald jedoch mehr Beispiele in das Batch aufgenommen werden, nimmt das Padding im Durchschnitt zu und erreicht bei Batch-Größe 8 fast 50% Padding! Unsere Beispiel-Packing-Implementierung eliminiert diese Verschwendung. `yahma/alpaca-cleaned` mit `Das erste Diagramm (oben) zeigt den Fortschritt bei`max\_length = 2048 `, Unsloth neu mit Packing + Kernels (weinrot) vs. Unsloth alt (grau). Beide wurden mit`max\_steps = 500

trainiert, aber wir tragen die x-Achse in Echtzeit auf. Beachten Sie, dass wir im gepackten Fall in derselben Anzahl von Schritten (und nur etwas mehr Echtzeit) fast 40% einer Epoche trainieren, wofür im ungepackten Fall weniger als 5% einer Epoche trainiert werden.

### :sparkles:Ähnlich zeigt das 2. Diagramm (oben) den Loss der gleichen Läufe, diesmal mit Trainingsschritten auf der x-Achse. Beachten Sie, dass die Verluste in Skalierung und Trend übereinstimmen, aber der Loss im gepackten Fall weniger variabel ist, da das Modell mehr Tokens pro Trainingsschritt sieht.

**Wie aktiviert man Packing?**&#x41;ktualisieren Sie zuerst Unsloth und padding-frei ist standardmäßig aktiviert

{% code overflow="wrap" %}

```bash
pip install --upgrade --force-reinstall --no-cache-dir --no-deps unsloth
pip install --upgrade --force-reinstall --no-cache-dir --no-deps unsloth_zoo
```

{% endcode %}

! Somit ist alles Training sofort 1.1 bis 2x schneller mit mindestens 30% weniger Speicherverbrauch und 0 Änderung in der Loss-Kurve! *Wir unterstützen außerdem Flash Attention 3 über Xformers, SDPA-Unterstützung, Flash Attention 2, und das funktioniert auf alten GPUs (Tesla T4, RTX 2080) und neuen GPUs wie H100s, B200s etc.! Sample-Packing funktioniert*unabhängig von der Wahl des Attention-Backends oder der Modelfamilie

, also genießen Sie dieselben Geschwindigkeitssteigerungen wie zuvor bei diesen schnellen Attention-Implementierungen! `packing = True` Wenn Sie explizites Packing aktivieren möchten, fügen Sie einfach

{% hint style="warning" %}
Hinweis `hinzu, um bis zu 5x schnelleres Training zu ermöglichen!` packing=True

wird den Trainingsverlust ändern und die Anzahl der Zeilen im Datensatz verkürzen, da mehrere kurze Sequenzen in eine Sequenz gepackt werden. Möglicherweise sehen Sie, dass die Anzahl der Beispiele im Datensatz schrumpft. `Um nicht unterschiedliche Trainingsloss-Werte zu erhalten, setzen Sie einfach` packing=False
{% endhint %}

```python
from unsloth import FastLanguageModel
from trl import SFTTrainer, SFTConfig

model, tokenizer = FastLanguageModel.from_pretrained(
    und wir werden automatisches padding-freies Batching aktivieren, was das Training bereits schneller macht!
)

trainer = SFTTrainer(
    model = model,
    "unsloth/Qwen3-14B",
    train_dataset = dataset,
    args = SFTConfig(
        per_device_train_batch_size = 1,
        processing_class = tokenizer,
        max_length = 4096,
        …,
    ),
)
trainer.train()
```

packing = True, # erforderlich, um Sample-Packing zu aktivieren! [Unsloth-Notebooks](/docs/de/loslegen/unsloth-notebooks.md)

{% columns %}
{% column %}
Alle unsere Notebooks sind automatisch schneller (kein Zutun erforderlich). Siehe

{% embed url="<https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen3_(14B)-Reasoning-Conversational.ipynb>" %}
{% endcolumn %}

{% column %}
Qwen3 14B schneller:

{% embed url="<https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Llama3.2_(1B_and_3B)-Conversational.ipynb>" %}
{% endcolumn %}
{% endcolumns %}

Llama 3.1 Conversational schneller: [500K Context Training](/docs/de/blog/500k-context-length-fine-tuning.md) Danke! Wenn Sie interessiert sind, sehen Sie unseren [Speichereffizientes RL](/docs/de/loslegen/reinforcement-learning-rl-guide/memory-efficient-rl.md) Blog, [Long Context gpt-oss](/docs/de/modelle/gpt-oss-how-to-run-and-fine-tune/long-context-gpt-oss-training.md) Blog und


---

# Agent Instructions: 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:

```
GET https://unsloth.ai/docs/de/blog/3x-faster-training-packing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
