პრაქტიკაში, ეს უფრო კომპლექსურია. თუ მხოლოდ დედუპლიკაციის მაქსიმიზაციაზე ვიქნებოდით ორიენტირებული, დიზაინი მოითხოვდა ბლოკის მინიმალურ ზომას. ამით ჩვენ მნიშვნელოვან დამატებით დატვირთვას შევუქმნიდით ინფრასტრუქტურას და დეველოპერებს Hub-ზე. Hugging Face-ის Xet გუნდში, ჩვენ CDC-ს (Content-Defined Chunking) თეორიიდან წარმოებამდე ვაქცევთ, რათა ხელოვნური ინტელექტის დეველოპერებს უფრო სწრაფი ატვირთვა და ჩამოტვირთვა მივაწოდოთ (ზოგიერთ შემთხვევაში 2-3-ჯერ უფრო სწრაფად). ჩვენი მთავარი პრინციპი მარტივია: უზრუნველვყოთ სწრაფი ექსპერიმენტები და თანამშრომლობა გუნდებისთვის, რომლებიც ქმნიან და ავითარებენ მოდელებსა და მონაცემთა ნაკრებებს. ეს ნიშნავს, რომ ყურადღება გამახვილებულია არა მხოლოდ დედუპლიკაციაზე; ჩვენ ვახდენთ ოპტიმიზაციას, თუ როგორ მოძრაობს მონაცემები ქსელში, როგორ ინახება ის და მთელი განვითარების გამოცდილება. წარმოიდგინეთ 200GB რეპოზიტორიუმის ატვირთვა Hub-ზე. დღეს ამის გაკეთების რამდენიმე გზა არსებობს, მაგრამ ყველა მათგანი ფაილზე ორიენტირებულ მიდგომას იყენებს. Hub-ზე ფაილების უფრო სწრაფი გადაცემის უზრუნველსაყოფად, ჩვენ გავხსენით xet-core და hf_xet, რომელიც არის huggingface_hub-თან ინტეგრაცია და იყენებს Rust-ში დაწერილ ბლოკებზე დაფუძნებულ მიდგომას. თუ განვიხილავთ 200GB რეპოზიტორიუმს უნიკალური ბლოკებით, ეს ნიშნავს 3 მილიონ ჩანაწერს (დაახლოებით 64KB თითო ბლოკზე) კონტენტის მისამართის საცავში (CAS), რომელიც ყველა რეპოზიტორიუმს უმაგრებს ზურგს. თუ მოდელის ახალი ვერსია აიტვირთება ან რეპოზიტორიუმში შეიქმნება ფილიალი სხვა მონაცემებით, ემატება მეტი უნიკალური ბლოკი, რაც ზრდის ჩანაწერებს CAS-ში. Hub-ზე თითქმის 45PB მონაცემით, რომელიც განაწილებულია 2 მილიონ მოდელზე, მონაცემთა ნაკრებსა და სივრცის რეპოზიტორიუმზე, მხოლოდ ბლოკებზე დაფუძნებულმა მიდგომამ შეიძლება გამოიწვიოს 690 მილიარდი ბლოკი. ამ მოცულობის კონტენტის მხოლოდ ბლოკების გამოყენებით მართვა უბრალოდ შეუძლებელია, რადგან: მოკლედ, ქსელის მოთხოვნები იზრდება, მონაცემთა ბაზები იბრძვიან მეტამონაცემების სამართავად, და ყოველი ბლოკის ორკესტრირების ღირებულება მკვეთრად იზრდება, სანამ თქვენ ელოდებით თქვენი ფაილების გადაცემას. ეს გამოწვევები მიგვიყვანს მთავარ გაცნობიერებამდე: დედუპლიკაცია არის შესრულების ოპტიმიზაცია და არა საბოლოო მიზანი. საბოლოო მიზანია გაუმჯობესდეს დეველოპერების გამოცდილება, რომლებიც ავითარებენ და თანამშრომლობენ მოდელებსა და მონაცემთა ნაკრებებზე. სისტემის კომპონენტებს კლიენტიდან შენახვის ფენამდე არ სჭირდებათ დედუპლიკაციის გარანტირება. ამის ნაცვლად, ისინი იყენებენ დედუპლიკაციას, როგორც ერთ-ერთ ინსტრუმენტს მრავალთაგან ამ მიზნის მისაღწევად. დედუპლიკაციის შეზღუდვის მოხსნით, ჩვენ ბუნებრივად მივდივართ მეორე დიზაინის პრინციპამდე: თავიდან ავიცილოთ კომუნიკაციის ან შენახვის სტრატეგიები, რომლებიც 1:1-ზე იზრდება ბლოკების რაოდენობასთან ერთად. რას ნიშნავს ეს? ჩვენ ვახდენთ მასშტაბირებას აგრეგაციით. აგრეგაცია იღებს ბლოკებს და აჯგუფებს მათ, ჭკვიანურად ახდენს მათ რეფერენციას ისე, რომ უზრუნველყოფს მოხერხებულ (და პრაქტიკულ) სარგებელს: ბლოკები და შარდები ერთად მნიშვნელოვან სარგებელს ხსნის. თუმცა, როდესაც ვინმე ახალ ფაილს ტვირთავს, როგორ გავიგოთ, ატვირთული იყო თუ არა ბლოკი მანამდე, რათა თავიდან ავიცილოთ ზედმეტი მოთხოვნა? ყოველი ბლოკისთვის ქსელის მოთხოვნის შესრულება არ არის მასშტაბირებადი და ეწინააღმდეგება ზემოთ ხსენებულ „არა 1:1-ზე“ პრინციპს. გამოსავალი არის ძირითადი ბლოკები (key chunks), რომლებიც წარმოადგენს ყველა ბლოკის 0.1%-იან ქვეჯგუფს, შერჩეულს მარტივი მოდულოს პირობით, ბლოკის ჰეშის საფუძველზე. ჩვენ გთავაზობთ გლობალურ ინდექსს ამ ძირითად ბლოკებზე და შარდებზე, რომლებშიც ისინი გვხვდება, ისე, რომ როდესაც ბლოკი მოთხოვნილია, დაკავშირებული შარდი დაბრუნდება ადგილობრივი დედუპლიკაციის უზრუნველსაყოფად. ეს საშუალებას გვაძლევს გამოვიყენოთ სივრცითი ლოკალიზაციის პრინციპები. თუ ძირითადი ბლოკი შარდშია მითითებული, სავარაუდოა, რომ სხვა მსგავსი ბლოკის მითითებები ხელმისაწვდომია იმავე შარდში. ეს კიდევ უფრო აუმჯობესებს დედუპლიკაციას და ამცირებს ქსელის და მონაცემთა ბაზის მოთხოვნებს. Hub ამჟამად ინახავს 3.5PB-ზე მეტ .gguf ფაილს, რომელთა უმეტესობა Hub-ზე არსებული სხვა მოდელების კვანტიზირებული ვერსიებია. კვანტიზირებული მოდელები წარმოადგენს საინტერესო შესაძლებლობას დედუპლიკაციისთვის კვანტიზაციის ბუნების გამო, სადაც მნიშვნელობები შეზღუდულია მცირე მთელი რიცხვების დიაპაზონით და მასშტაბირებულია. ეს ზღუდავს მნიშვნელობების დიაპაზონს წონის მატრიცებში, რაც ბუნებრივად იწვევს მეტ გამეორებას. გარდა ამისა, კვანტიზირებული მოდელების მრავალი რეპოზიტორიუმი ინახავს მრავალ სხვადასხვა ვარიანტს (მაგ., Q4_K, Q3_K, Q5_K) დიდი გადაფარვით. ამის კარგი პრაქტიკული მაგალითია bartowski/gemma-2-9b-it-GGUF, რომელიც შეიცავს google/gemma-2-9b-it-ის 29 კვანტიზაციას, საერთო მოცულობით 191GB. ასატვირთად, ჩვენ ვიყენებთ hf_xet-ს, რომელიც ინტეგრირებულია huggingface_hub-თან, რათა შეასრულოს ბლოკის დონეზე დედუპლიკაცია ლოკალურად, შემდეგ კი მოახდინოს მონაცემების აგრეგაცია და შენახვა ბლოკის დონეზე. ატვირთვის შემდეგ, ჩვენ შეგვიძლია დავინახოთ საინტერესო ნიმუშები! ჩვენ შევიტანეთ ვიზუალიზაცია, რომელიც აჩვენებს დედუპლიკაციის კოეფიციენტს თითოეული ბლოკისთვის. რაც უფრო მუქია ბლოკი, მით უფრო ხშირად ხდება მისი ნაწილების რეფერენცია მოდელების ვერსიებში. თუ გადახვალთ სივრცეში, სადაც განთავსებულია ეს ვიზუალიზაცია, ნებისმიერ სითბოს რუკის უჯრედზე გადაფრენა ნარინჯისფრად გაანათებს ყველა რეფერენციას ბლოკზე ყველა მოდელში, ხოლო უჯრედზე დაწკაპუნებით შეირჩევა ყველა სხვა ფაილი, რომელიც იზიარებს ბლოკებს: ერთი დედუპლიკირებული ბლოკი შესაძლოა მხოლოდ რამდენიმე MB-ის დაზოგვას ნიშნავდეს, მაგრამ როგორც ხედავთ, ბევრი გადამფარავი ბლოკია! ამდენი ბლოკის შემთხვევაში, ეს სწრაფად გროვდება. 191GB-ის ატვირთვის ნაცვლად, gemma-2-9b-it-GGUF რეპოზიტორიუმის Xet-ით მხარდაჭერილი ვერსია ინახავს 1515 უნიკალურ ბლოკს, საერთო ჯამში დაახლოებით 97GB-ს ჩვენს სატესტო CAS გარემოში.