日本語版
最新ニュース
科学&テクノロジー

QLora、Deepspeed を使用してコンシューマー GPU の百万規模のデータセットで LLAMA3 を微調整する | スーマン著 | 2024年4月

モデル : LLAMA-8b-命令データセット: Openhermes-2.5(700k トレーニング、300k テスト)GPU: 4 RTX 4090、24GB私はフルタイムのソフトウェア エンジニア 2 で、プラットフォーム チームの中核を担っています。 限られた自由時間では、表形式データ、NLP、サウンドに興味を持ち、機械学習の世界のさまざまな側面を探索しています。 私がここで共有しているものはすべて、インターネット中のスクラップを 1 か所にまとめたものです。 私は小規模な NLP モデルのトレーニングにはそれなりの経験があり、DeBERTa v3 を使用して Kaggle コンテストにソリューションを提出し、上位 50% に入る十分なスコアを獲得しましたが、大規模な言語モデルを扱ってみたことはありません。 初めてなので見落とし等ありましたらご指摘ください。 はい、これが私の最初のブログ投稿です。 これを書くことは間違いなく私にとって役に立ちますし、読者にとっても役立つことを願っていますこの首の長い生き物が誕生から AI 分野に革命をもたらしたことを知らない人はいないでしょう。 OSS を活用した LLM 全体が近い将来に止まりそうにない革命の始まりとなった llama のリリースは冗談とは別に。Lama についてさらに詳しく、技術的に知りたい場合は、これをチェックしてください。…

QLora、Deepspeed を使用してコンシューマー GPU の百万規模のデータセットで LLAMA3 を微調整する | スーマン著 |  2024年4月

1714013298
2024-04-25 02:03:29

モデル : LLAMA-8b-命令

データセット: Openhermes-2.5(700k トレーニング、300k テスト)

GPU: 4 RTX 4090、24GB

私はフルタイムのソフトウェア エンジニア 2 で、プラットフォーム チームの中核を担っています。 限られた自由時間では、表形式データ、NLP、サウンドに興味を持ち、機械学習の世界のさまざまな側面を探索しています。 私がここで共有しているものはすべて、インターネット中のスクラップを 1 か所にまとめたものです。 私は小規模な NLP モデルのトレーニングにはそれなりの経験があり、DeBERTa v3 を使用して Kaggle コンテストにソリューションを提出し、上位 50% に入る十分なスコアを獲得しましたが、大規模な言語モデルを扱ってみたことはありません。 初めてなので見落とし等ありましたらご指摘ください。 はい、これが私の最初のブログ投稿です。 これを書くことは間違いなく私にとって役に立ちますし、読者にとっても役立つことを願っています

この首の長い生き物が誕生から AI 分野に革命をもたらしたことを知らない人はいないでしょう。 OSS を活用した LLM 全体が近い将来に止まりそうにない革命の始まりとなった llama のリリースは冗談とは別に。

Lama についてさらに詳しく、技術的に知りたい場合は、これをチェックしてください。 投稿 | リンクトイン 、これは、インターネット上で見つけることができる最も技術的に単純化された説明の 1 つです。 グループ化されたマルチクエリ アテンション、KV キャッシュ、ロータリー位置埋め込み (RoPE) など、非常にクールなアーキテクチャに実装されたものはほとんどありません。 これらはこの記事の範囲外です。 彼らは LLama のバージョンをリリースし続け、最新バージョンは数日前にリリースされました。 そして今回は、大量のデータが数 GB のパラメータに圧縮されました。

Meta が Llama 3 ~ Advanced LLM に関する 10 の重要な事実を発表 (forbes.com)

DeepSpeed は、分散トレーニングと推論を簡単、効率的、効果的に行う深層学習最適化ライブラリです。

https://github.com/microsoft/DeepSpeed

このモデルは、レンタルした 4 つの RTX 4090 GPU を使用してトレーニングします。 広大な.aiしたがって、複数の GPU にわたってモデルをトレーニングするには、いくつかの手順を実行する必要があります。 複数の GPU でのトレーニングは、単一の GPU でのトレーニングと比較して複雑なタスクです。 なぜ? 単一の GPU でトレーニングする場合、オプティマイザーの状態、パラメーター、勾配は単一のシステム内に存在するため、1 つの GPU でモデルを反復処理するのに役立ちます。

ここで、別の GPU を追加すると、それぞれ独自の状態 (オプティマイザーの状態、パラメーター、勾配) を持つモデルをトレーニングする 2 つのシステムが存在します。 1 エポックまたは複数のステップの後、単一の結果を取得したいと考えます。 ここで、2 つのシステムが 2 つのデータ バッチを並行してトレーニングしていると想像してください。 状態について通信し、データ損失を最小限に抑えて結果を収束する必要があります。 複数の GPU を利用するには複数の方法があります。すべての GPU でパラメーター、勾配、およびオプティマイザーの状態を複製することも、オプティマイザーの状態のみ、またはオプティマイザーの状態と勾配のみをシャードすることもできます。 DeepSpeed は、問題なく GPU 全体に負荷を分散するのに役立ちます。 そして、Huggingface の Accelerate パッケージを使用すると、これを簡単に実行できます。

ステージ 3 を使用します。これにより、すべてのパラメーター、勾配、オプティマイザーの状態がシャード化され、メモリ要件が少なくなった状態でトレーニングできるようになります。

詳細はブログで、 ZeRO と DeepSpeed: 新しいシステム最適化により、1,000 億を超えるパラメーターを使用したトレーニング モデルが可能になります — Microsoft Research

QLoRA について何か書くまでは、このブログを参照してより技術的なコンテキストを取得してください。 QLoRAとは何ですか? | QLoRA — 重みとバイアス (wandb.ai)基本的に 70B/8B モデルはサイズが非常に大きいため、微調整すると、通常の人の予算ではどの GPU でも完全に微調整することができなくなります。そのため、非常に少ないリソースで微調整を試みた結果、LoRA が役に立ちました。低ランクのパラメータでトレーニングし、それらを元の重みとマージするだけでしたが、その後、事前トレーニングされた LLM を 4 ビット精度に量子化することでメモリ消費量をさらに削減する QLoRA が登場しました。量子化はそれ自体がトピックなので、これを超えるものではありません。

こちらの記事も参考にしてみてください LoRA の微調整とハイパーパラメータの説明 (わかりやすい英語) | エントリーポイントAI

llama3 命令モデルを微調整します metal-llama/Meta-Llama-3–8B-Instruct · ハグフェイス 以上 オープンエルメス teknium によって提供されたデータセット。

Meta には独自のチャット形式があるため、提供された形式に従って、llama3 リポジトリ内のエンコード アルゴリズムを読み取ろうとしました。

データセットをロードする

from datasets import load_dataset

dataset = load_dataset("teknium/OpenHermes-2.5")

インスピレーションを得たエンコード ユーティリティ ラマ3リポジトリ

def _return_header(message)-> str:
role = message["from"]
header = ""
if role == "system":
header = "system"
elif role == "gpt":
header = "assistant"
elif role == "human":
header = "user"
return header

def encode_header(message):
text = ''
text = text + "<|start_header_id|>"
header = _return_header(message)
text = text + header
text = text + "<|end_header_id|>"
text = text + "nn"
return text

def encode_message(message)->str:
text = encode_header(message)
text = text + message["value"].strip()
text = text + "<|eot_id|>"
return text

def encode_dialog_prompt(dialog):
text = ''
text = text + "<|begin_of_text|>"
for message in dialog:
text = text + encode_message(message)
return text

ds = dataset.map(lambda x: {"content":encode_dialog_prompt(x['conversations'])}, num_proc=10)

冗長な列を削除し、トレーニングと検証に分割します

ds = ds.remove_columns(['custom_instruction', 'topic', 'model_name', 'model', 'skip_prompt_formatting', 'category', 'conversations', 'views', 'language', 'id', 'title', 'idx', 'hash', 'avatarUrl', 'system_prompt', 'source'])
train_test_split = ds["train"].train_test_split(test_size=0.3)

そしてそれをハブにプッシュし、

train_test_split.push_to_hub("sumandas/openhermes-2.5-llama3")

結果として得られるデータセット、 sumandas/openhermes-2.5-llama3 · ハグ顔のデータセット、テキスト例

<|begin_of_text|><|start_header_id|>system<|end_header_id|> You are an AI assistant. Provide a detailed answer so user don’t need to search outside to understand the answer.<|eot_id|><|start_header_id|>user<|end_header_id|> Instructions: Given a sentence, generate what should be the most likely next statement. The next statement should be reasonable and logically correct. Input: The screen is full of white bubbles and words, while a pair of hands plays the piano. The bubbles and words disappear and it Output:<|eot_id|><|start_header_id|>assistant<|end_header_id|> Output: becomes apparent that the hands are creating a visual representation of the music being played, captivating the audience with this unique sensory experience.<|eot_id|>

すべてのリソースはすでにインターネットで入手可能でしたので、セットアップと要件に合わせてそれらを微調整するだけでした。

前提条件、

  1. cuda開発キットをインストールする conda install cuda またはフォローしてください developer.nvidia.com/cuda-downloads?target_os=Linux
  2. ディープスピードをインストールする
  3. フラッシュアテンションをインストールする pip install flash-attn — no-build-isolation
  4. 私が使用しているこれらのライブラリをインストールします 紫外線 依存関係をより迅速に解決するには、
git+https://github.com/huggingface/transformers
git+https://github.com/huggingface/accelerate
git+https://github.com/huggingface/peft
git+https://github.com/huggingface/trl
huggingface-hub
bitsandbytes
evaluate
datasets
einops
wandb
tiktoken
xformers
sentencepiece
deepspeed
torch==2.2.2

トレーニングコード

これは、都合に応じて複数のモードでトレーニングできるスイス ナイフ トレーニング コードです。このリポジトリで見つかりました。 pacman100/LLM-ワークショップ: Sourab Mangrulkar による LLM ワークショップ (github.com)

training.py このファイルは、適切な設定で加速を使用して起動するファイルであり、ここに training.py の要点を置くだけです。 https://gist.github.com/sumandas0/0483db8514ea43e45cc5e5f5525914ab

このトレーニング コードは、huggingface の SFTTrainer を使用します (詳細) 監修付き微調整トレーナー (huggingface.co)

これで複数のことができます。loftq、unsloth、FFT、通常の lora でトレーニングできますが、ここでは Deepspeed ZerO ステージ 3 で QloRa を使用することにします。

まず、deepspeed を使用するためのアクセラレーション設定を定義します。

注: GPU アップデート数の数を増やすと、 プロセス数

それでは、accelerate コマンドを実行してトレーニングを開始しましょう。

accelerate launch --config_file "deepspeed_config.yaml"  train.py 
--seed 100
--model_name_or_path "meta-llama/Meta-Llama-3-8B-Instruct"
--dataset_name "sumandas/openhermes-2.5-llama3"
--chat_template_format "none"
--add_special_tokens False
--append_concat_token False
--splits "train,test"
--max_seq_len 2048
--num_train_epochs 1
--logging_steps 5
--log_level "info"
--logging_strategy "steps"
--evaluation_strategy "epoch"
--save_strategy "steps"
--push_to_hub
--hub_private_repo True
--report_to "wandb"
--hub_strategy "every_save"
--bf16 True
--packing True
--learning_rate 1e-4
--lr_scheduler_type "cosine"
--weight_decay 1e-4
--warmup_ratio 0.0
--max_grad_norm 1.0
--output_dir "llama3-openhermes-2.5"
--per_device_train_batch_size 4
--per_device_eval_batch_size 4
--gradient_accumulation_steps 2
--gradient_checkpointing True
--use_reentrant True
--dataset_text_field "content"
--use_flash_attn True
--use_peft_lora True
--lora_r 8
--lora_alpha 16
--lora_dropout 0.1
--lora_target_modules "all-linear"
--use_4bit_quantization True
--use_nested_quant True
--bnb_4bit_compute_dtype "bfloat16"
--bnb_4bit_quant_storage_dtype "bfloat16"

ノート、

  1. 最初に環境変数 HF_HUB_ENABLE_HF_TRANSFER=1 を設定します。
  2. また、output_dir は、すべてのチェックポイントが保存される Huggingface 内に作成されるリポジトリでもあり、チェックポイントはデフォルトで 500 ステップごとに作成されます。
  3. チャットテンプレートの形式を次のように設定しました none 、すでに自分の方法でフォーマットしているため、他のフォーマットがある場合は、たとえばchatml、zephyrなどに使用してください。
  4. lora_target_modules これは QLoRa 特有のもので、すべての線形レイヤーを微調整することを示す論文が公開されており、完全な微調整と同等の結果が得られます。
  5. LoRa のハイパーパラメータの設定については、この素晴らしいブログをご覧ください。 LoRA の微調整とハイパーパラメータの説明 (わかりやすい英語) | エントリーポイントAI
  6. WANDB_API_KEY= を設定します。 wandb に報告している場合は削除してください report_to='wandb'

これでトレーニングが全力で実行されるはずです。GPU 使用率を確認してください。

微調整は 1 エポックだけ実行し、約 15 時間かかりました。 損失曲線

図: トレーニングの損失 電車/損失 (24/04/25 02:44:11) | ハグフェイス — 重みとバイアス (wandb.ai)

WandBの概要

{
"train/learning_rate": 0.00004551803455482833,
"eval/steps_per_second": 0.893,
"_wandb.runtime": 51487,
"_runtime": 51480.36651659012,
"_timestamp": 1713698971.6200776,
"train/epoch": 1.0571428571428572,
"train/grad_norm": 0.14189070214353952,
"train/global_step": 8325,
"eval/samples_per_second": 7.141,
"_step": 1665,
"eval/loss": 0.963840126991272,
"train/loss": 0.9674,
"eval/runtime": 7532.9797
}

微調整後、得られるモデルは、今すぐ使い始めることができる完全なモデルではなく、小さなアダプター モデルになります。アダプターを元のメタ llama3 ウェイトに追加する必要があります。

PEFT アダプター モデルをロードし、

from peft import PeftModel
from transformers import AutoModelForCausalLM

base_model = AutoModelForCausalLM.from_pretrained("meta-llama/Meta-Llama-3-8B-Instruct",torch_dtype=torch.bfloat16, device_map="auto")
adapter_model = PeftModel.from_pretrained(base_model, "sumandas/llama3-openhermes-2.5")
adapter_model.merge_and_unload()

次に、アダプター モデルを hf に保存します。

adapter_model.push_to_hub("sumandas/llama3-openhermes-2.5")
import torch
import transformers
from transformers import pipeline

pipe = pipeline("text-generation", model="sumandas/llama3-openhermes-2.5",model_kwargs={"torch_dtype": torch.bfloat16},
device="cuda")

generate_kwargs = {
"do_sample": True,
"temperature": 0.7,
"max_new_tokens": 35,
}

pipe("<|begin_of_text|><|start_header_id|>user<|end_header_id|> Describe the food of Thailand<|eot_id|><|start_header_id|>assistant<|end_header_id|>",max_length=2048)

応答、

Thai cuisine is a blend of bold flavors and aromatic ingredients that create a harmonious balance of sweet, sour, salty, bitter, and spicy taste. The food in Thailand varies between different regions, but some common ingredients found throughout include rice, noodles, vegetables, herbs, and spices. Rice is a staple of Thai cuisine and is served with almost every meal, whether it is stir-fried, boiled, or used to make congee or fried rice. Noodles, made from rice or wheat, are also very popular and can be found served with various broths, sauces, and toppings in many Thai dishes. Thai food is known for its use of fresh herbs and spices such as lemongrass, galangal, coriander, basil, kaffir lime leaves, ginger, and garlic, which give the dishes their distinct flavors. Thai chilies are also widely used to add varying levels of heat to the food. Some popular Thai dishes include Tom Yum soup (hot and sour soup with lemongrass, kaffir lime leaves, and chilies), Pad Thai (stir-fried rice noodles with vegetables, peanuts, and a tangy sauce), and green curry (a spicy curry made with green chilies, coconut milk, and Thai basil). Many Thai dishes are also accompanied by a variety of sauces and condiments, including fish sauce, soy sauce, chili paste, and tamarind sauce. Fresh fruits like mango, papaya, and pineapple are also commonly enjoyed as a sweet ending to a meal. Overall, Thai food is a vibrant and flavorful cuisine that combines traditional ingredients and cooking techniques with a balance of flavors that tantalize the taste buds.<|eot_id|>

もし価値があるなら、私のモデルとデータセットに愛を送ってください:)

sumandas/openhermes-2.5-llama3 · ハグ顔のデータセット

sumandas/llama3-openhermes-2.5 · 抱きしめる顔

#QLoraDeepspeed #を使用してコンシューマー #GPU #の百万規模のデータセットで #LLAMA3 #を微調整する #スーマン著 #2024年4月

執筆者について: nipponese

Nipponese News編集部は、国内外のニュースを日本語で分かりやすくお届けします。