PEFT documentation

Lily: 레이어 간 저랭크 상호 연결 적응

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

Lily: 레이어 간 저랭크 상호 연결 적응

Lily는 어댑터 행렬에 대해 크로스 레이어 가중치 공유를 도입하는 파라미터 효율적 파인튜닝 기법입니다. LoRA에서와 같이 레이어마다 독립적인 AB 쌍을 학습하는 대신, Lily는 로컬 공유 A 어댑터(각 A는 stride_A개의 연속된 레이어 블록에 걸쳐 공유됨)와 글로벌 공유 B 전문가(num_B개의 B 어댑터로 구성된 작은 풀이 모든 레이어에 걸쳐 공유됨)를 사용합니다. 각 포워드 패스에서, 경량 데이터 의존 라우터는 B 전문가들의 softmax 가중치 조합을 계산하여 해당 레이어와 입력에 대한 유효한 B를 생성합니다.

이 공유 방식은 어댑터 행렬의 총 개수를 2N(표준 LoRA)에서 N / stride_A + num_B로 줄여, 매개변수 예산을 확보하여 훨씬 더 큰 랭크 r를 사용할 수 있게 합니다. 일반적으로 LoRA에서 사용하는 것보다 2×~4× 큰 랭크를 사용할 수 있습니다. 더 높은 랭크와 더 나은 상호 연결성은 가중치 업데이트 ΔW = A × combined_B의 유효 랭크를 높여 적응 성능을 향상시킵니다.

B 조합은 데이터 의존적이므로(라우터 가중치가 런타임의 입력 활성화에 따라 달라짐), merge 및 unmerge는 지원되지 않습니다. 배포에 가중치 병합이 필요한 경우 LoRA와 같은 다른 방법을 고려해 보세요.

Lily에는 현재 다음과 같은 추가 제약 조건이 있습니다:

  • nn.Linear 레이어만 지원됩니다.
  • 양자화 레이어는 지원되지 않습니다.

이러한 제약 조건이 사용 사례에 적합하지 않다면, 다른 방법을 고려해 보세요.

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

저순위 적응(Low-rank adaptation, LoRA)은 사전 학습된 가중치 W에 대해 저순위 어댑터 A와 B를 통해 가중치 업데이트 ΔW = AB를 학습하는, 널리 사용되는 매개변수 효율적 미세 조정(PEFT) 방법입니다. LoRA는 하드웨어 효율성을 보장하지만, 저순위 가중치 업데이트로 인해 적응 성능이 제한됩니다. 본 논문에서는 로컬에서 공유되는 A와 글로벌에서 공유되는 B 전문가(experts)를 갖춘 상호 연결 프레임워크를 도입하는 새로운 PEFT 방법인 레이어 간 저순위 상호 연결 적응(Low-rank interconnected adaptation across layers, Lily)을 제안합니다. 이 구조는 레이어별 중복된 AB 쌍을 제거하여, 동일하거나 더 적은 매개변수로 더 높은 순위의 ΔW를 가능하게 합니다. 표현력을 강화하기 위해 데이터 의존적 라우터를 사용하여 A-B 상호 연결을 결정함으로써, B 전문가가 동일한 동작으로 수렴하는 것을 방지하고 도메인 전반의 표현력을 향상시킵니다. 다양한 모달리티, 아키텍처, 모델 크기에 걸친 실험은 Lily의 우수한 성능과 효율성을 입증합니다.

벤치마크 개요

API

LilyConfig

클래스 peft.LilyConfig

< >

( 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 = 32stride_A: int = 1num_B: int = 2scaling: float = 1.0target_modules: Optional[Union[list[str], str]] = Noneexclude_modules: Optional[Union[list[str], str]] = Nonemodules_to_save: Optional[list[str]] = Nonelayers_to_transform: Optional[Union[list[int], int]] = Nonelayers_pattern: Optional[Union[list[str], str]] = Noneinit_weights: bool = True )

매개변수

  • r (int) — Lily의 랭크입니다. 각 어댑터의 내부 히든 차원과 가중치 업데이트 A @ B의 랭크를 결정합니다. Lily에서는 일반적으로 LoRA보다 어댑터 수가 적어 각 어댑터가 더 많은 용량을 가져야 하므로, LoRA에서 일반적으로 사용하는 랭크보다 더 큰 r 값을 사용하는 것이 권장됩니다. 보통은 LoRA 랭크의 2x, 3x, 또는 4x입니다. 학습 가능한 매개변수의 총 수는 r * (total_layers / stride_A + num_B)에 비례하므로, stride_A를 크게 유지하고 num_B를 작게 유지하면서 r을 늘리는 것이 권장되는 트레이드오프입니다.
  • stride_A (int) — 하나의 A 어댑터를 공유하는 연속 레이어의 수입니다. 예를 들어, stride_A=4, 인 경우, 인접한 4개 레이어가 동일한 A 어댑터를 공유하여 총 total_layers / stride_A 개의 서로 다른 A 어댑터가 생성됩니다. A 어댑터는 입력을 크기 r. stride_A 보다 작지 않은 값이어야 합니다. 권장 값: 2, 3 또는 4 (즉, 2, 3 또는 4개 레이어마다 공유). stride_A를 크게 유지하고(서로 다른 A 어댑터의 수를 줄이고) 대신 r을 증가시키는 것이 반대 트레이드오프(작은 stride_A, 작은 r)보다 더 나은 성능을 제공합니다. stride_A=1로 설정하면 각 레이어가 자체 A 어댑터를 가집니다. 참고: A 공유는 각 target(동일한 target 접미사를 가진 레이어) 내에서 발생합니다. 예를 들어, target_modules가 ['q_proj', 'v_proj']이고 stride_A=2로 설정한 경우, 인접한 2개 q_proj 레이어는 A 어댑터를 공유하고, 인접한 2개 v_proj 레이어는 다른 A 어댑터를 공유하지만, 접미사가 다르기 때문에 q_proj와 v_proj 레이어는 서로 A 어댑터를 공유하지 않습니다.
    1. 권장 값: 2, 3 또는 4 (즉, 2, 3 또는 4개 레이어마다 공유). stride_A를 크게 유지하고(고유한 A 어댑터가 적음) 대신 r를 증가시키는 것이 반대되는 트레이드오프(작은 stride_A, 작은 r)보다 더 나은 성능을 제공합니다. stride_A=1로 설정하면 모든 레이어가 자체 A 어댑터를 가집니다. 참고: A 공유는 각 타겟 내에서 발생합니다(같은 타겟 접미사를 가진 레이어). 예를 들어, target_modules가 ['q_proj', 'v_proj']이고 stride_A=2로 설정한 경우, 인접한 q_proj 레이어 2개마다 A 어댑터를 공유하고, 인접한 v_proj 레이어 2개마다 다른 A 어댑터를 공유하지만, q_proj와 v_proj 레이어는 접미사가 다르므로 서로 A 어댑터를 공유하지 않습니다.
  • num_B (int) — 공유되는 B 어댑터의 수입니다. A 어댑터(레이어별로 그룹화됨)와 달리, 모든 B 어댑터는 모든 레이어에 걸쳐 전역적으로 공유됩니다. 각 forward pass마다 라우터가 softmax 정규화된 가중치를 사용하여 모든 num_B개의 B 어댑터의 가중치 합을 계산하여 단일 결합된 B 어댑터를 생성하며, 이 어댑터는 저순위 표현을 원래 차원으로 다시 투영합니다. num_B은 total_layers / stride_A와 유사한 크기로 설정하는 것이 권장됩니다. 권장 값: total_layers / 2, total_layers / 3 또는 total_layers / 4. stride_A와 마찬가지로, 작은 r에 큰 num_B보다 큰 r에 작은 num_B를 선호하는 것이 좋습니다. 참고: 라우터를 학습하려면 라우터가 B 어댑터의 가중치 합을 계산하도록 학습하기 때문에 최소 2개의 B 어댑터(즉, num_B >= 2)가 필요합니다. 참고: B 공유는 각 타겟(동일한 타겟 접미사를 가진 레이어) 내에서 발생합니다. 예를 들어, target_modules가 ['q_proj', 'v_proj']이고 num_B=4로 설정한 경우, 모든 q_proj 레이어에 걸쳐 공유되는 4개의 B 어댑터와 모든 v_proj 레이어에 걸쳐 공유되는 다른 4개의 B 어댑터가 생성됩니다. 그러나 q_proj와 v_proj 레이어는 서로 다른 접미사를 가지므로 서로 B 어댑터를 공유하지 않습니다.
  • target_modules (Union[List[str], str], 선택 사항) — Lily를 적용할 모듈의 이름입니다. 모듈 이름 문자열 목록(예: ['q_proj', 'v_proj']) 또는 정규식 패턴(예: '.*decoder.*(SelfAttention|EncDecAttention).*(q|v)$')을 사용할 수 있습니다. 지정하지 않으면 Lily는 모든 지원되는 linear layer에 적용됩니다.
  • scaling (float) — 동결된 가중치의 forward pass에 합쳐진 어댑터 출력(scaling * A @ combined_B)을 더하기 전에 적용되는 스칼라 곱셈 인자입니다. LoRA와 달리 Lily는 alpha / r 수식을 사용하지 않고, 대신 scaling을 직접적인 곱셈 인자로 사용합니다. 이러한 설계 덕분에 로그 스케일(예: 0.01, 0.1, 1.0, 10.0)에서 값을 스윕하는 것이 간단해집니다. 최적의 값은 작업에 따라 달라지며 하이퍼파라미터로 취급해야 합니다. 1.0으로 시작하는 것을 권장합니다.
  • modules_to_save (List[str], 선택 사항) — Lily 레이어를 제외한 최종 체크포인트에 학습 가능 상태로 설정되고 저장될 모듈 목록입니다. 예를 들어, 시퀀스 분류 또는 토큰 분류 작업에서 최종 레이어인 classifier/score는 무작위로 초기화되므로 학습 가능 상태로 설정되고 저장되어야 합니다.
  • exclude_modules (Union[List[str], str], 선택 사항) — 어댑터를 적용하지 않을 모듈의 이름입니다. 문자열을 전달하면 정규식 매칭이 수행됩니다. 문자열 목록을 전달하면 정확한 매칭이 수행되거나, 모듈 이름이 전달된 문자열 중 하나로 끝나는지 확인됩니다.
  • layers_to_transform (Union[list[int], int], 선택 사항) — 변환할 레이어 인덱스입니다. 이 인수가 지정되면 PEFT는 해당 리스트에 지정된 레이어 인덱스만 변환합니다. 단일 정수가 전달되면 PEFT는 해당 인덱스의 레이어만 변환합니다.
  • layers_pattern (Optional[Union[List[str], str]], 선택 사항) — layers_to_transform가 None과 다르고 레이어 패턴이 공통 레이어 패턴에 없는 경우에만 사용되는 레이어 패턴 이름입니다. 이는 모델의 nn.ModuleList를 대상으로 해야 하며, 보통 'layers' 또는 'h'라고 불립니다.
  • init_weights (bool) — 기본 초기화 스킴을 사용하여 Lily 어댑터 가중치를 초기화할지 여부: A 행렬은 Kaiming uniform으로, B 행렬은 0으로 초기화되어 학습 시작 시 어댑터 출력이 0이 되도록 하며 사전 학습된 모델을 방해하지 않습니다. 특별한 이유가 없는 한 True로 유지하는 것이 강력히 권장됩니다.

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

LilyModel

class peft.LilyModel

< >

( 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 (LilyConfig) — Lily 모델의 구성입니다.
  • adapter_name (str) — 어댑터의 이름이며, 기본값은 "default"입니다.

반환값

torch.nn.Module

Lily PEFT 모델.

transformers의 사전 학습된 모델에서 Low-Rank Interconnected Adaptation Across Layers (Lily) 모델을 생성합니다.

해당 방법은 https://arxiv.org/abs/2407.09946에서 자세히 설명되어 있습니다.

속성:

Update on GitHub