- llama2.c ist eine „Full-Stack“-Trainings- und Inferenzlösung, die die Llama-2-LLM-Architektur in PyTorch trainiert und die Inferenz mit der einfachen C-Datei
run.causführt - Der zentrale Fokus liegt auf Minimalismus und Einfachheit; es handelt sich um eine Lehr-Implementierung, die die Llama-2-Architektur fest einkodiert und aus einer einzigen reinen C-Inferenzdatei ohne Abhängigkeiten besteht
- Aus der Perspektive, dass selbst sehr kleine LLMs starke Leistung liefern können, wenn die Domäne ausreichend eingegrenzt ist, wird ein Beispielmodell auf Basis von TinyStories bereitgestellt
- Das 15M-Parameter-Modell ist ein Download von etwa 60 MB und kann nach
make runmit./run stories15M.binausgeführt werden - Es werden auch Modelle mit 42M und 110M Parametern angeboten; das 110M-Modell wird als gleich groß wie GPT-1 bezeichnet
- Das 15M-Parameter-Modell ist ein Download von etwa 60 MB und kann nach
- Auch Metas Llama-2-Modelle können inferiert werden, da die neuronale Netzwerkarchitektur identisch ist. Allerdings müssen die Checkpoints gemäß den Meta-Richtlinien bezogen und anschließend mit
export.pyin das llama2.c-Format umgewandelt werden- Derzeit führt
run.cnur fp32-Inferenz aus, daher lassen sich Modelle größer als 7B wahrscheinlich nicht produktiv laden - 13B und größer funktionieren derzeit wegen Integer-Overflow in der Pointer-Arithmetik nicht; das ist noch nicht behoben
- Derzeit führt
- int8-quantisierte Inferenz ist in
runq.cimplementiert; dabei werden mit der Q8_0-Methode die an der Matmul beteiligten Gewichte quantisiert, und Aktivierungswerte werden zur Laufzeit dynamisch quantisiert und dequantisiert- Ein fp32-Export von Llama 2 7B erzeugt eine 26-GB-Datei, ein quantisierter Export der Version 2 eine 6,7-GB-Datei
- In der Umgebung des Autors lief fp32 mit OpenMP und 64 Threads mit 4,6 tok/s, int8 mit 14 tok/s, was einer 4-fachen Reduktion der Checkpoint-Größe und einem Geschwindigkeitsgewinn von etwa dem 3-Fachen entspricht
- Die Nutzung umfasst das Ausführen der C-Inferenz, die Eingabe eines Prompts, die Steuerung von Temperature- und Top-p-Sampling, das Starten des Chat-Modus und die Angabe eines benutzerdefinierten Tokenizers
- Ein Beispielaufruf hat die Form
./run stories42M.bin -t 0.8 -n 256 -i "One day, Lily met a Shoggoth" - Chat-Modelle werden mit dem Flag
-m chatgestartet, etwa./run llama2_7b_chat.bin -m chat - Ein benutzerdefinierter Tokenizer wird mit
tokenizer.pyin das.bin-Format exportiert und dann über das Flag-zangegeben
- Ein Beispielaufruf hat die Form
- Modelle auf Hugging Face, die die Llama-2-Architektur verwenden, können mit dem Flag
--hfvonexport.pyin eine.bin-Datei exportiert werden - Der Trainingsablauf reicht vom Herunterladen und Vor-Tokenisieren von TinyStories über das Ausführen von
train.pybis zum Export des Modells und anschließender C-Inferenz- Das standardmäßige TinyStories-Beispiel ist derzeit das einzige bereitgestellte Datensatzbeispiel
- Für das Training eines benutzerdefinierten Tokenizers wird
sentencepieceverwendet; im Beispiel kommt die Einstellung--vocab_size=4096zum Einsatz
- Performance-bezogene Builds sind in
make run,make runfastundmake runompaufgeteilt; der OpenMP-Build aktiviert#pragma omp parallel forinnerhalb von Matmul und Attention, um Schleifenarbeit auf mehrere Prozessoren zu verteilen - Build-Anleitungen für verschiedene Plattformen werden für Windows, Centos 7, Amazon Linux 2018 und Mac bereitgestellt
- Unter Windows werden
build_msvc.batodermake win64verwendet - Unter Centos 7 und Amazon Linux 2018 werden
make rungnuodermake runompgnuverwendet - Für den OpenMP-Build auf dem Mac wird nach der Installation von clang über brew
make runomp CC=/opt/homebrew/opt/llvm/bin/clangverwendet
- Unter Windows werden
- Für Tests stehen
pytestund der C-Testmake testcczur Verfügung;test_all.pyführt 200 Forward-Schritte in C und Python aus und vergleicht sie mit bekannten erwarteten Ausgaben - Das Projektziel ist, eine einfache Referenzimplementierung zu bewahren, die aus zwei gut lesbaren
.py-Dateien für das Training und C-Inferenzcode besteht, und nicht auf komplexe Frameworks oder viele Optionen abzuzielen - Die Lizenz ist MIT
1 Kommentare
Hacker-News-Kommentare
Als ich sah, dass es auf HN gepostet wurde, fand ich es interessant :) Der ursprüngliche Checkpoint läuft auf einem MacBook Air M1, mit
-O3kompiliert, mit unerwartet schnellen 100 tok/s, daher wird jetzt ein größeres 44M-Modell trainiertEs dürfte trotzdem interaktiv ausführbar sein, und vielleicht könnte sogar ein 7B-Llama-Modell in Reichweite kommen
nanoGPTein wenig angepasst und versucht, ein 12M-Modell mit 2 GB von GPT-4-generierten Daten aus TinyStories vorzutrainieren, und das Ergebnis war ziemlich überraschendDanach habe ich es noch etwas an Wikipedia angepasst, und es wurde zu einem deutlich klügeren und deutlich kleineren plausiblen Unsinnsgenerator als ein geglättetes n-Gramm-Modell. Kleine LLMs werden in vielen Bereichen wohl Mainstream, und das nächste Ziel ist, Llama2 7B auf 10~100M zu verkleinern, ohne dass es dabei wesentlich dümmer wird
Eine GPU-Instanz bei etwas wie Linode zu mieten ist viel teurer als ein normaler Web-App-Server, daher würde ich gern wissen, ob das völlig unrealistisch ist oder ob so ein Ansatz oder andere Methoden ein realistischer Weg sind
Es gibt eine Version von Georgi Gerganov, bekannt durch llama.cpp, die mit Emscripten im Browser läuft: https://ggerganov.com/llama2.c/
Der laufende Twitter-Thread ist hier: https://twitter.com/ggerganov/status/1683174252990660610
Sowohl das Original als auch diese Arbeit sind wirklich großartig, und auch wenn es eher ein Proof of Concept mit sehr kleinen Modellen ist, sind Local-first-LLMs besonders spannend. Die Idee, mit lokaler Inferenz Web-Apps zu bauen, gefällt mir
Wenn das zu Optimierungen, Forschung an kleineren Modellen, Teil-Downloads und der Nutzung von WebGPU führt, könnte es der Ausgangspunkt für eine neue Art sein, private lokale LLM-basierte Apps zu bauen. Die gleichen Fähigkeiten wie bei LLMs, die auf riesigen Clustern mit High-End-GPUs gehostet werden, dürften schwer sein, aber es gibt viele Anwendungsfälle, die dieser Ansatz eröffnen kann
Zum Beispiel beginnt es mit „Once upon a time...“ und wirkt wie eine Geschichte über Lily und Timmy, dann tauchen „Butterfly would pauseWhy“, „TextField“,
querySelector,HttpRequestund Fragmente aus verschiedenen Sprachen auf, bis die Ausgabe völlig auseinanderfälltFür Interessierte gibt es auch eine Rust-Version. Im Release-Modus erreicht sie etwa 106 tokens/second
https://github.com/garrisonhess/llama2.c/blob/517a1a3e487f31...
Die Nicht-Web-Version unterstützt GPUs vollständig, ist aber überhaupt nicht minimalistisch
Manchmal zersplittert das sogar die Bemühungen der Community, ein Projekt zu verbessern
Viele scheinen nicht zu verstehen, wie kühn dieser Schritt ist
Andrej bekommt bei OpenAI (MSFT) eine hohe Vergütung und hilft trotzdem Apple, Facebook und vor allem der Open-Source-Bewegung. Es wäre aber wohl schwer, ihn zu verdrängen, denn dann könnte er sofort zu Tesla oder xAI gehen
Ich habe den Eindruck, dass Llama-2 für kreative Arbeiten wegen des starken Safety-Filterings praktisch unbrauchbar ist: https://i.imgur.com/GFY0wSL.png
Dieses Verhalten ließ sich allerdings nur teilweise reproduzieren, wenn es bei Llama2-70b-chat TGI Hugging Face als zweite Nachricht gesendet wurde; möglicherweise gibt es etwas Merkwürdiges an der Art des Promptings, das dieses Verhalten verursacht. Ich konnte das Modell selbst noch nicht ausführen, um weiter nachzuforschen
Chat/instruct hat Vorteile wie leichtere Verteilung an Drittanwender, einfachere Prompts und eingebaute Sicherheitsvorkehrungen, aber für den eigenen Gebrauch ist es dem vortrainierten Modell wirklich deutlich unterlegen. An diesem Punkt könnte Llama 2 gegenüber OpenAI im Vorteil sein, weil OpenAI die vortrainierten GPT-3-Modelle eingestellt hat und sich offenbar künftig nur noch auf Chat-Modelle konzentrieren will
Ich will keine Sicherheits-Schere. Es ist in Ordnung, Dinge einzuschränken, die auf dem eigenen Server laufen, aber man sollte mir keine Modelle geben, die ich auf meinem Computer nicht nach Belieben ändern und verwenden kann
Andrej hat hier ausführlicher dazu gepostet: https://twitter.com/karpathy/status/1683143097604243456?s=46...
Falls man sich für solche Themen interessiert: Dieser Code lässt sich sauber mit dem WASI SDK bauen und läuft ohne Änderungen in einer Wasm-Runtime
Ich frage mich, wie viel Speicher man braucht, um ein neuronales Netz auszuführen
Reicht es, zunächst nur die ersten beiden Schichten von der Festplatte zu lesen und die Aktivierungswerte aller Knoten zu berechnen, dann die erste Schicht zu verwerfen, die dritte Schicht zu lesen und erneut zu berechnen, dann die zweite Schicht zu verwerfen usw.? Wenn ja, würde das bedeuten, dass der Speicher nur groß genug für zwei Schichten sein muss?
Kurz gesagt hängt das maximale RAM von der Quantisierungsmethode ab, und grob liegen 7B-Modelle bei 4–8 GB, 13B-Modelle bei 8–15 GB, 30B-Modelle bei 13–33 GB und 70B-Modelle bei 31–75 GB
Mir kam gerade der Gedanke: Aktuelle LLMs geben eine Wahrscheinlichkeitsverteilung zurück, ein Zufalls-Sampler wählt eines aus und hängt es an die Ausgabe an, dann wiederholt sich der Vorgang
Wäre es stattdessen möglich, dass der Zufallsgenerator N Token auswählt, die die Verteilung annähern, das LLM daraus N neue Verteilungen erzeugt und man diese dann irgendwie kombiniert, um aus der kombinierten Verteilung wieder N Token auszuwählen?
Beispiele gibt es unter https://huggingface.co/docs/transformers/internal/generation...
Wie genau man das machen würde, weiß ich allerdings nicht
Natürlich braucht man dabei pro Tokengenerierung N-mal so viel Rechenaufwand. Man könnte die Top-N auswählen oder, falls nötig, Temperature Scaling auf die Logits anwenden und daraus N sampeln
Ist das für Lehrzwecke gedacht? Wenn man den Erfolg von llama.cpp und diesem Projekt sieht, wirkt es so, als würde sich die Branche statt auf allgemeine Frameworks wie PyTorch, TensorFlow oder ONNX Runtime eher in Richtung separater Quellcode pro veröffentlichtem Modell bewegen
Und nein: Trotz des Namens unterstützt llama.cpp nicht nur llama. Es ist auch nicht vollständig maßgeschneidert, sondern baut auf der allgemeineren Tensor-Bibliothek bzw. dem Framework
ggmlaufWenn man dann ein Modell findet, das gut funktioniert, fließt diese Weiterentwicklung oft in die nächste Framework-Version ein. Deshalb gibt es in TensorFlow Grundbausteine wie CNN, GRU und TransformerEncoder, und zugleich entstehen hardware-spezifische Implementierungen, die Allgemeingültigkeit zugunsten von Geschwindigkeit opfern