PEFT documentation

AdaMSS

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

AdaMSS

AdaMSS(AdaMSS: Adaptive Multi-Subspace Approach for Parameter-Efficient Fine-Tuning)は、SVDを用いて重み行列を分解し、分解された空間を複数の学習可能な部分空間にクラスタリングするパラメータ効率の良いファインチューニング手法です。各部分空間は独立した低ランクの更新を学習し、元の重みは凍結されたままです。AdaMSSは、勾配情報に基づいて訓練中に重要度の低い部分空間を動的に剪定するAdaptive Subspace Allocation(ASA)もサポートしています。

論文の抄録は以下の通りです:

大規模モデルのパラメータ効率の良いファインチューニングのための適応型マルチサブスペース手法である AdaMSS を提案します。ネットワークの重みにおける大きな単一のサブスペース内で動作する従来のパラメータ効率の良いファインチューニング手法とは異なり、AdaMSS はサブスペースの分割を活用して複数の小さなサブスペースを取得し、学習中に学習可能なパラメータ数を適応的に削減します。最終的には、ターゲットとなる下流タスクに最も関連性の高いサブスペースの小さな部分集合に関連するパラメータのみを更新します。最低ランクの表現を使用することで、AdaMSS はよりコンパクトな表現力とモデルパラメータのより微細なチューニングを実現します。理論的な解析により、AdaMSS は LoRA や PiSSA、その他の単一サブスペースの低ランクベースの手法よりも優れた汎化保証を持つことが示されています。画像分類、自然言語理解、自然言語生成タスクにわたる広範な実験により、AdaMSS はフルファインチューニングと同等の性能を達成し、ほとんどのケースで他のパラメータ効率の良いファインチューニング手法を上回ることが示されました。その一方で、必要な学習可能なパラメータ数は少ないです。特に、ViT-Large モデルにおいて、AdaMSS は 7 つのタスクにわたって LoRA よりも平均精度が 4.7% 高く、学習可能なパラメータ数はわずか 15.4% にとどまります。RoBERTa-Large において、AdaMSS は 6 つのタスクにわたって平均精度で PiSSA を 7% 上回り、学習可能なパラメータ数を約 94.4% 削減しています。これらの結果は、AdaMSS がパラメータ効率の良いファインチューニングにおいて有効であることを示しています。AdaMSS のコードは https: //github.com/jzheng20/AdaMSS で利用できます。

AdaMSSには現在、以下の制約があります:

  • サポートされているのはnn.Linearレイヤーのみです。
  • KMeansクラスタリングステップにはscikit-learnが必要です。

これらの制約が使用ケースに合わない場合は、他の方法を検討してください。

ベンチマーク概要

API

AdamssConfig

クラス peft.AdamssConfig

< >

( task_type: Optional[Union[str, TaskType]] = Nonepeft_type: Optional[Union[str, PeftType]] = Noneauto_mapping: Optional[dict] = Nonepeft_version: Optional[str] = Nonebase_model_name_or_path: Optional[str] = Nonerevision: Optional[str] = Noneinference_mode: bool = Falser: int = 100num_subspaces: int = 5subspace_rank: int = 1target_modules: Optional[Union[list[str], str]] = Noneinit_weights: Optional[Literal['orthogonal']] = 'orthogonal'modules_to_save: Optional[list[str]] = Nonelayers_to_transform: Optional[Union[list[int], int]] = Nonelayers_pattern: Optional[Union[list[str], str]] = Noneuse_asa: bool = Falseasa_target_subspaces: int = 50init_warmup: int = 50final_warmup: int = 1000mask_interval: int = 100asa_importance_beta: float = 0.85asa_uncertainty_beta: float = 0.85asa_schedule_exponent: float = 3.0use_dynamic_rank: bool = Falsesvd_threshold: float = 0.1random_seed: int = 0 )

パラメータ

  • r (int) — SVD分解の総ランク(論文ではRと表記されます)。クラスタリング前に重み行列を表現するために使用される固有ベクトルの数を決定します。値を高くすると元の重みからより多くの情報を捕捉できますが、計算量とメモリ使用量が増加します。値を低くすると、より強い正則化効果が得られます。一般的な値の範囲は50から500です。デフォルト値は100です。
  • num_subspaces (int) — SVD分解された空間をクラスタリングするサブスペースの数(K)です。各サブスペースは独立した低ランクの更新を学習します。この値を大きくすると、より細粒度の適応が可能になりますが、学習可能なパラメータの数が比例して増加します。ASA(Adaptive Subspace Allocation)を使用する場合、これはプルーニング前の初期のサブスペース数を決定します。一般的な値は3から10の範囲です。デフォルト値は5です。
  • subspace_rank (int) — 学習可能な各サブスペースのランク (r_i) です。これは、各サブスペースが適応を学習するための容量を制御します。値を高くすると表現力は向上しますが、学習可能なパラメータ数も増加します。学習可能なパラメータの総数は O(num_subspaces subspace_rank (in_dim + out_dim) / num_subspaces) に比例して増加します。ほとんどのタスクでは、1〜4 の値が適切に機能します。デフォルト値は 1 です。
  • target_modules (Optional[Union[list[str], str]]) — AdaMSSを適用するモジュールの名前です。指定した場合、これらのモジュールのみが適応されます。正確なモジュール名のリスト、または正規表現を指定できます。例えば、アテンション層には['q_proj', 'v_proj']、正規表現によるマッチングには'.*decoder.*(SelfAttention|EncDecAttention).*(q|v)$'のように指定します。
  • modules_to_save (Optional[list[str]]) — AdaMSS レイヤー以外で、学習可能に設定し、最終的なチェックポイントに保存するモジュールのリストです。これらのモジュールは、低ランクの更新ではなく、完全にファインチューニングされます。分類タスクにおける classifier や score のような、ランダムに初期化されたヘッドには必須です。
  • init_weights (Literal["orthogonal"]) — AdaMSS の学習可能重みの初期化方法です。現在サポートされているのは “orthogonal” のみで、B 行列(出力投影)に直交初期化を使用します。A 行列はゼロで初期化され、モデルが事前学習済み重みから開始されることを保証します。チェックポイントから読み込む際に初期化をスキップする場合は None を設定してください。デフォルトは “orthogonal” です。
  • layers_to_transform (Optional[Union[list[int], int]]) — AdaMSSを適用する特定のレイヤーのインデックスです。指定した場合、これらのレイヤーのみが適応され、適応によって最も恩恵を受けるレイヤーを実験的に特定するのに役立ちます。単一の整数または整数のリストを指定できます。
  • layers_pattern (Optional[Union[list[str], str]]) — layers_to_transform が指定されている場合、レイヤー名にマッチさせるためのパターンです。一般的なパターンに従わないモジュール名からレイヤーのインデックスを抽出するために使用されます。
  • use_asa (bool) — Adaptive Subspace Allocation (ASA) を有効にするかどうか。有効にすると、ASA は勾配情報に基づいて、学習中に重要度の低いサブスペースを動的に剪定し、性能を維持しながら実効的なパラメータ数を削減します。学習コールバックとの統合が必要です。デフォルトは False です。
  • asa_target_subspaces (int) — ASA が有効な場合、すべてのレイヤーにわたるアクティブなサブスペースの合計目標数です。ASA は、この目標に達するまで段階的にサブスペースを剪定します。値が小さいほど、より積極的な剪定が行われ、学習可能なパラメータ数が少なくなります。num_subspaces * num_target_modules より小さい値である必要があります。モデルサイズに応じて、典型的な値は 20 から 100 の範囲です。デフォルト値は 50 です。use_asa=True の場合、正の整数である必要があります。
  • init_warmup (int) — ASA 剪定を開始する前に待機するトレーニングステップ数です。ウォームアップ期間中、すべてのサブスペースがアクティブなままになり、重要度スコアが安定するのを許可します。値を高くすると重要度の正確な推定により多くの時間を確保できますが、剪定が遅延します。一般的な値は 50 から 200 の範囲です。デフォルトは 50 です。use_asa=True の場合、final_warmup より小さい値である必要があります。
  • final_warmup (int) — ASA がプルーニングを完了し、asa_target_subspaces 個のアクティブなサブスペースに到達するトレーニングステップです。プルーニングは init_warmup と final_warmup の間に分散されます。総トレーニングステップに基づいて設定する必要があり、通常は総トレーニングステップの 1/3 から 1/2 です。デフォルト値は 1000 です。use_asa=True の場合、init_warmup より大きい値である必要があります。
  • mask_interval (int) — ASA マスクの更新間隔の学習ステップ数です。値を小さくすると適応の頻度が高まりますが、オーバーヘッドが増加します。値を大きくすると、更新間の重要度推定がより安定します。一般的な値は 50 から 200 の範囲です。デフォルト値は 100 です。use_asa=True の場合、正の整数である必要があります。
  • asa_importance_beta (float) — サブスペース重要度スコアを平滑化するための指数移動平均 (EMA) 係数です。値が高い (1.0 に近い) ほど過去の重要度への重みが増し、安定性が得られます。値が低いほど、最近の勾配に対して重要度がより敏感に反応します。一般的な値の範囲は 0.8 から 0.95 です。デフォルト値は 0.85 です。
  • asa_uncertainty_beta (float) — 重要度不確実性の推定を平滑化するためのEMA係数です。不確実性が勾配の分散にどのくらいの速さで適応するかを制御します。asa_importance_betaと同様に、値が大きいほどより安定した推定が得られます。一般的な値の範囲は0.8から0.95です。デフォルト値は0.85です。
  • asa_schedule_exponent (float) — ASA のウォームアップ期間中に、総サブスペースから asa_target_subspaces への減衰率を制御するスケジュールの指数です。値が大きいほど初期のプルーニングが速くなります(より積極的な初期削減)。一方、値が小さいほど、より緩やかな線形に近い減衰になります。式は以下の通りです: current_active_subspaces = asa_target_subspaces + (asa_total_subspaces - asa_target_subspaces) * (progress ** exponent)。一般的な値の範囲は 1.0(線形)から 5.0(積極的)です。デフォルト値は 3.0 です。use_asa=True の場合、正の数である必要があります(指数がゼロまたは負の場合、スケジュールが恒久的な no-op に退化するか、progress がちょうど 0.0 に達した時点で ZeroDivisionError が発生します)。
  • use_dynamic_rank (bool) — 特異値の大きさに基づいてサブスペースのランクを動的に決定するかどうか。True の場合、各サブスペースのランクは閾値を超える特異値を数えることで決定され、異なるサブスペースが異なる有効ランクを持つことができます。False の場合、すべてのサブスペースが固定の subspace_rank を使用します。デフォルトは False です。
  • svd_threshold (float) — 動的ランク選択のための閾値比率です。use_dynamic_rank=True の場合のみ使用されます。特異値が threshold * max_singular_value を超える場合、その特異値は有意であるとみなされます。値を高くすると、実効ランクが低くなります(より積極的な切り詰めが行われます)。一般的な値の範囲は 0.05 から 0.2 です。デフォルト値は 0.1(最大値の 10%)です。

Adamss(Adaptive Multi-Subspaces)メソッド用の設定クラスです。

AdaMSSは、SVDを用いて重み行列を分解し、分解された空間を複数の学習可能な部分空間にクラスタリングするパラメータ効率の良いファインチューニング手法です。元の重みを凍結したまま、これらの部分空間内で低ランクの更新を学習します。

AdamssModel

クラス peft.AdamssModel

< >

( modelconfigadapter_namelow_cpu_mem_usage: bool = Falsestate_dict: Optional[dict] = None ) → torch.nn.Module

パラメータ

  • model (torch.nn.Module) — 適応させる対象のモデル。
  • config (AdamssConfig) — Adamssモデルの設定です。
  • adapter_name (str) — アダプターの名前。デフォルトは"default"です。

戻り値

torch.nn.Module

Adamssモデル。

事前学習済みモデルからAdamss(Adaptive Multi-Subspaces)モデルを作成します。

このメソッドは、SVDを用いて重み行列を分解し、分解された空間を複数の学習可能な部分空間にクラスタリングすることで、パラメータ効率の良いファインチューニングを実現します。

例:

>>> from transformers import AutoModelForImageClassification
>>> from peft import AdamssConfig, get_peft_model

>>> config = AdamssConfig(
...     r=500,
...     num_subspaces=5,
...     target_modules=["query", "value"],
... )

>>> model = AutoModelForImageClassification.from_pretrained("google/vit-base-patch16-224")
>>> adamss_model = get_peft_model(model, config)

属性:

  • model (~torch.nn.Module) — 適応させる対象のモデル。
  • peft_config (AdamssConfig): Adamssモデルの設定です。

update_and_allocate

< >

( global_step: int )

パラメータ

  • global_step (int) — 現在のトレーニングステップ。

重要度スコアを更新し、ASA マスキングを適用します(有効な場合)。

ASAが有効な場合、このメソッドはloss.backward()の後にoptimizer.zero_grad()の前に、すべてのトレーニングステップで呼び出す必要があります。内部的には、以下を行います:

  1. ウォームアップ期間中、各ステップでEMAを使用して重要度スコアを累積します。
  2. マスク間隔で、グローバルなトップKマスキングを適用し、重要度をリセットします。

これはASAの単一のエントリポイントです。HuggingFaceのTrainerでAdamssAsaCallbackを使用すると、このメソッドに委譲されます。カスタムな学習ループでは、コールバックの代わりにこのメソッドを直接呼び出してください。

例:

for step, batch in enumerate(dataloader):
loss = model(**batch).loss loss.backward() optimizer.step() model.base_model.update_and_allocate(step)
optimizer.zero_grad()
Update on GitHub