paint-brush
alpaca-lora: 手作りの大規模言語モデルの実験@ishootlaser
4,386 測定値
4,386 測定値

alpaca-lora: 手作りの大規模言語モデルの実験

Wei18m2023/10/16
Read on Terminal Reader

長すぎる; 読むには

大規模言語モデル (LLM) はソフトウェア開発に革命をもたらし、LangChain やセマンティック カーネルなどのツールとのユーザー インタラクションを強化しています。これらは、コンテンツ作成のさまざまな段階を支援し、複雑なプロセスを合理化します。しかし、LLM プロバイダーへの依存、コンテンツ検閲、カスタマイズ オプションに関する懸念により、オープンソースの代替手段の模索が行われています。この記事では、独自の LLM、alpaca-lora をトレーニングするための微調整方法を検討し、特に V100 GPU などのハードウェアで微調整を成功させるためのプロセス、課題、潜在的な解決策についての洞察を提供します。目標は、即時の繰り返しを避けながら、一貫性があり文脈に関連した応答を生成する LLM を作成することです。
featured image - alpaca-lora: 手作りの大規模言語モデルの実験
Wei HackerNoon profile picture
0-item


大規模言語モデル(LLM) は、ChatGPT のリリース以来、ソフトウェア開発におけるバズワードになりました。人間と自然な会話ができる能力は氷山の一角にすぎません。 LangChain や Semantic Kernel などのツールで強化された LLM は、ユーザーがソフトウェアと対話する方法を完全に変える可能性があります。言い換えれば、LLM は機能とデータ ソース間の相乗効果を生み出し、より効率的で直感的なユーザー エクスペリエンスを提供できます。


たとえば、次のバイラルビデオのために、多くの人がすでに AI ベースのコンテンツ作成ツールを使用しています。典型的なビデオ制作パイプラインには、ほんの数例を挙げると、脚本作成、ロジスティクス、ストーリーボード作成、編集、マーケティングが含まれます。プロセスを合理化するために、LLM は、コンテンツ作成者が脚本を書きながらリサーチを行い、撮影用の小道具を購入し、脚本に基づいてストーリーボードを生成し (画像生成には安定した拡散が必要な場合があります)、編集プロセスを促進し、目を引くタイトルを作成するのに役立ちます。 /ソーシャルメディアで視聴を集めるためのビデオの説明。 LLM はこれらすべてを調整する中核ですが、LLM をソフトウェア製品に組み込む場合には、いくつかの懸念事項が生じる可能性があります。


  1. OpenAI の API を使用すると、このサービスに依存しすぎてしまいますか?価格をつり上げたらどうなるでしょうか?サービスの可用性が変更された場合はどうなりますか?


  2. OpenAI がコンテンツを検閲したり、特定のユーザー入力に対して非建設的なフィードバックを提供したりする方法が好きではありません。 (あるいはその逆です。OpenAI の検閲が、私のユースケースでは機密性の高い特定のものを無視するのが気に入らないのです。)


  3. クライアントがプライベート クラウドまたはオンプレミスの展開を希望する場合、 ChatGPTの代替手段は何ですか?


  4. ただコントロールしたいだけなのです。 LLM をカスタマイズする必要があるので、安くしたいと考えています。


こうした懸念があるため、OpenAI の GPT モデルに相当するオープンソースのモデルが存在するのではないかと考えています。幸いなことに、素晴らしいオープンソース コミュニティはすでにいくつかの非常に有望なソリューションを共有しています。私は、独自の LLM をトレーニングするためのパラメーター効率の高い微調整方法であるalpaca-loraを試してみることにしました。このブログ投稿では、そのプロセス、遭遇した問題、それらをどのように解決したか、次に何が起こるかについて説明します。このテクニックを独自の LLM のトレーニングにも使用したい場合は、この情報が役立つことを願っています。


さぁ、始めよう!


コンテンツの概要

  • LLaMA、アルパカ、LoRAとは何ですか?
  • 微調整の実験
    • ソースコードを素早くスキャンする
    • 最初の試み
    • 最初の観察
    • 2回目の試みと(ある程度の)成功
    • 7Bを超える
  • まとめ


LLaMA、アルパカ、LoRAとは何ですか?

LLaMA は、 Meta AI の基礎言語モデルのコレクションです。これらの自己回帰モデルのパラメータ数は 7B ~ 65B であり、研究目的でのみ使用できます。 Meta は最近、いくつかの制限付きで商用利用できるLLaMA 2をリリースしました。 LLaMA モデル ファミリを特別なものにしているのは、そのトレーニング コーパスとパフォーマンスです。 Meta によれば、LLaMA は公開されているデータセットでトレーニングされています。その 13B バリアントは、ほとんどのベンチマークで GPT-3 (175B モデル) に匹敵するパフォーマンスを達成します。


alpaca は、LLaMA に基づいて命令に従う LLM を構築するというスタンフォード大学の試みです。それはこのように動作します:


  1. 言語モデルに命令、入力、応答のトリプレットを生成するよう依頼します。

  2. 生成されたデータを使用して LLaMA を微調整します。


微調整後、LLaMA はユーザーの指示に従い、それに応じて応答することができます。


以下は、バニラ LLaMA の応答と微調整された LLaMA 応答の比較です。

 { "instruction": "Answer user's question.", "input": "Can you put a medium voltage circuit breaker in a low voltage switchgear? Why? Explain in detail.", "vanilla LLaMA": { "answer": "Yes, you can put a medium voltage circuit breaker in a low voltage switchgear. The medium voltage circuit breaker can be put in a low voltage switchgear because the medium voltage circuit breaker can be put in a low voltage switchgear because the medium voltage circuit breaker can be put in a low voltage switchgear because the medium voltage circuit breaker can be put....(repetition continues)" }, "fine-tuned LLaMA": { "answer": "No, it is not possible to put a medium voltage circuit breaker in a low voltage switchgear. This is because low voltage switchgear is designed to handle voltages up to 1 kV, while medium voltage switchgear is designed to handle voltages from 1 kV to 38 kV. The circuit breakers, contacts, and other components in low voltage switchgear are not suitable for the higher voltages and currents of medium voltage switchgear. Using a medium voltage circuit breaker in a low voltage switchgear could result in damage to the components and could pose a safety hazard." } }


ご覧のとおり、微調整すると LLM の動作が大幅に変わります。バニラ モデルは繰り返しループにはまってしまいます。微調整されたモデルは 100% 正しい応答を生成しませんでしたが、少なくともその答えは断固とした「ノー」です。微調整は、使用可能な LLM を作成するために必要なステップです。多くの場合、オープンソースの微調整された LLM を導入するだけで十分です。ただし、カスタマイズされたビジネス ユース ケースによっては、ドメイン固有のデータセットでモデルを微調整することが望ましい場合があります。


アルパカの最大の欠点は、資源が必要なことです。その GitHub ページには次のように記載されています。

単純に、7B モデルを微調整するには、約 7 x 4 x 4 = 112 GB の VRAM が必要です。


これは、A100 80GB GPU が処理できる VRAM よりも多くなります。 LoRA を使用すると、VRAM 要件を回避できます。


LoRA は次のように動作します。

  1. トランスフォーマー モデルのクエリ投影重み $W_q$ など、モデル内のいくつかの重みを選択します。アダプターの重みを選択した重みに追加します (はい、算術加算です)。
  2. 元のモデルをフリーズし、追加されたウェイトのみをトレーニングします。


追加された重量にはいくつかの特別な特性があります。この論文に触発されて、Edward Hu et al.元のモデルの重み $W_o\in R^{d \times k}$ に対して、下流タスク用に微調整された重み $W_o'=W_o+BA$ を生成できることを示しました。ここで、$B\in R^{d \times r}$ 、 $A \in R^{r \times k}$ および $r\ll min(d, k)$ は、アダプターの重みの「固有ランク」です。アダプターの重みに適切な $r$ を設定することが重要です。$r$ が小さいとモデルのパフォーマンスが低下し、$r$ が大きいとアダプターの重みサイズが増加しますが、それに比例してパフォーマンスは向上しません。


この手法は切り捨て SVD に似ており、行列をいくつかの小さな行列に分解し、いくつかの最大の特異値のみを保持することで行列を近似します。 $W_o\in R^{100 \times 100}$ と仮定すると、完全な微調整では 10,000 個のパラメータが変更されることになります。 $r=8$ を使用した LoRA 微調整は、微調整された重みを $B\in R^{100 \times 8}$ と $A\in R^{8 \times 100}$ の 2 つの部分に分解します。パートには 800 個のパラメータが含まれています (合計 1600 個のパラメータ)。学習可能なパラメータの数は 6.25 分の 1 に減少します。


LoRA でモデルを変換した後、トレーニング可能な重みが最大 1% しかないモデルが得られましたが、そのパフォーマンスは特定の領域で大幅に向上しました。これにより、RTX 4090 や V100 などのよりアクセスしやすいハードウェアで 7B または 13B モデルをトレーニングできるようになります。


微調整の実験

GPU アクセラレーション VM インスタンス ( p2s.2xlarge 、 8vCPU、64GB RAM、1x V100 32GB VRAM) を使用して Huawei Cloud で実験を実行しました。 V100 は bfloat16 データ型をサポートしておらず、その tensor コアは int8 をサポートしていないことが知られています。加速度。これら 2 つの制限により、混合精度トレーニングの速度が低下し、混合精度トレーニング中に数値オーバーフローが発生する可能性があります。これについては、後の議論のために念頭に置いておこうと思います。

ソースコードを素早くスキャンする

finetune.pygenerate.pyはプロジェクトの中核です。最初のスクリプトは LLaMA モデルを微調整し、2 番目のスクリプトは微調整されたモデルを使用してユーザーとチャットします。まず、 finetune.pyのメイン フローを見てみましょう。


  1. 事前にトレーニングされた大規模な基礎モデルをロードする
model = LlamaForCausalLM.from_pretrained( base_model, # name of a huggingface compatible LLaMA model load_in_8bit=True, torch_dtype=torch.float16, device_map=device_map, )


  1. モデルのトークナイザーをロードします
tokenizer = LlamaTokenizer.from_pretrained(base_model) tokenizer.pad_token_id = ( 0 # unk. we want this to be different from the eos token ) tokenizer.padding_side = "left" # Allow batched inference


  1. トレーニング テンプレートに基づいて、 tokenizegenerate_and_tokenize_promptという 2 つの関数を使用してモデル入力を準備します。


  2. ハグフェイスのPEFTを使用してLoRAに適応したモデルを作成する

config = LoraConfig( r=lora_r, # the lora rank lora_alpha=lora_alpha, # a weight scaling factor, think of it like learning rate target_modules=lora_target_modules, # transformer modules to apply LoRA to lora_dropout=lora_dropout, bias="none", task_type="CAUSAL_LM", ) model = get_peft_model(model, config)


  1. トレーナー インスタンスを作成してトレーニングを開始する
trainer = transformers.Trainer( model=model, train_dataset=train_data, eval_dataset=val_data, args=transformers.TrainingArguments( ...


これは非常に簡単です。


最後に、スクリプトはチェックポイント、アダプターの重み、アダプター構成を含むモデル フォルダーを生成します。


次に、 generate.pyのメインフローを見てみましょう


  1. 負荷モデルとアダプターの重み
model = LlamaForCausalLM.from_pretrained( base_model, device_map={"": device}, torch_dtype=torch.float16, ) model = PeftModel.from_pretrained( model, lora_weights, device_map={"": device}, torch_dtype=torch.float16, )


  1. 世代構成を指定する
generation_config = GenerationConfig( temperature=temperature, top_p=top_p, top_k=top_k, num_beams=num_beams, **kwargs, ) generate_params = { "input_ids": input_ids, "generation_config": generation_config, "return_dict_in_generate": True, "output_scores": True, "max_new_tokens": max_new_tokens, }


  1. ストリーミング生成モードと非ストリーミング生成モードの関数を定義します。
 if stream_output: # streaming ... # Without streaming with torch.no_grad(): generation_output = model.generate( input_ids=input_ids, generation_config=generation_config, return_dict_in_generate=True, output_scores=True, max_new_tokens=max_new_tokens, ) s = generation_output.sequences[0] output = tokenizer.decode(s) yield prompter.get_response(output)


  1. Gradio サーバーを起動してモデルをテストします。
 gr.Interface( ...


最初の試み

プロジェクトのREADME.mdは、次の微調整設定により、スタンフォード アルパカに匹敵するパフォーマンスの LLaMA 7B が生成されると記載されています。 「公式」アルパカローラの体重がハグフェイスで共有されました。


 python finetune.py \ --base_model='decapoda-research/llama-7b-hf' \ --num_epochs=10 \ --cutoff_len=512 \ --group_by_length \ --output_dir='./lora-alpaca' \ --lora_target_modules='[q_proj,k_proj,v_proj,o_proj]' \ --lora_r=16 \ --micro_batch_size=8


ただし、私の経験では、使用可能なモデルは得られませんでした。 V100 で実行すると、次の重大な問題が発生します。


  1. load_in_8bitを使用してモデルをロードすると、データ型エラーが発生します。
  2. バインディング スクリプトにより、PEFT が無効なアダプターを生成します。無効なアダプターは元の LLaMA モデルに変更を加えず、意味不明な結果を生成するだけです。
  3. decapoda-research/llama-7b-hfモデルは明らかに間違ったトークナイザーを使用していました。そのpad トークン、bos トークン、eos トークンは、LLaMA の公式トークナイザーとは異なります。
  4. 前述したように、V100 には int8/fp16 混合トレーニングに対する適切なサポートがありません。これにより、 training loss = 0.0eval loss = NaNなどの予期しない動作が発生します。


調査して VM の膨大な時間を無駄にした後、単一の V100 でトレーニングを機能させるために必要な変更を見つけました。

 ... # do not use decapoda-research/llama-7b-hf as base_model. use a huggingface LLaMA model that was properly converted and has a correct tokenizer, eg, yahma/llama-7b-hf or huggyllama/llama-7b. # decapoda-research/llama-7b-hf is likely to cause overflow/underflow on V100. train loss goes to 0 and eval loss becomes NaN. using yahma/llama-7b-hf or huggyllama/llama-7b somehow mitigates this issue model = LlamaForCausalLM.from_pretrained( base_model, load_in_8bit=True, # only work for 7B LLaMA. On a V100, set True to save some VRAM at the cost of slower training; set False to speed up training at the cost of more VRAM / smaller micro batch size torch_dtype=torch.float16, device_map=device_map, ) ... # comment out the following line if load_in_8bit=False model = prepare_model_for_int8_training(model) ... # set legacy=False to avoid unexpected tokenizer behavior. make sure no tokenizer warning was raised during tokenizer instantiation tokenizer = LlamaTokenizer.from_pretrained(base_model, legacy=False) ... # the following binding script results in invalid adapter. simply comment them out old_state_dict = model.state_dict model.state_dict = ( lambda self, *_, **__: get_peft_model_state_dict( self, old_state_dict() ) ).__get__(model, type(model)) ... # if load_in_8bit=True, need to cast data type during training with torch.autocast('cuda'): trainer.train(resume_from_checkpoint=resume_from_checkpoint)


これらの変更を加えた後、これらのトレーニング引数によって使用可能なモデルが生成されます。

 { "args": [ "--base_model", "yahma/llama-7b-hf", "--num_epochs=10", "--data_path", "yahma/alpaca-cleaned", "--output_dir", "./your output dir", "--cutoff_len=512", "--lora_target_modules=[q_proj,k_proj,v_proj,o_proj]", "--lora_r=16", "--micro_batch_size=2", "--batch_size=16", "--wandb_project", "your wandb project name" ], }


トレーニング スクリプトは、「最良の」モデル (評価損失が最も低いチェックポイント) だけでなく、いくつかのチェックポイントも保存することに注意してください。さらに分析するために、wandb を使用してトレーニング/評価の損失を記録しました。


最初の観察

微調整されたモデルに対していくつかのランダムな質問を投げます。ある程度の合理的な応答が生成されます。


以下に一例を示します。

指示: ユーザーの質問に注意深く答えてください。


入力: 開閉装置サーキットブレーカートラックを準備するとどうなりますか?


回答: 開閉装置サーキットブレーカートラックが「ラックアウト」している場合、それはトラック内のすべてのサーキットブレーカーが開いており、トラックが非通電状態であることを意味します。これは通常、トラックの整備、修理、検査のときに行われます。サーキットブレーカーが設置されると、トラックは安全に作業できるようになり、必要なメンテナンスや修理が完了したら再通電することができます。


この例では、LLM の内部知識をクエリします。モデルは開閉装置についてよく知っているようでした。しかし、その推論能力を経験的にテストしようとすると、非常に奇妙な結果が得られました。


命令:


プロジェクトに関する以下の情報が与えられた場合、質問に答えてください。 Chinese-Llama-2 プロジェクトは、中国語の大規模言語モデル Llama-2 の理解、生成、翻訳機能を強化することを目的としています。 LoRA 微調整、フルパラメータ命令微調整、二次事前トレーニングなどの手法を適用して、関連するデータセット、トレーニング ガイド、モデル パラメータをダウンロードして活用することを心からお勧めします。


入力: このプロジェクトではどのような方法が使用されていますか?


回答: Chinese-Llama-2 プロジェクトは、中国語の大規模言語モデル Llama-2 の理解、生成、翻訳機能を強化することを目的としています。 LoRA 微調整、フルパラメータ命令微調整、二次事前トレーニングなどの手法を適用して、関連するデータセット、トレーニング ガイド、モデル パラメータをダウンロードして活用することを心からお勧めします。</s>


ご覧のとおり、モデルはプロンプトを繰り返すことを好みます。私はこれをプロンプト リピーターモデルと呼んでいますが、他の開発者もリポジトリの問題でこの動作を報告していました。質問に答える能力は、プロンプトをより慎重に設計することでさらに向上します。異なるモデル間での迅速な有効性を保証できないため、この動作は実稼働システムでは望ましくないものです。モデルはプロンプトに対する感度を低くする必要があります。この LLM のパフォーマンスを何とか改善したいと考えています。


次回のセッションでは、この問題の原因と微調整の結果を改善する方法について説明します。

2回目の試みと(ある程度の)成功

微調整結果を改善するために私が試みた 3 つのことは次のとおりです。


  1. プロンプトでの損失をマスクします (プロンプトの繰り返しを避けるのに役立ちます)

  2. group-by-lengthオプションをオフにします (パフォーマンスの向上に役立ち、損失曲線がより滑らかに見えます)

  3. 評価損失曲線を信頼しないでください。評価損失が「最良の」チェックポイントよりも高い可能性がある場合でも、トレーニング損失が低いチェックポイントを使用してください。 (ここでは評価損失が最適な行列ではないため、パフォーマンスの向上に役立ちます)


この3つのポイントを一つずつ解説していきます。

プロンプトでの損失をマスクアウトする

この投稿公式の lora Weights コミット メッセージを見つけるまで、プロンプトが繰り返される原因を探していました。彼らは、プロンプトは損失の計算から除外されるべきであると提案しました。基本的に、モデルにプロンプト トークンの出力を奨励する必要はありません。トレーニング中にプロンプトをマスクしても、モデルがプロンプト トークンを繰り返すことは促進されません。以下のグラフはこれを説明しています。3 つのトレーニング実行のうち、 stoic-star-6はトレーニング中にプロンプトをマスクしなかった唯一の実行です。したがって、そのトレーニング損失は最初の方が高くなります。 a)損失の計算時にプロンプトがマスクされておらず、 b)トレーニングが不十分な場合、モデルは指示に従うよりもプロンプトを繰り返す可能性が高くなるのではないかと思います。


ソース コードでは、プロンプト トークンを -100 に設定することで損失マスキングが行われます。

-100に設定されたインデックスを持つトークンは無視され (マスクされ)、損失は[0, ..., config.vocab_size]のラベルを持つトークンに対してのみ計算されます。


group-by-lengthオプションをオフにする

group-by-lengthオプションを使用すると、huggingface のTrainer同様の長さの入力をバッチにグループ化できるようになります。これは、入力シーケンスをパディングするときに VRAM の使用量を節約するのに役立ちます。ただし、単一バッチ内のサンプルのばらつきは大幅に減少します。トレーニング プロセス中は、通常、モデルをさまざまなトレーニング サンプルにさらすことを好みます。 group-by-length Falseに設定すると、サンプルの変動が減少します。また、トレーニング中に損失の変動も引き起こします (たとえば、連続する 2 つのバッチの長さが 10 と 50 にパディングされています。短いバッチほど損失が低く、長いバッチほど損失が高くなります。その結果、図に示すように、損失曲線が振動します。下に)。


一方で、 group-by-lengthバッチ内のサンプルの変動が減少するため、モデルのパフォーマンスもこれによって影響を受ける可能性があると考えられます。以下の図はgroup-by-lengthした場合と使用しない場合のトレーニング損失を比較しています。 group-by-lengthが有効になっている実行peach-violet-19の方が平均損失が大きいことは明らかです。


評価損失曲線を信頼しないでください

すべての実行で、トレーニング損失と評価損失が発散していることが観察されました。


以下に例を示します。

この例では、最適なチェックポイントはepoch=2付近で発生します。元のリポジトリで提案されているように最適なチェックポイントをロードすると、前のセッションで説明したようにプロンプト リピーターモデルが得られる可能性が高くなります。


トレーニングの終わり近くにモデル チェックポイントをロードすることで、よりパフォーマンスの高いモデルが得られました。以前と同じ質問をすると、モデルは正しい答えを返しました。


命令:

プロジェクトに関する以下の情報が与えられた場合、質問に答えてください。 Chinese-Llama-2 プロジェクトは、中国語の大規模言語モデル Llama-2 の理解、生成、翻訳機能を強化することを目的としています。 LoRA 微調整、フルパラメータ命令微調整、二次事前トレーニングなどの手法を適用して、関連するデータセット、トレーニング ガイド、モデル パラメータをダウンロードして活用することを心からお勧めします。


入力: このプロジェクトではどのような方法が使用されていますか?


回答: Chinese-Llama-2 プロジェクトでは、LoRA 微調整、フルパラメータ命令微調整、二次事前トレーニングなどの手法が使用されています。</s>


しかし、評価損失から判断すると、このモデルのパフォーマンスは悪くなるはずです。ジレンマの原因は何でしょうか?

評価損失は、大規模な言語モデルのパフォーマンスを測定するための良いマトリックスではないと思います。 LLaMA はトレーニングと評価の損失にCrossEntropyLossを使用します。


 # modelling_llama.py from transformers library ... # forward function under LlamaForCausalLM class if labels is not None: # Shift so that tokens < n predict n shift_logits = logits[..., :-1, :].contiguous() shift_labels = labels[..., 1:].contiguous() # Flatten the tokens loss_fct = CrossEntropyLoss() loss = loss_fct(shift_logits.view(-1, self.config.vocab_size), shift_labels.view(-1))


評価セットでテストする場合、モデルは異なる表現で同じ答えを生成する可能性があります。

 { "evaluation prompt": "What is 1 + 3?" "evaluation answer": "4." "prediction answer": "The answer is 4." }


どちらの答えも正解ですが、予測の答えが評価の答えと完全に一致しない場合、評価の損失が高くなります。この場合、モデルのパフォーマンスを測定するには、より優れた評価行列が必要です。適切な評価については後ほど考えます。現時点では、トレーニング損失が最も少ないモデルが最良のモデルであると仮定しましょう。

7Bを超える

V100の13Bモデルをファインチューニングしてみました。 V100 は、7B モデルでは int8 トレーニングと fp16 トレーニングの両方を処理できますが、13B モデルでは int8 トレーニングを処理できません。 load_int_8bit = Trueの場合、13B モデルはtraining_loss = 0.0を生成します。いくつかのデバッグ ツールを使用すると、これが発生する理由を理解できます (スポイラー警告:オーバーフロー/アンダーフローが原因です)。


トレーニング中にパラメータを検査するために、huggingface のDebugUnderflowOverflowツールを使用しました。最初の順方向パスで、inf/nan 値が検出されました。

具体的には、以下の図に示すように、 DebugUnderflowOverflow LlamaDecoderLayerの 2 番目の入力で負の無限大値を捕捉しました。 2 番目の入力は、 attention_maskです。もう少し詳しく調べたところ、 attention_maskパディング要素に対して非常に大きな負の値を持つことになっていることがわかりました。偶然にも、負の無限大の値がすべてのシーケンスの先頭にあります。この観察により、負の無限大の値がこの層で発生すると考えられます。さらなる調査により、無限値が次のいくつかのレイヤーでさらなる無限値を引き起こさないこともわかりました。したがって、 LlamaDecoderLayerでのオーバーフローは、異常なトレーニング損失の根本原因ではない可能性が高くなります。



次に、各層の出力を調べました。以下の図に示すように、最終層の出力がオーバーフローしていることは明らかです。これは、 int-8 重みの精度の制限 (またはfloat16の範囲の制限。 bfloat16この問題を回避できる可能性があります) が原因であると考えられます。



オーバーフローの問題を解決するために、トレーニング中に float16 を使用しました。 V100 には、何らかのトリックを使用しない限り、13B モデルをトレーニングするのに十分な VRAM がありません。 Hugging Face DeepSpeed は、トレーニング VRAM の使用量を削減するために、CPU オフロードなどのいくつかの方法を提供します。ただし、最も簡単なトリックは、トレーニングを開始する前にmodel.gradient_checkpointing_enable()を呼び出して勾配チェックポイントを有効にすることです。


勾配チェックポイントは、トレーニング速度と引き換えに VRAM 使用量を減らします。通常、前方パス中にアクティベーションが計算され、後方パス中に使用するためにメモリに保存されます。これには追加のメモリが必要になります。ただし、勾配チェックポイントでは、前方パス中にアクティベーションを保存するのではなく、後方パス中に再計算されるため、VRAM が節約されます。このテクニックに関する素晴らしい記事があります。


float16 と勾配チェックポイントを有効にして Llama 13B をトレーニングすることができました。

 python finetune.py \ --base_model=yahma/llama-13b-hf \ --num_epochs=10 \ --output_dir 'your/output/dir' \ --lora_target_modules='[q_proj,k_proj,v_proj,o_proj]' \ --cutoff_len=1024 \ --lora_r=16 \ --micro_batch_size=4 \ --batch_size=128 \ --wandb_project 'alpaca_lora_13b' \ --train_on_inputs=False


13B モデルは、名前エンティティ認識などのいくつかの高度なタスクを処理できます。テストにはプロンプトの例を使用します。これは 13B モデルの正確な応答です。

大丈夫です!これはエキサイティングなスタートです。このモデルを使用すると、LangChain を使用して複雑なアプリケーションを作成できます。


現時点では、モデルを自動評価するためのツールがまだ不足しています。言語モデル評価ハーネスを使用して、多くのテスト ケースでモデルを評価したり、独自のテスト ケースを作成したりすることもできます。これは、Hugging Face が Open LLM Leaderboard に使用しているのと同じツールです。評価は LLM 開発の重要な側面ですが、この記事ではトレーニング プロセスのみに焦点を当てます。評価については今後の記事でお話しするかもしれません。


まとめ

この記事では、大規模基礎モデル (LFM) の概念と、LFM を希望どおりに動作させるためのいくつかの微調整方法を紹介しました。次に、LFM を微調整するためのパラメーター効率の高い手法である LoRA に焦点を当て、微調整コードとパフォーマンス向上テクニックについて説明しました。最後に、さらに一歩進んで、V100 GPU で Llama 13B モデルをトレーニングすることに成功しました。 13B モデルのトレーニングではいくつかの問題が発生しましたが、これらの問題はハードウェアの制限によって課せられていることがわかり、解決策が提示されました。最終的に、機能する微調整された LLM が得られましたが、まだ LLM のパフォーマンスを定量的に評価していません。



著者について


こんにちは!私の名前はウェイです。私は専任の問題解決者であり、 ABBのシニア AI スペシャリストおよび分析プロジェクト リード、そして機械学習の Google デベロッパー エキスパートです。私はミネソタ大学ツインシティーズ校で機械工学の修士号を取得し、イリノイ大学アーバナシャンペーン校で機械工学の学士号を取得しています。


私の技術スタックは Python / C# プログラミング、コンピューター ビジョン、機械学習、アルゴリズム、マイクロサービスに重点を置いていますが、ゲーム開発 (Unity)、フロント/バックエンド開発、技術的リーダーシップ、シングルボードコンピュータやロボット工学をいじくり回す。


この記事が何らかの形で人々のお役に立てれば幸いです。読んでいただきありがとうございます。問題解決に向けて頑張ってください!