Apache Parquet არის სვეტოვანი შენახვის ფორმატი, რომელიც ფართოდ გამოიყენება მონაცემთა ინჟინერიის საზოგადოებაში. დღეის მდგომარეობით, Hugging Face მასპინძლობს თითქმის 21 პეტაბაიტის (PB) მონაცემთა ნაკრებებს, საიდანაც მხოლოდ Parquet ფაილებზე მოდის 4 PB-ზე მეტი. ამიტომ, Parquet-ის შენახვის ოპტიმიზაცია მაღალი პრიორიტეტია. Hugging Face-მა წარმოადგინა ახალი საცავის ფენა, სახელწოდებით Xet, რომელიც იყენებს კონტენტზე დაფუძნებულ დანაწილებას (content-defined chunking) მონაცემთა ნაწილების ეფექტურად დედუპლიკაციისთვის, რაც ამცირებს შენახვის ხარჯებს და აუმჯობესებს ატვირთვა/ჩამოტვირთვის სიჩქარეებს. მიუხედავად იმისა, რომ Xet ფორმატის მიმართ აგნოსტიკურია, Parquet-ის განლაგებამ და სვეტ-ნაწილზე (მონაცემთა გვერდი) დაფუძნებულმა შეკუმშვამ შეიძლება გამოიწვიოს მონაცემების სრულიად განსხვავებული ბაიტ-დონის წარმოდგენა მცირე ცვლილებების შემთხვევაშიც კი, რაც ოპტიმალური დედუპლიკაციის შესრულებას აფერხებს. ამ პრობლემის გადასაჭრელად, Parquet ფაილები უნდა დაიწეროს ისე, რომ მინიმუმამდე დაიყვანოს ბაიტ-დონის განსხვავებები მსგავს მონაცემებს შორის — აქ შემოდის კონტენტზე დაფუძნებული დანაწილება (CDC). მოდით, განვიხილოთ ახალი Parquet CDC ფუნქციის მუშაობის უპირატესობები Hugging Face-ის Xet საცავის ფენასთან ერთად გამოყენებისას. დემონსტრაციის მიზნით, ჩვენ გამოვიყენებთ OpenOrca მონაცემთა ნაკრების მართვადი ზომის ქვეჯგუფს. pyarrow>=21.0.0 ვერსიიდან მოყოლებული, ჩვენ შეგვიძლია გამოვიყენოთ Hugging Face URI-ები pyarrow ფუნქციებში Parquet (და სხვა ფაილის ფორმატების) ფაილების პირდაპირ წასაკითხად და ჩასაწერად Hub-ზე hf:// URI სქემის გამოყენებით. ვხედავთ, რომ ცხრილი სრულად აიტვირთა (total bytes == total transfer) როგორც ახალი მონაცემები, რადგან ის ჯერ არ იყო ცნობილი Xet საცავის ფენისთვის. ახლა წავიკითხოთ ის უკან, როგორც pyarrow ცხრილი: გაითვალისწინეთ, რომ pyarrow-ის ყველა ფუნქცია, რომელიც ფაილის გზას იღებს, ასევე იღებს Hugging Face URI-ს, როგორიცაა pyarrow მონაცემთა ნაკრებები, CSV ფუნქციები, ინკრემენტული Parquet მწერალი ან მხოლოდ Parquet მეტამონაცემების წაკითხვა: კონტენტზე დაფუძნებული დანაწილების ფუნქციის ეფექტურობის დემონსტრირებისთვის, ვნახავთ, როგორ მუშაობს ის შემდეგ შემთხვევებში: მიუხედავად იმისა, რომ ეს გამოყენების შემთხვევა ტრივიალურად ჟღერს, ტრადიციული ფაილური სისტემები არ ახდენენ ფაილების დედუპლიკაციას, რაც მონაცემების სრულ ხელახლა ატვირთვასა და ჩამოტვირთვას იწვევს. ამის საპირისპიროდ, სისტემა, რომელიც იყენებს კონტენტზე დაფუძნებულ დანაწილებას, შეუძლია ამოიცნოს, რომ ფაილის შინაარსი იდენტურია და თავიდან აიცილოს ზედმეტი მონაცემთა გადაცემა. ჩვენ ვხედავთ, რომ ახალი მონაცემები არ ატვირთულა და ოპერაცია მყისიერი იყო. ახლა ვნახოთ, რა მოხდება, თუ იგივე ფაილს კვლავ ავტვირთავთ, ოღონდ სხვა რეპოზიტორიაში: ატვირთვა კვლავ მყისიერი იყო, რადგან დედუპლიკაცია რეპოზიტორიებს შორისაც მუშაობს. ეს Xet საცავის ფენის საკვანძო მახასიათებელია, რაც უზრუნველყოფს მონაცემთა ეფექტურ გაზიარებასა და თანამშრომლობას. დეტალებისა და მასშტაბირების გამოწვევების შესახებ მეტის წაკითხვა შეგიძლიათ ბლოგპოსტში „From Chunks to Blocks: Accelerating Uploads and Downloads on the Hub“. პირველ რიგში, ჩავწეროთ ორიგინალი და შეცვლილი ცხრილები ლოკალურ parquet ფაილებში, რათა ვნახოთ მათი ზომები: ახლა ავტვირთოთ ისინი Hugging Face-ზე, რათა ვნახოთ, რამდენი მონაცემი გადაიცემა რეალურად: ჩვენ ვხედავთ, რომ მხოლოდ ახალი სვეტები და ფაილის ქვედა ნაწილში მოთავსებული ახალი parquet მეტამონაცემები აიტვირთა, ხოლო ორიგინალი მონაცემები ხელახლა არ გადაცემულა. ეს Xet საცავის ფენის უზარმაზარი უპირატესობაა, რადგან ის საშუალებას გვაძლევს ეფექტურად დავამატოთ ახალი სვეტები მთელი მონაცემთა ნაკრების ხელახლა გადაცემის გარეშე. იგივე ეხება სვეტების წაშლასაც, როგორც ქვემოთ ვხედავთ: იმის უკეთ გასაგებად, თუ რა აიტვირთა, შეგვიძლია ვიზუალურად წარმოვაჩინოთ განსხვავებები ორ parquet ფაილს შორის დედუპლიკაციის შეფასების ხელსაწყოს გამოყენებით: ორი ახალი სვეტის დამატება ნიშნავს, რომ გვაქვს უხილავი მონაცემთა გვერდები, რომლებიც უნდა გადაიცეს (წითლად მონიშნული), მაგრამ მონაცემების დანარჩენი ნაწილი უცვლელი რჩება (მწვანედ მონიშნული), ასე რომ, ის ხელახლა არ გადაიცემა. გაითვალისწინეთ მცირე წითელი არე ქვედა ნაწილის მეტამონაცემებში, რომელიც თითქმის ყოველთვის იცვლება Parquet ფაილის შეცვლისას. დედუპლიკაციის სტატისტიკა აჩვენებს <დედუპლიცირებული ზომა> / <საერთო ზომა> = <დედუპლიკაციის კოეფიციენტი>, სადაც უფრო მცირე კოეფიციენტები ნიშნავს დედუპლიკაციის უფრო მაღალ შესრულებას. ასევე, ვიზუალურად წარმოვაჩინოთ განსხვავება სვეტის წაშლის შემდეგ: რადგან ჩვენ მთლიან სვეტებს ვშლით, ცვლილებებს მხოლოდ ქვედა ნაწილის მეტამონაცემებში ვხედავთ; ყველა სხვა სვეტი უცვლელი რჩება და უკვე არსებობს საცავის ფენაში, ამიტომ ისინი ხელახლა არ გადაიცემა. კიდევ ერთი გავრცელებული გამოყენების შემთხვევაა ცხრილში სვეტების ტიპების შეცვლა, მაგალითად, შენახვის ზომის შესამცირებლად ან მონაცემების კონკრეტული მოთხოვნებისთვის ოპტიმიზაციისთვის. მოდით, შევცვალოთ question_length სვეტის მონაცემთა ტიპი int64-დან int32-ზე და ვნახოთ, რამდენი მონაცემი გადაიცემა: კვლავ, ჩვენ ვხედავთ, რომ მხოლოდ ახალი სვეტი და განახლებული parquet მეტამონაცემები აიტვირთა. ახლა ვიზუალურად წარმოვაჩინოთ დედუპლიკაციის სითბოს რუკა: პირველი წითელი რეგიონი მიუთითებს ახალ დამატებულ სვეტზე, ხოლო მეორე წითელი რეგიონი მიუთითებს განახლებულ მეტამონაცემებზე ქვედა ნაწილში. მონაცემების დანარჩენი ნაწილი უცვლელი რჩება და ხელახლა არ გადაიცემა. ჩვენ ვაპირებთ ახალი რიგების დამატებას კონკატენაციით.