PEFT documentation
OFT
OFT

Orthogonal Finetuning (OFT) y OFTv2 son un método desarrollado para adaptar modelos de difusión de texto a imagen. Funciona reparametrizando las matrices de pesos preentrenadas con su matriz ortogonal para preservar la información del modelo preentrenado. Para reducir el número de parámetros, OFT introduce una estructura de bloque diagonal en la matriz ortogonal. El método se centra principalmente en preservar el rendimiento generativo de un modelo preentrenado en el modelo afinado. Intenta mantener la misma similitud coseno (energía hipersférica) entre todas las neuronas por pares en una capa, ya que esto captura mejor la información semántica entre las neuronas. Esto significa que OFT es más capaz de preservar el sujeto y es mejor para la generación controlable (similar a ControlNet).
El resumen del artículo es:
Los grandes modelos de difusión de texto a imagen poseen capacidades impresionantes para generar imágenes fotorrealistas a partir de indicaciones de texto. Cómo guiar o controlar de manera efectiva a estos potentes modelos para que realicen diferentes tareas posteriores se convierte en un problema abierto importante. Para abordar este desafío, introducimos un método de ajuste fino fundamentado: Orthogonal Finetuning (OFT), para adaptar los modelos de difusión de texto a imagen a tareas posteriores. A diferencia de los métodos existentes, OFT puede preservar de forma demostrable la energía hipersférica, que caracteriza la relación neuronal por pares en la hipersfera unitaria. Descubrimos que esta propiedad es crucial para preservar la capacidad de generación semántica de los modelos de difusión de texto a imagen. Para mejorar la estabilidad del ajuste fino, proponemos además Constrained Orthogonal Finetuning (COFT), que impone una restricción de radio adicional a la hipersfera. Específicamente, consideramos dos tareas importantes de ajuste fino de texto a imagen: la generación dirigida por sujeto, cuyo objetivo es generar imágenes específicas de un sujeto a partir de unas pocas imágenes de dicho sujeto y una indicación de texto, y la generación controlable, cuyo objetivo es permitir que el modelo reciba señales de control adicionales. Demostramos empíricamente que nuestro marco OFT supera a los métodos existentes en calidad de generación y velocidad de convergencia.
OFT preserva la energía hipersférica al aprender una transformación ortogonal para las neuronas, de modo que la similitud de coseno entre ellas permanezca inalterada, lo que potencialmente conduce a un menor olvido del conocimiento aprendido previamente. En la práctica, esto implica tomar el producto matricial de una matriz ortogonal con la matriz de pesos preentrenada. Sin embargo, para ser eficiente en parámetros, la matriz ortogonal se representa como una matriz diagonal por bloques con bloques de rango r. Mientras que LoRA reduce el número de parámetros entrenables mediante estructuras de bajo rango, OFT reduce el número de parámetros entrenables mediante una estructura de matriz diagonal por bloques dispersa.
Resumen de las pruebas de rendimiento
Fusionar los pesos de OFT en el modelo base
De manera similar a LoRA, los pesos aprendidos por OFT pueden integrarse en las matrices de pesos preentrenadas mediante la función [~OFTModel.merge_and_unload(). Esta función fusiona los pesos del adaptador con el modelo base, lo que permite utilizar el modelo recién fusionado de forma efectiva como un modelo independiente.
Uso de ejemplo de OFT
Para usar OFT para el ajuste fino cuantizado con TRL para el ajuste fino SFT, PPO o DPO, siga el siguiente esquema:
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
clase peft.OFTConfig
< source >( 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 )
Parámetros
- r (
int) — Rango de OFT, número de bloques de OFT por capa inyectada. Unrmayor resulta en matrices de actualización más dispersas con menos parámetros entrenables. Solo puede especificarrooft_block_size, pero no ambos simultáneamente, porquer×oft_block_size= dimensión de la capa. Por simplicidad, le permitimos especificarrooft_block_sizee inferir el otro. El valor predeterminado esr = 0; se recomienda al usuario que establezcaoft_block_sizeen su lugar para mayor claridad. - oft_block_size (
int) — Tamaño de bloque de OFT entre las diferentes capas. Unoft_block_sizemayor resulta en matrices de actualización más densas con más parámetros entrenables. Eligeoft_block_sizepara que sea divisible por la dimensión de entrada de la capa (in_features), por ejemplo, 4, 8, 16. Solo puedes especificarrooft_block_size, pero no ambos a la vez, porquer×oft_block_size= dimensión de la capa. Por simplicidad, te permitimos especificarrooft_block_sizee inferir el otro. El valor predeterminado esoft_block_size = 32. - use_cayley_neumann (bool) — Especifica si se debe usar la parametrización de Cayley-Neumann (eficiente pero
aproximada) o la parametrización de Cayley estándar (exacta pero computacionalmente costosa debido a la inversa de
matriz). Recomendamos establecerla en
Truepara una mejor eficiencia, aunque el rendimiento puede ser ligeramente inferior debido al error de aproximación. Pruebe ambas configuraciones (TrueyFalse) según sus necesidades. El valor predeterminado esFalse. - module_dropout (
float) — La probabilidad de dropout multiplicativo, que se logra estableciendo los bloques OFT como identidad durante el entrenamiento, de manera similar a la capa de dropout en LoRA. - 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, 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. - fan_in_fan_out (
bool) — Establezca este valor en True si la capa a reemplazar almacena los pesos como (fan_in, fan_out). - bias (
str) — Tipo de sesgo para OFT. Puede ser ‘none’, ‘all’ o ‘oft_only’. Si se establece en ‘all’ o ‘oft_only’, los sesgos correspondientes se actualizarán durante el entrenamiento. Tenga en cuenta que esto significa que, incluso al desactivar los adaptadores, el modelo no producirá la misma salida que habría generado el modelo base sin adaptación. - 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. - init_weights (
bool) — Si se debe realizar la inicialización de los pesos de OFT. - 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 silayers_to_transformes diferente deNone. Esto debe apuntar alnn.ModuleListdel modelo, que a menudo se llama'layers'o'h'. - 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. - coft (
bool) — Si se debe usar la variante restringida de OFT o no. Desactivado por defecto. - eps (
float) — La intensidad de control de COFT. El grado de libertad de rotación. Solo tiene efecto sicoftse establece en True. - block_share (
bool) — Si se comparten o no los parámetros de OFT entre bloques. Por defecto, esFalse.
Esta es la clase de configuración para almacenar la configuración de un OFTModel.
check_kwargs
< source >( **kwargs )
Comprueba si los kwargs son válidos para la configuración.
OFTModel
clase peft.OFTModel
< source >( 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 (
torch.nn.Module) — El modelo al que se adjuntarán las capas del afinador de adaptadores. - config (OFTConfig) — La configuración del modelo OFT.
- adapter_name (
str) — El nombre del adaptador, por defecto es"default". - low_cpu_mem_usage (
bool,optional, defaults toFalse) — Crea pesos de adaptador vacíos en el dispositivo meta. Útil para acelerar el proceso de carga.
Devuelve
torch.nn.Module
El modelo OFT.
Crea un modelo de Orthogonal Finetuning a partir de un modelo preentrenado. El método se describe en https://huggingface.co/papers/2306.07280
Ejemplo:
>>> from diffusers import StableDiffusionPipeline
>>> from peft import OFTModel, OFTConfig
>>> config_te = OFTConfig(
... r=8,
... target_modules=["k_proj", "q_proj", "v_proj", "out_proj", "fc1", "fc2"],
... module_dropout=0.0,
... init_weights=True,
... )
>>> config_unet = OFTConfig(
... r=8,
... 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 = OFTModel(model.text_encoder, config_te, "default")
>>> model.unet = OFTModel(model.unet, config_unet, "default")Atributos:
- model (
~torch.nn.Module) — El modelo que se va a adaptar. - peft_config (OFTConfig): La configuración del modelo OFT.