PEFT documentation

クイックツアー

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.21.0).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

クイックツアー

PEFTは、大規模な事前学習済みモデルのファインチューニングのためのパラメータ効率の高い手法を提供します。従来のパラダイムでは、各下流タスクに対してモデルのすべてのパラメータをファインチューニングしていましたが、現在のモデルには膨大な数のパラメータがあるため、このアプローチは非常にコストが高く、実用的ではなくなっています。代わりに、より少ない数のプロンプトパラメータを学習するか、低ランク適応(LoRA)のような再パラメータ化手法を使用して学習可能なパラメータの数を減らす方が効率的です。

PEFTは、既存のモデル(「ベースモデル」)の任意の場所に学習可能なパラメータを追加するためのフレームワークと考えることができます。具体的なPEFT手法は、学習可能なパラメータを特定の方式で配置したり、学習プロセスを変更したりすることで、ベースモデルの全パラメータを学習した場合と同等のファインチューニング性能を実現します。

このクイックツアーでは、PEFTの主な機能と、通常はコンシューマーデバイスではアクセスできない大規模モデルの学習や推論を実行する方法について説明します。

PEFTの設定とモデル

PEFTのどの手法においても、PEFT手法をどのように適用するかを指定するすべてのパラメータ、特に学習可能なパラメータで対象とする既存モデルのレイヤーを指定する設定を作成する必要があります。設定が完了したら、ベースモデルとともにget_peft_model()関数に設定を渡して、学習可能なPeftModelを作成します。

LoRAを例に挙げますが、ここでは共通のパラメータについてのみ説明します。他の多くのPEFT手法を使用することも検討できます。 設定には通常、以下が含まれます:

  • target_modules: ベースモデルのどのモジュールを適応させるか
  • task_type (デフォルト: None、利用可能なTaskTypeを参照): 学習対象タスクの性質です。指定すると、アダプター重みの保存時に関連するレイヤーを自動的に保存したり、互換性の問題を警告したりするのに役立ちます。
  • inference_mode (デフォルト: False): モデルを推論に使用しているかどうか

選択するPEFTメソッドによって、更新行列のサイズなどを決定する特定のパラメータを追加します。 以下は、実環境で遭遇する可能性のある設定の例です。

from peft import LoraConfig, TaskType

peft_config = LoraConfig(target_modules=["q_proj"], task_type=TaskType.CAUSAL_LM, inference_mode=False, r=8, lora_alpha=32, lora_dropout=0.1)

PEFT設定の内部動作の詳細については、設定ガイドを参照してください。

LoraConfigを設定したら、get_peft_model()関数を使用してPeftModelを作成します。この関数は、ベースモデル(Transformersライブラリから読み込むことも可能ですが、必須ではありません)と、LoRAによる学習用にモデルを設定するためのパラメータを含むLoraConfigを受け取ります。

ファインチューニングしたいベースモデルを読み込みます。

from transformers import AutoModelForCausalLM

model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-1B")

次に、ベースモデルとpeft_configをget_peft_model()関数でラップして、PeftModelを作成します。

Wrappingとは、PEFTが対象のレイヤー(ここではすべてのq_projレイヤー)を、対象レイヤーの型に対応するアダプター固有のレイヤーに置き換えることを指します。ここでは線形レイヤーを扱っているため、この場合はlora.Linearレイヤーになります。注意してください。これらの変更はメモリを節約するためにインプレースで行われるため、ベースモデルが変更された状態になります。

q_projのみを指定しましたが、実際にはmodel.layers[:].self_attn.q_projのすべてのレイヤーを対象としています。これは、PEFTがデフォルトで一致するサフィックスを検索するためです。より複雑なレイヤーパターンを対象にする場合は、正規表現を含む文字列を渡してください。

ベースモデルのレイヤーはラップされ、保持され、学習されません。一方、新しい学習可能な重みが追加され、それらが結合されます。これらの新しい重みがどのように構成され、ベースモデルの重みとどのように結合されるかは、異なるPEFT手法を区別する重要な要素の一つです。

学習を開始する前に、ヘルスチェックを実行してアダプタの状態を確認し、学習可能なパラメータの数を調べます。

from peft import get_peft_model, LoraConfig

peft_config = LoraConfig()  # or your other PEFT method of choice
peft_model = get_peft_model(model, peft_config)
peft_model.print_healthcheck()

ヘルスチェックには、アダプタの状態、モデル設定、環境に加えて、学習可能なパラメータの割合が含まれます。

ヘルスチェックを実行する

マージ済みまたは整合性のないアダプターなどの疑わしい状態を特定し、バグレポート用のコンパクトなレポートを作成するには、print_healthcheck()を使用します。

peft_model.print_healthcheck()

次のような表示がされるはずです:

PEFT healthcheck
Model:
  ID: meta-llama/Llama-3.2-1B, type: LlamaForCausalLM, adapters: default (LORA)
Environment:
  peft: 0.21.0, transformers: 5.18.0.dev0, torch: 2.14.0+cu130, Python: 3.13.9
Runtime:
  training: True, devices: cpu, dtypes: bfloat16=1,235,814,400, float32=851,968, gradient checkpointing: False
Parameters:
  trainable: 851,968, total: 1,236,666,368, percent trainable: 0.0689%, adapter layers: 32
State:
  adapter is enabled: True, active: default, merged: none
Layer types:
  default:
    lora.Linear=32

出力は変更される可能性があるため、パースしようとしないでください。プログラムでの使用には、同じ情報をJSONシリアライズ可能な辞書として返すhealthcheck()を呼び出してください。

以上です 🎉! これで、TransformersのTrainer、Accelerate、またはカスタムのPyTorch学習ループを使用してモデルを学習できます。

例えば、Trainerクラスで学習を行うには、いくつかの学習ハイパーパラメータを設定したTrainingArgumentsクラスをセットアップします。

training_args = TrainingArguments(
    output_dir="your-name/meta-llama/my-llama3.2-adapter",
    learning_rate=1e-3,
    per_device_train_batch_size=32,
    per_device_eval_batch_size=32,
    num_train_epochs=2,
    weight_decay=0.01,
    eval_strategy="epoch",
    save_strategy="epoch",
    load_best_model_at_end=True,
)

モデル、学習引数、データセット、トークナイザー、およびその他の必要なコンポーネントをTrainerに渡し、trainを呼び出して学習を開始します。

trainer = Trainer(
    model=peft_model,
    args=training_args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["test"],
    data_collator=data_collator,
    compute_metrics=compute_metrics,
)

trainer.train()

モデルの保存

モデルの学習が完了したら、save_pretrained() 関数を使用してモデルをディレクトリに保存できます。

peft_model.save_pretrained("output_dir")

You can also save your model to the Hub (make sure you’re logged in to your Hugging Face account first) with the push_to_hub function.

from huggingface_hub import notebook_login

notebook_login()
peft_model.push_to_hub("your-name/my-llama3.2-adapter")

どちらの方法も、学習した追加のPEFT重みのみを保存するため、保存、転送、読み込みが非常に効率的です。例えば、LoRAで学習したこのfacebook/opt-350mモデルには、adapter_config.jsonとadapter_model.safetensorsの2つのファイルしか含まれていません。adapter_model.safetensorsファイルはわずか6.3MBです!

Hubに保存されているopt-350mモデルのアダプター重みは約6MBであり、モデル重みのフルサイズである約700MBと比較すると非常に小さいです。

推論

利用可能なAutoPeftModelクラスの完全なリストについては、AutoPeftModelのAPIリファレンスをご覧ください。

AutoPeftModel クラスと from_pretrained メソッドを使用すると、PEFT で学習したモデルを推論用に簡単に読み込むことができます:

from peft import AutoPeftModelForCausalLM
from transformers import AutoTokenizer
import torch

device = torch.accelerator.current_accelerator().type if hasattr(torch, "accelerator") else "cuda"

peft_model = AutoPeftModelForCausalLM.from_pretrained("ybelkada/opt-350m-lora")
tokenizer = AutoTokenizer.from_pretrained("facebook/opt-350m")

peft_model = peft_model.to(device)
peft_model.eval()
inputs = tokenizer("Preheat the oven to 350 degrees and place the cookie dough", return_tensors="pt")

outputs = peft_model.generate(input_ids=inputs["input_ids"].to(peft_model.device), max_new_tokens=50)
print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True)[0])

"Preheat the oven to 350 degrees and place the cookie dough in the center of the oven. In a large bowl, combine the flour, baking powder, baking soda, salt, and cinnamon. In a separate bowl, combine the egg yolks, sugar, and vanilla."

AutoPeftModelFor クラスで明示的にサポートされていない他のタスク(自動音声認識など)でも、AutoPeftModel ベースクラスを使用して、そのタスク用のモデルを読み込むことができます。

from peft import AutoPeftModel

peft_model = AutoPeftModel.from_pretrained("smangrul/openai-whisper-large-v2-LORA-colab")

学習済みPEFTアダプターをモデルに読み込む最も一般的な方法は、from_pretrained()を使用することです:

from transformers import AutoPeftModelForCausalLM
from peft import PeftModel

base_model = AutoModelForCausalLM.from_pretrained("meta-llama/llama3.2-1B")
peft_model = PeftModel.from_pretrained(base_model, "my-user/my-llama-adapter")  # you can also pass a directory instead of a hub path

複数のアダプター

PEFTでは、ベースモデルの上に複数のアダプター(このドキュメントではLoRA)をインストールできます。get_peft_modelを呼び出すと、"default"という名前のアダプターが1つだけ存在しますが、peft_model.add_adapter(adapter_name=...)を呼び出すことで、追加のアダプターを任意の数を追加できます。

これは、ラップされたレイヤーが各アダプター名に対して固有の学習可能な重みセットを有しているため、機能します。すべてのアダプターがデフォルトでアクティブかつ学習可能になるわけではありません。アダプターをアクティブにするには、名前を指定して明示的に有効化する必要があります。これにより、タスク固有の知識が必要なアダプター間で素早く切り替えたり、1つのモデル上で異なるユースケースを提供したりできます。

アダプターを有効にするには、まずpeft_model.set_adapter(<adapter_name>)を呼び出すことを忘れないでください。

簡単な例:

peft_model.add_adapter(adapter_name='new_adapter')
peft_model.set_adapter('new_adapter')

次のステップ

PEFTのいずれかの手法でモデルをトレーニングする方法をご覧いただいたので、プロンプトチューニングなどの他の手法も試してみてください。手順はクイックツアーで示されたものと同様です:

  1. PEFT手法(例:LoraConfigやその他の設定、メソッド概要を参照)用のPeftConfigを準備します
  2. 設定とベースモデルからPeftModelを作成するには、get_peft_model()メソッドを使用します。

その後、お好みの方法でトレーニングできます。推論用にPEFTモデルを読み込むには、AutoPeftModelクラスを使用できます。

特定のタスク(セマンティックセグメンテーション、多言語自動音声認識、DreamBooth、トークン分類など)に対して、別のPEFT手法でモデルをトレーニングする場合は、タスクガイドも併せてご覧ください。

Update on GitHub