ეს გაკვეთილი გულისხმობს, რომ თქვენ გაქვთ PyTorch-ის საბაზისო ცოდნა და იცით, როგორ გაწვრთნათ მარტივი მოდელი. ის აჩვენებს მრავალ GPU-ზე წვრთნას Distributed Data Parallelism (DDP) პროცესის მეშვეობით, აბსტრაქციის სამი სხვადასხვა, მზარდი დონის გამოყენებით: ქვემოთ მოცემულია PyTorch-ის საბაზისო სავარჯიშო კოდი, რომელიც ქმნის და წვრთნის მოდელს MNIST-ზე, ოფიციალური MNIST მაგალითის საფუძველზე. ჩვენ განვსაზღვრავთ საწვრთნელ მოწყობილობას (cuda): ვქმნით PyTorch DataLoaders-ს: გადაგვაქვს მოდელი CUDA მოწყობილობაზე: ვქმნით PyTorch ოპტიმიზატორს: და ბოლოს ვქმნით გამარტივებულ სავარჯიშო და შეფასების ციკლს, რომელიც ასრულებს მონაცემთა ნაკრებზე ერთ სრულ იტერაციას და ითვლის ტესტის სიზუსტეს: აქედან გამომდინარე, შესაძლებელია ყოველივე ამის python სკრიპტში მოთავსება ან Jupyter Notebook-ზე გაშვება. თუმცა, როგორ გაუშვებდით ამ სკრიპტს ორ GPU-ზე ან მრავალ მანქანაზე, თუ ეს რესურსები ხელმისაწვდომია, რამაც შეიძლება გააუმჯობესოს წვრთნის სიჩქარე განაწილებული წვრთნის მეშვეობით? უბრალოდ `python myscript.py`-ის გაშვება სკრიპტს მხოლოდ ერთი GPU-ს გამოყენებით ამუშავებს. სწორედ აქ შემოდის თამაშში `torch.distributed`. როგორც სახელი გულისხმობს, `torch.distributed` გამიზნულია განაწილებულ გარემოში სამუშაოდ. ეს შეიძლება მოიცავდეს მრავალ კვანძს (multi-node), სადაც გაქვთ რამდენიმე მანქანა, თითოეული ერთი GPU-თი, ან მრავალ GPU-ს (multi-gpu), სადაც ერთ სისტემას აქვს მრავალი GPU, ან ორივეს კომბინაციას. ჩვენი ზემოთ მოცემული კოდის განაწილებულ გარემოში სამუშაოდ გადასაყვანად, ჯერ უნდა განისაზღვროს რამდენიმე საწყისი კონფიგურაცია, რაც დეტალურად არის აღწერილი DDP გაკვეთილში ("Getting Started with DDP Tutorial"). პირველ რიგში, უნდა გამოცხადდეს setup და cleanup ფუნქციები. ეს გახსნის დამუშავების ჯგუფს (processing group), რომლის მეშვეობითაც ყველა გამოთვლით პროცესს შეუძლია კომუნიკაცია. შენიშვნა: გაკვეთილის ამ ნაწილისთვის უნდა ვივარაუდოთ, რომ ისინი გაგზავნილია python სკრიპტის ფაილებში. მოგვიანებით განხილული იქნება „Accelerate“-ის გამშვები (launcher), რომელიც ამ აუცილებლობას აღმოფხვრის. თავსატეხის ბოლო ნაწილია, როგორ გავაგზავნო ჩემი მონაცემები და მოდელი სხვა GPU-ზე? სწორედ აქ შემოდის თამაშში `DistributedDataParallel` მოდული. ის დააკოპირებს თქვენს მოდელს თითოეულ GPU-ზე, და როდესაც `loss.backward()` იქნება გამოძახებული, შესრულდება უკუ-განაწილება (backpropagation) და მოდელის ყველა ასლის შედეგად მიღებული გრადიენტები იქნება საშუალოდ დაყვანილი/შემცირებული (averaged/reduced). ეს უზრუნველყოფს, რომ ოპტიმიზატორის ნაბიჯის შემდეგ თითოეულ მოწყობილობას ჰქონდეს იგივე წონები. ქვემოთ მოცემულია ჩვენი საწვრთნელი გარემოს მაგალითი, ფუნქციად გადაკეთებული, ამ შესაძლებლობით: შენიშვნა: აქ "rank" არის მიმდინარე GPU-ს საერთო რანგი ყველა სხვა ხელმისაწვდომ GPU-სთან შედარებით, რაც ნიშნავს, რომ მათ აქვთ რანგი 0-დან n-1-მდე. ოპტიმიზატორი უნდა გამოცხადდეს კონკრეტულ მოწყობილობაზე არსებული მოდელის (ანუ `ddp_model` და არა `model`) საფუძველზე, რათა ყველა გრადიენტი სწორად იყოს გათვლილი. და ბოლოს, სკრიპტის გასაშვებად PyTorch-ს აქვს მოსახერხებელი `torchrun` ბრძანების ხაზის მოდული, რომელიც დაგეხმარებათ. უბრალოდ გადაეცით კვანძების რაოდენობა, რომელიც უნდა გამოიყენოს, ასევე გასაშვები სკრიპტი და მზად ხართ: ზემოთ მოცემული სავარჯიშო სკრიპტს გაუშვებს ორ GPU-ზე, რომლებიც ერთ მანქანაზეა განთავსებული და ეს არის PyTorch-ით მხოლოდ განაწილებული წვრთნის შესრულების ძირითადი საფუძვლები. ახლა კი ვისაუბროთ „Accelerate“-ზე, ბიბლიოთეკაზე, რომელიც მიზნად ისახავს ამ პროცესის უფრო შეუფერხებლად ქცევას და ასევე დახმარებას რამდენიმე საუკეთესო პრაქტიკის დანერგვაში. „Accelerate“ არის ბიბლიოთეკა, რომელიც შექმნილია იმისთვის, რომ მოგცეთ საშუალება შეასრულოთ ის, რაც ზემოთ გავაკეთეთ, თქვენი კოდის მნიშვნელოვანი მოდიფიკაციის გარეშე. გარდა ამისა, „Accelerate“-ში თანდაყოლილ მონაცემთა მილსადენს (data pipeline) შეუძლია ასევე გააუმჯობესოს თქვენი კოდის მუშაობა. ჯერ მოდით, ზემოთ შესრულებული მთელი კოდი ერთ ფუნქციაში შევფუთოთ, რათა დაგვეხმაროს განსხვავების ვიზუალიზაციაში: შემდეგ ვისაუბროთ იმაზე, თუ როგორ შეუძლია „Accelerate“-ს დახმარება. ზემოთ მოცემულ კოდს აქვს რამდენიმე პრობლემა: „Accelerate“ ამას ეხმარება `Accelerator` კლასის მეშვეობით. მისი მეშვეობით, კოდი თითქმის უცვლელი რჩება, გარდა სამი ხაზის, როდესაც ერთ კვანძს მრავალ კვანძს ვადარებთ, როგორც ქვემოთაა ნაჩვენები: ამით თქვენი PyTorch-ის სავარჯიშო ციკლი ახლა უკვე მზად არის ნებისმიერ განაწილებულ გარემოში გასაშვებად `Accelerator` ობიექტის წყალობით. ეს კოდი შემდეგ მაინც შეიძლება გაიშვას `torchrun CLI`-ის ან „Accelerate“-ის საკუთარი CLI ინტერფეისის, `accelerate launch`-ის მეშვეობით. შედეგად, `Accelerate`-ის გამოყენებით განაწილებული წვრთნის შესრულება და რაც შეიძლება მეტი PyTorch-ის ძირითადი კოდის შენარჩუნება გამარტივდა. ადრე აღინიშნა, რომ „Accelerate“ ასევე აუმჯობესებს DataLoaders-ის ეფექტურობას. ეს ხდება მორგებული „Samplers“-ის მეშვეობით, რომლებსაც შეუძლიათ ავტომატურად გაგზავნონ ბატჩების ნაწილები სხვადასხვა მოწყობილობაზე წვრთნის დროს, რაც საშუალებას იძლევა მონაცემთა ერთჯერადი ასლი იყოს ცნობილი ერთდროულად, ნაცვლად ოთხი ასლისა მეხსიერებაში, კონფიგურაციის მიხედვით. ამასთან ერთად, მეხსიერებაში სულ არის ორიგინალური მონაცემთა ნაკრების მხოლოდ ერთი სრული ასლი. ამ მონაცემთა ნაკრების ქვეჯგუფები იყოფა ყველა კვანძს შორის, რომლებიც გამოიყენება წვრთნისთვის, რაც საშუალებას იძლევა ბევრად უფრო დიდი მონაცემთა ნაკრებები გაწვრთნათ ერთ ინსტანციაზე გამოყენებული მეხსიერების „აფეთქების“ გარეშე. ადრე აღინიშნა, რომ შეგიძლიათ განაწილებული კოდი პირდაპირ თქვენი Jupyter Notebook-იდან გაუშვათ. ეს მოდის „Accelerate“-ის `notebook_launcher` უტილიტიდან, რომელიც იძლევა მრავალ GPU-ზე წვრთნის დაწყების საშუალებას Jupyter Notebook-ის შიგნით არსებული კოდის საფუძველზე.