Das PyTorch-Team bringt Ihnen persönlich bei, wie Sie die Inferenz großer Modelle beschleunigen können.
Generative KI hat sich im vergangenen Jahr rasant entwickelt. Darunter war die Textgenerierung immer ein besonders beliebtes Feld. In vielen Open-Source-Projekten Um bessere Ergebnisse zu erzielen, wird eine kontinuierliche Optimierung durchgeführt. Als eines der beliebtesten Frameworks in der Machine-Learning-Community hat PyTorch diese neue Chance natürlich genutzt und kontinuierlich optimiert. Damit jeder diese Innovationen besser verstehen kann, hat das PyTorch-Team speziell eine Reihe von Blogs eingerichtet, die sich mit der Verwendung von reinem nativem PyTorch zur Beschleunigung generativer KI-Modelle befassen.
Codeadresse: https://github.com/pytorch-labs/gpt-fast Werfen wir zunächst einen Blick auf die Ergebnisse. Das Team hat LLM neu geschrieben und die Inferenzgeschwindigkeit war zehnmal schneller als die Basislinie, ohne an Genauigkeit zu verlieren, wobei weniger als 1000 Zeilen reiner nativer PyTorch-Code verwendet wurden!
Alle Benchmarks werden auf A100-80GB ausgeführt, die Leistung ist auf 330W begrenzt. Diese Optimierungen umfassen:
- Torch.compile: PyTorch-Modell-Compiler. PyTorch 2.0 fügt eine neue Funktion namens Torch.compile () hinzu, mit der vorhandene Modelle mit einer Codezeile beschleunigt werden können das Modell;
- GPU-Quantisierung: Beschleunigen Sie das Modell durch Reduzierung der Rechengenauigkeit;
- Spekulative Dekodierung: eine große Modellinferenzbeschleunigungsmethode, die ein kleines „Entwurfs“-Modell verwendet, um große „Ziele“ vorherzusagen ;
- Tensor Parallel: Beschleunigen Sie die Modellinferenz, indem Sie das Modell auf mehreren Geräten ausführen.
Als nächstes wollen wir sehen, wie jeder Schritt umgesetzt wird. 6 Schritte zur Beschleunigung der Inferenz großer ModelleDie Studie zeigt, dass die Inferenzleistung des großen Modells vor der Optimierung 25,5 tok/s beträgt, was nicht sehr gut ist: Nach einigem Nachforschen habe ich endlich den Grund gefunden: übermäßiger CPU-Overhead. Dann gibt es den folgenden 6-stufigen Optimierungsprozess.
Schritt 1: Reduzieren Sie den CPU-Overhead mit Torch.compile und statischem KV-Cache, um 107,0 TOK/S zu erreichen. torch.compile ermöglicht es Benutzern, größere Bereiche in einem einzigen Kompilierungsbereich zu erfassen, insbesondere im Modus ="reduce-overhead" (siehe Code unten), diese Funktion ist sehr effektiv bei der Reduzierung des CPU-Overheads. Darüber hinaus wird in diesem Artikel auch fullgraph=True angegeben, um zu überprüfen, ob im Modell keine „Grafikunterbrechung“ vorliegt ( Das heißt , der Teil, den Torch.compile nicht kompilieren kann).
Aber selbst mit dem Segen von Torch.compile gibt es immer noch einige Hindernisse. Die erste Hürde ist der KV-Cache. Das heißt, wenn der Benutzer mehr Token generiert, wächst die „logische Länge“ des KV-Cache. Dieses Problem tritt aus zwei Gründen auf: Erstens ist es sehr teuer, den KV-Cache jedes Mal neu zuzuweisen (und zu kopieren), wenn der Cache wächst. Zweitens macht es diese dynamische Zuweisung schwieriger, den Overhead zu reduzieren. Um dieses Problem zu lösen, verwendet dieser Artikel einen statischen KV-Cache, weist die Größe des KV-Cache statisch zu und maskiert dann nicht verwendete Werte im Aufmerksamkeitsmechanismus.
Das zweite Hindernis ist die Vorfüllphase. Die Textgenerierung mit Transformer kann als zweistufiger Prozess betrachtet werden: 1. Vorabfüllungsphase zur Verarbeitung der gesamten Eingabeaufforderung 2. Dekodierung des Tokens.Obwohl der KV-Cache aufgrund der variablen Länge von statisch eingestellt ist Die Eingabeaufforderung und die Vorabfüllung der Stufen benötigen noch mehr Dynamik. Daher müssen zum Kompilieren dieser beiden Phasen separate Kompilierungsstrategien verwendet werden.
Obwohl diese Details etwas knifflig sind, sind sie nicht schwer umzusetzen und die Leistungsverbesserungen sind enorm. Nach diesem Vorgang stieg die Leistung um mehr als das Vierfache, von 25 tok/s auf 107 tok/s.
Schritt 2: Beseitigen Sie den Speicherbandbreitenengpass durch int8-Gewichtsquantisierung und erreichen Sie 157,4 tok/sDurch das Obige haben wir die Auswirkungen gesehen, die durch die Anwendung von Torch.compile, statischem KV-Cache, usw. Riesige Beschleunigung, aber das PyTorch-Team war damit nicht zufrieden und fand andere Optimierungspunkte. Sie glauben, dass der größte Engpass bei der Beschleunigung des generativen KI-Trainings die Kosten für das Laden von Gewichten aus dem globalen GPU-Speicher in Register sind. Mit anderen Worten: Jeder Vorwärtsdurchlauf muss jeden Parameter auf der GPU „berühren“. Wie schnell können wir also theoretisch auf jeden Parameter im Modell „zugreifen“?
Um dies zu messen, verwendet dieser Artikel die Model Bandwidth Utilization (MBU). Die Berechnung erfolgt ganz einfach wie folgt:
Bei einem 7B-Parametermodell wird beispielsweise jeder Parameter in fp16 (2) gespeichert Bytes pro Parameter) können 107 Token/s erreicht werden. Der A100-80GB verfügt über eine theoretische Speicherbandbreite von 2 TB/s. Wie in der Abbildung unten gezeigt, können Sie durch Umsetzen der obigen Formel in bestimmte Werte eine MBU von 72 % erhalten! Dieses Ergebnis ist recht gut, da viele Studien Schwierigkeiten haben, die 85 % zu durchbrechen.
Aber auch diesen Wert möchte das PyTorch-Team steigern. Sie stellten fest, dass sie weder die Anzahl der Parameter im Modell noch die Speicherbandbreite der GPU ändern konnten. Sie entdeckten jedoch, dass sie die Anzahl der für jeden Parameter gespeicherten Bytes ändern konnten!
Also werden sie die int8-Quantisierung verwenden.
Bitte beachten Sie, dass es sich hierbei nur um die quantisierten Gewichte handelt, die Berechnung selbst erfolgt weiterhin in bf16. Darüber hinaus ist es mit Torch.compile einfach, effizienten Code für die int8-Quantisierung zu generieren.
Wie in der Abbildung oben gezeigt, ist aus der dunkelblauen Linie (torch.compile + int8) ersichtlich, dass die Leistung erheblich verbessert wird, wenn nur die Gewichtsquantisierung von Torch.compile + int8 verwendet wird. Die Anwendung der int8-Quantisierung auf das Llama-7B-Modell verbessert die Leistung um etwa 50 % auf 157,4 Token/s.
Schritt 3: Spekulative Dekodierung verwenden
Selbst nach der Verwendung von Techniken wie der int8-Quantisierung stand das Team immer noch vor einem anderen Problem: Um 100 Token zu generieren, muss das Gewicht 100 sein geladen Zweitklassig.
Auch wenn die Gewichte quantisiert sind, ist es unvermeidlich, die Gewichte immer wieder zu laden. Es stellt sich heraus, dass die Nutzung der spekulativen Dekodierung diese strikte serielle Abhängigkeit aufheben und die Geschwindigkeit steigern kann.
Diese Studie verwendet ein Entwurfsmodell, um 8 Token zu generieren, und verwendet dann ein Validierungsmodell, um sie parallel zu verarbeiten und nicht übereinstimmende Token zu verwerfen. Dieser Prozess unterbricht serielle Abhängigkeiten. Die gesamte Implementierung benötigt etwa 50 Zeilen nativen PyTorch-Code.
Schritt 4: Verwenden Sie die int4-Quantisierung und die GPTQ-Methode, um die Gewichtung weiter zu reduzieren und 202,1 tok/s zu erreichen.In diesem Artikel wurde festgestellt, dass die Genauigkeit des Modells beginnt, wenn die Gewichtung 4 Bit beträgt verringern.
Um dieses Problem zu lösen, werden in diesem Artikel zwei Techniken verwendet: Die erste besteht darin, einen feineren Skalierungsfaktor zu verwenden, die andere darin, eine fortgeschrittenere Quantisierungsstrategie zu verwenden. Wenn wir diese Operationen miteinander kombinieren, erhalten wir Folgendes:
Schritt 5: Wenn wir alles zusammen kombinieren, erhalten wir 244,7 Tok/sZuletzt kombinieren wir alle Techniken zusammen, um besser zu werden. Die Leistung beträgt 244,7 Tok /S.
Schritt sechs: Tensor-Parallelität Bisher ging es in diesem Artikel um die Minimierung der Latenz auf einer einzelnen GPU. Tatsächlich ist es auch möglich, mehrere GPUs zu verwenden, wodurch die Latenz noch weiter verbessert wird. Zum Glück stellt das PyTorch-Team Low-Level-Tools für Tensorparallelität bereit, die nur 150 Zeilen Code erfordern und keine Modelländerungen erfordern.
Alle zuvor genannten Optimierungen können weiterhin mit Tensorparallelität kombiniert werden, die zusammen eine int8-Quantisierung für das Llama-70B-Modell bei 55 Token/s ermöglichen.
Fassen Sie abschließend kurz den Hauptinhalt des Artikels zusammen. Auf Llama-7B verwendet dieser Artikel die Kombination aus „compile + int4 quant + speculative decoding“, um 240+ tok/s zu erreichen. Bei Llama-70B führt dieses Papier auch die Tensorparallelität ein, um etwa 80 tok/s zu erreichen, was nahe an der SOTA-Leistung liegt oder diese übertrifft. Originallink: https://pytorch.org/blog/accelerating-generative-ai-2/Das obige ist der detaillierte Inhalt vonMit weniger als 1.000 Codezeilen hat das PyTorch-Team Llama 7B zehnmal schneller gemacht. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!