# GraLoRA

[**Granular Low-Rank Adaptation (GraLoRA)**](https://huggingface.co/papers/2505.20355)は、量子化における周知の問題から得られた知見に基づき、低ランク適応の**表現力**を高めると同時に、**外れ値**アクティベーションに対する頑健性を向上させることを目的としたPEFT手法です。

![GraLoRA Overview](https://github.com/SqueezeBits/GraLoRA/raw/main/figure/gralora_overview.png)

標準的なLoRAが特徴空間全体に単一の低ランクアダプタを適用するのに対し、GraLoRAは構造化かつ細粒度の適応スキームを導入します。適応空間を $𝑘^2$ 個のより小さい独立したアダプタペアのグリッドに分割し、それぞれが入力および出力次元の局所的な部分集合を担当します。その結果、各アダプタは、元のLoRAアダプタの両次元が $k$ 分の1の大きさの部分空間で動作します。

この細粒度な分解により、空間的に局所化された文脈認識型の更新が可能になり、追加のパラメータや計算コストなしに表現能力を効果的に高めることができます。GraLoRAは、より小さな部分空間内で極端な活性化の影響を分離することで、適応過程における勾配の歪みを軽減し、チャネル間のバランスを維持します。

---

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

*Low-Rank Adaptation (LoRA) は、生成モデルのパラメータ効率ファインチューニング (PEFT) において、そのシンプルさと有効性から広く利用されている手法です。最近の改良にもかかわらず、LoRA には根本的な制約が残っています。それは、ボトルネックを広げた際に過学習が発生することです。LoRA はランク 32〜64 で最も高い性能を発揮しますが、より高いランクでは精度が頭打ちになるか低下し、フルファインチューニング (FFT) の性能には依然として届きません。その根本原因は、LoRA の構造的なボトルネックにあり、これが無関係な入力チャネルへの勾配の絡み合いを引き起こし、勾配伝播を歪めていると特定しました。これを解決するため、重み行列をサブブロックに分割し、それぞれに独自の低ランクアダプタを適用する新しい構造、Granular Low-Rank Adaptation (GraLoRA) を提案します。GraLoRA は、計算コストやストレージコストをほぼ増やさずに LoRA の制約を克服し、表現能力を効果的に高め、FFT の挙動により近づけます。コード生成、常識推論、数学的推論、一般的な言語理解、画像生成の各ベンチマークにおける実験により、GraLoRA は LoRA や他のベースラインを一貫して上回り、HumanEval+ の Pass@1 で最大 +8.5% の絶対的な向上を達成しました。これらの改善はモデルサイズやランク設定を問わず有効であり、GraLoRA は PEFT におけるスケーラブルかつ堅牢なソリューションとなります。*

## ベンチマーク概要

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

# API

## GraloraConfig[[peft.GraloraConfig]]

#### peft.GraloraConfig[[peft.GraloraConfig]]

```python
peft.GraloraConfig(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, r: int = 32, hybrid_r: int = 0, target_modules: list[str] | str | None = None, alpha: int = 64, gralora_dropout: float = 0.0, gralora_k: int = 2, fan_in_fan_out: bool = False, bias: str = 'none', modules_to_save: list[str] | None = None, init_weights: bool = True, layers_to_transform: list[int] | int | None = None, layers_pattern: str | None = None)
```

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

**パラメータ:**

r (`int`) : GraLoRA attention dimensionは、GraLoRAアダプタのランクを決定します。GraLoRAアダプタの総パラメータ数は、同じランクrのLoRAと同じですが、表現力はgralora_k倍になります。

hybrid_r (`int`) : Hybrid GraLoRA rankは、Hybrid GraLoRA手法を使用する際に、vanilla LoRA手法に割り当てられるランクを決定します。GraLoRAとvanilla LoRAの組み合わせであるHybrid GraLoRAは、hybrid_r > 0 の場合に利用可能になります。GraLoRAアダプタのパラメータ数は r + hybrid_r です。

target_modules (`Union[List[str], str]`) : GraLoRA に置き換えるモジュール名のリスト、またはモジュール名の正規表現です。例えば、['q', 'v'] や '.*decoder.*(SelfAttention|EncDecAttention).*(q|v)$' などです。また、すべての linear/Conv1D に一致するワイルドカード 'all-linear' も指定できます（モデルが PreTrainedModel の場合、出力層は除外されます）。指定しない場合、モデルのアーキテクチャに基づいてモジュールが選択されます。アーキテクチャが不明な場合はエラーが発生します。この場合、対象モジュールを手動で指定する必要があります。

alpha (`int`) : GraLoRA alpha。GraLoRA alphaは、GraLoRAアダプターのスケーリング係数です。スケールは alpha / (r + hybrid_r) になります。

gralora_dropout (`float`) : GraLoRA dropoutは、GraLoRAアダプター用のdropout確率です。GraLoRAアダプターの過学習を防ぎ、汎化性能を向上させるために使用されます。

gralora_k (`int`) : GraLoRA k は、GraLoRA アダプター内のサブブロックの数を決定します。GraLoRA アダプターが有効であるためには、ランク r が gralora_k で割り切れる必要があります。パラメータの総数は、gralora_k の値に関わらず維持されます。GraLoRA アダプターの全体のランクは gralora_k 倍に増加し、各サブブロックのランクは gralora_k 分の 1 に減少します。ランクが 32 以下の場合には gralora_k=2、ランクが 64 以上の場合には gralora_k=4 を推奨します。

fan_in_fan_out (`bool`) : 置き換えるレイヤーが (fan_in, fan_out) の形式で重みを保存している場合は、これを True に設定します。例えば、gpt-2 は (fan_in, fan_out) の形式で重みを保存する `Conv1D` を使用しているため、これを `True` に設定する必要があります。

bias (`str`) : gralora のバイアスタイプです。'none'、'all'、または 'gralora_only' を指定できます。'all' または 'gralora_only' を指定した場合、対応するバイアスが学習中に更新されます。この設定により、アダプターを無効にしても、モデルは適応なしのベースモデルと同一の出力を生成しなくなる点にご注意ください。

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

init_weights (`bool`) : GraLoRA層の重みをデフォルトの初期化で初期化するかどうか。何をしているか完全に把握している場合を除き、この設定を変更しないでください。

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

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

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

## GraloraModel[[peft.GraloraModel]]

#### peft.GraloraModel[[peft.GraloraModel]]

```python
peft.GraloraModel(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/gralora/model.py#L28)

**パラメータ:**

model ([PreTrainedModel](https://huggingface.co/docs/transformers/main/en/main_classes/model#transformers.PreTrainedModel)) : 適応させる対象のモデル。

config ([GraloraConfig](/docs/peft/main/ja/package_reference/gralora#peft.GraloraConfig)) : Graloraモデルの設定です。

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

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

Graloraモデル。

事前学習済みのTransformersモデルから、ベクトルベースのRandom Matrix Adaptation（Gralora）モデルを作成します。

例:

```py
>>> from transformers import AutoModelForCausalLM
>>> from peft import GraloraConfig, get_peft_model

>>> base_model = AutoModelForCausalLM.from_pretrained("facebook/opt-125m")
>>> config = GraloraConfig(r=128)
>>> model = get_peft_model(base_model, config)
```

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

