Ziel dieses Projekts ist eine saubere und prägnante Neuimplementierung von GPT-2. Die in src/model.rs
enthaltene Modellimplementierung umfasst weniger als 300 Codezeilen. Während dies vor allem für (meine eigenen) Bildungszwecke eine unterhaltsame Übung war, zeigt sie den Nutzen von Rust und Burn im Bereich des maschinellen Lernens: Das gesamte Projekt wird in einer einzigen Binärdatei kompiliert, was die Bereitstellung relativ einfach macht.
Derzeit wird nur ein Tokenizer auf Zeichenebene unterstützt, sodass offizielle Gewichtungen, die einen BPE-Tokenizer erfordern, noch nicht verwendet werden können. Zum Spaß können Sie jedoch das kleine Spielzeugmodell ausprobieren, das ich trainiert habe (siehe Schlussfolgerung).
Das Projekt umfasst außerdem eine einfache CLI für Training und Inferenz.
Usage: gpt-burn <COMMAND>
Commands:
run Generate text using a pre-trained model
train Train a new model
Sie können gpt-burn
mit Nix installieren:
nix run github:felix-andreas/gpt-burn
Oder mit cargo
installieren:
cargo install --git https://github.com/felix-andreas/gpt-burn
Alternativ können Sie das Repo klonen und aus dem Quellcode erstellen:
nix develop # optional
cargo run --release
Wenn Sie Nix nicht verwenden und eine Ubuntu-basierte Distribution verwenden, müssen Sie diese zusätzlichen Abhängigkeiten installieren:
apt install pkg-config libssl-dev libvulkan1 mesa-vulkan-drivers vulkan-tools
Ich habe ein Spielzeugmodell mit einem Tokenizer auf Zeichenebene auf dem deutschen Wikipedia-Korpus für 20.000 Stapel (Stapelgröße 128) mit den folgenden Parametern trainiert:
Parameter | Wert |
---|---|
Parameter | 83M |
Kontextlänge | 128 |
n_layers | 12 |
n_heads | 12 |
d_model | 768 |
Sie können es hier herunterladen und anschließend extrahieren. Oder führen Sie beides in einem einzigen Befehl aus:
curl -s ' https://drive.usercontent.google.com/download?id=1GGLaPnmPQ8Z2B9vJQoI6-K128X9LJKG0&export=download&confirm=t ' | tar xzf -
Führen Sie dann das Modell aus:
gpt-burn run ./model_83M
Sie sollten etwas in dieser Richtung sehen:
So wurden bis 1977 679 nachhaltige Wörgler Torbauten vorgeworfen, die Einwohnerzahl Sirkes bestand 2015 bis 1998.
Sie war trotz weniger als 10.000 ausgedehnter Größen wahrscheinlich auf folgende Breitenauflagen mit 932 km.
2016 wurden rund 145 Händen nach Deutschland geladen.
Weitere Befehlszeilenoptionen sind:
Usage: gpt-burn run [OPTIONS] <MODEL_PATH>
Arguments:
<MODEL_PATH>
Options:
-p, --prompt <PROMPT>
-n, --n-new-tokens <N_NEW_TOKENS> [default: 1000]
-s, --seed <SEED> [default: 0]
Um Ihr eigenes Modell zu trainieren, führen Sie Folgendes aus:
gpt-burn train --context-length 128 --n-layers 12 --n-heads 12 --d-model 768 --batch-size 128 --learning-rate 0.0003 --seed 0 --text-corpus ./corpus.txt
Wichtig
Stellen Sie sicher, corpus.txt
eine utf-8-kodierte Textdatei ist!
Sie können die meisten Hyperparameter als Befehlszeilenoption übergeben:
Usage: gpt-burn train [OPTIONS]
Options:
-o, --output-path <PATH>
-c, --context-length <CONTEXT_LENGTH> [default: 64]
-d, --d-model <D_MODEL> [default: 64]
-l, --n-layers <N_LAYERS> [default: 2]
-h, --n-heads <N_HEADS> [default: 2]
-n, --n-steps <N_STEPS> [default: 50]
-b, --batch-size <BATCH_SIZE> [default: 32]
-r, --learning-rate <LEARNING_RATE> [default: 0.003]
-s, --seed <SEED> [default: 0]
-t, --text-corpus <TEXT_CORPUS> [default: .data/corpus.txt]
-m, --n-mega-bytes <N_MEGA_BYTES> Only use first <n> megabytes of dataset for training
-x, --no-save Don't save trained model (useful for debugging)
Das Modell kann über die Eigenschaft Tokenizer
mit verschiedenen Tokenizern verwendet werden. Unten sehen Sie, wie der folgende Satz lautet
Albert Einstein war ein schweizerisch-US-amerikanischer theoretischer Physiker deutscher Herkunft.
wird von den verschiedenen Tokenizern codiert.
Der CharTokenizer
teilt jedes Zeichen in einen separaten Token auf:
Tokens: ["A", "l", "b", "e", "r", "t", " ", "E", "i", "n", "s", "t", "e", "i", "n", " ", "w", "a", "r", " ", "e", "i", "n", " ", "s", "c", "h", "w", "e", "i", "z", "e", "r", "i", "s", "c", "h", "-", "U", "S", "-", "a", "m", "e", "r", "i", "k", "a", "n", "i", "s", "c", "h", "e", "r", " ", "t", "h", "e", "o", "r", "e", "t", "i", "s", "c", "h", "e", "r", " ", "P", "h", "y", "s", "i", "k", "e", "r", " ", "d", "e", "u", "t", "s", "c", "h", "e", "r", " ", "H", "e", "r", "k", "u", "n", "f", "t", "."]
Values: [28, 13, 3, 6, 19, 21, 1, 32, 10, 15, 20, 21, 6, 10, 15, 1, 24, 2, 19, 1, 6, 10, 15, 1, 20, 4, 9, 24, 6, 10, 27, 6, 19, 10, 20, 4, 9, 66, 48, 46, 66, 2, 14, 6, 19, 10, 12, 2, 15, 10, 20, 4, 9, 6, 19, 1, 21, 9, 6, 16, 19, 6, 21, 10, 20, 4, 9, 6, 19, 1, 43, 9, 26, 20, 10, 12, 6, 19, 1, 5, 6, 22, 21, 20, 4, 9, 6, 19, 1, 35, 6, 19, 12, 22, 15, 7, 21, 67]
Der SimpleVowelTokenizer
teilt Wörter vor dem nächsten Vokal, wenn der Block länger als drei Zeichen ist, und erzeugt ein Ergebnis, das Silben ähnelt:
Tokens: ["Albert", " ", "Einst", "ein", " ", "war", " ", "ein", " ", "schw", "eizer", "isch", "-", "US", "-", "amer", "ikan", "isch", "er", " ", "theor", "etisch", "er", " ", "Phys", "iker", " ", "deutsch", "er", " ", "Herk", "unft"]
Values: [2, 0, 3, 9, 0, 19, 0, 9, 0, 16, 10, 15, 1, 6, 1, 7, 13, 15, 11, 0, 17, 12, 11, 0, 5, 14, 0, 8, 11, 0, 4, 18]