დაიღალეთ მეხსიერებიდან ამოწურვის (OOM) შეცდომებით დიდი მოდელების წვრთნის მცდელობისას? ჩვენ გთავაზობთ გამოსავალს. დიდი მოდელები ძალიან პროდუქტიულია [1], მაგრამ მათი წვრთნა არსებული აპარატურით რთულია. დიდი მოდელების წვრთნისთვის არსებული აპარატურის მაქსიმალურად გამოსაყენებლად, შესაძლებელია მონაცემთა პარალელიზმის (Data Parallelism) გამოყენება ZeRO - ნულოვანი სიჭარბის ოპტიმიზატორის (Zero Redundancy Optimizer) [2] მეშვეობით. ქვემოთ მოცემულია მონაცემთა პარალელიზმის მოკლე აღწერა ZeRO-ს გამოყენებით, დიაგრამით ამ ბლოგპოსტიდან: ა. ეტაპი 1: ოპტიმიზატორის მდგომარეობების დანაწილება მონაცემთა პარალელურ მუშაკებს/GPU-ებს შორის ბ. ეტაპი 2: ოპტიმიზატორის მდგომარეობებისა და გრადიენტების დანაწილება მონაცემთა პარალელურ მუშაკებს/GPU-ებს შორის გ. ეტაპი 3: ოპტიმიზატორის მდგომარეობების, გრადიენტებისა და მოდელის პარამეტრების დანაწილება მონაცემთა პარალელურ მუშაკებს/GPU-ებს შორის დ. ოპტიმიზატორის გადმოტვირთვა (Optimizer Offload): გრადიენტებისა და ოპტიმიზატორის მდგომარეობების გადატანა CPU-ზე/დისკზე, ZeRO ეტაპი 2-ის საფუძველზე. ე. პარამეტრების გადმოტვირთვა (Param Offload): მოდელის პარამეტრების გადატანა CPU-ზე/დისკზე, ZeRO ეტაპი 3-ის საფუძველზე. ამ სტატიაში განვიხილავთ, თუ როგორ გამოვიყენოთ მონაცემთა პარალელიზმი ZeRO-ს მეშვეობით Accelerate-ის გამოყენებით. DeepSpeed-მა, FairScale-მა და PyTorch FullyShardedDataParallel (FSDP)-მ ZeRO-ს ძირითადი იდეები უკვე განახორციელეს. ისინი ინტეგრირებულია 🤗 transformers Trainer-სა და 🤗 accelerate-ში, რასაც თან ახლდა შესანიშნავი ბლოგები: „მეტი მოთავსება და სწრაფი წვრთნა ZeRO-ს გამოყენებით DeepSpeed-ისა და FairScale-ის მეშვეობით“ [4] და „დიდი მოდელების წვრთნის აჩქარება PyTorch Fully Sharded Data Parallel-ის გამოყენებით“ [5]. უკანა ფონზე მიმდინარე პროცესების ახსნას აღნიშნულ ბლოგებს მივანდობთ და ძირითადად DeepSpeed ZeRO-ს გამოყენებაზე გავამახვილებთ ყურადღებას Accelerate-ის მეშვეობით. აპარატურის კონფიგურაცია: 2x24GB NVIDIA Titan RTX GPU. 60GB ოპერატიული მეხსიერება (RAM). განვიხილავთ ტექსტის კლასიფიკაციისთვის მხოლოდ ენკოდერის მოდელის დახვეწის ამოცანას. MRPC GLUE მონაცემთა ნაკრებზე დახვეწისთვის გამოვიყენებთ წინასწარ გაწვრთნილ microsoft/deberta-v2-xlarge-mnli (900M პარამეტრი) მოდელს. კოდი ხელმისაწვდომია აქ: run_cls_no_trainer.py. ის ოფიციალურ ტექსტის კლასიფიკაციის მაგალითს ჰგავს (აქ), დამატებითი ლოგიკით, რომელიც ზომავს წვრთნისა და შეფასების დროს. მოდით, შევადაროთ განაწილებული მონაცემთა პარალელიზმის (DDP) და DeepSpeed ZeRO Stage-2-ის პროდუქტიულობა მრავალ-GPU გარემოში. DeepSpeed ZeRO Stage-2-ის კოდის ცვლილებების გარეშე გასააქტიურებლად, გთხოვთ, გაუშვათ accelerate config და გამოიყენოთ Accelerate DeepSpeed Plugin. ZeRO Stage-2 DeepSpeed Plugin-ის მაგალითი: ახლა, წვრთნისთვის გაუშვით ქვემოთ მოცემული ბრძანება: ```bash accelerate launch \ --config_file deepspeed_zero2.yaml \ run_cls_no_trainer.py \ --model_name_or_path microsoft/deberta-v2-xlarge-mnli \ --dataset_name glue \ --dataset_config_name mrpc \ --max_length 128 \ --per_device_train_batch_size 40 \ --learning_rate 2e-5 \ --num_train_epochs 3 \ --output_dir ./output_dir ``` ჩვენს ერთ-კვანძოვან მრავალ-GPU კონფიგურაციაში, DDP-ის მიერ მხარდაჭერილი მაქსიმალური პაკეტის ზომა OOM შეცდომის გარეშე არის 8. ამის საპირისპიროდ, DeepSpeed ZeRO-Stage 2 საშუალებას იძლევა 40 ზომის პაკეტის გამოყენებას OOM შეცდომების გარეშე. შესაბამისად, DeepSpeed DDP-სთან შედარებით 5-ჯერ მეტი მონაცემის მოთავსებას უზრუნველყოფს თითოეულ GPU-ზე. ქვემოთ მოცემულია wandb-ის გაშვების გრაფიკების ამონარიდი და შედარებითი ცხრილი DDP-სა და DeepSpeed-ს შორის. **ცხრილი 1: DeepSpeed ZeRO Stage-2-ის ბენჩმარკინგი DeBERTa-XL (900M) მოდელზე** | | DDP (batch size 8) | DeepSpeed ZeRO Stage-2 (batch size 40) | |-----------|----------------------|--------------------------------------| | **GPU Memory** | 24GB | 24GB | | **Train Time** | 260s | 75s | | **Eval Time** | 10s | 10s | | **Accuracy** | 0.90 | 0.90 | პაკეტის ამ დიდი ზომით, ჩვენ ვაკვირდებით წვრთნის საერთო დროის ~3.5-ჯერ აჩქარებას პროდუქტიულობის მეტრიკის ვარდნის გარეშე, ეს ყველაფერი ყოველგვარი კოდის ცვლილების გარეშე. შესანიშნავია! 🤗. მეტი პარამეტრის დასარეგულირებლად, დაგჭირდებათ DeepSpeed კონფიგურაციის ფაილის და მინიმალური კოდის ცვლილებების გამოყენება. მოდით, ვნახოთ, როგორ გავაკეთოთ ეს. პირველ რიგში, განვიხილავთ მიმდევრობა-მიმდევრობაზე (sequence-to-sequence) მოდელის დახვეწის ამოცანას საკუთარი ჩეთბოტის გასაწვრთნელად. კონკრეტულად, ჩვენ დავხვეწავთ facebook/blenderbot-400M-distill მოდელს smangrul/MuDoConv (Multi-Domain Conversation) მონაცემთა ნაკრებზე. მონაცემთა ნაკრები შეიცავს საუბრებს 10 სხვადასხვა წყაროდან, რომლებიც მოიცავს პერსონებს, დაფუძნებას სპეციფიკურ ემოციურ კონტექსტებში, მიზანზე ორიენტირებულ (მაგ., რესტორნის დაჯავშნა) და ზოგად ვიკიპედიის თემებს (მაგ., კრიკეტი). კოდი ხელმისაწვდომია აქ: run_seq2seq_no_trainer.py. ჩეთბოტების მიმზიდველობისა და ადამიანურობის ეფექტურად გაზომვის ამჟამინდელი პრაქტიკა არის ადამიანური შეფასებები, რაც ძვირია [6]. შესაბამისად, ამ მაგალითისთვის, თვალყური ადევნებული მეტრიკა არის BLEU ქულა (რაც იდეალური არ არის, მაგრამ ასეთი ამოცანებისთვის კონვენციური მეტრიკაა). შესაძლებელია კოდის ადაპტირება უფრო დიდი T5 მოდელების წვრთნისთვის, თუკი გაქვთ GPU-ებზე წვდომა, რომელიც მხარს უჭერს bfloat16 სიზუსტეს, წინააღმდეგ შემთხვევაში თქვენ წააწყდებით NaN დანაკარგის (loss) მნიშვნელობებს. ჩვენ ჩავატარებთ სწრაფ ბენჩმარკს 10000 საწვრთნელ ნიმუშზე და 1000 შესაფასებელ ნიმუშზე, რადგან გვაინტერესებს DeepSpeed-ისა და DDP-ის შედარება. წვრთნისთვის გამოვიყენებთ DeepSpeed ZeRO Stage-2 კონფიგურაციას zero2_config_accelerate.json (მოცემულია ქვემოთ). კონფიგურაციის სხვადასხვა მახასიათებლის დეტალური ინფორმაციისთვის, გთხოვთ, იხილოთ DeepSpeed-ის დოკუმენტაცია. ```json { "zero_optimization": { "stage": 2, "offload_optimizer": { "device": "cpu" } }, "fp16": { "enabled": true, "loss_scale": 0, "initial_scale_power": 16 }, "train_batch_size": 40, "gradient_accumulation_steps": 1 } ``` DeepSpeed ZeRO Stage-2-ის ზემოაღნიშნული კონფიგურაციით გასააქტიურებლად, გთხოვთ, გაუშვათ accelerate config და მოთხოვნისას მიუთითოთ კონფიგურაციის ფაილის გზა. დამატებითი დეტალებისთვის, იხილეთ 🤗 accelerate-ის ოფიციალური დოკუმენტაცია DeepSpeed კონფიგურაციის ფაილის შესახებ. ZeRO Stage-2 DeepSpeed კონფიგურაციის ფაილის მაგალითი: ახლა, წვრთნისთვის გაუშვით ქვემოთ მოცემული ბრძანება: ```bash accelerate launch \ --config_file deepspeed_zero2.yaml \ run_seq2seq_no_trainer.py \ --model_name_or_path facebook/blenderbot-400M-distill \ --dataset_name smangrul/MuDoConv \ --max_length 128 \ --per_device_train_batch_size 40 \ --learning_rate 2e-5 \ --num_train_epochs 3 \ --output_dir ./output_dir \ --with_deepspeed \ --deepspeed_config_file zero2_config_accelerate.json ``` DeepSpeed კონფიგურაციის გამოყენებისას, თუ მომხმარებელმა კონფიგურაციაში მიუთითა ოპტიმიზატორი და სკედულერი, მას მოუწევს accelerate.utils.DummyOptim და accelerate.utils.DummyScheduler-ის გამოყენება. ეს არის ერთადერთი მცირე ცვლილებები, რაც მომხმარებელმა უნდა გააკეთოს. ქვემოთ მოცემულია DeepSpeed კონფიგურაციის გამოყენებისას საჭირო მინიმალური ცვლილებების მაგალითი: ```python # Original code: # optimizer = AdamW(model.parameters(), lr=learning_rate) # lr_scheduler = get_scheduler( # name="linear", optimizer=optimizer, num_warmup_steps=0, num_training_steps=num_training_steps # ) # Changes for DeepSpeed config: from accelerate.utils import DummyOptim, DummyScheduler optimizer = DummyOptim(model.parameters(), lr=learning_rate) lr_scheduler = DummyScheduler(optimizer, total_num_steps=num_training_steps, warmup_num_steps=0) ``` **ცხრილი 2: DeepSpeed ZeRO Stage-2-ის ბენჩმარკინგი BlenderBot (400M) მოდელზე** | | DDP (batch size 8) | DeepSpeed ZeRO Stage-2 (batch size 40) | |-----------|----------------------|--------------------------------------| | **GPU Memory** | 24GB | 24GB | | **Train Time** | 180s | 50s | | **Eval Time** | 8s | 8s | | **BLEU Score** | 20.5 | 20.5 | ჩვენს ერთ-კვანძოვან მრავალ-GPU კონფიგურაციაში, DDP-ის მიერ მხარდაჭერილი მაქსიმალური პაკეტის ზომა...