# FourierFT: 離散フーリエ変換によるファインチューニング

[FourierFT](https://huggingface.co/papers/2405.03003)は、離散フーリエ変換（DFT）を利用してモデルの調整可能な重みを圧縮する、パラメータ効率の高いファインチューニング手法です。この手法は、はるかに少ないパラメータ数で、GLUEベンチマークおよび一般的なViT分類タスクにおいてLoRAを上回る性能を発揮します。

FourierFTには現在、以下の制約があります：

- サポートされているのは`nn.Linear`レイヤーのみです。
- 量子化レイヤーはサポートされていません。

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

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

> 低ランク適応（LoRA）は、基盤モデルのファインチューニングにおいて最近大きな注目を集めています。低ランク行列 A と B を組み込むことで重みの変化を表現し、つまり Delta W=BA とすることで、学習可能なパラメータ数を効果的に削減します。LoRA の進歩にもかかわらず、大規模なカスタマイズ適応やより大きなベースモデルを扱う際には、ストレージの課題に直面しています。本研究では、フーリエ変換の強力な表現力を活用することで、学習可能なパラメータをさらに圧縮することを目的としています。具体的には、FourierFT を導入し、Delta W を空間領域の行列として扱い、そのスペクトル係数のごく一部のみを学習します。学習されたスペクトル係数を用いて、逆離散フーリエ変換を実行し、Delta W を復元します。実証的に、FourierFT 手法は、自然言語理解、自然言語生成、指示チューニング、画像分類を含むさまざまなタスクにおいて、LoRA よりも少ないパラメータ数で同等以上のパフォーマンスを示しています。例えば、LLaMA2-7B モデルで指示チューニングを実行する場合、LoRA の 33.5M に対して、FourierFT はわずか 0.064M の学習可能なパラメータで LoRA を上回ります。

## ベンチマーク概要

<iframe src="https://peft-internal-testing-peft-method-comparison-embed.hf.space/?highlight[type]=FOURIERFT" frameborder="0" width="850" height="1000"
>

# API

## FourierFTConfig[[peft.FourierFTConfig]]

#### peft.FourierFTConfig[[peft.FourierFTConfig]]

```python
peft.FourierFTConfig(task_type: Optional[Union[str, TaskType]] = None, peft_type: Optional[Union[str, PeftType]] = None, auto_mapping: Optional[dict] = None, peft_version: Optional[str] = None, base_model_name_or_path: Optional[str] = None, revision: Optional[str] = None, inference_mode: bool = False, n_frequency: int = 1000, scaling: float = 150.0, random_loc_seed: Optional[int] = 777, fan_in_fan_out: bool = False, target_modules: Optional[Union[list[str], str]] = None, exclude_modules: Optional[Union[list[str], str]] = None, bias: str = 'none', modules_to_save: Optional[list[str]] = None, layers_to_transform: Optional[Union[list[int], int]] = None, layers_pattern: Optional[Union[list[str], str]] = None, n_frequency_pattern: Optional[dict] = <factory>, init_weights: bool = False)
```

[ソース](https://github.com/huggingface/peft/blob/main/src/peft/tuners/fourierft/config.py#L25)

**パラメータ:**

n_frequency (`int`) : Discrete Fourier Transform における学習可能な周波数の数です。'n_frequency' は 0 より大きく d^2 以下（重み W が d 行 d 列の次元を持つと仮定した場合）の整数です。また、各 delta W 重みを更新するために必要な学習可能パラメータの数でもあります。'n_frequency' は PEFT のパフォーマンスと効率に影響します。具体的には、トレーニング速度への影響はほとんどありませんが、値が高いほど（通常）GPU メモリコストが増大し、精度が向上します。同じ `target_modules` を使用する場合、LoRA のパラメータ数は FourierFT の (2*d*r/n_frequency) 倍です。'n_frequency' に関する設定の以下の例を、ユーザーの参考としてご利用いただけます。RoBERTa-large モデルを用いた NLU タスクでは、'n_frequency': 1000 を採用することで、LoRA の 'r': 8 とほぼ同様の結果を得ることができます。この場合、LoRA のパラメータ数は FourierFT の約 16 倍です。ViT-large モデルを用いた画像分類タスクでは、'n_frequency': 3000 を採用することで、LoRA の 'r': 16 とほぼ同様の結果を得ることができ、この場合 LoRA のパラメータ数は FourierFT の約 11 倍です。

scaling (`float`) : デルタ W 行列のスケーリング値です。LoRA メソッドの 'lora_alpha' パラメータと同様に、スケーリングに使用される重要なハイパーパラメータです。'scaling' はハイパーパラメータ探索の過程で決定できます。ただし、このプロセスをスキップしたい場合は、以下のシナリオの設定を参照できます。RoBERTa-base および RoBERTa-large モデルの両方において、すべての NLU (GLUE) タスクで、このパラメータを 100.0 または 150.0 に設定できます。LLaMA ファミリーのモデルの両方において、すべてのインストラクションチューニングで、このパラメータを 300.0 に設定できます。ViT-base および ViT-large モデルの両方において、すべての画像分類タスクで、このパラメータを 300.0 に設定できます。

random_loc_seed (`int`) : 周波数のランダムな位置、つまりスペクトルエントリ行列のシード。

target_modules (`Union[list[str],str]`) : FourierFT に置き換えるモジュール名のリスト、またはモジュール名の正規表現です。例えば、['q', 'v'] や '.*decoder.*(SelfAttention|EncDecAttention).*(q|v)$' などです。サポートされるのは線形層のみです。

exclude_modules (`Optional[Union[List[str], str]]`) : アダプタを適用しないモジュールの名前。文字列を渡す場合、正規表現によるマッチングが行われます。文字列のリストを渡す場合、完全一致が行われるか、モジュールの名前が渡された文字列のいずれかで終わるかがチェックされます。

fan_in_fan_out (`bool`) : 置き換えるレイヤーが (fan_in, fan_out) のように重みを保存している場合は、これを True に設定します。

bias (`str`) : FourierFTのバイアスタイプ。'none'、'all'、または'fourier_only'のいずれかを指定できます。

modules_to_save (`list[str]`) : FourierFT層を除き、最終チェックポイントで学習可能かつ保存されるように設定するモジュールのリスト。例えば、シーケンス分類やトークン分類タスクでは、最終層である`classifier/score`がランダムに初期化されるため、学習可能かつ保存される必要があります。

layers_to_transform (`Union[list[int],int]`) : 変換対象のレイヤーのインデックスです。この引数が指定されている場合、PEFT はこのリスト内で指定されたレイヤーのインデックスのみを変換します。単一の整数が渡された場合、PEFT はそのインデックスのレイヤーのみを変換します。

layers_pattern (`Optional[Union[List[str], str]]`) : `layers_to_transform`がNoneと異なる場合、かつレイヤーパターンが共通のレイヤーパターンに含まれない場合にのみ使用されるレイヤーパターンの名前です。これはモデルの`nn.ModuleList`を対象とすべきであり、通常`'layers'`または`'h'`と呼ばれます。

n_frequency_pattern (`dict`) : 既定の指定と異なる n_frequency を持つ、レイヤー名または正規表現から n_frequency へのマッピング。例えば、`{model.decoder.layers.0.encoder_attn.k_proj: 1000`}。

init_weights (`bool`) : フーリエ重みの初期化方法です。スペクトラムを標準正規分布で初期化する場合は、これを False（デフォルト）に設定します。スペクトラムをゼロで初期化する場合は、これを True に設定します。

これは[FourierFTModel](/docs/peft/main/ja/package_reference/fourierft#peft.FourierFTModel)の設定を保存するための設定クラスです。

## FourierFTModel[[peft.FourierFTModel]]

#### peft.FourierFTModel[[peft.FourierFTModel]]

```python
peft.FourierFTModel(model, peft_config: Union[PeftConfig, dict[str, PeftConfig]], adapter_name: str, low_cpu_mem_usage: bool = False, state_dict: Optional[dict[str, torch.Tensor]] = None)
```

[ソース](https://github.com/huggingface/peft/blob/main/src/peft/tuners/fourierft/model.py#L31)

**パラメータ:**

model (`torch.nn.Module`) : 適応させる対象のモデル。

config ([FourierFTConfig](/docs/peft/main/ja/package_reference/fourierft#peft.FourierFTConfig)) : FourierFTモデルの設定です。

adapter_name (`str`) : アダプターの名前。デフォルトは`"default"`です。

low_cpu_mem_usage (`bool`、`optional`、デフォルトは`False`) : メタデバイス上に空のアダプター重みを生成します。読み込みプロセスを高速化するために有用です。

**戻り値:** `torch.nn.Module`

FourierFTモデル。

事前学習済みのTransformersモデルからFourierFTモデルを作成します。

この手法の詳細は、https://huggingface.co/papers/2405.03003 に記載されています。

**属性**:
- **model** ([PreTrainedModel](https://huggingface.co/docs/transformers/main/en/main_classes/model#transformers.PreTrainedModel)) -- 適応させる対象のモデル。
- **peft_config** ([FourierFTConfig](/docs/peft/main/ja/package_reference/fourierft#peft.FourierFTConfig)): Fourierモデルの設定です。

