Pratique du cadre anti-distillation du grand modèle de langage à source fermée Lion
aperçu
Vue d'ensemble du cadre de distillation contradictoire : nous distillons un LLM étudiant basé sur un LLM de haut niveau à source fermée, qui a trois rôles : enseignant, arbitre et générateur. Il y a trois phases d'itération :
-
La phase d'imitation, pour un ensemble de consignes, aligne les réponses de l'élève sur celles de l'enseignant ;
-
Différencier les étapes et identifier les instructions difficiles ;
-
Dans la phase de génération, sur la base des instructions difficiles identifiées, de nouvelles instructions difficiles sont générées pour augmenter le défi du modèle étudiant.
compensation de poids
Nous publions les poids Lion sous forme de poids delta pour nous conformer à la licence du modèle LLaMA.
Lion-7B (poids delta) https://huggingface.co/YuxinJiang/Lion
Vous pouvez ajouter notre delta aux poids LLaMA d'origine pour obtenir des poids Lion. illustrer:
-
Obtenez des poids LLaMA bruts au format huggingface https://huggingface.co/docs/transformers/main/model_doc/llama
-
Téléchargez notre modèle delta https://huggingface.co/YuxinJiang/Lion
-
Utilisez le script suivant pour obtenir les pondérations du Lion en appliquant notre delta :
python src/weight_diff.py récupérer --path_raw huggyllama/llama-7b --path_diff YuxinJiang/Lion --path_tuned <path_to_store_recovered_weights>
raisonnement
Pour l'inférence et la formation de Lion, veuillez d'abord installer les dépendances suivantes :
pip install -r requirements.txt
Nous fournissons à Lion un script de décodage, qui lit le fichier d'entrée et génère la réponse correspondante pour chaque échantillon, puis les fusionne dans le fichier de sortie.Il peut fonctionner sur une seule machine avec un GPU de 16 Go.
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
former
Vous trouverez ci-dessous une itération de notre cadre de distillation contradictoire :
1. Étape d'imitation
1.1 Obtenir la réponse de l'enseignant LLM sur le bassin de formation
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 Ajustement de l'instruction des élèves en fonction des réponses des enseignants au bassin de formation
Le réglage fin a été effectué sur une machine avec 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
Résoudre le problème du MOO
En termes simples, le réglage fin du modèle 7B nécessite environ 7 x 8 x 2 = 112 Go de mémoire vidéo. Les commandes données ci-dessus activent le partitionnement des paramètres, de sorte qu'aucune copie redondante du modèle n'est stockée sur un GPU. Si vous souhaitez réduire davantage l'utilisation de la mémoire vidéo, voici quelques options :
Utilisez `–FSDP "full_shard auto_wrap offload"` pour activer le déchargement du processeur pour FSDP. Cela permet d'économiser de la mémoire vidéo au prix de durées d'exécution plus longues.
D'après notre expérience, DeepSpeed stage 3 (avec déchargement) est parfois plus économe en mémoire que FSDP avec déchargement. Voici un exemple utilisant des GPU DeepSpeed stage-3 et 8 avec des paramètres et un déchargement d'optimiseur :
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 bibliothèque DeepSpeed fournit également quelques [fonctions utiles](https://deepspeed.readthedocs.io/en/latest/memory.html) pour estimer l'utilisation de la mémoire vidéo.
[LoRA](https://arxiv.org/abs/2106.09685) affine le découpage de bas niveau des en-têtes d'intégration de requête, de clé et de valeur. Cela réduit l'encombrement total de la mémoire vidéo de 112 Go à environ 7x4 = 28 Go. Nous pourrions publier notre réimplémentation de cela à l'avenir, mais pour l'instant, le référentiel de code (https://github.com/huggingface/peft) peut être une ressource utile.
2. Différencier les étapes
2.1 Obtenir la réponse du professeur sur le pool de cache
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 Obtenir la réponse de l'élève au pool de cache
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 Les arbitres sont tenus de produire deux points de score en fonction de la qualité de la performance des enseignants et des élèves
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 Distinguer les commandes difficiles et faciles
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. Phase de génération
3.1 Générer de nouvelles instructions difficiles
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 Générer de nouvelles instructions 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>
Résultats expérimentaux
Afin de vérifier l'efficacité de la méthode, l'auteur applique le cadre anti-distillation proposé au grand modèle de langage à source fermée bien connu ChatGPT, et transfère ses connaissances à un modèle de pré-formation de base open source LLaMA, qui se compose de 7 milliards de paramètres. L'auteur a choisi les données d'entraînement d'Alpaca (générées à partir de seulement 175 instructions de départ sélectionnées manuellement) comme instruction d'entraînement initiale et a effectué 3 itérations d'AKD, en utilisant un total de 70 000 données de suivi d'instructions pour l'entraînement. Le modèle formé final est nommé Lion.