PEFT documentation

PSOFT

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

PSOFT

PSOFT es un método de ajuste fino eficiente en parámetros basado en Ajuste Fino Ortogonal (OFT) que preserva las relaciones geométricas de los vectores de columnas de pesos preentrenados, al tiempo que logra un equilibrio entre el rendimiento y la eficiencia multidimensional, que incluye el número de parámetros, el uso de memoria y el coste computacional. Al restringir las transformaciones ortogonales a un subespacio principal de bajo rango derivado de los pesos preentrenados, PSOFT cierra la brecha entre LoRA y OFT, proporcionando tanto garantías teóricas como adaptabilidad práctica. Su eficacia se valida mediante evaluaciones exhaustivas en diversos conjuntos de referencia, incluidos GLUE, VTAB-1K, GSM8K, MATH y conjuntos de referencia de razonamiento de sentido común.

  • Solo se admiten capas nn.Linear.
  • No se admiten capas cuantizadas.

El resumen del artículo es:

Impulsado por el rápido crecimiento de los parámetros de los modelos, el ajuste fino eficiente de parámetros (PEFT) se ha vuelto esencial para adaptar modelos grandes a diversas tareas de bajo nivel con recursos computacionales limitados. Dentro de este paradigma, el ajuste fino ortogonal y sus variantes preservan las representaciones semánticas de los modelos preentrenados, pero tienen dificultades para lograr tanto expresividad como eficiencia en términos de número de parámetros, memoria y cómputo. Para superar esta limitación, proponemos el ajuste fino ortogonal eficiente con adaptación del subespacio principal (PSOFT), que confina las transformaciones ortogonales al subespacio principal de los pesos preentrenados. Específicamente, PSOFT construye este subespacio mediante descomposición de matrices para habilitar transformaciones compatibles, establece una condición teórica que mantiene estrictamente la geometría de este subespacio para la preservación semántica esencial, e introduce vectores ajustables eficientes que relajan gradualmente la ortogonalidad durante el entrenamiento para mejorar la adaptabilidad. Experimentos extensos en 35 tareas de NLP y CV a través de cuatro modelos representativos demuestran que PSOFT ofrece una solución práctica y escalable para lograr simultáneamente la preservación semántica, la expresividad y la eficiencia multidimensional en PEFT.

Cómo funciona PSOFT

PSOFT descompone cada matriz de pesos WpreW_{pre} en WpriW_{pri} y WresW_{res} usando SVD: Wpre=USV⊤W_{\text{pre}} = U S V^\top

El subespacio principal Wpri=UrSrVr⊤=ABW_{\text{pri}} = U_r S_r V_r^\top = AB se construye a partir de los $r$ componentes singulares principales:

Wpre=Wpri+Wres=AB+Wres,W_{\text{pre}} = W_{\text{pri}} + W_{\text{res}} = AB + W_{\text{res}},

Wps-tuned=ARB+Wres.W_{\text{ps-tuned}} = ARB + W_{\text{res}}. (PSOFT-SO: PSOFT con ortogonalidad estricta)

Wps-tuned=A diag(α) R diag(β) B+Wres.W_{\text{ps-tuned}} = A \, \mathrm{diag}(\alpha) \, R \, \mathrm{diag}(\beta) \, B + W_{\text{res}}. (PSOFT-RO: PSOFT con ortogonalidad relajada

Durante el entrenamiento, $A$, $B$ y WresW_{\text{res}} se mantienen congelados, y solo RR (o RR con α\alpha y $\beta$) es entrenable.

Para ser compatible con el marco PEFT (que espera actualizaciones aditivas de pesos), PSOFT se implementa en la siguiente forma aditiva: Wps-tuned=Wpre+A(R−Ir)BW_{\text{ps-tuned}} = W_{\text{pre}} + A (R - I_r) B

Parámetros entrenables

Tras aplicar PSOFT:

  • Los pesos del modelo original ($A$, $B$ y $W_{\text{res}}$) se mantienen congelados.
  • Solo la matriz ortogonal RR (y opcionalmente $\alpha$, $\beta$) son entrenables.
  • No se introducen parámetros de sesgo adicionales.

Uso básico

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PsoftConfig, get_peft_model

# Load base model
model_id = "facebook/opt-125m"
model = AutoModelForCausalLM.from_pretrained(model_id)

# Configure PSOFT
config = PsoftConfig(
    r=32,                                   # the dimension of trainable matrix R,
    psoft_alpha=32,                         # scaling factor (typically set to r in PSOFT),
    target_modules=["q_proj", "v_proj"],    # target attention projection layers
    ab_svd_init="psoft_init",        # principal subspace initialization
    psoft_svd="full",                       # SVD method
    psoft_orth=True,                        # enable orthogonal R (Cayley parameterization)
    psoft_mag_a=True,                       # enable tunable vector alpha
    psoft_mag_b=True,                       # enable tunable vector beta
    use_cayley_neumann=False,               # disable Cayley–Neumann approximation
    num_cayley_neumann_terms=5,             # number of Neumann series terms
    cayley_neumann_eps=None,                # improve numerical stability
)

# Apply PSOFT
model = get_peft_model(model, config)
model.train()

tokenizer = AutoTokenizer.from_pretrained(model_id)
tokenizer.pad_token = tokenizer.eos_token

# Train
inputs = tokenizer("Hello world", return_tensors="pt", padding=True)
loss = model(**inputs, labels=inputs["input_ids"]).loss
loss.backward()

trainable = [p for p in model.parameters() if p.requires_grad]
optimizer = torch.optim.AdamW(trainable, lr=5e-4)
optimizer.step()
optimizer.zero_grad(set_to_none=True)

Opciones de configuración

Modo diferente

(PSOFT-SO: PSOFT con ortogonalidad estricta)

config = PsoftConfig(psoft_orth=True,psoft_mag_a=False,psoft_mag_b=False)

(PSOFT-RO: PSOFT con ortogonalidad relajada)

config = PsoftConfig(psoft_orth=True,psoft_mag_a=True,psoft_mag_b=True)

Buenas prácticas

  1. Elección del rango: los rangos más pequeños (p. ej., 32–128) son adecuados para tareas más simples, mientras que los rangos más grandes (p. ej., 64–256) ofrecen una mayor expresividad para tareas más complejas, a costa de un aumento en los parámetros y la computación.
  2. Scaling Factor: El factor de escala suele establecerse en rr en PSOFT.
  3. Tasa de aprendizaje: Utilice tasas de aprendizaje estándar (p. ej., 1e-4 a 5e-3) para un entrenamiento estable.
  4. Inicialización SVD: la opción lowrank es más eficiente en memoria y cómputo que full, lo que la hace más adecuada para modelos grandes.
  5. Aproximación de Cayley–Neumann: cuando el rango es grande, habilitar la aproximación de Cayley–Neumann puede mejorar significativamente la eficiencia computacional, mientras que el beneficio es menos notable para rangos pequeños. En la práctica, un número pequeño de términos de la serie de Neumann (típicamente 5) suele ofrecer un buen equilibrio entre precisión y eficiencia.

Resumen de las pruebas de rendimiento

API

PsoftConfig

clase peft.PsoftConfig

< >

( 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 = 32target_modules: Optional[Union[list[str], str]] = Noneexclude_modules: Optional[Union[list[str], str]] = Nonepsoft_alpha: int = 32psoft_dropout: float = 0.0fan_in_fan_out: bool = Falseab_svd_init: Literal['psoft_init', 'pissa_init'] = 'psoft_init'psoft_svd: Literal['full', 'lowrank'] = 'full'psoft_svd_lowrank_niter: int = 10random_seed: int = 0psoft_orth: bool = Truepsoft_mag_b: bool = Truepsoft_mag_a: bool = Trueuse_cayley_neumann: bool = Falsenum_cayley_neumann_terms: int = 5cayley_neumann_eps: Optional[float] = Nonemodules_to_save: Optional[list[str]] = Noneinit_weights: bool = Truelayers_to_transform: Optional[Union[list[int], int]] = Nonelayers_pattern: Optional[Union[list[str], str]] = None )

Parámetros

  • r (int) — Por defecto, 32. El rango PSOFT (r) controla la capacidad del adaptador a través de una transformación R de r*r. Los rangos más pequeños, de 32 a 128, suelen ser suficientes para tareas simples. Las tareas más complejas pueden beneficiarse de rangos de 64 a 256, lo que aumenta la expresividad a costa de parámetros y cómputo adicionales. Consulte el artículo para ver configuraciones validadas empíricamente: https://openreview.net/forum?id=FSHrinMArK.
  • target_modules (Optional[Union[List[str], str]]) — Los nombres de los módulos a los que se aplicará el adaptador. Si se especifica, solo se reemplazarán los módulos con los nombres indicados. Al pasar una cadena de caracteres, se realizará una coincidencia mediante expresión regular. Al pasar una lista de cadenas de caracteres, se realizará una coincidencia exacta o se verificará si el nombre del módulo termina con alguna de las cadenas pasadas. Si se especifica como ‘all-linear’, se seleccionarán todos los módulos lineales/Conv1D (si el modelo es un PreTrainedModel, excluyendo la capa de salida). Si no se especifica, los módulos se elegirán según la arquitectura del modelo. Si la arquitectura no es conocida, se generará un error; en este caso, debe especificar los módulos objetivo manualmente.
  • exclude_modules (Optional[Union[List[str], str]]) — Los nombres de los módulos a los que no se aplicará el adaptador. Al pasar una cadena de caracteres, se realizará una coincidencia mediante expresión regular. Al pasar una lista de cadenas de caracteres, se realizará una coincidencia exacta o se comprobará si el nombre del módulo termina con alguna de las cadenas de caracteres pasadas.
  • psoft_alpha (int) — Por defecto, 32. Controla el factor de escalado de PSOFT. Misma semántica que alpha de LoRA.
  • psoft_dropout (float) — Valor predeterminado: 0.0. Dropout para la ruta PSOFT. Misma semántica que el dropout de LoRA.
  • fan_in_fan_out (bool) — Establezca este valor en True si la capa que se va a reemplazar almacena los pesos como (fan_in, fan_out). Por ejemplo, gpt-2 utiliza Conv1D, que almacena los pesos como (fan_in, fan_out), por lo que este valor debe establecerse en True.
  • ab_svd_init (Literal["psoft_init", "pissa_init"]) — Por defecto, ‘psoft_init’. Estrategia de inicialización para A y B utilizada para construir el subespacio principal en PSOFT. ‘psoft_init’: inicialización basada en SVD con A ortogonal por filas, lo que garantiza una ortogonalidad estricta (PSOFT). ‘pissa_init’: inicialización basada en SVD con A y B simétricas (PiSSA estándar).
  • psoft_svd (Literal["full", "lowrank"]) — Por defecto, ‘full’. Backend de SVD para la inicialización: ‘full’ usa torch.linalg.svd; ‘lowrank’ usa torch.svd_lowrank.
  • psoft_svd_lowrank_niter (int) — Solo se utiliza cuando psoft_svd=‘lowrank’. El valor predeterminado es 10. Número de iteraciones de potencia utilizadas por torch.svd_lowrank cuando psoft_svd=‘lowrank’.
  • psoft_orth (bool) — Por defecto, ‘True’. Si es True, restringe R para que sea ortogonal mediante parametrización de Cayley, preservando las relaciones geométricas entre las columnas de los vectores de pesos preentrenados. Si es False, R es una matriz libre sin restricciones de ortogonalidad.
  • psoft_mag_b (bool) — Por defecto, ‘True’. Si es True, aprende un vector de escalado diagonal en el lado ‘output’ de R. Se suele combinar con psoft_mag_a para aumentar la adaptabilidad a la tarea, con una ligera distorsión de la geometría preentrenada.
  • psoft_mag_a (bool) — Por defecto, ‘True’. Si es True, aprende un vector de escalado diagonal en el lado ‘input’ de R. Se suele combinar con psoft_mag_b para aumentar la adaptabilidad a la tarea, con una ligera distorsión de la geometría preentrenada.
  • use_cayley_neumann (bool) — Por defecto, ‘False’. Indica si se debe utilizar la formulación de Cayley-Neumann de PSOFT o no. Establecerlo en True mejora la eficiencia computacional, pero a costa de un mayor error de aproximación para la ortogonalidad.
  • num_cayley_neumann_terms (int) — Por defecto, 5. Solo se utiliza cuando use_cayley_neumann=True. Número de términos de Cayley-Neumann a utilizar. Un número mayor resulta en un menor error de aproximación para la ortogonalidad.
  • cayley_neumann_eps (optional[float]) — Por defecto, ‘None’. Solo se utiliza cuando use_cayley_neumann=True. Límite opcional de la norma de Frobenius para la matriz generadora Q en la aproximación de Cayley-Neumann. Si es None (valor predeterminado), no se aplica ningún reescalado. Si se establece en un valor en (0, 1) (p. ej., 0.9), Q se reescala siempre que ||Q||_F supere el umbral para mejorar la estabilidad numérica. Consulte https://spherelab.ai/oftv2/ para obtener más detalles.
  • init_weights (bool) — Por defecto, ‘True’. Indica si se deben inicializar los pesos de las capas PSOFT con su inicialización predeterminada. No cambies esta configuración, a menos que sepas exactamente lo que estás haciendo.
  • modules_to_save (List[str]) — Lista de módulos, aparte de las capas de adaptador, que se configurarán como entrenables y se guardarán en el punto de control final.
  • layers_to_transform (Union[List[int], int]) — Los índices de las capas a transformar. Si se pasa una lista de enteros, se aplicará el adaptador a los índices de capa especificados en esta lista. Si se pasa un solo entero, se aplicarán las transformaciones a la capa en este índice.
  • layers_pattern (Optional[Union[List[str], str]]) — El nombre del patrón de capas, utilizado solo si layers_to_transform es diferente de None. Esto debe apuntar al nn.ModuleList del modelo, que a menudo se llama 'layers' o 'h'.

Configuración para PSOFT (Ajuste fino ortogonal eficiente con adaptación del subespacio principal).

PSOFT inserta una transformación ortogonal R de r*r entre las matrices de bajo rango A y B, de modo que la actualización de bajo rango es ΔW = B @ (R-I) @ A. Solo se entrena R (y los vectores ajustables opcionales); A y B se inicializan con psoft_init (basado en SVD, con A ortogonal por filas) y se congelan.

PsoftModel

clase peft.PsoftModel

< >

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

Parámetros

  • model — El modelo que se va a adaptar.
  • config — PsoftConfig.
  • adapter_name — Nombre del adaptador, valor predeterminado “default”.
  • low_cpu_mem_usage — Crea pesos de adaptador vacíos en el dispositivo meta.

Modelo PSOFT (Efficient Orthogonal Fine-Tuning with Principal Subspace Adaptation).

Inserta una transformación ortogonal (o escalada) R de r*r entre A y B de bajo rango: ΔW = B @ (R-I) @ A. Use ab_svd_init="psoft_init" para inicializar A/B a partir de SVD y congelarlos, entrenando solo R (y vectores de magnitud opcionales).

Update on GitHub