Práctica del marco anti-destilación del modelo de lenguaje grande de código cerrado de Lion
descripción general
Descripción general del marco de destilación contradictorio: destilamos un LLM de estudiante basado en un LLM de código cerrado de alto nivel, que tiene tres roles: maestro, árbitro y generador. Hay tres fases de iteración:
-
La fase de imitación, para un conjunto de instrucciones, alinea las respuestas del estudiante con las del maestro;
-
Diferenciar entre etapas e identificar instrucciones difíciles;
-
En la fase de generación, a partir de las instrucciones difíciles identificadas, se generan nuevas instrucciones difíciles para aumentar el desafío al modelo de estudiante.
compensación de peso
Publicamos los pesos Lion como pesos delta para cumplir con la licencia del modelo LLaMA.
Lion-7B (pesos delta) https://huggingface.co/YuxinJiang/Lion
Puede agregar nuestro delta a los pesos originales de LLaMA para obtener pesos de león. ilustrar:
-
Obtenga pesos LLaMA sin procesar en formato huggingface https://huggingface.co/docs/transformers/main/model_doc/llama
-
Descarga nuestro modelo delta https://huggingface.co/YuxinJiang/Lion
-
Use el siguiente script para obtener los pesos de los leones aplicando nuestro delta:
python src/weight_diff.py recuperar --path_raw huggyllama/llama-7b --path_diff YuxinJiang/Lion --path_tuned <ruta_almacenar_pesos_recuperados>
razonamiento
Para la inferencia y el entrenamiento de Lion, primero instale las siguientes dependencias:
pip install -r requirements.txt
Proporcionamos a Lion un script de decodificación, que lee el archivo de entrada y genera la respuesta correspondiente para cada muestra, y finalmente las fusiona en el archivo de salida. Puede ejecutarse en una sola máquina con una GPU de 16 GB.
python src/lion_inference.py \
--model_dir <path_to_hf_converted_lion_ckpt_and_tokenizer> \
--data_dir <path_to_input_json_file> \
--output_dir <path_to_output_json_file> \
--num_gpus 1
tren
A continuación se muestra una iteración de nuestro marco de destilación contradictorio:
1. Etapa de imitación
1.1 Obtener la respuesta del profesor LLM sobre el pool de formación
python src/chatgpt_inference.py \
-q <path_to_json_file_for_the_Train_Pool> \
-o <path_to_chatgpt_inference_for_the_Train_Pool> \
--api_key <your_openai_api_key>
1.2 Ajustar la instrucción de los estudiantes en función de las respuestas de los maestros al grupo de capacitación
El ajuste fino se realizó en una máquina con 8 GPU A100 80G.
torchrun --nproc_per_node=8 --master_port=<your_random_port> src/train.py \
--model_name_or_path <path_to_hf_converted_ckpt_and_tokenizer> \
--data_path <path_to_chatgpt_inference_for_the_Train_Pool> \
--bf16 True \
--output_dir result \
--num_train_epochs 3 \
--model_max_length 1024 \
--per_device_train_batch_size 2 \
--per_device_eval_batch_size 2 \
--gradient_accumulation_steps 8 \
--evaluation_strategy "no" \
--save_strategy "steps" \
--save_steps 500 \
--save_total_limit 1 \
--learning_rate 2e-5 \
--weight_decay 0. \
--warmup_ratio 0.03 \
--lr_scheduler_type "cosine" \
--logging_steps 1 \
--fsdp "full_shard auto_wrap" \
--fsdp_transformer_layer_cls_to_wrap 'LlamaDecoderLayer' \
--tf32 True
Resolver el problema de MOO
En pocas palabras, ajustar el modelo 7B requiere alrededor de 7 x 8 x 2 = 112 GB de memoria de video. Los comandos proporcionados anteriormente habilitan la fragmentación de parámetros, por lo que no se almacenan copias redundantes del modelo en ninguna GPU. Si desea reducir aún más el uso de la memoria de video, aquí tiene algunas opciones:
Use `–FSDP "full_shard auto_wrap offload"` para activar la descarga de CPU para FSDP. Esto ahorra memoria de video a costa de tiempos de ejecución más largos.
Según nuestra experiencia, la etapa 3 de DeepSpeed (con descarga) a veces es más eficiente en términos de memoria que FSDP con descarga. Aquí hay un ejemplo que usa GPU DeepSpeed etapa 3 y 8 con parámetros y descarga del optimizador:
deepspeed src/train_deepspeed.py \
--model_name_or_path <path_to_hf_converted_ckpt_and_tokenizer> \
--data_path <path_to_chatgpt_inference_for_the_Train_Pool> \
--output_dir result \
--num_train_epochs 3 \
--model_max_length 1024 \
--per_device_train_batch_size 16 \
--per_device_eval_batch_size 1 \
--gradient_accumulation_steps 1 \
--evaluation_strategy "no" \
--save_strategy "steps" \
--save_steps 600 \
--save_total_limit 1 \
--learning_rate 2e-5 \
--warmup_ratio 0.03 \
--logging_steps 1 \
--lr_scheduler_type "cosine" \
--report_to "tensorboard" \
--gradient_checkpointing True \
--deepspeed srcs/configs/deepspeed_config.json \
--fp16 True
La biblioteca DeepSpeed también proporciona algunas [funciones útiles] (https://deepspeed.readthedocs.io/en/latest/memory.html) para estimar el uso de la memoria de video.
[LoRA](https://arxiv.org/abs/2106.09685) ajusta el corte de bajo nivel de los encabezados de incrustación de consulta, clave y valor. Esto reduce el consumo total de memoria de video de 112 GB a aproximadamente 7x4 = 28 GB. Es posible que lancemos nuestra reimplementación de esto en el futuro, pero por ahora el repositorio de código (https://github.com/huggingface/peft) puede ser un recurso útil.
2. Diferenciar entre etapas
2.1 Obtenga la respuesta del maestro en el grupo de caché
python src/chatgpt_inference.py \
-q <path_to_json_file_for_the_Cache_Pool> \
-o <path_to_chatgpt_inference_for_the_Cache_Pool> \
--api_key <your_openai_api_key>
2.2 Obtener la respuesta del alumno a la reserva de caché
python src/lion_inference.py \
--model_dir <path_to_hf_converted_lion_ckpt_and_tokenizer> \
--data_dir <path_to_json_file_for_the_Cache_Pool> \
--output_dir <path_to_lion_inference_for_the_Cache_Pool> \
--num_gpus 8
2.3 Se requiere que los árbitros emitan dos puntos de puntuación en función de la calidad del desempeño de los maestros y los estudiantes
python src/chatgpt_referee.py \
-a <path_to_chatgpt_inference_for_the_Cache_Pool> <path_to_lion_inference_for_the_Cache_Pool> \
-o <path_to_output_review_file> \
--api_key <your_openai_api_key>
2.4 Distinguir Comandos Difíciles y Fáciles
python src/discrimination.py \
--review_path <path_to_output_review_file> \
--chatgpt_inference_path <path_to_chatgpt_inference_for_the_Cache_Pool> \
--lion_inference_path <path_to_lion_inference_for_the_Cache_Pool> \
--hard_save_path <path_to_identified_hard_instructions> \
--easy_save_path <path_to_identified_easy_instructions>
3. Fase de generación
3.1 Generar nuevas instrucciones difíciles
python -m src/generate_hard_instruction generate_instruction_following_data \
--seed_tasks_path <path_to_identified_hard_instructions> \
--output_dir <path_to_generated_hard_instructions> \
--num_instructions_to_generate 3000 \
--api_key <your_openai_api_key>
3.2 Generar nuevas instrucciones simples
python -m src/generate_easy_instruction generate_instruction_following_data \
--seed_tasks_path <path_to_identified_easy_instructions> \
--output_dir <path_to_generated_easy_instructions> \
--num_instructions_to_generate 3000 \
--api_key <your_openai_api_key>
Resultados experimentales
Para verificar la efectividad del método, el autor aplica el marco anti-destilación propuesto al conocido modelo de lenguaje grande de código cerrado ChatGPT, y transfiere su conocimiento a un modelo de preentrenamiento básico de código abierto LLaMA, que consta de 7 mil millones de parámetros. El autor eligió los datos de entrenamiento de Alpaca (generados a partir de solo 175 instrucciones semilla seleccionadas manualmente) como la instrucción de entrenamiento inicial y realizó 3 iteraciones de AKD, utilizando un total de 70 000 datos de seguimiento de instrucciones para el entrenamiento. El último modelo entrenado se llama León.