Dieses Projekt befindet sich noch in der Entwicklung. Einige Funktionen sind möglicherweise noch nicht implementiert und die Dokumentation ist möglicherweise unvollständig.
Ein kleines, aber leistungsstarkes LLM-Inferenzsystem, das auf Forschungszwecke zugeschnitten ist.
vLLM-äquivalente Leistung mit nur 2.000 Codezeilen (2 % von vLLM).
Es gibt so viele Open-Source-Frameworks für die LLM-Bereitstellung, darunter HuggingFace Transformers, vLLM, LightLLM, DistServe und DeepSpeed-MII. Warum SwiftLLM?
Der Grund dafür ist, dass diese Frameworks auf die Produktion und nicht auf die Forschung zugeschnitten sind. Sie sind mit zahlreichen Funktionen ausgestattet, wie etwa über 100 Modellunterstützungen, verschiedenen Hardware-Unterstützungen, LoRA, Quantisierung, Multimodalität, Präfix-Caching, Strahlsuche usw. Obwohl es sich um eine All-in-One-Lösung für die Produktion handelt, ist ihre Codebasis zu groß und komplex, um sie zu verstehen und zu ändern (vLLM verfügt beispielsweise über mehr als 100.000 Codezeilen), was es schwierig macht, sie für Forschungszwecke zu verwenden. Auch ihre historische Belastung ist ein Problem.
SwiftLLM ist als kleines, aber leistungsstarkes LLM-Inferenzsystem konzipiert, das auf Forschungszwecke zugeschnitten ist. „Winzig“ bedeutet, dass es nur Funktionen enthält, die für die Forschung wesentlich sind, „leistungsstark“ bedeutet, dass es keine Kompromisse bei der Leistung eingeht, und schließlich bedeutet „schnell“, dass es leicht zu verstehen und zu ändern ist. Die Codebasis von SwiftLLM unterstützt zwar grundlegende Funktionen (siehe Liste unten) und kann eine mit vLLM äquivalente Leistung erzielen, umfasst jedoch weniger als 2.000 Codezeilen (~2 % von vLLM), geschrieben in Python und OpenAI Triton (eine DSL zum Schreiben). CUDA-Kernel), wodurch es einfach zu lesen, zu ändern, zu debuggen, zu testen und zu erweitern ist und problemlos in Ihre neuartigen und brillanten Forschungsideen integriert werden kann.
Derzeit unterstützt SwiftLLM die folgenden Funktionen:
Und wir planen, in Zukunft Unterstützung für die folgenden Funktionen hinzuzufügen:
Um die Codebasis klein zu halten, werden wir die folgenden Funktionen nicht unterstützen. Wenn Sie sie in Ihrem Forschungsprojekt verwenden möchten, müssen Sie sie möglicherweise selbst implementieren:
Denken Sie daran, dass SwiftLLM KEINE Komplettlösung für die Produktion ist. Es wird empfohlen, es als „Grundlage“ für Ihr Forschungsprojekt zu betrachten, und möglicherweise müssen Sie einige Funktionen selbst implementieren. Wir ermutigen Sie, mein lieber Forscher, den Code zu lesen, ihn zu verstehen, ihn zu ändern und ihn entsprechend Ihren Forschungsanforderungen zu erweitern.
Die Architektur von SwiftLLM kann in zwei Hauptteile unterteilt werden: die Steuerebene und die Datenebene .
Kurz gesagt: Die Kontrollebene entscheidet, „was berechnet werden soll“ oder „wie geplant werden soll“, während die Datenebene entscheidet, „wie berechnet werden soll“ oder „wie implementiert werden soll“ und die konkrete Berechnung durchführt. Sie arbeiten nach dem Master-Worker-Prinzip: Die Kontrollebene agiert wie ein Master, der die Planung und Koordination auf hoher Ebene durchführt und Aufträge an die Datenebene sendet, die wie ein Worker fungiert und die Berechnungen auf niedriger Ebene durchführt.
Der Code für die Steuerungsebene befindet sich im swiftllm/server
Verzeichnis, einschließlich Komponenten wie Engine
, Scheduler
, dem API-Server und TokenizationEngine
. Der Code für die Datenebene befindet sich im Verzeichnis swiftllm/worker
, einschließlich Beschreibungen des Berechnungsdiagramms (in swiftllm/worker/model.py
), der Implementierung von Ebenen im Modell (in swiftllm/layers
) und der OpenAI-Triton-Kernel ( Sie können sich „Kernel“ als auf der GPU ausgeführte Funktionen vorstellen (in swiftllm/kernels
).
Nehmen wir als Beispiel den Spielzeug-API-Server (in swiftllm/server/api_server.py
):
EngineConfig
verwendet, um eine Engine
zu erstellen.Engine.initialize
initialisiert, wo sie den Scheduler
, die TokenizationEngine
und eine Reihe von Workern (derzeit nur einer, da Tensor-Parallelität nicht unterstützt wird) erstellt. Anschließend wird der Worker angewiesen, profile_num_blocks
auszuführen, um die Anzahl der GPU-Blöcke zu berechnen. Anschließend weist die Engine alle Worker an, ihren KV-Cache und KV-Swap zuzuweisen.Engine.start_all_event_loops
aktiviert. In jedem Schritt der Schleife fragt die Engine den Scheduler nach dem nächsten Batch von zu berechnenden Anforderungen ab, befiehlt dem Worker, den Ein-/Austausch durchzuführen, und sendet dann den Batch zur Berechnung an den Worker. Derzeit befinden sich die Steuerungsebene ( Engine
) und die Datenebene ( LlamaModel
) auf demselben Knoten. Nach der Implementierung von Tensor-Parallelität/Pipeline-Parallelität kann die Datenebene auf mehrere Knoten verteilt werden.
Wir bieten zwei Möglichkeiten, SwiftLLM zu verwenden: die Verwendung sowohl der Steuerebene als auch der Datenebene oder die Verwendung nur der Datenebene.
Wenn Ihre Idee einfach oder elegant genug ist, dass sie nahtlos in die vorhandene Steuerungsebene integriert werden kann, können Sie sowohl die Steuerungsebene als auch die Datenebene verwenden. In einem anderen Fall, in dem Sie eine großartige Idee implementieren möchten, können Sie nur die Datenebene nutzen und selbst eine neue Steuerungsebene implementieren.
Zuerst richten wir die Umgebung ein:
packaging
über pip install packaging
Und dann kommt die Installation:
git clone https://github.com/interestingLSY/swiftLLM.git
cd
in das Repo ( cd swiftLLM
) und installieren Sie andere Abhängigkeiten über pip install -r requirements.txt
.pip install -e .
um SwiftLLM in Ihrer Umgebung zu installieren.pip install -e csrc
Hier einige Beispiele:
.bin
-Format als auch das .safetensors
-Format werden unterstützt. Angenommen, Ihr Modellgewicht ist unter /data/to/weight/
gespeichert.python3 examples/offline.py --model-path /data/to/weight
ausprobieren. In diesem Beispiel wird nur die Datenebene verwendet. Wenn Sie SwiftLLM ohne die Steuerebene verwenden möchten, ist dies ein guter Ausgangspunkt.Engine
verwendet, können Sie python3 examples/online.py --model-path /data/to/weight
ausprobieren. Dies ist ein großartiges Beispiel, wenn Sie planen, sowohl die Steuerebene als auch die Datenebene zu verwenden.swiftllm/server/api_server.py
. Es startet einen API-Server und stellt eine vLLM-ähnliche Schnittstelle für die Online-Bereitstellung bereit. Obwohl SwiftLLM winzig klein ist (auch kleine können bezaubernd sein!), macht SwiftLLM keine Kompromisse bei der Leistung. Wir haben SwiftLLM in mehreren Szenarien evaluiert und zeigen, dass SwiftLLM im Vergleich zu vLLM eine gleichwertige oder sogar bessere Leistung erzielen kann.
Das erste Szenario ist „eine einzelne Vorwärtsoperation“, bei der wir das Modell mit einer Reihe von Eingaben füttern und es ein Ausgabetoken generieren lassen (entspricht einer „Vorwärts“-Operation). Dies ist der grundlegende Vorgang der LLM-Inferenz (sowohl online als auch offline), daher ist seine Leistung von entscheidender Bedeutung.
Hier verwenden wir das Modell LLaMA-3 7B mit NVIDIA A100 80G PCIE / RTX 4090 GPU unter FP16-Präzision. Die Ergebnisse sind unten aufgeführt (je niedriger desto besser):
Es ist ersichtlich, dass SwiftLLM unter denselben Einstellungen eine gleichwertige Leistung (oder sogar eine bessere) als vLLM erreichen kann.
Das zweite Szenario ist die „Online-Bereitstellung“, bei der wir einen API-Server starten, Eingabeaufforderungen aus einem realen Datensatz abfragen und das Modell Vervollständigungen generieren lassen. Dies ist das Szenario, in dem LLM in realen Anwendungen wie Chatbots oder Code-Vervollständigungen eingesetzt wird.
Hier verwenden wir den ShareGPT-Datensatz, um Eingabeaufforderungen abzutasten, und verwenden einen Poisson-Prozess mit verschiedenen Lambdas, um unterschiedliche Ankunftsraten von Anfragen zu simulieren. Die Ergebnisse sind unten aufgeführt (je niedriger desto besser):
Es ist ersichtlich, dass SwiftLLM auf A100 80G PCIE eine gleichwertige Leistung wie vLLM erreichen kann, während SwiftLLM auf RTX 4090 vLLM deutlich übertrifft (hauptsächlich aus diesem Grund hat unsere Steuerungsebene einen geringeren Overhead).