Haben Sie Probleme mit KI oder Full-Stack-Entwicklung? Unsere Experten sind für Sie da: maßgeschneiderte Beratung, technische Integration und mehr. Erreichen Sie uns unter [email protected].

Feinabstimmung von LLaMA, OpenLLaMA und XGen mit JAX auf einer GPU oder einer TPU

LLaMA, OpenLLaMA und XGen sind hochmoderne generative KI-Modelle. Diese Modelle liefern sogar noch viel bessere Ergebnisse, wenn sie mit Ihren eigenen Daten feinabgestimmt werden. In diesem Artikel sehen wir uns an, wie man diese Modelle mit JAX und der EasyLM-Bibliothek sowohl auf einer GPU als auch auf einer TPU feinabstimmen kann.

LLaMA, OpenLLaM und XGen

Das LLaMA-Modell wurde im Februar 2023 von Meta veröffentlicht. Dieses generative KI-Modell ist ein Open-Source-Modell, das in verschiedenen Größen angeboten wird: 7B Parameter, 13B Parameter, 33B Parameter und 65B Parameter.

Im Juni 2021, als GPT-J veröffentlicht wurde, begann die Welt zu erkennen, dass generative Open-Source-KI-Modelle ernsthaft mit OpenAI GPT-3 konkurrieren können. Jetzt wurde mit LLaMA die Messlatte wieder deutlich höher gelegt und dieses Modell scheint eine sehr gute Open-Source-Alternative zu OpenAI ChatGPT und GPT-4 zu sein.

Die LLaMA-Lizenz ist allerdings nicht geschäftsfreundlich: Dieses Modell kann nicht für kommerzielle Zwecke verwendet werden... Aber die gute Nachricht ist, dass es jetzt andere Modelle gibt.

OpenLLaMA, veröffentlicht im Juni 2023, ist eine alternative Version von LLaMA, entwickelt vom Berkeley AI Research Team, die sehr gute Ergebnisse liefert und für Unternehmen genutzt werden kann. Zur Zeit sind 2 Versionen verfügbar: 7B-Parameter und 13B-Parameter.

XGen, von Salesforce im Juni 2023 veröffentlicht, ist ein weiteres sehr leistungsfähiges Basismodell, das in kommerziellen Anwendungen verwendet werden kann. Zum jetzigen Zeitpunkt ist nur eine Version mit 7B-Parametern verfügbar. Es ist erwähnenswert, dass dieses Modell einen 8k-Token-Kontext unterstützt, während LLaMA und OpenLLaMA nur einen 2k-Token-Inhalt unterstützen.

Warum sollten Sie Ihr eigenes Modell verfeinern?

Bei den oben genannten Modellen handelt es sich um Basismodelle, was bedeutet, dass sie auf einem großen Textkorpus unüberwacht trainiert wurden.

Diese grundlegenden KI-Modelle sind in der Regel eine gute Basis, aber sie müssen so abgestimmt werden, dass sie genau verstehen, was Sie wollen, und gute Ergebnisse liefern. Der einfachste Weg, dies zu erreichen, ist die Verwendung von "few-shot learning" (auch bekannt als "prompt engineering"). Lesen Sie hier unseren speziellen Lernleitfaden mit wenigen Bildern.

Few-Shot-Lernen ist praktisch, da es im laufenden Betrieb durchgeführt werden kann, ohne dass eine neue Version des generativen KI-Modells erstellt werden muss, aber manchmal reicht es nicht aus.

Um Ergebnisse auf dem neuesten Stand der Technik zu erhalten, müssen Sie ein KI-Modell für Ihren eigenen Anwendungsfall feinabstimmen. Feinabstimmung bedeutet, dass Sie einige Parameter des Modells auf der Grundlage Ihrer eigenen Daten ändern und dann Ihre eigene Version des Modells erhalten.

Feinabstimmung ist viel billiger als das Trainieren eines generativen KI-Modells von Grund auf, aber sie erfordert immer noch Rechenleistung, so dass Sie fortschrittliche Hardware benötigen, um Ihr eigenes Modell feinabzustimmen. Einige neuere alternative Feinabstimmungstechniken erfordern weniger Rechenleistung (siehe p-tuning, prompt tuning, soft tuning, parameter-effiziente Feinabstimmung, Adapter, LoRA, QLoRA...), aber bisher ist es uns nicht gelungen, mit diesen Techniken dasselbe Qualitätsniveau zu erreichen, weshalb wir sie in diesem Tutorial nicht erwähnen werden.

Feinabstimmung von LLaMA auf einer TPU mit JAX und EasyLM

In diesem Tutorium konzentrieren wir uns auf die Feinabstimmung von LLaMA mit der EasyLM-Bibliothek, die vom Berkeley AI Research Team veröffentlicht wurde: https://github.com/young-geng/EasyLM. This library is based on JAX which makes the fine-tuning process fast and compatible with both GPUs and Google TPUs.

Mit der gleichen Technik können Sie auch OpenLLaMA oder XGen feineinstellen.

Wir haben LLaMA 7B hier auf einer Google TPU V3-8 feinabgestimmt, aber Sie können dasselbe perfekt auf einer A100 GPU tun (lesen Sie einfach sorgfältig den Teil "Installation" in der EasyLM-Dokumentation, die etwas anders ist). Natürlich können Sie auch größere Versionen von LLaMA (13B, 33B, 65B...) feinabstimmen, aber Sie werden viel mehr als eine TPU V3-8 oder eine einzelne A100 GPU benötigen.

Los geht's!

Erstellen Sie zunächst einen Textgenerierungsdatensatz für Ihren Anwendungsfall im JSONL-Format, wobei Sie "text" als Schlüssel für jedes Beispiel verwenden. Hier ist ein einfacher Sentiment-Analyse-Datensatz:

{"text":"[Content]: I love NLP Cloud, this company is awesome!\n[Sentiment]: Positive"}
{"text":"[Content]: Training LLMs is a complex but rewarding process.\n[Sentiment]: Neutral"}
{"text":"[Content]: My fine-tuning keeps crashing because of an OOM error! It just does not work at all!\n[Sentiment]: Negative"}

Bitte beachten Sie ein paar wichtige Dinge. Erstens enthält dieser Datensatz der Einfachheit halber nur 3 Beispiele, aber im wirklichen Leben werden Sie viel mehr Beispiele benötigen. 300 Beispiele sind normalerweise ein guter Anfang. Zweitens müssen Sie bei der Verwendung Ihres fein abgestimmten Modells für die Inferenz genau dieselbe Formatierung befolgen und die Präfixe "[Inhalt]:" und "[Stimmung]:" verwenden. Schließlich ist das Token "</s>" wichtig, weil es bedeutet, dass das Modell an dieser Stelle aufhören soll zu generieren. Weitere Beispiele für Datensätze finden Sie in der NLP Cloud-Dokumentation: Hier erfahren Sie mehr.

Erstellen Sie eine TPU V3-8 VM auf Google Cloud mit der Softwareversion V2 Alpha:

Melden Sie sich per SSH an der VM an und installieren Sie EasyLM:

git clone https://github.com/young-geng/EasyLM
cd EasyLM
bash ./scripts/tpu_vm_setup.sh

Sie können nun die LLaMA-Gewichte herunterladen und konvertieren. Die erste Möglichkeit ist, Meta nach den offiziellen Gewichten zu fragen: https://ai.facebook.com/blog/large-language-model-llama-meta-ai/. Dann konvertieren Sie die Gewichte mit diesem Skript in EasyLM: https://github.com/young-geng/EasyLM/blob/main/EasyLM/models/llama/convert_torch_to_easylm.py. Die zweite Möglichkeit ist die Verwendung der LLaMA-Gewichte auf HuggingFace: https://huggingface.co/decapoda-research/llama-7b-hf. Dann konvertieren Sie die Gewichte mit diesem Skript in EasyLM: https://github.com/young-geng/EasyLM/blob/main/EasyLM/models/llama/convert_hf_to_easylm.py.

Laden Sie Ihren Datensatz auf die VM hoch und zählen Sie, wie viele Token er enthält, indem Sie den HF LLaMA-Tokenizer verwenden:

pip install -U transformers
python -c "from transformers import LlamaTokenizer; tokenizer = LlamaTokenizer.from_pretrained('decapoda-research/llama-7b-hf'); f = open('/path/to/your/dataset', 'r'); print(len(tokenizer.encode(f.read())))"

Wenn Sie Ihr Modell für einen Kontext mit 1024 Token trainieren, müssen Sie die zurückgegebene Anzahl von Token durch 1024 teilen.

Wenn Sie Ihr Modell für einen Kontext mit 2048 Token trainieren, müssen Sie die zurückgegebene Anzahl von Token durch 2048 teilen.

Diese Zahl ist die Anzahl der Schritte pro Epoche. Wenn Sie also beispielsweise 5 Epochen trainieren wollen (was normalerweise eine gute Einstellung ist), müssen Sie diese Zahl mit 5 multiplizieren und den resultierenden Wert in --total_steps unten eingeben.

Hier ein konkretes Beispiel: Wenn Ihr Datensatz 100.000 Token enthält und Sie einen Kontext mit 1024 Token und 5 Epochen wünschen, beträgt die Gesamtzahl der Schritte (100.000/1024)*5 = 488.

Je nach Kontextlänge setzen Sie --train_dataset.json_dataset.seq_length auf 1024 oder 2048. Beachten Sie, dass die Feinabstimmung eines Modells für einen Kontext mit 2048 Token mehr Speicherplatz erfordert. Wenn dies also nicht unbedingt erforderlich ist, empfehlen wir, dass Sie bei einem Kontext mit 1024 Token bleiben.

Sie können nun die Feinabstimmung starten:

nohup python -u EasyLM/EasyLM/models/llama/llama_train.py \
--total_steps=your number of steps \
--save_model_freq=usually same as your number of steps \
--optimizer.adamw_optimizer.lr_warmup_steps=usually 10% of total steps \
--train_dataset.json_dataset.path='/path/to/your/dataset' \
--train_dataset.json_dataset.seq_length=1024 or 2048 \
--load_checkpoint='params::/path/to/converted/model' \
--tokenizer.vocab_file='/path/to/tokenizer' \
--logger.output_dir=/path/to/output  \
--mesh_dim='1,4,2' \
--load_llama_config='7b' \
--train_dataset.type='json' \
--train_dataset.text_processor.fields='text' \
--optimizer.type='adamw' \
--optimizer.accumulate_gradient_steps=1 \
--optimizer.adamw_optimizer.lr=0.002 \
--optimizer.adamw_optimizer.end_lr=0.002 \
--optimizer.adamw_optimizer.lr_decay_steps=100000000 \
--optimizer.adamw_optimizer.weight_decay=0.001 \
--optimizer.adamw_optimizer.multiply_by_parameter_scale=True \
--optimizer.adamw_optimizer.bf16_momentum=True &

Einige Erklärungen:

--save_model_freq: wie oft Sie Ihr Modell während des Prozesses speichern möchten. Wenn Sie nur eine Feinabstimmung an einem kleinen Datensatz vornehmen, können Sie nur am Ende des Prozesses speichern, und in diesem Fall ist dieser Wert gleich --total_steps.

--optimizer.adamw_optimizer.lr_warmup_steps: 10% der Gesamtschrittzahl ist in der Regel ein guter Wert.

--tokenizer.vocab_file: der Pfad zur Tokenizer.model-Datei. Wenn Sie zum Beispiel das decapoda-Repository auf HuggingFace verwenden, ist hier der Link zum Tokenizer: https://huggingface.co/decapoda-research/llama-7b-hf/resolve/main/tokenizer.model

--logger.output_dir: Pfad zum endgültigen Modell und den Protokollen

Die anderen Parameter können unangetastet bleiben.

Sobald der Feinabstimmungsprozess abgeschlossen ist, können Sie Ihr Modell unter dem in --logger.output_dir angegebenen Pfad abrufen.

Verwendung des Feinabstimmungsmodells für die Inferenz

Sie haben jetzt Ihr eigenes, fein abgestimmtes Modell und wollen es natürlich auch nutzen!

Eine erste Strategie besteht darin, die EasyLM-Bibliothek für die Inferenz zu verwenden. In diesem Fall können Sie den Inferenzserver wie folgt starten:

python EasyLM/EasyLM/models/llama/llama_serve.py  \
--mesh_dim='1,1,-1' \
--load_llama_config='7b' \
--load_checkpoint='params::/path/to/your/model' \
--tokenizer.vocab_file='/path/to/tokenizer'

Dann senden Sie Ihre Anfragen einfach mit cURL wie folgt:

curl "http://0.0.0.0:5007/generate" \
-H "Content-Type: application/json" \
-X POST -d '{"prefix_text":["[Content]: EasyLM works really well!\n[Sentiment]:"]}'

Eine zweite Strategie besteht darin, Ihr Modell in das HuggingFace-Format zu exportieren, um Inferenzen mit einem anderen Framework durchzuführen. Hier sehen Sie, wie Sie es exportieren können:

python EasyLM/EasyLM/models/llama/convert_easylm_to_hf.py \
--load_checkpoint='params::/path/to/output/model/streaming_params' \
--tokenizer_path='/path/to/tokenizer' \
--model_size='7b' \
--output_dir='/path/to/converted/model'

Schlussfolgerung

Das Jahr 2023 war ein großer Meilenstein für generative Open-Source-KI-Modelle. Ab diesem Zeitpunkt kann jeder großartige Modelle wie LLaMA, OpenLLaMA, XGen, Orca, Falcon... nutzen.

Die Feinabstimmung dieser Modelle ist der beste Weg, um Spitzenergebnisse zu erzielen, die auf Ihren eigenen Anwendungsfall zugeschnitten sind und die besten proprietären KI-Modelle wie ChatGPT (GPT-3.5), GPT-4, Claude... deutlich übertreffen können.

In diesem Leitfaden habe ich Ihnen gezeigt, wie Sie LLaMA, OpenLLaMA und XGen feineinstellen können. Wenn Sie Fragen haben, zögern Sie nicht, mich zu kontaktieren, und wenn Sie fortgeschrittene generative KI-Modelle ohne technische Komplexität feineinstellen und einsetzen möchten, have a look at the NLP Cloud dedicated documentation!

Mark
Ingenieur für maschinelles Lernen bei NLP Cloud