LLMファインチューニング🤗ことはじめ (2024/3)

HuggingFaceが提供しているライブラリ等を用いてLLMのファインチューニングや推論をしたいとき、手始めに参考になるかもしれない事柄や文書などをまとめた。


## 公開されている代表的なLLM

|Model Hub ID|コメント|
|:--|:--|
|[facebook/opt-125m](https://huggingface.co/facebook/opt-125m)|とても軽量なLLM|
|[microsoft/phi-2](https://huggingface.co/microsoft/phi-2)|軽量かつ高性能なLLM|
|[meta-llama/Llama-2-7b-hf](https://huggingface.co/meta-llama/Llama-2-7b-hf)|有名なオープンソースLLM|
|[lmsys/vicuna-7b-v1.5](https://huggingface.co/lmsys/vicuna-7b-v1.5)|Llama 2にInstruction tuningを施したLLM|
|[mistralai/Mistral-7B-v0.1](https://huggingface.co/mistralai/Mistral-7B-v0.1)|高性能なLLM|
|[llava-hf/llava-1.5-7b-hf](https://huggingface.co/llava-hf/llava-1.5-7b-hf)|Vicunaと[CLIP](https://openai.com/research/clip)をベースに画像を入力できるようにしたMLLM|


## HuggingFaceが提供するライブラリ

|ライブラリ名|コメント|
|:--|:--|
|[Transformers](https://huggingface.co/docs/transformers/index)|Model、TokenizerやTrainerなど、LLMを使うためのクラスが揃っている|
|[Datasets](https://huggingface.co/docs/datasets/index)|データセットを簡単にロードして使うためのライブラリ|
|[PEFT](https://huggingface.co/docs/peft/index)|効率的なファインチューニング手法を実装したライブラリ|
|[Accelerate](https://huggingface.co/docs/accelerate/index)|分散学習手法を実装したライブラリ|
|[TRL](https://huggingface.co/docs/trl/index)|Instruction tuningをするのに便利なクラスを提供する|
|[TGI](https://huggingface.co/docs/text-generation-inference/index)|LLMの推論サーバ|


## ファインチューニングの大まかな流れ

1. ベースとなるモデルを`AutoModelForCausalLM.from_pretrained()`などでロードする
2. トークナイザも`AutoTokenizer.from_pretrained()`などでロードする
3. データセットをDatasetsの`load_dataset()`でロードする
3.1. 必要に応じて`map()`メソッドでトークナイズなどデータの準備をする
4. `Trainer`にモデルやデータセット等を渡して学習を走らせる
4.1. Instruction tuningの場合は、かわりにTRLの`SFTTrainer`と`DataCollatorForCompletionOnlyLM`を使うと手軽に学習できる

### References

- [Fine-tuning a model with the Trainer API](https://huggingface.co/learn/nlp-course/chapter3/3?fw=pt) - 🤗 Course
- [Training a causal language model from scratch](https://huggingface.co/learn/nlp-course/chapter7/6?fw=pt) - 🤗 Course
- [Fine-Tuning Gemma Models in Hugging Face](https://huggingface.co/blog/gemma-peft) - 🤗 Blog
- [huggingfaceのTrainerクラスを使えばFineTuningの学習コードがスッキリ書けてめちゃくちゃ便利です](https://qiita.com/m__k/items/2c4e476d7ac81a3a44af)
- [huggingface/TRLのSFTTrainerクラスを使えばLLMのInstruction Tuningのコードがスッキリ書けてとても便利です](https://qiita.com/m__k/items/23ced0db6846e97d41cd)


## 1つのGPUでLLMを効率的に扱う

量子化(Quantization)と呼ばれる手法を用いることで、モデルの重みを8bitや4bitで表現することができ、限られたGPUメモリでもより大きなモデルを動かすことができる。bitsandbytesはモデルに即座に適用できるのに対し、AWQやGPTQは素のモデルに適用する場合にはキャリブレーションが必要。これらはTransformersに統合されている。

|量子化手法|コメント|
|:--|:--|
|[bitsandbytes](https://huggingface.co/docs/bitsandbytes/main/en/index)|8bit量子化および[QLoRA](https://huggingface.co/blog/4bit-transformers-bitsandbytes)の4bit量子化(NF4)を実装したライブラリ|
|[AWQ](https://huggingface.co/docs/transformers/main/en/quantization#awq)|4bit量子化(INT4)。要キャリブレーション|
|[GPTQ](https://huggingface.co/blog/gptq-integration)|AWQの前身といえる量子化手法。要キャリブレーション|

訓練では[LoRA](https://huggingface.co/docs/peft/main/en/conceptual_guides/lora)などを用いることで、重みをすべて学習するよりも効率化できる。また、Gradient accumulationなどの手法を用いることでも、メモリ使用量を抑えることができる。


### References

- [bnb-4bit-training.ipynb](https://colab.research.google.com/drive/1VoYNfYDKcKRQRor98Zbf2-9VQTtGJ24k?usp=sharing) - QLoRAでファインチューニングするサンプルコード
- [Quantization](https://huggingface.co/docs/peft/main/en/developer_guides/quantization) - 🤗 PEFT
- [Methods and tools for efficient training on a single GPU](https://huggingface.co/docs/transformers/en/perf_train_gpu_one) - 🤗 Transformers
- [Fine-tuning Mistral 7B with W&B](https://wandb.ai/vincenttu/finetuning_mistral7b/reports/Fine-tuning-Mistral-7B-with-W-B--Vmlldzo1NTc3MjMy)
- [OpenCALM-7BをLoRAでinstruction tuningするための実装解説 / QLoRAの実装も紹介](https://qiita.com/m__k/items/173ade78990b7d6a4be4)


## 実験の管理
`Trainer`には[W&B](https://wandb.ai/)への連携が統合されており、Webでの実験のトラッキングやチェックポイントの保存が簡単にできる。


### References

- [Hugging Face Transformers](https://docs.wandb.ai/ja/guides/integrations/huggingface) - W&B Integrations


## 推論サーバ

LLMの推論サーバを用いることで、複数の推論を効率的に実行することができる。

[vLLM](https://docs.vllm.ai/en/latest/)は多くのLLMに対応し、LoRAのAdapterを適用することもできる。Attentionの実装に[PagedAttention](https://blog.vllm.ai/2023/06/20/vllm.html)を用いることで高いスループットを実現している。[OpenAI API](https://platform.openai.com/docs/api-reference)互換なので、OpenAI APIを用いているアプリケーションからdrop-in replacementとして使える。

[SGLang](https://github.com/sgl-project/sglang)は[RadixAttention](https://lmsys.org/blog/2024-01-17-sglang/)を用いてvLLM以上に高いスループットを達成する。また、複雑なプロンプトのフローを効率的に記述するための言語も提供する。

### デプロイ

[SkyPilot](https://skypilot.readthedocs.io/en/latest/)を用いることで、最も安価にGPUインスタンスを使用可能なクラウドプロバイダを自動的に選択して[推論サーバをデプロイ](https://skypilot.readthedocs.io/en/latest/serving/sky-serve.html)できる。


### References

- [Introducing SkyServe: 50% Cheaper AI Serving on Any Cloud with High Availability](https://blog.skypilot.co/introducing-sky-serve/)