PEFT documentation

OFT

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

OFT

Controlling Text-to-Image Diffusion by Orthogonal Finetuning

Orthogonal Finetuning (OFT)와 OFTv2는 텍스트-이미지 확산 모델을 적응시키기 위해 개발된 방법입니다. 사전 학습된 가중치 행렬을 직교 행렬로 재매개변수화하여 사전 학습 모델의 정보를 보존하는 방식으로 작동합니다. 매개변수 수를 줄이기 위해 OFT는 직교 행렬에 블록 대각 구조를 도입합니다. 이 방법은 주로 사전 학습 모델의 생성 성능을 미세 조정된 모델에서 보존하는 데 초점을 맞춥니다. 뉴런 간 의미 정보를 더 잘 포착할 수 있기 때문에, 레이어 내 모든 쌍별 뉴런 사이의 동일한 코사인 유사도(hyperspherical energy)를 유지하려고 합니다. 즉, OFT는 주제를 보존하는 능력이 더 뛰어나며, 제어 가능한 생성(예: ControlNet과 유사)에 더 적합합니다.

해당 논문의 초록은 다음과 같습니다:

대형 텍스트-이미지 확산 모델은 텍스트 프롬프트로부터 사진처럼 사실적인 이미지를 생성하는 데 인상적인 능력을 갖추고 있습니다. 이러한 강력한 모델을 효과적으로 유도하거나 제어하여 다양한 다운스트림 작업을 수행하는 방법은 중요한 미해결 과제가 되었습니다. 이 도전을 해결하기 위해, 텍스트-이미지 확산 모델을 다운스트림 작업에 적응시키기 위한 원칙적인 파인튜닝 방법인 직교 파인튜닝(Orthogonal Finetuning, OFT)을 소개합니다. 기존 방법과 달리 OFT는 단위 초구면(hypersphere) 위의 뉴런 간 쌍별 관계를 특징짓는 초구면 에너지(hyperspherical energy)를 보존할 수 있음을 증명할 수 있습니다. 이 특성이 텍스트-이미지 확산 모델의 의미론적 생성 능력을 보존하는 데 결정적임을 발견했습니다. 파인튜닝 안정성을 개선하기 위해, 초구면에 추가적인 반지름 제약 조건을 부과하는 제약 직교 파인튜닝(Constrained Orthogonal Finetuning, COFT)을 추가로 제안합니다. 구체적으로, 두 가지 중요한 텍스트-이미지 파인튜닝 작업을 고려합니다. 주체 기반 생성은 주체의 몇 장의 이미지와 텍스트 프롬프트가 주어졌을 때 주체 특이적 이미지를 생성하는 것을 목표로 하고, 제어 가능한 생성은 모델이 추가적인 제어 신호를 입력받을 수 있도록 하는 것을 목표로 합니다. 실험적으로, 우리의 OFT 프레임워크가 생성 품질과 수렴 속도 측면에서 기존 방법들을 능가함을 보여줍니다.

OFT는 뉴런에 대한 직교 변환을 학습하여 뉴런 간의 코사인 유사도를 변경하지 않도록 함으로써 초구면 에너지를 보존합니다. 이는 이전에 학습된 지식의 망각을 줄이는 데 기여할 수 있습니다. 실제로는 직교 행렬과 사전 학습된 가중치 행렬의 행렬 곱을 취하는 것을 의미합니다. 그러나 매개변수 효율성을 위해 직교 행렬은 랭크 r 블록으로 구성된 블록 대각 행렬로 표현됩니다. LoRA가 저랭크 구조를 통해 학습 가능한 매개변수의 수를 줄이는 반면, OFT는 희소 블록 대각 행렬 구조를 통해 학습 가능한 매개변수의 수를 줄입니다.

벤치마크 개요

base model에 OFT 가중치를 병합

LoRA와 유사하게, OFT가 학습한 가중치는 ~OFTModel.merge_and_unload() 함수를 사용하여 사전 학습된 가중치 행렬에 통합할 수 있습니다. 이 함수는 어댑터 가중치를 베이스 모델과 병합하여, 새로 병합된 모델을 독립적인 모델로 효과적으로 사용할 수 있게 합니다.

OFT 사용 예시

SFT, PPO, 또는 DPO 파인튜닝을 위해 TRL로 양자화 파인튜닝에 OFT를 사용하려면 다음 개요를 따르세요:

from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
from trl import SFTTrainer
from peft import OFTConfig

if use_quantization:
    bnb_config = BitsAndBytesConfig(
        load_in_4bit=True,
        bnb_4bit_quant_type="nf4",
        bnb_4bit_compute_dtype=torch.bfloat16,
        bnb_4bit_use_double_quant=True,
        bnb_4bit_quant_storage=torch.bfloat16,
    )

model = AutoModelForCausalLM.from_pretrained(
    "model_name",
    quantization_config=bnb_config
)
tokenizer = AutoTokenizer.from_pretrained("model_name")

# Configure OFT
peft_config = OFTConfig(
    oft_block_size=32,
    use_cayley_neumann=True,
    target_modules="all-linear",
    bias="none",
    task_type="CAUSAL_LM"
)

trainer = SFTTrainer(
    model=model,
    train_dataset=ds['train'],
    peft_config=peft_config,
    processing_class=tokenizer,
    args=training_arguments,
    data_collator=collator,
)

trainer.train()

API

OFTConfig

클래스 peft.OFTConfig

< >

( 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 = 0oft_block_size: int = 32module_dropout: float = 0.0target_modules: Optional[Union[list[str], str]] = Nonefan_in_fan_out: bool = Falsebias: Literal['none', 'all', 'oft_only'] = 'none'exclude_modules: Optional[Union[list[str], str]] = Noneinit_weights: bool = Truelayers_to_transform: Optional[Union[list[int], int]] = Nonelayers_pattern: Optional[Union[list[str], str]] = Nonemodules_to_save: Optional[list[str]] = Nonecoft: bool = Falseeps: float = 6e-05block_share: bool = Falseuse_cayley_neumann: bool = Truenum_cayley_neumann_terms: int = 5 )

매개변수

  • r (int) — OFT 랭크, 주입된 레이어당 OFT 블록의 수입니다. r 값이 클수록 학습 가능한 파라미터가 적은 더 희소한 업데이트 행렬이 생성됩니다. r × oft_block_size = 레이어 차원이므로, r 또는 oft_block_size 중 하나만 지정할 수 있습니다. 편의상 r 또는 oft_block_size 중 하나를 지정하면 나머지 값을 추론하도록 했습니다. 기본값은 r = 0이며, 명확성을 위해 oft_block_size를 설정하는 것이 권장됩니다.
  • oft_block_size (int) — 각 레이어에 걸친 OFT 블록 크기. oft_block_size 값이 클수록 학습 가능한 매개변수가 더 많은 더 밀집된 업데이트 행렬이 생성됩니다. 레이어의 입력 차원(in_features)으로 나누어 떨어지는 값, 예를 들어 4, 8, 16 등을 oft_block_size로 선택하십시오. r × oft_block_size = 레이어 차원이므로, r 또는 oft_block_size 중 하나만 지정할 수 있고 동시에 둘 다 지정할 수 없습니다. 편의상 r 또는 oft_block_size 중 하나를 지정하면 나머지 값을 추론하도록 했습니다. 기본값은 oft_block_size = 32입니다.
  • use_cayley_neumann (bool) — Cayley-Neumann 매개변수화(효율적이지만 근사)를 사용할지, 아니면 일반 Cayley 매개변수화(정확하지만 행렬 역산으로 인해 계산 비용이 높음)를 사용할지 지정합니다. 더 나은 효율성을 위해 True로 설정하는 것을 권장하지만, 근사 오차로 인해 성능이 약간 저하될 수 있습니다. 필요에 따라 두 설정(True 및 False)을 모두 테스트해 보시기 바랍니다. 기본값은 False입니다.
  • module_dropout (float) — LoRA의 dropout 레이어와 유사하게, 학습 중에 OFT 블록을 항등으로 설정하여 적용되는 곱셈형 dropout 확률입니다.
  • target_modules (Optional[Union[list[str], str]]) — 어댑터를 적용할 모듈의 이름입니다. 이 값이 지정되면, 지정된 이름을 가진 모듈만 교체됩니다. 문자열을 전달하면 정규식 매칭이 수행됩니다. 문자열 목록을 전달하면 정확한 매칭이 수행되거나, 모듈 이름이 전달된 문자열 중 하나로 끝나는지 확인됩니다. 이 값이 ‘all-linear’로 지정되면 출력 레이어를 제외한 모든 선형 모듈이 선택됩니다. 이 값이 지정되지 않으면 모델 아키텍처에 따라 모듈이 선택됩니다. 아키텍처가 알려지지 않은 경우 오류가 발생하며, 이 경우 대상 모듈을 수동으로 지정해야 합니다.
  • fan_in_fan_out (bool) — 대체할 레이어가 가중치를 (fan_in, fan_out) 형식으로 저장하는 경우 True로 설정합니다.
  • bias (str) — OFT의 bias 유형입니다. ‘none’, ‘all’, ‘oft_only’ 중 하나를 지정할 수 있습니다. ‘all’ 또는 ‘oft_only’로 설정하면 해당 bias가 학습 중에 업데이트됩니다. 어댑터를 비활성화하더라도, 어댑팅이 적용되지 않은 기본 모델과 동일한 출력을 생성하지 않는다는 점에 유의하세요.
  • exclude_modules (Optional[Union[List[str], str]]) — 어댑터를 적용하지 않을 모듈의 이름입니다. 문자열을 전달하면 정규식 매칭이 수행됩니다. 문자열 목록을 전달하면 정확한 매칭이 수행되거나, 모듈 이름이 전달된 문자열 중 하나로 끝나는지 확인됩니다.
  • init_weights (bool) — OFT 가중치 초기화를 수행할지 여부.
  • layers_to_transform (Union[List[int], int]) — 변환할 레이어의 인덱스입니다. 정수 목록을 전달하면 이 목록에 지정된 레이어 인덱스에 어댑터를 적용합니다. 단일 정수를 전달하면 해당 인덱스의 레이어에 변환을 적용합니다.
  • layers_pattern (Optional[Union[List[str], str]]) — layers_to_transform가 None과 다르면만 사용되는 레이어 패턴 이름입니다. 이는 모델의 nn.ModuleList를 대상으로 해야 하며, 보통 'layers' 또는 'h'라고 불립니다.
  • modules_to_save (List[str]) — 어댑터 레이어를 제외한 최종 체크포인트에 학습 가능 상태로 설정되고 저장될 모듈 목록.
  • coft (bool) — OFT의 제약 변형을 사용할지 여부입니다. 기본값은 off입니다.
  • eps (float) — COFT의 제어 강도입니다. 회전 자유도를 나타냅니다. coft가 True로 설정된 경우에만 효과가 있습니다.
  • block_share (bool) — 블록 간에 OFT 매개변수를 공유할지 여부입니다. 기본값은 False입니다.

이것은 OFTModel의 구성을 저장하기 위한 구성 클래스입니다.

check_kwargs

< >

( **kwargs )

매개변수

  • kwargs (추가 키워드 인자, 선택 사항) — 자식 클래스 초기화에 전달되는 추가 키워드 인자입니다.

kwargs가 구성에 유효한지 확인합니다.

OFTModel

클래스 peft.OFTModel

< >

( modelpeft_config: Union[PeftConfig, dict[str, PeftConfig]]adapter_name: strlow_cpu_mem_usage: bool = Falsestate_dict: Optional[dict[str, torch.Tensor]] = None ) → torch.nn.Module

매개변수

  • model (torch.nn.Module) — 어댑터 튜너 레이어가 연결될 모델입니다.
  • config (OFTConfig) — OFT 모델의 설정입니다.
  • adapter_name (str) — 어댑터의 이름이며, 기본값은 "default"입니다.
  • low_cpu_mem_usage (bool, optional, 기본값 False) — 메타 디바이스에 빈 어댑터 가중치를 생성합니다. 로딩 프로세스를 가속하는 데 유용합니다.

반환값

torch.nn.Module

OFT 모델.

사전 학습된 모델에서 Orthogonal Finetuning 모델을 생성합니다. 해당 방법은 https://huggingface.co/papers/2306.07280에 설명되어 있습니다.

예:

>>> from diffusers import StableDiffusionPipeline
>>> from peft import OFTConfig, get_peft_model

>>> config_te = OFTConfig(
...     oft_block_size=32,
...     target_modules=["k_proj", "q_proj", "v_proj", "out_proj", "fc1", "fc2"],
...     module_dropout=0.0,
...     init_weights=True,
... )
>>> config_unet = OFTConfig(
...     oft_block_size=32,
...     target_modules=[
...         "proj_in",
...         "proj_out",
...         "to_k",
...         "to_q",
...         "to_v",
...         "to_out.0",
...         "ff.net.0.proj",
...         "ff.net.2",
...     ],
...     module_dropout=0.0,
...     init_weights=True,
... )

>>> model = StableDiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5")
>>> model.text_encoder = get_peft_model(model.text_encoder, config_te)
>>> model.unet = get_peft_model(model.unet, config_unet)

속성:

  • model (~torch.nn.Module) — 적응할 모델.
  • peft_config (OFTConfig): OFT 모델의 구성입니다.
Update on GitHub