1 Punkte von GN⁺ 2025-03-16 | 1 Kommentare | Auf WhatsApp teilen
  • Es wird gezeigt, dass sich anstelle von Layer Norm/RMSNorm, die in Transformern bislang nahezu unverzichtbar waren, Dynamic Tanh (DyT) einsetzen lässt und dabei eine ähnliche oder bessere Leistung als bei herkömmlichen normalisierungsbasierten Modellen erzielt wird
  • DyT ist eine elementweise Operation in der Form DyT(x) = tanh(αx) und geht von der Beobachtung aus, dass Layer Normalization innerhalb von Transformern oft ein S-förmiges Eingabe-Ausgabe-Mapping erzeugt, das tanh ähnelt
  • Die Implementierung umfasst nur wenige Zeilen in PyTorch und wendet mit lernbaren Parametern alpha, weight und bias Skalierung und Bias auf die Ausgabe von tanh(alpha * x) an
  • Die Auswertung deckt ein breites Spektrum von Vision-, Sprach-, Audio- und DNA-Sequenzmodellierung ab, darunter ViT, ConvNeXt, MAE, DINO, DiT, LLaMA, wav2vec 2.0, HyenaDNA, Caduceus
  • Auch ohne separates Hyperparameter-Tuning liefern die Modelle in mehreren Konfigurationen ähnliche oder bessere Ergebnisse als normalisierungsbasierte Vergleichsmodelle, was die Annahme infrage stellt, dass Normalisierungsschichten zwingend erforderlich sind

Was Dynamic Tanh verändert

  • DyT ist eine einfache Schicht, die Layer Norm oder RMSNorm in Transformer-Blöcken ersetzt
  • Die Kernoperation ist das elementweise angewendete DyT(x) = tanh(αx)
  • Es wird gezeigt, dass Transformer ohne Normalisierungsschichten eine ähnliche oder sogar höhere Leistung als klassische normalisierte Transformer erreichen können
  • Ausgangspunkt der Idee ist die Beobachtung, dass die von Layer Normalization in Transformern häufig erzeugte Eingabe-Ausgabe-Beziehung einer skalierten tanh-Funktion ähnelt

Implementierung

  • Das DyT-Modul lässt sich in PyTorch kurz implementieren
class DyT(nn.Module):
    def __init__(self, num_features, alpha_init_value=0.5):
        super().__init__()
        self.alpha = nn.Parameter(torch.ones(1) * alpha_init_value)
        self.weight = nn.Parameter(torch.ones(num_features))
        self.bias = nn.Parameter(torch.zeros(num_features))

    def forward(self, x):
        x = torch.tanh(self.alpha * x)
        return x * self.weight + self.bias
  • alpha ist ein lernbarer Parameter und sein Initialwert ist auf 0.5 gesetzt
  • Auch weight und bias sind lernbare Parameter und werden auf die Ausgabe von tanh(alpha * x) angewendet

Beobachtungen aus der Layer Normalization

  • Die Layer Normalization (LN) von Transformern erzeugt ein Eingabe-Ausgabe-Mapping, das einer skalierten tanh-Funktion nahekommt
  • In frühen Schichten ist dieses Mapping meist annähernd linear
  • In tieferen Schichten tritt die für tanh typische S-förmige Kurve deutlicher hervor
  • Zu den beobachteten Modellen gehören Vision Transformer (ViT), das Sprach-Transformer-Modell wav2vec 2.0 sowie ausgewählte LN-Schichten des Diffusion Transformer (DiT)

Umfang der Auswertung und Ergebnisse

  • DyT wurde über verschiedene Architekturen und Aufgaben hinweg evaluiert
    • Überwachtes Lernen im Vision-Bereich: ViT, ConvNeXt
    • Selbstüberwachtes Lernen im Vision-Bereich: MAE, DINO
    • Diffusionsmodell: DiT
    • Großes Sprachmodell: LLaMA
    • Selbstüberwachtes Lernen für Audio: wav2vec 2.0
    • DNA-Sequenzmodellierung: HyenaDNA, Caduceus
  • In allen Fällen zeigen Transformer mit DyT eine ähnliche oder bessere Leistung als normalisierungsbasierte Vergleichsmodelle
  • Die Auswertung reicht breit von Erkennung bis Generierung, von überwachtem bis selbstüberwachtem Lernen und von Computer Vision bis zu Sprachmodellen

Referenzmaterial

  • Download Paper: Das Paper mit allen Details der Forschung
  • View on GitHub: Repository mit Implementierungsdetails
  • View Summary: Kurze Zusammenfassung der Forschungsergebnisse
  • Transformers without Normalization ist als Paper für die CVPR 2025 aufgenommen

1 Kommentare

 
GN⁺ 2025-03-16
Meinungen auf Hacker News
  • Falls das stimmt, ist es eine ziemlich gute inkrementelle Verbesserung. Die Modellleistung scheint dadurch nicht wesentlich zu steigen, aber da es weniger Rechenaufwand verursacht als RMSNorm, das die meisten aktuellen State-of-the-Art-LLMs verwenden, könnten Training schneller und günstiger werden.
    • Allerdings ist der Anteil von RMSNorm an der gesamten Rechenlast eines Transformers ziemlich klein. Reduktionsoperationen lassen sich normalerweise mit den Operationen davor und danach fusionieren.
    • Ich habe es gerade in meinen persönlichen Benchmarks fürs Transformer-Training ausprobiert, und das Ergebnis ist sehr enttäuschend. Es konvergiert deutlich langsamer als mit RMSNorm.
      Das Anpassen von alpha hatte kaum Wirkung, daher könnten erhebliches Hyperparameter-Tuning oder eine ausgefeiltere Initialisierung nötig sein. Ich habe sowohl die PyTorch-Standardinitialisierung als auch orthogonale Initialisierung ausprobiert, aber es gab keinen Unterschied.
      Oder es könnte daran liegen, dass der von mir verwendete skalare Optimizer nicht gut dazu passt. Ich nutze einen eigenen skalaren Optimizer, der schneller konvergiert als Adam, aber bei DyT-Schichten schien er nur etwa auf dem Niveau von Adam zu liegen.
      Oder es holt vielleicht erst nach zig Milliarden Tokens auf; für so lange Tests habe ich aber kein Budget.
  • Wenn man niedrigpräzise Formate wie float8 verwendet, müssen Aktivierungswerte vor der Normalisierung normalerweise auf BF16 angehoben werden. Je niedriger die Präzision wird, desto größer wird daher der Anteil der Normalisierungsschichten an der Rechenlast.
    Wenn man solche Schichten ersetzen kann, hilft das dabei, die Rechenkosten deutlich zu senken.
  • Ich müsste die Details lesen, aber das Entfernen der Normalisierung könnte sehr bedeutsam sein. Wenn man neue Architekturen ausprobiert, ist es immer mühsam, das Netzwerk so abzustimmen, dass es richtig normalisiert ist.
    tanh wird allerdings auch andere Auswirkungen haben, denn Normalisierung löst manchmal Konditionierungsprobleme. Trotzdem ist es begrüßenswert, mehr Alternativen zu haben.
  • Ist dann vanishing gradient jetzt kein Problem mehr?
    • Wenn man die Schichten passend initialisiert, kann man auch in tiefen Netzen verhindern, dass die Gradientenbeträge verschwinden oder explodieren. Wenn man zum Beispiel die Ausgaben jeder Schicht auf Mittelwert 0 und Standardabweichung 1 bringt, liegen auch die Gradienten in einem vernünftigen Bereich.
      Ich empfehle das ursprüngliche ResNet-Paper von Kaiming He et al. und die Folgearbeiten.
      Als modernen Ansatz für RNNs lohnt sich DeepMinds https://arxiv.org/abs/2303.06349.
      Der Kernpunkt ist, dass der größte Eigenwert, also der Spektralradius, nahe bei 1 liegen sollte. Das bedeutet, dass Aktivierungswerte bei wiederholter Anwendung linearer Transformationen weder größer noch kleiner werden.
    • ResNet hat vanishing gradients meiner Ansicht nach weitgehend gelöst. Explodierende Gradienten behandelt man normalerweise mit guter Parameterinitialisierung und Normalisierung. Dieses Paper schlägt im Grunde eine Alternative zur Normalisierung vor.
    • Gute Frage. Das war ein Problem aus der Zeit, als man tanh als Aktivierungsfunktion verwendet hat, und von vor Residual Connections und Normalisierungsschichten. tanh in einem Setting mit anderen Aktivierungsfunktionen und Residual Connections wie eine Normalisierung zu verwenden, wirkt plausibel.
    • Wie in der Abbildung zu sehen ist, lernt ein Transformer Residuals. Er hat die Form y = x + f(x).
  • Vielleicht sehe nur ich das so, aber die Graphen im Paper scheinen LNinput und LNoutput zu vergleichen und dabei auch nach tanh(a*x) noch Gewicht und Bias anzuhängen.
    Um die Ähnlichkeit zu betrachten, müsste man doch eigentlich mit dem Output von LayerNorm vergleichen, nachdem man Gewicht und Bias entfernt hat.
    Wenn das Endergebnis gut ist, ist es egal, aber wenn man nur den tatsächlich ersetzten Teil isoliert betrachtet, könnte man besser verstehen, was passiert.
    • Wenn man sich die Implementierung ansieht, scheint nach der Berechnung von tanh noch Gewicht und Bias angewendet zu werden.
  • Was bedeutet das praktisch?
    • Laut Abstract kann ein Transformer ohne Normalisierung durch Einfügen von DyT meist ohne Hyperparameter-Tuning genauso gut oder besser abschneiden als sein normalisiertes Gegenstück.