მოდელების ეფექტური ვარჯიში: პარალელიზმის სტრატეგიების მიმოხილვა Accelerate-სა და Axolotl-ში
ეს სტატია განიხილავს მოდელების ვარჯიშის პარალელიზმის სხვადასხვა სტრატეგიას, მათ შორის მონაცემთა პარალელიზმს (DP) და სრულად დაშარდულ მონაცემთა პარალელიზმს (FSDP), აქცენტს აკეთებს მათ მუშაობის პრინციპებზე, უპირატესობებსა და გამოყენების შემთხვევებზე. განხილულია, თუ როგორ შეიძლება ამ ტექნიკების ინტეგრირება Accelerate-სა და Axolotl-ის ბიბლიოთეკებში, როგორ უნდა მოხდეს მათი კომბინირება და რა გამოწვევები არსებობს დიდ მოდელებთან მუშაობისას, განსაკუთრებით კომუნიკაციის დანახარჯების მინიმიზაციის კუთხით მრავ
აი, როგორ შეგიძლიათ მისი დამატება თქვენს სავარჯიშო სკრიპტში: ჩვენ ასევე შევიტანეთ უფრო ყოვლისმომცველი, სრულფასოვანი სავარჯიშო სკრიპტი Accelerate-ის საცავში, რომელიც აჩვენებს, თუ როგორ უნდა დააკონფიგურიროთ თქვენი მონაცემთა ჩამტვირთავი (dataloader), ოპტიმიზატორი (optimizer) და სავარჯიშო ციკლი (training loop), და როგორ შეინახოთ თქვენი მოდელი ვარჯიშის შემდეგ. იმისათვის, რომ კიდევ უფრო გავამარტივოთ მოდელების მასშტაბური წვრილი დარეგულირება (fine-tuning) და პარალელიზმის სტრატეგიების სხვადასხვა წვრილი დარეგულირების ტექნიკასთან კომბინირება, ჩვენ ასევე ინტეგრირებული გვაქვს ეს ტექნიკა Axolotl-ში. იმისათვის, რომ დაუყოვნებლივ დაიწყოთ მუშაობა, ჩვენ შევამოწმეთ რამდენიმე კონფიგურაციის მაგალითი, რომელთა მოდიფიცირებაც შეგიძლიათ თქვენი საჭიროებების შესაბამისად — სცადეთ ერთი მათგანი: ასევე შეგიძლიათ შეამოწმოთ Axolotl ND-Parallelism-ის დოკუმენტაცია დამატებითი დეტალებისთვის — ND პარალელური ტექნიკების თქვენს არსებულ კონფიგურაციებში დამატება ისეთივე მარტივია, როგორც ერთი ან მეტი შემდეგი ველის ჩამატება თქვენს Axolotl-ის კონფიგურაციის ფაილში: ჩვენ გავამარტივეთ პარალელიზმის სხვადასხვა სტრატეგიის ხარისხების კონფიგურაცია და მათი კომბინირების მეთოდები Accelerate-ის ParallelismConfig კლასის, ან Axolotl-ის კონფიგურაციის ველების მეშვეობით, მაგრამ როგორ გავიგოთ, რომელი კონფიგურაცია იმუშავებს საუკეთესოდ ჩვენი კონკრეტული გამოყენების შემთხვევისთვის?
როდესაც ვაფართოებთ მოდელების ვარჯიშს ათობით ან თუნდაც ასობით მილიარდი პარამეტრით, ძირითადი გამოწვევა მოდის პარალელიზმის სხვადასხვა სტრატეგიის გაგებიდან და იმის გაგებიდან, თუ როგორ ურთიერთქმედებენ ისინი კომუნიკაციის ზედნადები ხარჯების მინიმიზაციისთვის მოწყობილობებს შორის. ამ პოსტში ჩვენ განვიხილავთ, თუ როგორ მუშაობს პარალელიზმის სხვადასხვა სტრატეგია და როდის და როგორ შეიძლება მათი კომბინირება. მონაცემთა პარალელიზმი (Data Parallelism - DP) არის ყველაზე გავრცელებული ტექნიკა მრავალ GPU-ზე მოდელების ვარჯიშისთვის და მოიცავს მოდელის, გრადიენტების და ოპტიმიზატორის მდგომარეობების რეპლიკაციას თითოეულ მოწყობილობაზე, მონაცემთა პაკეტების თანაბრად განაწილებას GPU-ებს შორის, და გრადიენტების სინქრონიზაციას მოწყობილობებს შორის პარამეტრების განახლებამდე. ამან შეიძლება მნიშვნელოვნად გაზარდოს გამტარუნარიანობა ერთ მოწყობილობაზე ვარჯიშთან შედარებით, მაგრამ მოითხოვს, რომ თქვენი მოდელი ჯდებოდეს ერთ მოწყობილობაზე.
ჩვენ შეგვიძლია ვაკონტროლოთ მოდელის რეპლიკების რაოდენობა Accelerate-ის ParallelismConfig-ში `dp_replicate_size` პარამეტრის ან Axolotl-ის კონფიგურაციის ველის გამოყენებით. აღსანიშნავია, რომ DP არის უმაღლესი დონის პარალელიზმის სტრატეგია, რაც ნიშნავს, რომ თუ ვიყენებთ `dp_replicate_size=2`-ს და ვათავსებთ მას სხვა პარალელიზმის სტრატეგიებთან, გვექნება მოდელის 2 რეპლიკა, რომელთაგან თითოეულზე ასევე იმოქმედებს სხვა პარალელიზმის სტრატეგიები. მაგალითად, თუ ვიყენებთ `dp_replicate_size=2`-ს და `tp_size=2`-ს, გვექნება მოდელის 2 რეპლიკა, რომელთაგან თითოეულს ექნება 2 ტენზორული პარალელური შარდი (shard). ტერმინს „შარდი“ ვიყენებთ იმ მონაცემების აღსაწერად ერთ მოწყობილობაზე, რომელიც უფრო დიდი მონაცემთა ნაწილის დაყოფაა. რა ხდება, თუ ჩვენი მოდელი ძალიან დიდია და ვერ ჯდება ერთ მოწყობილობაზე? სრულად დაშარდული მონაცემთა პარალელიზმი (Fully Sharded Data Parallel - FSDP) ამ პრობლემას წყვეტს მოდელის წონების, გრადიენტების და ოპტიმიზატორის მდგომარეობების შარდინგით (თანაბრად განაწილებით) GPU-ებს შორის (ეს შთაგონებულია DeepSpeed-ის ZeRO-3-ით), მაშინ როდესაც თითოეული მოწყობილობა მაინც იღებს მონაცემთა სრული პაკეტის თავის ნაწილს. როგორც ზემოთ მოცემული დიაგრამიდან შეამჩნევთ, იმის ნაცვლად, რომ მოითხოვდეს მთელი მოდელის სრულ ასლს თითოეულ მოწყობილობაზე, ჩვენ ვაგროვებთ მხოლოდ ერთი ფენის წონებს ერთდროულად, წინა მიმართულებით გადაცემამდე (forward pass), რის შემდეგაც წონები შეიძლება კვლავ დაიშარდოს. ამ გზით, ჩვენ ვცვლით მეხსიერების გამოყენებას კომუნიკაციის ზედნადები ხარჯების სანაცვლოდ, რაც საჭიროა დაშარდული პარამეტრების შეგროვებისთვის ყოველი წინა და უკანა მიმართულებით გადაცემამდე (forward and backward pass), და ადგილობრივი გრადიენტების reduce-scatter ოპერაციების შესასრულებლად. ჩვენ შეგვიძლია ვაკონტროლოთ ეს კომპრომისი FSDP-ში, პარამეტრების შეგროვების დეტალიზაციის დონის (granularity) დარეგულირებით. ერთ უკიდურეს შემთხვევაში, ჩვენ შეგვიძლია შევაგროვოთ და ხელახლა დავშარდოთ ჩვენი მოდელის ყოველი ფენა, რაც გამოიწვევს მეხსიერების ყველაზე დაბალ პიკურ გამოყენებას, მაგრამ გამოიწვევს კომუნიკაციის ყველაზე მაღალ ხარჯებს. პრაქტიკაში, გავრცელებული მიდგომაა მთელი ტრანსფორმატორის დეკოდერის ბლოკის წონების ერთდროულად შეგროვება.
მიუხედავად იმისა, რომ შეგვიძლია შევასრულოთ მეხსიერება-გამოთვლის დამატებითი კომპრომისები და გადმოვტვირთოთ მოდელის პარამეტრები და გრადიენტები CPU-ზე, უფრო დიდი მოდელების ვარჯიშისთვის, ეს შეიძლება იყოს აკრძალულად ნელი. ამის ნაცვლად, განვიხილოთ, როგორ შეგვიძლია ეფექტურად გამოვიყენოთ კიდევ უფრო მეტი მოწყობილობა უფრო დიდი მოდელების ვარჯიშისთვის მონაცემთა მაღალი გამტარუნარიანობის შენარჩუნებით. ტერმინს „კვანძი“ ვიყენებთ ერთი მანქანის აღსანიშნავად, რომელიც მასპინძლობს მრავალ GPU-ს (მაქსიმუმ 8-მდე), სწრაფი კვანძშიდა საკომუნიკაციო არხებით, მაგ., NVLink-ის გამოყენებით GPU-ებს შორის. მრავალი კვანძის გამოყენებისას ვარჯიშისთვის, ჩვენ ვეყრდნობით შედარებით ნელ კვანძებსშორის საკომუნიკაციო არხებს მანქანებს შორის, მაგ., Infiniband-ის გამოყენებით. ჩვენ ასევე ვიყენებთ ტერმინს „მსოფლიო ზომა“ (world size) პროცესის აუზში მოწყობილობების საერთო რაოდენობის აღსანიშნავად — მაგ., ერთი კვანძი 8 GPU-ით წარმოადგენს მსოფლიო ზომას 8, ხოლო 4 კვანძი წარმოადგენს მსოფლიო ზომას 32. FSDP-ის გამოყენებისას მრავალ კვანძზე, მოწყობილობების მთელ კომპლექტს კვანძებს შორის ვექცევით ისე, თითქოს ერთ კვანძზე ვვარჯიშობდეთ. მაგალითად, 4 კვანძით, რომელთაგან თითოეული შეიცავს 8 GPU-ს, ჩვენ ვასრულებთ ჩვენს შარდინგს 32 მოწყობილობაზე და ვასრულებთ ჩვენს კოლექტიურ all-reduce და reduce-scatter ოპერაციებს როგორც კვანძშიდა, ასევე კვანძებსშორისი საკომუნიკაციო ბეკენდების გამოყენებით. ამ გზით, FSDP-ს შეუძლია მარტო მასშტაბირება GPU-ების მნიშვნელოვან რაოდენობამდე დიდი გლობალური პაკეტის ზომით (global batch size), მონაცემთა გამტარუნარიანობის გაზრდის მიზნით. თუმცა, დგება მომენტი, როდესაც რამდენიმე გამოწვევა ჩნდება, რამაც შეიძლება მოითხოვოს...
თეგები:
#ai
#ხელოვნური ინტელექტი
#მანქანური სწავლება
#gpu
#fsdp
#accelerate
#მოდელის ვარჯიში
#პარალელიზმი
#მონაცემთა პარალელიზმი
#axolotl
#დისტრიბუციული ვარჯიში
წყარო: huggingface.co
AI-ით გადამუშავებული