Ce projet vise à être une réimplémentation propre et concise de GPT-2. L'implémentation du modèle, contenue dans src/model.rs
, comporte moins de 300 lignes de code. Bien qu'il s'agisse d'un exercice amusant principalement à des fins éducatives (mes propres), il démontre l'utilité de Rust and Burn dans le domaine de l'apprentissage automatique : l'ensemble du projet se compile en un seul binaire, ce qui rend le déploiement relativement simple.
Pour le moment, seul un tokeniseur au niveau du caractère est pris en charge, donc les poids officiels nécessitant un tokenizer BPE ne peuvent pas encore être utilisés. Cependant, pour vous amuser, vous pouvez essayer le petit modèle de jouet que j'ai formé (voir inférence).
Le projet comprend également une CLI simple pour la formation et l'inférence.
Usage: gpt-burn <COMMAND>
Commands:
run Generate text using a pre-trained model
train Train a new model
Vous pouvez installer gpt-burn
avec Nix :
nix run github:felix-andreas/gpt-burn
Ou installez avec cargo
:
cargo install --git https://github.com/felix-andreas/gpt-burn
Vous pouvez également cloner le dépôt et créer à partir des sources :
nix develop # optional
cargo run --release
Si vous n'utilisez pas Nix et utilisez une distribution basée sur Ubuntu, vous devez installer ces dépendances supplémentaires :
apt install pkg-config libssl-dev libvulkan1 mesa-vulkan-drivers vulkan-tools
J'ai formé un modèle de jouet avec un tokeniseur au niveau du personnage sur le corpus Wikipédia allemand pour 20 000 lots (taille du lot de 128) avec les paramètres suivants :
Paramètre | Valeur |
---|---|
paramètres | 83M |
longueur du contexte | 128 |
n_layers | 12 |
n_heads | 12 |
d_model | 768 |
Vous pouvez le télécharger ici et l'extraire ensuite. Ou faites les deux en une seule commande :
curl -s ' https://drive.usercontent.google.com/download?id=1GGLaPnmPQ8Z2B9vJQoI6-K128X9LJKG0&export=download&confirm=t ' | tar xzf -
Ensuite, exécutez le modèle :
gpt-burn run ./model_83M
Vous devriez voir quelque chose du genre :
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.
Les autres options de ligne de commande sont :
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]
Pour entraîner votre propre modèle, exécutez :
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
Important
Assurez-vous corpus.txt
est un fichier texte codé en utf-8 !
Vous pouvez transmettre la plupart des hyperparamètres en tant qu'option de ligne de commande :
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)
Le modèle peut être utilisé avec différents tokenizers via le trait Tokenizer
. Ci-dessous vous voyez comment la phrase suivante
Albert Einstein war ein schweizerisch-US-amerikanischer theoretischer Physiker deutscher Herkunft.
est codé par les différents tokenizers.
Le CharTokenizer
divise chaque personnage en un jeton distinct :
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]
Le SimpleVowelTokenizer
divise les mots avant la voyelle suivante si le morceau comporte plus de trois caractères, créant un résultat qui ressemble à des syllabes :
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]