Zmagasz się z AI lub rozwojem full-stack? Nasi eksperci są tutaj, aby Cię poprowadzić: dostosowane porady, integracja techniczna i nie tylko. Skontaktuj się z nami pod adresem [email protected].

Jak dostroić LLaMA, OpenLLaMA i XGen za pomocą JAX na GPU lub TPU

LLaMA, OpenLLaMA i XGen to najnowocześniejsze generatywne modele sztucznej inteligencji. Modele te dają jeszcze lepsze wyniki, gdy zostaną dostrojone na własnych danych. W tym artykule zobaczymy, jak dostroić te modele zarówno na GPU, jak i TPU, przy użyciu JAX i biblioteki EasyLM.

LLaMA, OpenLLaM i XGen

Model LLaMA został wydany przez Meta w lutym 2023 roku. Ten generatywny model sztucznej inteligencji jest modelem open-source proponowanym w kilku rozmiarach: 7B parametrów, 13B parametrów, 33B parametrów i 65B parametrów.

W czerwcu 2021 r., kiedy wydano GPT-J, świat zaczął zdawać sobie sprawę, że modele generatywnej sztucznej inteligencji typu open source mogą poważnie konkurować z OpenAI GPT-3. Teraz dzięki LLaMA poprzeczka została ponownie wyraźnie podniesiona, a model ten wydaje się być bardzo dobrą alternatywą open source dla OpenAI ChatGPT i GPT-4.

Licencja LLaMA nie jest jednak przyjazna dla biznesu: model ten nie może być wykorzystywany do celów komercyjnych... Ale dobrą wiadomością jest to, że istnieją już inne modele.

OpenLLaMA, wydana w czerwcu 2023 roku, jest alternatywną wersją LLaMA, opracowaną przez zespół Berkeley AI Research, która daje bardzo dobre wyniki i może być wykorzystywana w biznesie. W chwili pisania tego tekstu dostępne są 2 wersje: 7B parametrów i 13B parametrów.

XGen, wydany przez Salesforce w czerwcu 2023 roku, to kolejny bardzo potężny model podstawowy, który może być używany w aplikacjach komercyjnych. W chwili pisania tego tekstu dostępna jest tylko wersja z parametrami 7B. Warto zauważyć, że model ten obsługuje kontekst 8k tokenów, podczas gdy LLaMA i OpenLLaMA obsługują tylko zawartość 2k tokenów.

Dlaczego warto dopracować własny model?

Powyższe modele są modelami podstawowymi, co oznacza, że zostały wytrenowane w sposób nienadzorowany na dużym korpusie tekstów.

Te fundamentalne modele sztucznej inteligencji zwykle stanowią dobrą podstawę, ale należy je dostroić, aby właściwie rozumiały to, czego chcesz i zwracały dobre wyniki. Najłatwiejszym sposobem na osiągnięcie tego celu jest zastosowanie uczenia kilkukrotnego (znanego również jako "inżynieria podpowiedzi"). Zachęcamy do zapoznania się z naszym dedykowanym przewodnikiem szkoleniowym tutaj.

Few-shot learning jest wygodny, ponieważ może być wykonywany w locie bez konieczności tworzenia nowej wersji generatywnego modelu sztucznej inteligencji, ale czasami nie jest wystarczający.

Aby uzyskać najnowocześniejsze wyniki, będziesz chciał dostroić model sztucznej inteligencji do własnego przypadku użycia. Dopracowanie oznacza modyfikację niektórych parametrów modelu w oparciu o własne dane, a następnie uzyskanie własnej wersji modelu.

Dostrajanie jest znacznie tańsze niż trenowanie generatywnego modelu sztucznej inteligencji od podstaw, ale nadal wymaga mocy obliczeniowej, więc do dostrojenia własnego modelu potrzebny jest zaawansowany sprzęt. Niektóre niedawne alternatywne techniki dostrajania wymagają mniejszej mocy obliczeniowej (patrz p-tuning, szybkie dostrajanie, miękkie dostrajanie, efektywne dostrajanie parametrów, adaptery, LoRA, QLoRA...), ale jak dotąd nie udało nam się uzyskać tego samego poziomu jakości za pomocą tych technik, więc nie będziemy o nich wspominać w tym samouczku.

Precyzyjne dostrajanie LLaMA na TPU za pomocą JAX i EasyLM

W tym samouczku skupimy się na dostrojeniu LLaMA za pomocą biblioteki EasyLM, wydanej przez zespół Berkeley AI Research: 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.

Można również dostroić OpenLLaMA lub XGen przy użyciu tej samej techniki.

Dostrajamy tutaj LLaMA 7B na Google TPU V3-8, ale możesz zrobić to samo na GPU A100 (po prostu uważnie przeczytaj część "Instalacja" w dokumentacji EasyLM, która jest nieco inna). Oczywiście można również dostroić większe wersje LLaMA (13B, 33B, 65B...), ale będziesz potrzebował znacznie więcej niż TPU V3-8 lub pojedynczy procesor graficzny A100.

Zaczynamy!

Najpierw utwórz zestaw danych do generowania tekstu dla swojego przypadku użycia, w formacie JSONL, używając "text" jako klucza dla każdego przykładu. Oto prosty zestaw danych do analizy nastrojów:

{"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"}

Należy zwrócić uwagę na kilka ważnych rzeczy. Po pierwsze, ten zestaw danych zawiera tylko 3 przykłady dla uproszczenia, ale w prawdziwym życiu będziesz potrzebować znacznie więcej przykładów. 300 przykładów to zazwyczaj dobry początek. Po drugie, gdy będziesz używać swojego dostrojonego modelu do wnioskowania, będziesz musiał ściśle przestrzegać tego samego formatowania, używając prefiksów "[Content]:" i "[Sentiment]:". Wreszcie, token "</s>" jest ważny, ponieważ oznacza, że model powinien przestać generować w tym miejscu. Więcej przykładów zestawów danych można znaleźć w dokumentacji NLP Cloud: Dowiedz się więcej tutaj.

Utwórz maszynę wirtualną TPU V3-8 w Google Cloud z wersją oprogramowania V2 Alpha:

SSH do maszyny wirtualnej i zainstaluj EasyLM:

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

Możesz teraz pobrać i przekonwertować wagi LLaMA. Pierwszą opcją jest poproszenie Meta o oficjalne wagi: https://ai.facebook.com/blog/large-language-model-llama-meta-ai/. Następnie przekonwertuj wagi na EasyLM za pomocą tego skryptu: https://github.com/young-geng/EasyLM/blob/main/EasyLM/models/llama/convert_torch_to_easylm.py. Drugą opcją jest użycie obciążników LLaMA na HuggingFace: https://huggingface.co/decapoda-research/llama-7b-hf. Następnie przekonwertuj wagi na EasyLM za pomocą tego skryptu: https://github.com/young-geng/EasyLM/blob/main/EasyLM/models/llama/convert_hf_to_easylm.py.

Prześlij swój zestaw danych do maszyny wirtualnej, policz ile tokenów zawiera, używając tokenizatora HF LLaMA:

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())))"

Jeśli trenujesz swój model dla kontekstu 1024 tokenów, będziesz musiał podzielić zwróconą liczbę tokenów przez 1024.

Jeśli trenujesz swój model dla kontekstu 2048 tokenów, będziesz musiał podzielić zwróconą liczbę tokenów przez 2048.

Liczba ta będzie liczbą kroków na epokę. Na przykład, jeśli chcesz trenować przez 5 epok (co zwykle jest dobrym ustawieniem), musisz pomnożyć tę liczbę przez 5 i umieścić wynikową wartość w --total_steps poniżej.

Oto konkretny przykład: jeśli zbiór danych zawiera 100 000 tokenów, a kontekst ma obejmować 1024 tokeny i 5 epok, całkowita liczba kroków wyniesie (100 000/1024)*5 = 488.

W zależności od długości kontekstu, ustaw --train_dataset.json_dataset.seq_length na 1024 lub 2048 poniżej. Należy pamiętać, że dostrojenie modelu dla kontekstu 2048 tokenów wymaga więcej pamięci, więc jeśli nie jest to absolutnie konieczne, zalecamy trzymanie się kontekstu 1024 tokenów.

Można teraz rozpocząć proces dostrajania:

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 &

Kilka wyjaśnień:

--save_model_freq: jak często ma być zapisywany model podczas procesu. Jeśli dostrajasz tylko mały zestaw danych, możesz zapisywać tylko na końcu procesu, a w takim przypadku wartość ta będzie równa --total_steps.

--optimizer.adamw_optimizer.lr_warmup_steps: 10% całkowitych kroków to zazwyczaj dobra wartość.

--tokenizer.vocab_file: ścieżka do pliku tokenizer.model. Na przykład, jeśli korzystasz z repozytorium decapoda na HuggingFace, oto link do tokenizera: https://huggingface.co/decapoda-research/llama-7b-hf/resolve/main/tokenizer.model

--logger.output_dir: ścieżka do ostatecznego modelu i logów

Pozostałe parametry można pozostawić bez zmian.

Po zakończeniu procesu dostrajania można pobrać model ze ścieżki określonej w opcji --logger.output_dir.

Wykorzystanie modelu dostrojonego do wnioskowania

Masz teraz swój własny, dopracowany model i oczywiście chcesz go używać!

Pierwszą strategią jest wykorzystanie biblioteki EasyLM do wnioskowania. W takim przypadku można uruchomić serwer wnioskowania w następujący sposób:

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'

Następnie wystarczy wysłać żądania za pomocą cURL w następujący sposób:

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]:"]}'

Drugą strategią jest wyeksportowanie modelu do formatu HuggingFace w celu przeprowadzenia wnioskowania w innym frameworku. Oto jak można go wyeksportować:

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'

Wnioski

Rok 2023 był wielkim kamieniem milowym dla generatywnych modeli sztucznej inteligencji typu open source. W chwili pisania tego tekstu każdy może korzystać ze świetnych modeli, takich jak LLaMA, OpenLLaMA, XGen, Orca, Falcon...

Dopracowanie tych modeli to najlepszy sposób na uzyskanie najnowocześniejszych wyników, dostosowanych do własnego przypadku użycia, które mogą znacznie przewyższyć najlepsze zastrzeżone modele AI, takie jak ChatGPT (GPT-3.5), GPT-4, Claude....

W tym przewodniku pokazałem, jak dostroić LLaMA, OpenLLaMA i XGen. Jeśli masz pytania, nie wahaj się ze mną skontaktować, a jeśli chcesz łatwo dostroić i wdrożyć zaawansowane generatywne modele sztucznej inteligencji bez żadnych technicznych komplikacji, have a look at the NLP Cloud dedicated documentation!

Mark
Inżynier ds. uczenia maszynowego w NLP Cloud