改進 Hugging Face Hub 上的 Parquet 重複資料刪除

釋出於 2024 年 10 月 5 日
在 GitHub 上更新

Hugging Face 的 Xet 團隊正在努力提高 Hub 儲存架構的效率,使使用者能夠更輕鬆、更快速地儲存和更新資料和模型。由於 Hugging Face 託管了近 11PB 的資料集,其中僅 Parquet 檔案就佔用了超過 2.2PB 的儲存空間,因此最佳化 Parquet 儲存的優先順序非常高。

大多數 Parquet 檔案都是從各種資料分析管道或資料庫批次匯出的,通常以完整快照而非增量更新的形式出現。當用戶希望定期更新資料集時,資料去重變得至關重要。只有透過去重,我們才能儘可能緊湊地儲存所有版本,而無需在每次更新時重新上傳所有內容。在理想情況下,我們應該能夠以僅比其最大版本稍大的空間儲存不斷增長的資料集的每個版本。

我們的預設儲存演算法使用位元組級內容定義分塊 (CDC),該演算法通常在插入和刪除時具有良好的去重效果,但 Parquet 佈局帶來了一些挑戰。在這裡,我們使用來自 FineWeb 資料集的一個包含 1,092,000 行的 2GB Parquet 檔案進行實驗,以瞭解一些簡單修改在 Parquet 檔案上的表現,並使用我們的去重估算器生成視覺化。

背景

Parquet 表透過將表分成行組工作,每個行組包含固定數量的行(例如 1000 行)。然後,行組中的每一列都被壓縮並存儲。

Parquet Layout

直觀地說,這意味著不干擾行分組的操作,如修改或追加,應該能夠很好地去重。那麼讓我們來測試一下!

追加

在這裡,我們向檔案中追加 10,000 行新資料,並將結果與原始版本進行比較。綠色代表所有去重塊,紅色代表所有新塊,介於兩者之間的陰影表示不同級別的去重。

Visualization of dedupe from data appends

我們可以看到,我們確實能夠對幾乎整個檔案進行去重,但只看到了檔案末尾的更改。新檔案去重率為 99.1%,僅需要 20MB 的額外儲存空間。這與我們的直覺非常吻合。

修改

鑑於其佈局,我們預期行修改會非常獨立,但事實並非如此。在這裡,我們對第 10000 行進行了少量修改,我們發現雖然檔案的大部分內容都去重了,但仍有許多小而規律間隔的新資料段!

Visualization of dedupe from data modifications

快速掃描 Parquet 檔案格式表明絕對檔案偏移量是 Parquet 列頭的一部分(請參閱 ColumnChunk 和 ColumnMetaData 結構)!這意味著任何修改都可能重寫所有列頭。因此,儘管資料去重效果良好(大部分為綠色),但每個列頭中都會有新的位元組。

在這種情況下,新檔案僅去重 89%,需要額外 230MB 的儲存空間。

刪除

在這裡,我們從檔案中間刪除了一行(注意:插入應具有類似的行為)。由於這會重新組織整個行組佈局(每個行組為 1000 行),我們發現雖然檔案的前半部分去重了,但剩餘檔案有全新的塊。

Visualization of dedupe from data deletion

這主要是因為 Parquet 格式會積極壓縮每列。如果我們關閉壓縮,我們可以更積極地去重。

Visualization of dedupe from data deletion without column compression

然而,如果我們將資料未壓縮儲存,檔案大小會增加近 2 倍。

是否可以同時實現去重和壓縮的優點?

內容定義行組

一個潛在的解決方案是不僅使用位元組級 CDC,而且將其應用於行級別:我們不再根據絕對計數(1000 行)分割行組,而是根據提供的“鍵”列的雜湊值進行分割。換句話說,當鍵列的雜湊值 % [目標行數] = 0 時,我就分割出一個行組,並允許最小和最大行組大小。

我在這裡快速且低效地演示了一個實驗:https://gist.github.com/ylow/db38522fb0ca69bdf1065237222b4d1c

透過這種方式,即使我刪除了一行,我們也能夠有效地對壓縮的 Parquet 檔案進行去重。在這裡,我們清楚地看到一個大的紅色塊,代表重寫的行組,隨後每個列頭都有一個小的更改。

Visualization of dedupe from data deletion with content defined row groups

最佳化 Parquet 以實現去重能力

根據這些實驗,我們可以考慮通過幾種方式改進 Parquet 檔案的去重能力:

  1. 對於檔案結構資料,使用相對偏移量而不是絕對偏移量。這將使 Parquet 結構與位置無關,易於“memcpy”,儘管這是一個涉及檔案格式更改的工作,可能難以實現。
  2. 支援行組上的內容定義分塊。該格式目前已支援此功能,因為它不要求行組大小統一,因此這可以在最小影響範圍內完成。只需更新 Parquet 格式寫入器即可。

雖然我們將繼續探索提高 Parquet 儲存效能的方法(例如:我們是否可以選擇在上傳前重寫 Parquet 檔案?在上傳時剝離絕對檔案偏移量並在下載時恢復?),我們很樂意與 Apache Arrow 專案合作,看看是否有興趣在 Parquet/Arrow 程式碼庫中實現其中一些想法。

同時,我們也在探索我們的資料去重過程在其他常見檔案型別上的行為。請務必嘗試我們的 去重估算器 並告訴我們您的發現!

社群

註冊登入 發表評論

© . This site is unofficial and not affiliated with Hugging Face, Inc.