🔍 Huggingface dataset map increase disk space
我們在「【Hugging Face】Ep.3 前往Datasets掏金趣」有稍微介紹過Dataset在Hugging Face裡面扮演著什麼樣的角色,以及如何使用,沒錯! 它非常的好用,也很適合管理我們龐大的訓練資料,但… 過程中也有一些小細節需要非常注意,尤其實儲存策略與硬碟空間的規劃,硬體與軟體之間都息息相關,雖然過程曲折,但學習起來之後處理各式各樣的資料集我們都能夠得心應手,加快AI產品發展的進程,為公司帶來更大的營收。
硬碟A的空間有限並不允許我們處理過程中緩存。
故事是這樣的, 有一天大雄在進行Hugging Face進行資料處理時, 他使用到了「Process」來進行資料的轉換, 並且使用了.map()
來改變欄位的值, 大概是這樣操作:
def 改變語句內容(ds: DatasetDict) -> DatasetDict:
實作細節...
ds = DatasetDict.load_from_disk(f'{資料集儲存的位置}')
# 注意: load_from_cache_file=True
ds = ds.map(改變語句內容, num_proc=4)
這時大雄卻發現到奇怪, 為什麼「資料集儲存的位置」容量怎麼增加了一倍? 到底是為什麼呢? 看著一臉無助的小夫, 我們只好來好好的協助一番。
首先我們先來看看官方關於map
的參數說明: https://huggingface.co/docs/datasets/v2.14.0/en/package_reference/main_classes#datasets.Dataset.map
我們可以看到keep_in_memory
參數, 感覺可以將緩存指向記憶體, 也確實如此, 但會有一些副作用…
再來好好看看緩存的文件: https://huggingface.co/docs/datasets/v2.14.0/en/cache
從中我們也發現到disable_caching
, 真有辦法解決? 接下來我們也會依序實驗並給出幾個解決方案。
這種方式當然最好, 既能保留舊版數據, 也能保留新版數據, 做實驗時能夠相互比對, 做個依據, 但現實總是資金有限, 畢竟硬碟也是成本啊…。
ds = DatasetDict.load_from_disk(f'{舊資料集}')
# 注意: load_from_cache_file=True
ds = ds.map(改變語句內容, num_proc=4)
# 直接覆蓋原有資料集
ds.save_to_disk(f'{舊資料集}')
# 保險一點也可以這樣做...
# ds.save_to_disk(f'{新資料集}')
# rm -rf 舊資料集
# mv 新資料集 舊資料集位置
但這方式一樣會將資料載入到記憶體, 也需要注意到記憶體空間是否足夠的問題。
from datasets import disable_caching, enable_caching
disable_caching()
關閉後一樣的動作執行...
enable_caching()
我們可以設定keep_in_memory
參數, 讓快取導引到記憶體。
ds = ds.map(..., num_proc=4, keep_in_memory=True)
但這會有副作用, 如果記憶體空間不足可能影響到其他程式, 因此不建議這麼做, 而且從硬碟到記憶體的時間也是一個耗損。
Hugging Face的Dataset真的是處理訓練資料的好幫手, 但方便的背後還是有其代價的, 因此我們也應試著去了解一下背後的原理才能做出較佳的策略。
順道一題,本文的目標是以淺顯易懂的文章讓正在AI路上的夥伴能夠輕鬆理解問題與解決方法,讓我們一起加快腳步,過關斬將,迎向AI應用的那一哩路。
喜歡撰寫文章的你,不妨來了解一下:
Web3.0時代下為創作者、閱讀者打造的專屬共贏平台 — 為什麼要加入?
歡迎加入一起練習寫作,賺取知識