Afinando Llama2 con DPO

Introducción

0a8c71720b4dabdfcaae8d442bd45bcc.jpeg

El aprendizaje reforzado a partir de la retroalimentación humana (RLHF) se ha convertido en realidad en el último paso en la formación de LLM como GPT-4 o Claude, que pueden garantizar que el resultado del modelo de lenguaje cumpla con las expectativas humanas en términos de chat o seguridad. Sin embargo, también introduce algunas complejidades relacionadas con RL en la PNL: es necesario construir una buena función de recompensa y entrenar un modelo para estimar el valor de cada estado; también es necesario tener en cuenta que el LLM final generado no se puede comparar con el original Los modelos están demasiado separados, lo que hace que el modelo sea propenso a producir galimatías en lugar de texto significativo. El proceso es muy complejo e involucra muchos componentes complejos, y estos componentes cambian dinámicamente durante el proceso de capacitación, por lo que no es fácil administrarlos bien.

Rafailov, Sharma, Mitchell y otros publicaron recientemente un artículo, Direct Preference Optimization, que propone convertir los objetivos basados ​​en el aprendizaje por refuerzo utilizados por los métodos existentes en objetivos que puedan optimizarse directamente mediante una simple pérdida binaria de entropía cruzada. El proceso de purificación de LLM se simplifica.

Este artículo presenta el método de optimización de preferencias directas (DPO), que ahora está integrado en la biblioteca TRL. Al mismo tiempo, también mostramos cómo ajustar el último modelo Llama v2 7B en el conjunto de datos de preferencias de intercambio de pila, que contiene varias preguntas y sus clasificaciones en varios portales de intercambio de pila después de la respuesta.

DPO a PPO

Al optimizar las preferencias derivadas de los humanos a través de RL, el enfoque tradicional ha sido utilizar un modelo de recompensa auxiliar para ajustar el modelo objetivo y maximizar las recompensas que el modelo objetivo puede obtener a través del mecanismo RL. De manera intuitiva, utilizamos el modelo de recompensa para proporcionar retroalimentación al modelo que se va a optimizar para alentarlo a generar más resultados con alta recompensa y menos resultados con baja recompensa. Al mismo tiempo, utilizamos un modelo de referencia congelado para garantizar que la desviación de salida no sea demasiado grande y continúe manteniendo la diversidad de salida. Esto generalmente requiere agregar un término de penalización de KL en relación con el modelo de referencia además del objetivo de maximización de recompensa al diseñar la función objetivo, lo que ayuda a evitar que el aprendizaje del modelo haga trampa o explote los modelos de recompensa.

DPO omite el paso de modelar la función de recompensa, que surge de una idea clave: el mapeo analítico de la función de recompensa a la política de RL óptima. Este mapeo mide intuitivamente qué tan bien una función de recompensa determinada coincide con datos de preferencia determinados. Con él, los autores pueden convertir directamente la pérdida de RL basada en el modelo de referencia y recompensa en una pérdida basada solo en el modelo de referencia, optimizando así el modelo de lenguaje directamente en los datos de preferencia. Por lo tanto, DPO comienza buscando la mejor solución para minimizar la pérdida RLHF, cambiando los parámetros para derivar una pérdida que solo requiere el modelo de referencia.

Con él, podemos optimizar directamente este objetivo de probabilidad sin la necesidad de modelos de recompensa o tediosos procesos de optimización del aprendizaje por refuerzo.

Cómo utilizar TRL para entrenar

Como se mencionó anteriormente, una tubería RLHF típica generalmente contiene los siguientes enlaces:

  1. Ajuste supervisado (SFT)
  2. Etiquetar datos con etiquetas de preferencia
  3. Entrene un modelo de recompensa basado en datos de preferencias
  4. optimización de la realidad virtual

La biblioteca TRL contiene las herramientas necesarias para todos estos pasos. El entrenamiento de DPO elimina directamente los dos enlaces de modelado de recompensa y RL (enlaces 3 y 4) y optimiza directamente el objetivo de DPO en función de los datos de preferencia marcados.

Al usar DPO, todavía debemos realizar el paso 1, pero solo necesitamos proporcionar los datos de preferencia preparados en el paso 2 al  DPOTrainer en TRL, y los pasos 3 y 4 ya no son necesarios. Los datos de preferencias anotados deben seguir un formato específico, que es un diccionario que contiene las siguientes 3 claves:

  • mensaje: la entrada rápida al modelo durante la inferencia
  • elegido: la mejor respuesta al mensaje dado
  • rechazado: es decir, una mala respuesta a una pregunta dada o una respuesta que no es una pregunta dada

Por ejemplo, para el conjunto de datos de preferencia de intercambio de pila, podemos usar la siguiente función de utilidad para asignar las muestras en el conjunto de datos al formato de diccionario anterior y eliminar todas las columnas originales:

def return_prompt_and_responses(muestras) -> Dict[str, str, str]:     return {       &
nbsp ;  "mensaje": [             "Pregunta: " + pregunta + " \n\nRespuesta: " Para preguntas en ejemplos["pregunta"] ;  ],





"rechazado": muestras ["response_k"], # clasificado peor que j
}

conjunto de datos = load_dataset(
    "lvwerra/stack-exchange-paired",
    split="entrenar",
    data_dir=" data/rl"
)
columnas_originales = dataset.column_names

dataset.map(
    return_prompt_and_responses,
    batched=Verdadero,
    remove_columns=columnas_originales
)

Una vez que tenga un conjunto de datos ordenado, la pérdida de DPO es esencialmente una pérdida supervisada que se recompensa implícitamente a través del modelo de referencia. Por lo tanto, desde el nivel superior, DPOTrainer requiere que ingresemos el modelo básico y el modelo de referencia a optimizar:

dpo_trainer = DPOTrainer(
    modelo, # El modelo básico de SFT  Una copia
del modelo base de SFT& nbsp;
Conjunto
de datos preparados
     tokenizer = tokenizer,
tamaño, tasa de aprendizaje, etc.
)

Entre ellos, el superparámetro beta es la temperatura de pérdida de DPO, normalmente entre 0,1 y 0,5. Controla cuánta atención prestamos al modelo de referencia: cuanto más pequeña es la beta, más ignoramos el modelo de referencia. Después de inicializar el entrenador, simplemente podemos llamar al siguiente método para entrenar en el conjunto de datos dado usando los argumentos de entrenamiento dados:

dpo_trainer.tren()

Experimento basado en Llama v2

La ventaja de implementar el entrenador DPO en TRL es que se pueden aprovechar las funciones existentes relacionadas con LLM en TRL y sus bibliotecas dependientes (como Peft y Accelerate). Con estas bibliotecas, incluso podemos utilizar la tecnología QLoRA proporcionada por la biblioteca bitsandbytes para entrenar el modelo Llama v2.

ajuste supervisado

Como se mencionó anteriormente, primero usamos SFTTrainer de TRL para realizar un ajuste fino supervisado en el modelo 7B Llama v2 usando QLoRA en el subconjunto de datos SFT:

# cargar el modelo base en cuantización de 4 bits bnb_config = BitsAndBytesConfig(     load_in_4bit=True,      bnb_4bit_quant_type=
"
nf4
" ,
    bnb_4bit_compute_dtype=torch.bfloat16,
)

base_model = AutoModelForCausalLM.from_pretrained(
    script_args.model_name, # "meta-llama/ Llama-2 -7b-hf"
    quantization_config=bnb_config,
    device_map={"": 0},
    trust_remote_code=True,
    use_auth_token=True,
)
base_model.config.use_cache = False

# Agregar capas LoRA en la parte superior del modelo base cuantificado peft_config = LoraConfig (     r=script_args.lora_r,   ;  
;
&
nbsp ;lora_alpha=script_args.lora_alpha,
    lora_dropout=script_args.lora_dropout,
    target_modules=["q_proj", "v_proj"],
   &nb sp ;bias="ninguno",
    task_type="CAUSAL_LM",
)
...
entrenador = SFTTrainer(
    model=base_model,
    train_dataset=train_dataset,
    eval_dataset=eval_dataset,
    peft_config=peft_config,
    packing=True,
    max_seq_length=Ninguno,
    tokenizer=tokenizer,
     args=training_args, # HF Argumentos del entrenador
)
entrenador.train()

Formación DPO

Una vez completado SFT, guardamos el modelo generado. Luego, continuamos entrenando DPO. Utilizamos el modelo generado por SFT como modelo básico y modelo de referencia de DPO, y entrenamos el modelo con DPO como función objetivo en los datos de preferencia de intercambio de pila generados anteriormente. Elegimos ajustar el modelo para LoRa, por lo que cargamos el modelo usando la función AutoPeftModelForCausalLM de Peft:

model = AutoPeftModelForCausalLM.from_pretrained(
    script_args.model_name_or_path, # ubicación del modelo SFT guardado     low_ cpu_mem_usage=Verdadero,  
&
nbsp ;  torch_dtype=torch.float16,
    load_in_4bit=True,
     is_trainable=True,
)
model_ref = AutoPeftModelForCausalLM.from_pretrained(
&nb sp;   ; script_args.model_name_or_path, # mismo modelo que el principal
    low_cpu_mem_usage=True,
    torch_dtype=torch.float16,
      load_in_4bit=Verdadero,
)
...
dpo_trainer = DPOTrainer(
    modelo,
    model_ref,
    args=training_args,
     beta=script_args.beta,
    train_dataset=train_dataset,
    eval_dataset=eval_dataset,
    tokenizer=tokenizer,
     peft_config=peft_config,
)
dpo_trainer.train()
dpo_trainer.save_model()

Como puede verse, cargamos el modelo en modo de 4 bits y luego lo entrenamos seleccionando el método QLora a través del parámetro peft_config . El formador también utiliza el conjunto de datos de evaluación para evaluar el progreso de la capacitación e informa algunas métricas clave, como, opcionalmente, registrar y mostrar recompensas implícitas a través de WandB. Finalmente, podemos enviar el modelo entrenado a HuggingFace Hub.

Resumir

El código fuente completo de los scripts de capacitación de SFT y DPO se puede encontrar en el directorio ejemplos/stack_llama_2, y el modelo combinado entrenado también se cargó en HF Hub (ver aquí).

Supongo que te gusta

Origin blog.csdn.net/specssss/article/details/132495138
Recomendado
Clasificación