PEFT documentation

PaCA: Adaptación de Conexión Parcial

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

PaCA: Adaptación de Conexión Parcial

PaCA (ICLR 2025) es un método PEFT que se centra en la velocidad de entrenamiento y la memoria de activación. Ajusta finamente r columnas de entrada seleccionadas aleatoriamente (“conexiones parciales”) de cada peso preentrenado objetivo. Los únicos parámetros entrenables son las actualizaciones de estas columnas; a diferencia de LoRA, PaCA no añade matrices adicionales de bajo rango.

Métodos como LoRA ejecutan una rama de bajo rango junto a cada capa preentrenada. La rama requiere pocos FLOPs, pero se ejecuta de forma secuencial con la capa preentrenada y conserva su propia copia de la activación de entrada para la pasada inversa. PaCA evita ambas cosas:

  • Un GEMM por capa. Las columnas adaptadas se escriben en el peso preentrenado justo antes de su matmul y se restauran justo después, de modo que el paso hacia adelante y el paso hacia atrás ejecutan cada uno un único matmul, exactamente como la capa base congelada.
  • Activaciones parciales. El gradiente de las columnas adaptadas solo depende de los r canales de entrada correspondientes, por lo que solo se guardan esos para la pasada inversa en lugar de la entrada completa.

En cuanto a los pesos resultantes, un adaptador PaCA es equivalente a un adaptador LoRA de rango r cuya matriz A es un selector de columnas fijo: W' = W + delta @ S, donde S selecciona las r columnas. Por lo tanto, se puede convertir en un adaptador LoRA de rango r sin pérdida mediante convert_to_lora(), por ejemplo, para servirlo con una pila de inferencia LoRA.

Cuándo usar PaCA:

  • Desea una precisión a nivel de LoRA, pero con pasos de ajuste fino más rápidos y menor memoria de activación, por ejemplo, para ajustar secuencias más largas o lotes más grandes en la misma GPU.
  • Desea un adaptador que se fusione exactamente en los pesos base (la actualización es una actualización de columna simple).

Restricciones actuales:

  • Solo se admiten capas nn.Linear (incluidas las capas lineales cuantizadas).
  • PaCA ejecuta el matmul en lugar de llamar al forward de la capa base, por lo que los hooks de forward registrados en la capa base no se invocan (se emite una advertencia). Registra los hooks en la capa PaCA.
  • No se admiten lotes de adaptadores mixtos (argumento adapter_names).
  • El entrenamiento con pesos fragmentados (FSDP, DeepSpeed ZeRO-3) aún no se ha probado.
  • torch.compile es compatible: durante la compilación, el intercambio de columnas, el matmul y la restauración se ejecutan como operaciones personalizadas opacas (torch.ops.peft.paca_linear_forward/_backward), por lo que el compilador no copia los pesos base. Esto requiere torch.library.custom_op (PyTorch >= 2.4); de lo contrario, se traza la implementación eager.
  • paca_alpha / r escala la actualización de la columna y, por lo tanto, actúa como un multiplicador de la tasa de aprendizaje efectiva.
  • Para la inferencia, fusiona el adaptador (merge_and_unload()); el forward sin fusionar sigue intercambiando las columnas en cada llamada.

Uso

from transformers import AutoModelForCausalLM
from peft import PacaConfig, get_peft_model

model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-3B")
config = PacaConfig(r=16, paca_alpha=16, target_modules="all-linear", random_seed=0)
model = get_peft_model(model, config)
model.print_trainable_parameters()

Por defecto, cada capa objetivo realiza el ajuste fino de r columnas seleccionadas aleatoriamente; en el artículo, esto rindió a la par que seleccionar las columnas por norma de peso o por gradientes acumulados. Para elegir las columnas usted mismo, por ejemplo para probar otra estrategia de selección o para usar un número diferente de columnas por capa, pase paca_indices_pattern. Sus claves son nombres de capas o expresiones regulares, como en rank_pattern de LoRA:

config = PacaConfig(
    r=16,
    paca_alpha=16,
    target_modules=["q_proj", "v_proj"],
    paca_indices_pattern={"layers.0.self_attn.q_proj": [0, 2, 4, 6], "layers.1.self_attn.v_proj": list(range(32))},
)

Las capas que coinciden con una clave ajustan las columnas dadas, mientras que todas las demás capas objetivo seleccionan r columnas aleatorias. La escala es paca_alpha / r con el r de la configuración en cada capa, por lo que paca_alpha significa lo mismo para todas las capas.

El resumen del artículo es:

Los algoritmos de ajuste fino eficiente en parámetros (PEFT) anteriores reducen el uso de memoria y los costos computacionales del ajuste fino de modelos de redes neuronales grandes al entrenar solo unos pocos parámetros de adaptador adicionales, en lugar de todo el modelo. Sin embargo, la reducción de costos computacionales debido a PEFT no se traduce necesariamente en una reducción del tiempo de entrenamiento; aunque los costos computacionales de las capas de adaptador son mucho menores que los de las capas preentrenadas, es bien sabido que esos dos tipos de capas se procesan secuencialmente en las GPU, lo que resulta en una sobrecarga de latencia significativa. LoRA y sus variantes evitan esta sobrecarga de latencia fusionando las matrices de adaptador de bajo rango con los pesos preentrenados durante la inferencia. Sin embargo, esas capas no pueden fusionarse durante el entrenamiento, ya que los pesos preentrenados deben permanecer congelados mientras las matrices de adaptador de bajo rango se actualizan continuamente a lo largo del entrenamiento. Además, LoRA y sus variantes no reducen la memoria de activaciones, ya que la primera matriz de adaptador de bajo rango aún requiere las activaciones de entrada a los pesos preentrenados para calcular los gradientes de los pesos. Para mitigar este problema, proponemos la Adaptación de Conexiones Parciales (PaCA), que ajusta finamente conexiones parciales seleccionadas aleatoriamente dentro de los pesos preentrenados en lugar de introducir capas de adaptador en el modelo. PaCA no solo mejora la velocidad de entrenamiento al eliminar la sobrecarga de tiempo debida al procesamiento secuencial de las capas de adaptador y preentrenadas, sino que también reduce la memoria de activaciones, ya que solo se necesitan almacenar activaciones parciales, en lugar de activaciones completas, para el cálculo de gradientes. En comparación con LoRA, PaCA reduce el tiempo de entrenamiento en un 22% y el uso total de memoria en un 16%, manteniendo una precisión comparable en diversos escenarios de ajuste fino, como el ajuste fino en el conjunto de datos MMLU y el ajuste de instrucciones en el conjunto de datos Oasst1. PaCA también puede combinarse con cuantización, lo que permite el ajuste fino de modelos grandes como LLaMA3.1-70B. Además, PaCA permite el entrenamiento con secuencias un 23% más largas y mejora el rendimiento en un 16% tanto en la GPU NVIDIA A100 como en la HPU INTEL Gaudi2 en comparación con LoRA.

Resumen de las pruebas de rendimiento

API

PacaConfig

clase peft.PacaConfig

< >

( 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 = 8paca_alpha: int = 8target_modules: list[str] | str | None = Noneexclude_modules: list[str] | str | None = Nonelayers_to_transform: list[int] | int | None = Nonelayers_pattern: list[str] | str | None = Nonerandom_seed: int | None = Nonepaca_indices_pattern: dict | None = <factory>init_weights: bool = Truemodules_to_save: list[str] | None = None )

Parámetros

  • r (int, opcional, valor predeterminado 8) — Número de columnas de entrada (conexiones parciales) que se ajustan finamente en cada capa objetivo. Para un peso de forma (out_features, in_features), PaCA entrena r * out_features parámetros, la misma cantidad que la matriz B de un adaptador LoRA con rango r. No debe exceder in_features.
  • paca_alpha (int, opcional, valor predeterminado 8) — Factor de escala. La actualización de las columnas seleccionadas es paca_alpha / r * delta. Al igual que lora_alpha, esto actúa como un multiplicador de la tasa de aprendizaje efectiva del adaptador.
  • target_modules (Union[list[str], str], opcional) — Lista de nombres de módulos o expresión regular de los nombres de módulos a reemplazar con PaCA. Por ejemplo, ['q_proj', 'v_proj'] o '.*decoder.*(SelfAttention|EncDecAttention).*(q|v)$'. Si se especifica como 'all-linear', se eligen todos los módulos lineales excepto la capa de salida. Solo se admiten capas nn.Linear.
  • exclude_modules (Union[list[str], str], opcional) — Los nombres de los módulos a los que no se aplicará el adaptador. Al pasar una cadena de caracteres, se realizará una coincidencia con una 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.
  • layers_to_transform (Union[list[int], int], opcional) — Los índices de las capas a transformar. Si se especifica este argumento, PEFT transformará solo los índices de capas especificados dentro de esta lista. Si se pasa un solo entero, PEFT transformará solo la capa en este índice.
  • layers_pattern (Optional[Union[list[str], str]], opcional) — 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'.
  • random_seed (int, opcional, valor predeterminado None) — Semilla utilizada para seleccionar las conexiones parciales. Cada capa utiliza una selección diferente derivada de esta semilla y del nombre de la capa. Si es None, se utiliza el generador global de números aleatorios de torch. Los índices seleccionados se guardan siempre en el punto de control del adaptador, por lo que la semilla no es necesaria para cargar un adaptador entrenado.
  • paca_indices_pattern (dict, opcional) — Mapeo opcional de nombres de capas o expresiones regulares a los índices de columnas de entrada que se ajustan en las capas coincidentes en lugar de r seleccionadas aleatoriamente, por ejemplo {'^model.layers.0.self_attn.q_proj': [0, 2, 4]}. Esto también permite un número diferente de columnas por capa. Los índices de una capa deben ser únicos y menores que in_features. La escala es paca_alpha / r con el r de esta configuración en todas las capas, independientemente del número de índices dados. Las capas objetivo que no coincidan con ninguna clave usan r columnas seleccionadas aleatoriamente.
  • init_weights (bool, opcional, valor predeterminado True) — Si es True, la actualización de las columnas seleccionadas se inicializa a cero, es decir, el modelo adaptado es idéntico al modelo base en la inicialización. Establezca False para inicializar con valores aleatorios; esto solo está previsto para pruebas.
  • modules_to_save (list[str], opcional) — Lista de módulos, aparte de las capas PaCA, que se deben establecer como entrenables y guardar en el checkpoint final. Por ejemplo, en tareas de clasificación de secuencias o clasificación de tokens, la capa final classifier/score se inicializa aleatoriamente y, por lo tanto, debe ser entrenable y guardada.

Esta es la clase de configuración para almacenar la configuración de un PacaModel.

PaCA (Partial Connection Adaptation, https://huggingface.co/papers/2503.01905) realiza el ajuste fino de r columnas de entrada seleccionadas aleatoriamente (conexiones parciales) de cada peso preentrenado objetivo. Los únicos parámetros entrenables son las actualizaciones de estas columnas; a diferencia de LoRA, PaCA no añade matrices adicionales de bajo rango. Justo antes de la multiplicación de matrices, las columnas adaptadas se intercambian con las del peso preentrenado y se restauran inmediatamente después, de modo que tanto la propagación hacia adelante como la hacia atrás ejecutan un único GEMM, y solo los r canales de entrada seleccionados se mantienen en memoria para la propagación hacia atrás.

PacaModel

clase peft.PacaModel

< >

( 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

Parámetros

  • model (PreTrainedModel) — El modelo que se va a adaptar.
  • config (PacaConfig) — La configuración del modelo PaCA.
  • adapter_name (str) — El nombre del adaptador, por defecto es "default".
  • low_cpu_mem_usage (bool, optional, defaults to False) — Crea pesos de adaptador vacíos en el dispositivo meta. Útil para acelerar el proceso de carga.

Devuelve

torch.nn.Module

El modelo PaCA.

Crea un modelo de Adaptación de Conexión Parcial (PaCA) a partir de un modelo preentrenado. El método se describe en https://huggingface.co/papers/2503.01905.

Ejemplo:

>>> from transformers import AutoModelForCausalLM
>>> from peft import PacaConfig, get_peft_model

>>> base_model = AutoModelForCausalLM.from_pretrained("facebook/opt-125m")
>>> config = PacaConfig(r=16, paca_alpha=16, target_modules="all-linear")
>>> model = get_peft_model(base_model, config)

Atributos:

Update on GitHub