Ein Beispiel für den RWKV -Ansatz für Sprachmodelle, die von jemandem in Rost geschrieben wurden, der nur sehr wenig über Mathematik oder neuronale Netzwerke weiß. Die erste Version war sehr, sehr stark auf den erstaunlichen Informationen und auf Python -Beispiel hier: https://johanwind.github.io/2023/03/23/rwkv_details.html
Siehe auch das Repository des RWKV -Erstellers: https://github.com/blinkdl/chatrwkv/
Wenn Sie im 32 -Bit -Modus geladen werden, wird viel Speicher verwendet. Das 3B -Modell verwendet rund 11 GB RAM, und das 7B -Modell passt möglicherweise auf eine 32 -GB -Maschine, die Sie bereit sind, andere Anwendungen zu schließen oder sich mit einem Austausch zu befassen. Sogar das Laden im 8 -Bit -Modus verwendet eine angemessene Menge an Speicher, wird jedoch nach Abschluss des Ladens fallen.
Sie benötigen Rost und Fracht eingerichtet: https://www.rust-lang.org/learn/get-started
Sie müssen ein RWKV -Modell herunterladen. Hier ist ein Link, mit dem Sie beginnen können (ca. 820 MB): https://huggingface.co/blinkdl/rwkv-4-pile-430m/resolve/main/rwkv-4-pile-430m-20220808-8066.pth
Auch der Tokenizer hier: https://github.com/blinkdl/chatrwkv/blob/main/20b_tokenizer.json
Pytorch -Modelldateien können direkt geladen werden. Wenn die Dateien mit .pt oder .pth endet, wird sie als Pytorch -Modell geladen. Wenn es mit .st oder .safetensors endet, wird es als Safetensoren geladen. Hinweis : Die Pytorch -Unterstützung ist derzeit experimentell und funktioniert möglicherweise nicht korrekt. Sie werden wahrscheinlich sofort einen Fehler bekommen, wenn es ein Problem gibt, daher sollte es nicht gefährlich sein, diesen Ansatz zu versuchen. Wenn Sie möchten, können Sie die torch deaktivieren und nur Unterstützung für Safetensors -Formatdateien erstellen.
Danach sollten Sie einfach in der Lage sein, cargo run --release . Sie können versuchen, ohne --release aber es ist wahrscheinlich, dass alles wahnsinnig langsam ist. Versuchen Sie es auch mit cargo run --release -- --help um Befehlszeilenoptionen anzuzeigen.
HINWEIS : Die Standardeinstellung besteht darin, alle logischen Kerne zu verwenden, siehe die Befehlszeilenoptionen.
Sie können die .pth -Modelldatei optional in das Safetensor -Format konvertieren. Schauen Sie sich utils/pth_to_safetensors.py für ein Beispiel an. Dazu benötigen Sie die safetensors und torch Python -Pakete eingerichtet. Ich schlage vor, dies in einer virtuellen Umgebung zu tun. Derzeit gibt es für diesen Schritt keinen großen Vorteil, da die Torch -Dateien direkt in der aktuellen Version geladen werden können.
Die GGML-Unterstützung benötigt derzeit eine gepatchte Version von ggml und ggml-sys aus dem llama-rs Projekt.
Die Cargo.toml ist so eingerichtet, dass sie auf den richtigen Zweig in meiner Gabel verweist. Dies wird jedoch verschwinden, sobald die erforderlichen Änderungen in GGML zusammengeführt werden. Natürlich wird dieses Repo aktualisiert, aber denken Sie daran, dass Ihre Kompiles möglicherweise schließlich fehlschlagen, wenn Sie versuchen, eine ältere Version zu verwenden, da dieser Zweig schließlich entfernt wird.
Hinweis: Dieser Teil ist jetzt irgendwie veraltet. Ich empfehle jedoch immer noch, die folgenden Links zu lesen. Beachten Sie auch, dass diese Beschreibung auf einer einfacheren Version des RWKV -Modells mit nur vier Zuständen pro Schicht basiert. Die Vollversion hat fünf.
Hier ist eine (möglicherweise falsche) hohe Beschreibung der Schritte zur Bewertung des Modells. Sie müssen sich auf die Quelle in smolrwkv/src/simple/model.rs beziehen, damit dies Sinn macht.
Überlegen Sie sich auch nachdrücklich, diese zuerst zu lesen:
Übrigens, lustige Tatsache: "Tensor" klingt wirklich schick, aber es ist im Grunde nur ein Array. Ein eindimensionaler Tensor ist nur ein eindimensionales Array, ein zweidimensionaler dimensionaler Tensor ist ein zweidimensionales Array. Sie können spezielle Eigenschaften haben (wie unveränderlich), aber das ist egal, um das Konzept im Allgemeinen zu verstehen. Wenn Sie Arrays kennen, haben Sie bereits die allgemeine Vorstellung von Tensoren.
Ein Token bewerten:
x aus ln0 .x nacheinander zu jeder Schicht und verwenden Sie die für die nächste erzeugte x .x , das eingefügt wurde.ln1 auf x an und füttern Sie es zum Zeitmischen. Dies verwendet den Tensor aus dem FFN -Teil des Modells.tm_state aus dem Ebenenstatus und nennen Sie es last_x . (Warum? Wer weiß!)tm_num und tm_den als last_num , last_den .tm_[state,num,den] Aktualisieren Sie also Ihren Ebenenstatus damit.x zurück, die aus den Berechnungen ergeben wurden.x vom Zeitmischung zu x ( x += time_mixing_x ) hinzu.ln2 auf x auf und füttern Sie es zum Kanalmischung. Dies verwendet Tensoren aus dem Feed -Forward -Netzwerkteil des Modells.cm_state aus dem Ebenenstatus und nennen Sie es last_x .cm_state berechnet. Aktualisieren Sie also den Ebenenstatus.x , die aus der Kanalmischung beruhte.x vom Kanalmischen zu x hinzu.x , das nach der Bewertung der letzten Schicht das Ergebnis war.Das Modell hat eine Liste von Token, die es "kennt". Manchmal ist ein Token einem Wort gleich, manchmal ist es nur ein Teil eines Wortes. In der Regel gibt es eine große Anzahl von Token im Bereich von 30.000 bis 60.000. Ich glaube, die aktuellen RWKV -Modelle haben 50.277 Token. Wie auch immer, Sie erhalten nach dem Ausführen des Modells eine Liste von 50.277 Schwimmpunktzahlen zurück.
Der höchste Wert aus dieser Liste ist das Token, das das Modell vorhersagt, ist die wahrscheinlichste Fortsetzung und so weiter. Wenn Sie eine sortierte Liste der Top 10-40 oder so Token-Wahrscheinlichkeiten generiert haben und zufällig ausgewählt werden, erhalten Sie relativ gesehen ziemlich angemessene Ausgabe. Ein faires zu sagen, dass ein winziges 430 -m -Modell im Allgemeinen nicht die vernünftigste Ausgabe erzeugt.
Gute Erläuterung, wie Sie mit dem nächsten Schritt umgehen können, sobald Sie die Liste der Wahrscheinlichkeiten haben: https://huggingface.co/blog/how-to-generate
Bei der Bewertung des Modells sind verschiedene komplizierte mathematische Dinge beteiligt, aber das einzige, was wirklich zählt, ist die Matrixmultiplikation ( pardot in der Quelle). Im Fall von RWKV ist es die Matrixvektor-Multiplikation (ein 2D-Array multipliziert mit einem 1D-Array). > 90% der Zeit, die das Modell für die Bewertung des Modells aufgewendet hat, befinden sich in diesen Matrix -Multiplikationsaufrufen.
Im Nicht-GGML-Modus verwendet die Mathematik/Array-Handhabung hier die ndarray Kiste. Es liefert eine .dot -Funktion. Dies wird jedoch niemals eine matrixvektorische Multiplikation parallel berechnen, obwohl die Kiste behauptet, Threading-Unterstützung zu erhalten. Da diese Berechnung für die Leistung so kritisch ist, habe ich meine eigene Funktion geschrieben, um die Berechnung in Stücke aufzuteilen und parallel auszuführen. Siehe die Funktionen im dumdot -Modul in smolrwkv/src/util.rs .
Die Tatsache, dass Sie eine Liste von Wahrscheinlichkeiten zurückbekommen und und keine eindeutige "Antwort" aus dem Modell ein anständiges Gegenargument für die Idee, dass LLMs in irgendeiner Weise bewusst sind oder sein könnten. Wenn Sie die Output von einem LLM betrachten, werden Sie die wahrscheinlichste Token nicht einmal sehen. Außerdem lustige Tatsache: Wenn Sie eine Eingabeaufforderung an ein Modell füttern, erfolgt eine Liste von Wahrscheinlichkeiten, genau wie wenn Sie sie um eine Antwort bitten. Diese Wahrscheinlichkeiten werden jedoch nur weggeworfen, mit Ausnahme des Ergebniss nach der Verarbeitung des allerletzten promptierten Tokens.
Eingabeaufforderung in fettem. Sind die Drachenbaumschlangen oder Hunde? Die Welt mag nie wissen!
* Loading tokenizer from: ./20B_tokenizer.json
* Loading model from: ./RWKV-4-Pile-430M-20220808-8066.safetensors
* Discovering model structure.
- Loading layer 1/24
[...]
- Loading layer 24/24
* Loading non-layer tensors.
* Loaded: layers=24, embed=1024, vocab=50277
In einem schockierenden Befund entdeckte Wissenschaftler eine Herde von Drachen, die in einem abgelegenen, zuvor unerforschten Tal in Tibet lebten. Noch überraschender für die Forscher war die Tatsache, dass die Drachen perfekte Chinesen sprachen.
Diese Drachen sprachen alle verschiedene Dialekte und diese Dialekte stimmten nicht mit der Muttersprache der Hunde überein.
Um zu entschlüsseln, was diese Drachen sprachen, nannten sie die Drachen und stellten fest, dass ihre Sprache anders war als der Mensch.
"Die Drachen verstanden menschliche Wörter und genauer menschliche Sprachen. Die Drachen sprachen die menschliche Sprache. Sie verstanden auch die Regeln für Chinesen", sagte das Forschungsteam gegenüber Mongabay.
Indem sie die Forschung durchführen, hoffen sie, die mysteriöse Geschichte der Drachen in den abgelegenen, abgelegenen Regionen der Welt, insbesondere in Tibet, zu beleuchten.
Das im Journal Open Science veröffentlichte Forschungsprojekt zeigt auch, dass Drachen tatsächlich Reptilien oder AKA -Baumschlangen sind.
Drache, keine Schlange
Nach Angaben des Forschungsteams sind die in Tibet gefundenen Drachen eine Rasse von Hunden, kein Reptil.
Während das Forschungsteam immer noch nicht in der Lage war, eine Erklärung zu finden, warum diese Drachen in Tibet leben, wurde zuvor angenommen, dass sie am wahrscheinlichsten an Land in der Nähe des tibetischen Plateaus anwesend waren.
"Die Drachen leben dort als Teil des großen Qinghai-Tibet-Plateaus, das fast völlig ungestört ist, und das gesamte Qinghai-Tibet-Plateau wurde allmählich in einen landwirtschaftlichen Zustand umgewandelt. Deshalb haben sie ein unverwechselbares Muster des Kauens an den Bäumen, und wahrscheinlich sind die Tiere nicht allzu groß, um in der Natur zu gehalten", erklärten die Forscher.