在 Hugging Face Hub 上改進 Parquet 去重

Hugging Face 正在優化其儲存架構,以提升 Parquet 檔案去重的效率,減少使用者更新大型資料集時所需的儲存開銷。此舉至關重要,因為 Parquet 檔案佔了 Hugging Face Hub 上近 11PB 資料集中的超過 2.2PB。

Parquet 去重的挑戰

為了降低儲存成本,Hugging Face 使用位元組層級的內容定義分塊(Content-Defined Chunking,CDC)來進行資料去重。雖然 CDC 在許多檔案類型的插入與刪除操作中都相當有效,但 Parquet 檔案的特定布局在增量更新時會帶來有效去重的挑戰。

Parquet 表格被組織為列群組(row groups),每個列群組內的每個欄位皆會被壓縮並儲存。這種結構意味著資料的變動可能對最終檔案位元組產生不成比例的影響,進而影響檔案相較於先前版本能夠去重的程度。

資料操作對去重的影響

Hugging Face 以 FineWeb 資料集中的 2GB、1,092,000 列的 Parquet 檔案進行實驗,分析不同操作對去重率的影響:

資料追加

追加 10,000 筆新列可獲得高效的去重。由於追加僅影響檔案的末端,新版本的去重率達 99.1%,僅需額外 20MB 的儲存空間。

資料修改

修改單一列(例如第 10,000 列)會顯著降低去重率。新檔案的去重率僅為 89%,需要額外 230MB 的儲存空間。這是因為 Parquet 檔案格式在欄位標頭中包含絕對檔案偏移(特別是在 ColumnChunkColumnMetaData 結構中),導致任何修改都會觸發所有欄位標頭的重寫。

資料刪除

從檔案中間刪除一列通常會導致剩餘檔案全部由新區塊組成,使檔案後半部的去重失效。這主要是因為欄位壓縮過於激進。雖然關閉壓縮可提升去重,但會使檔案大小翻倍,形成儲存效率與去重能力之間的取捨。

提議的解決方案:內容定義的列群組

為了在刪除或插入操作中同時保有壓縮與去重效率,Hugging Face 提議在列層級而非僅位元組層級使用內容定義分塊(Content-Defined Chunking)。

不再以固定列數(例如每 1,000 列)來切分列群組,而是根據提供的「Key」欄位的雜湊值來切分。當鍵欄位的雜湊值對目標列數取模等於零時(同時受最小與最大大小限制),即會分割列群組。

實驗結果顯示,即使在刪除列的情況下,此方法仍能在壓縮的 Parquet 檔案中實現高效去重,因為僅會重寫受影響的列群組與欄位標頭。

Parquet 儲存的未來優化方向

Hugging Face 確認了提升 Parquet 去重能力的兩條主要路徑:

  1. 相對偏移:將檔案結構資料中的絕對偏移改為相對偏移,使 Parquet 結構與位置無關。然而,這被視為對檔案格式的複雜變更。
  2. 內容定義的列群組:在列群組上實作內容定義分塊的支援。由於 Parquet 格式並不要求列群組大小一致,這可透過更新 Parquet 格式寫入器來實現,對現有格式的影響最小。

此外,Hugging Face 正在探索在上傳前可選擇性重寫 Parquet 檔案以去除絕對檔案偏移,並在下載時恢復的可能性。

Sources