我們?cè)趨f(xié)助某AI客戶排查一個(gè)UFS文件存儲(chǔ)的性能case時(shí)發(fā)現(xiàn),其使用的Pytorch訓(xùn)練IO性能和硬件的IO能力有很大的差距(后面內(nèi)容有具體性能對(duì)比數(shù)據(jù))。 > 讓我們感到困惑的是: UFS文件存儲(chǔ),我們使用fio自測(cè)可以達(dá)到單實(shí)例最低10Gbps帶寬、IOPS也可達(dá)到2w以上。該AI客戶在高IOPS要求的AI單機(jī)小模型訓(xùn)練場(chǎng)景下,或者之前使用MXNet、TensorFlow框架時(shí),IO都能跑到UFS理論性能,甚至在大型分布式訓(xùn)練場(chǎng)景中,UFS也可以完全勝任。" />
摘要:我們?cè)趨f(xié)助某客戶排查一個(gè)文件存儲(chǔ)的性能時(shí)發(fā)現(xiàn),其使用的訓(xùn)練性能和硬件的能力有很大的差距后面內(nèi)容有具體性能對(duì)比數(shù)據(jù)。但直接緩存數(shù)據(jù)在集群規(guī)模上升之后肯定是不現(xiàn)實(shí)的,我們初步只緩存各個(gè)訓(xùn)練文件的句柄信息,以降低元數(shù)據(jù)訪問(wèn)開銷。
我們?cè)趨f(xié)助某AI客戶排查一個(gè)UFS文件存儲(chǔ)的性能case時(shí)發(fā)現(xiàn),其使用的Pytorch訓(xùn)練IO性能和硬件的IO能力有很大的差距(后面內(nèi)容有具體性能對(duì)比數(shù)據(jù))。
讓我們感到困惑的是: UFS文件存儲(chǔ),我們使用fio自測(cè)可以達(dá)到單實(shí)例最低10Gbps帶寬、IOPS也可達(dá)到2w以上。該AI客戶在高IOPS要求的AI單機(jī)小模型訓(xùn)練場(chǎng)景下,或者之前使用MXNet、TensorFlow框架時(shí),IO都能跑到UFS理論性能,甚至在大型分布式訓(xùn)練場(chǎng)景中,UFS也可以完全勝任。
于是我們開啟了和客戶的一次深度聯(lián)合排查。
基于上述情況,首先考慮是不是使用Pytorch的姿勢(shì)不對(duì)?參考網(wǎng)上提到經(jīng)驗(yàn),客戶調(diào)整batch_size、Dataloader等參數(shù)。
Batch_size
默認(rèn)batch_size為256,根據(jù)內(nèi)存和顯存配置嘗試更改batch_size大小,讓一次讀取數(shù)據(jù)更多,發(fā)現(xiàn)實(shí)際對(duì)效率沒(méi)有提升。通過(guò)分析是由于batch_size設(shè)置與數(shù)據(jù)讀取邏輯沒(méi)有直接關(guān)系,IO始終會(huì)保留單隊(duì)列與后端交互,不會(huì)降低網(wǎng)絡(luò)交互上的整體延時(shí)(因?yàn)橛玫氖荱FS文件存儲(chǔ),后面會(huì)講到為什么用)。
Pytorch Dataloader
Pytorch框架dataloader的worker負(fù)責(zé)數(shù)據(jù)的讀取和加載、分配。通過(guò)batch_sampler將batch數(shù)據(jù)分配給對(duì)應(yīng)的worker,由worker從磁盤讀取數(shù)據(jù)并加載數(shù)據(jù)到內(nèi)存,dataloader從內(nèi)存中讀取相應(yīng)batch做迭代訓(xùn)練。這里嘗試調(diào)整了worker_num參數(shù)為CPU核數(shù)或倍數(shù),發(fā)現(xiàn)提升有限,反而內(nèi)存和CPU的開銷提升了不少,整體加重了訓(xùn)練設(shè)備的負(fù)擔(dān),通過(guò) worker加載數(shù)據(jù)時(shí)的網(wǎng)絡(luò)開銷并不會(huì)降低,與本地SSD盤差距依然存在。
這個(gè)也不難理解,后面用strace排查的時(shí)候,看到CPU更多的時(shí)候在等待。
所以:從目前信息來(lái)看,調(diào)整Pytorch框架參數(shù)對(duì)性能幾乎沒(méi)有影響。
在客戶調(diào)整參數(shù)的同時(shí),我們也使用了三種存儲(chǔ)做驗(yàn)證,來(lái)看這里是否存在性能差異、差異到底有多大。在三種存儲(chǔ)產(chǎn)品上放上同樣的數(shù)據(jù)集:
測(cè)試結(jié)果,如下圖:
注:SSHFS基于X86物理機(jī)(32核/64G/480G SSD*6 raid10)搭建,網(wǎng)絡(luò)25Gbps
結(jié)論:通過(guò)對(duì)存儲(chǔ)性能實(shí)測(cè), UFS文件存儲(chǔ)較本地盤、單機(jī)SSHFS性能差距較大。
為什么會(huì)選用這兩種存儲(chǔ)(SSHFS和本地SSD)做UFS性能對(duì)比?
當(dāng)前主流存儲(chǔ)產(chǎn)品的選型上分為兩類:自建SSHFS/NFS或采用第三方NAS服務(wù)(類似UFS產(chǎn)品),個(gè)別場(chǎng)景中也會(huì)將需要的數(shù)據(jù)下載到本地SSD盤做訓(xùn)練。傳統(tǒng)SSD本地盤擁有極低的IO延時(shí),一個(gè)IO請(qǐng)求處理基本會(huì)在us級(jí)別完成,針對(duì)越小的文件,IO性能越明顯。受限于單臺(tái)物理機(jī)配置,無(wú)法擴(kuò)容,數(shù)據(jù)基本 “即用即棄”。而數(shù)據(jù)是否安全也只能依賴磁盤的穩(wěn)定性,一旦發(fā)生故障,數(shù)據(jù)恢復(fù)難度大。但是鑒于本地盤的優(yōu)勢(shì),一般也會(huì)用作一些較小模型的訓(xùn)練,單次訓(xùn)練任務(wù)在較短時(shí)間即可完成,即使硬件故障或者數(shù)據(jù)丟失導(dǎo)致訓(xùn)練中斷,對(duì)業(yè)務(wù)影響通常較小。
用戶通常會(huì)使用SSD物理機(jī)自建SSHFS/NFS共享文件存儲(chǔ),數(shù)據(jù)IO會(huì)通過(guò)以太網(wǎng)絡(luò),較本地盤網(wǎng)絡(luò)上的開銷從us級(jí)到ms級(jí),但基本可以滿足大部分業(yè)務(wù)需求。但用戶需要在日常使用中同時(shí)維護(hù)硬件和軟件的穩(wěn)定性,并且單臺(tái)物理機(jī)有存儲(chǔ)上限,如果部署多節(jié)點(diǎn)或分布式文件系統(tǒng)也會(huì)導(dǎo)致更大運(yùn)維精力投入。
我們把前面結(jié)論放到一起看:
3、Pytorch+UFS的場(chǎng)景下, UFS文件存儲(chǔ)較本地SSD盤、單機(jī)SSHFS性能差距大。
結(jié)合以上幾點(diǎn)信息并與用戶確認(rèn)后的明確結(jié)論:
UFS結(jié)合非Pytorch框架使用沒(méi)有性能瓶頸, Pytorch框架下用本地SSD盤沒(méi)有性能瓶頸,用SSHFS性能可接受。那原因就很明顯了,就是Pytorch+UFS文件存儲(chǔ)這個(gè)組合存在IO性能問(wèn)題。
看到這里,大家可能會(huì)有個(gè)疑問(wèn):是不是不用UFS,用本地盤就解決了?
答案是不行,原因是訓(xùn)練所需的數(shù)據(jù)總量很大,很容易超過(guò)了單機(jī)的物理介質(zhì)容量,另外也出于數(shù)據(jù)安全考慮,存放單機(jī)有丟失風(fēng)險(xiǎn),而UFS是三副本的分布式存儲(chǔ)系統(tǒng),并且UFS可以提供更彈性的IO性能。
根據(jù)以上的信息快速排查3個(gè)結(jié)論,基本上可以判斷出: Pytorch在讀UFS數(shù)據(jù)過(guò)程中,文件讀取邏輯或者UFS存儲(chǔ)IO耗時(shí)導(dǎo)致。于是我們通過(guò)strace觀察Pytorch讀取數(shù)據(jù)整體流程:
通過(guò)strace發(fā)現(xiàn),CV2方式讀取UFS里的文件(NFSV4協(xié)議)有很多次SEEK動(dòng)作,即便是單個(gè)小文件的讀取也會(huì)“分片”讀取,從而導(dǎo)致了多次不必要的IO讀取動(dòng)作,而最耗時(shí)的則是網(wǎng)絡(luò),從而導(dǎo)致整體耗時(shí)成倍增長(zhǎng)。這也是符合我們的猜測(cè)。
簡(jiǎn)單介紹一下NFS協(xié)議特點(diǎn):
NAS所有的IO都需要經(jīng)過(guò)以太網(wǎng),一般局域網(wǎng)內(nèi)延時(shí)在1ms以內(nèi)。以NFS數(shù)據(jù)交互為例,通過(guò)圖中可以看出,針對(duì)一次完整的小文件IO操作將涉及元數(shù)據(jù)查詢、數(shù)據(jù)傳輸?shù)戎辽?次網(wǎng)絡(luò)交互,每次交互都會(huì)涉及到client與server集群的一個(gè)TTL,其實(shí)這樣的交互邏輯會(huì)存在一個(gè)問(wèn)題,當(dāng)單文件越小、數(shù)量越大時(shí)則延時(shí)問(wèn)題將越明顯,IO過(guò)程中有過(guò)多的時(shí)間消耗在網(wǎng)絡(luò)交互,這也是NAS類存儲(chǔ)在小文件場(chǎng)景下面臨的經(jīng)典問(wèn)題。
對(duì)于UFS的架構(gòu)而言,為了達(dá)到更高擴(kuò)展性、更便利的維護(hù)性、更高的容災(zāi)能力,采用接入層、索引層和數(shù)據(jù)層的分層架構(gòu)模式,一次IO請(qǐng)求會(huì)先經(jīng)過(guò)接入層做負(fù)載均衡,client端再訪問(wèn)后端UFS索引層獲取到具體文件信息,最后訪問(wèn)數(shù)據(jù)層獲取實(shí)際文件,對(duì)于KB級(jí)別的小文件,實(shí)際在網(wǎng)絡(luò)上的耗時(shí)比單機(jī)版NFS/SSHFS會(huì)更高。
從Pytorch框架下兩種讀圖接口來(lái)看:CV2讀取文件會(huì)“分片”進(jìn)行,而PIL雖然不會(huì)“分片”讀取,但是基于UFS分布式架構(gòu),一次IO會(huì)經(jīng)過(guò)接入、索引、數(shù)據(jù)層,網(wǎng)絡(luò)耗時(shí)也占比很高。我們存儲(chǔ)同事也實(shí)際測(cè)試過(guò)這2種方法的性能差異:通過(guò)strace發(fā)現(xiàn),相比OpenCV的方式,PIL的數(shù)據(jù)讀取邏輯效率相對(duì)高一些。
通過(guò)對(duì)Pytorch框架接口和模塊的調(diào)研,如果使用 OpenCV方式讀取文件可以用2個(gè)方法, cv2.imread和cv2.imdecode。
默認(rèn)一般會(huì)用cv2.imread方式,讀取一個(gè)文件時(shí)會(huì)產(chǎn)生9次lseek和11次read,而對(duì)于圖片小文件來(lái)說(shuō)多次lseek和read是沒(méi)有必要的。cv2.imdecode可以解決這個(gè)問(wèn)題,它通過(guò)一次性將數(shù)據(jù)加載進(jìn)內(nèi)存,后續(xù)的圖片操作需要的IO轉(zhuǎn)化為內(nèi)存訪問(wèn)即可。
兩者的在系統(tǒng)調(diào)用上的對(duì)比如下圖:
我們通過(guò)使用cv2.imdecode方式替換客戶默認(rèn)使用的cv2.imread方式,單個(gè)文件的總操作耗時(shí)從12ms下降到6ms。但是內(nèi)存無(wú)法cache住過(guò)大的數(shù)據(jù)集,不具備任意規(guī)模數(shù)據(jù)集下的訓(xùn)練,但是整體讀取性能還是提升明顯。使用cv2版本的benchmark對(duì)一個(gè)小數(shù)據(jù)集進(jìn)行加載測(cè)試后的各場(chǎng)景耗時(shí)如下(延遲的非線性下降是因?yàn)槠渲邪珿PU計(jì)算時(shí)間):
通過(guò)PIL方式讀取單張圖片的方式,Pytorch處理的平均延遲為7ms(不含IO時(shí)間),單張圖片讀取(含IO和元數(shù)據(jù)耗時(shí))平均延遲為5-6ms,此性能水平還有優(yōu)化空間。
由于訓(xùn)練過(guò)程會(huì)進(jìn)行很多個(gè)epoch的迭代,而每次迭代都會(huì)進(jìn)行數(shù)據(jù)的讀取,這部分操作從多次訓(xùn)練任務(wù)上來(lái)看是重復(fù)的,如果在訓(xùn)練時(shí)由本地內(nèi)存做一些緩存策略,對(duì)性能應(yīng)該有提升。但直接緩存數(shù)據(jù)在集群規(guī)模上升之后肯定是不現(xiàn)實(shí)的,我們初步只緩存各個(gè)訓(xùn)練文件的句柄信息,以降低元數(shù)據(jù)訪問(wèn)開銷。
我們修改了Pytorch的dataloader實(shí)現(xiàn),通過(guò)本地內(nèi)存cache住訓(xùn)練需要使用的文件句柄,可以避免每次都嘗試做open操作。測(cè)試后發(fā)現(xiàn)1w張圖片通過(guò)100次迭代訓(xùn)練后發(fā)現(xiàn),單次迭代的耗時(shí)已經(jīng)基本和本地SSD持平。但是當(dāng)數(shù)據(jù)集過(guò)大,內(nèi)存同樣無(wú)法cache住所有元數(shù)據(jù),所以使用場(chǎng)景相對(duì)有限,依然不具備在大規(guī)模數(shù)據(jù)集下的訓(xùn)練伸縮性。
以上client端的優(yōu)化效果比較明顯,但是客戶業(yè)務(wù)側(cè)需要更改少量訓(xùn)練代碼,最主要是client端無(wú)法滿足較大數(shù)據(jù)量的緩存,應(yīng)用場(chǎng)景有限,我們繼續(xù)從server端優(yōu)化,盡量降低整個(gè)鏈路上的交互頻次。
正常IO請(qǐng)求通過(guò)負(fù)載均衡到達(dá)索引層時(shí),會(huì)先經(jīng)過(guò)索引接入server,然后到索引數(shù)據(jù)server??紤]到訓(xùn)練場(chǎng)景具有目錄訪問(wèn)的空間局部性,我們決定增強(qiáng)元數(shù)據(jù)預(yù)取的功能。通過(guò)客戶請(qǐng)求的文件,引入該文件及相應(yīng)目錄下所有文件的元數(shù)據(jù),并預(yù)取到索引接入server,后續(xù)的請(qǐng)求將命中緩存,從而減少與索引數(shù)據(jù)server的交互,在IO請(qǐng)求到達(dá)索引層的第一步即可獲取到對(duì)應(yīng)元數(shù)據(jù),從而降低從索引數(shù)據(jù)server進(jìn)行查詢的開銷。
經(jīng)過(guò)這次優(yōu)化之后,元數(shù)據(jù)操作的延遲較最初能夠下降一倍以上,在客戶端不做更改的情況下,讀取小文件性能已達(dá)到本地SSD盤的50%??磥?lái)單單優(yōu)化server端還是無(wú)法滿足預(yù)期,通過(guò)執(zhí)行Pytorch的benchmark程序,我們得到UFS和本地SSD盤在整個(gè)數(shù)據(jù)讀取耗時(shí)。
此時(shí)很容易想到一個(gè)問(wèn)題:非Pytorch框架在使用UFS做訓(xùn)練集存儲(chǔ)時(shí),為什么使用中沒(méi)有遇到IO性能瓶頸?
通過(guò)調(diào)研其他框架的邏輯發(fā)現(xiàn):無(wú)論是MXNet的rec文件,Caffe的LMDB,還是TensorFlow的npy文件,都是在訓(xùn)練前將大量圖片小文件轉(zhuǎn)化為特定的數(shù)據(jù)集格式,所以使用UFS在存儲(chǔ)網(wǎng)絡(luò)交互更少,相對(duì)Pytorch直接讀取目錄小文件的方式,避免了大部分網(wǎng)絡(luò)上的耗時(shí)。這個(gè)區(qū)別在優(yōu)化時(shí)給了我們很大的啟示,將目錄樹級(jí)別小文件轉(zhuǎn)化成一個(gè)特定的數(shù)據(jù)集存儲(chǔ),在讀取數(shù)據(jù)做訓(xùn)練時(shí)將IO發(fā)揮出最大性能優(yōu)勢(shì)。
基于其他訓(xùn)練框架數(shù)據(jù)集的共性功能,我們UFS存儲(chǔ)團(tuán)隊(duì)趕緊開工,幾天開發(fā)了針對(duì)Pytorch框架下的數(shù)據(jù)集轉(zhuǎn)換工具,將小文件數(shù)據(jù)集轉(zhuǎn)化為UFS大文件數(shù)據(jù)集并對(duì)各個(gè)小文件信息建立索引記錄到index文件,通過(guò)index文件中索引偏移量可隨機(jī)讀取文件,而整個(gè)index文件在訓(xùn)練任務(wù)啟動(dòng)時(shí)一次性加載到本地內(nèi)存,這樣就將大量小文件場(chǎng)景下的頻繁訪問(wèn)元數(shù)據(jù)的開銷完全去除了,只剩下數(shù)據(jù)IO的開銷。該工具后續(xù)也可直接應(yīng)用于其他AI類客戶的訓(xùn)練業(yè)務(wù)。
工具的使用很簡(jiǎn)單,只涉及到兩步:
20行:新增from my_dataloader import *
205行:train_dataset = datasets.ImageFolder改為train_dataset = MyImageFolder
224行:datasets.ImageFolder改為MyImageFolder
通過(guò)github上Pytorch測(cè)試demo對(duì)imagenet數(shù)據(jù)集進(jìn)行5、10、20小時(shí)模擬訓(xùn)練,分別讀取不同存儲(chǔ)中的數(shù)據(jù),具體看下IO對(duì)整體訓(xùn)練速度的影響。(數(shù)據(jù)單位:完成的epoch的個(gè)數(shù))
測(cè)試條件:
GPU服務(wù)器:P404物理機(jī),48核256G,數(shù)據(jù)盤800G6 SATA SSD RAID10
SSHFS:X86物理機(jī)32核/64G,數(shù)據(jù)盤480G*6 SATA SSD RAID10
Demo:https://github.com/pytorch/examples/tree/master/imagenet
數(shù)據(jù)集:總大小148GB、圖片文件數(shù)量120w以上
通過(guò)實(shí)際結(jié)果可以看出: UFS數(shù)據(jù)集方式效率已經(jīng)達(dá)到甚至超過(guò)本地SSD磁盤的效果。而UFS數(shù)據(jù)集轉(zhuǎn)化方式,客戶端內(nèi)存中只有少量目錄結(jié)構(gòu)元數(shù)據(jù)緩存,在100TB數(shù)據(jù)的體量下,元數(shù)據(jù)小于10MB,可以滿足任意數(shù)據(jù)規(guī)模,對(duì)于客戶業(yè)務(wù)上的硬件使用無(wú)影響。
針對(duì)Pytorch小文件訓(xùn)練場(chǎng)景,UFS通過(guò)多次優(yōu)化,吞吐性能已得到極大提升,并且在后續(xù)產(chǎn)品規(guī)劃中,我們也會(huì)結(jié)合現(xiàn)有RDMA網(wǎng)絡(luò)、SPDK等存儲(chǔ)相關(guān)技術(shù)進(jìn)行持續(xù)優(yōu)化。詳細(xì)請(qǐng)?jiān)L問(wèn):https://docs.ucloud.cn/storage_cdn/ufs/overview
本文作者:UCloud 解決方案架構(gòu)師 馬杰
歡迎各位與我們交流有關(guān)云計(jì)算的一切~~~
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/126012.html
摘要:宋體是一款自主研發(fā)的分布式文件存儲(chǔ)產(chǎn)品,此前已推出容量型版本。宋體性能的提升不僅僅是因?yàn)榇鎯?chǔ)介質(zhì)的升級(jí),更有架構(gòu)層面的改進(jìn),本文將從協(xié)議索引存儲(chǔ)設(shè)計(jì)等幾方面來(lái)詳細(xì)介紹性能型升級(jí)改造的技術(shù)細(xì)節(jié)。UFS (UCloud File System) 是一款 UCloud 自主研發(fā)的分布式文件存儲(chǔ)產(chǎn)品,此前已推出容量型 UFS 版本。UFS 以其彈性在線擴(kuò)容、穩(wěn)定可靠的特點(diǎn),為眾多公有云、物理云、托管...
摘要:概覽概覽產(chǎn)品簡(jiǎn)介什么是訓(xùn)練服務(wù)交互式訓(xùn)練分布式訓(xùn)練分布式訓(xùn)練簡(jiǎn)介分布式訓(xùn)練分布式訓(xùn)練產(chǎn)品優(yōu)勢(shì)產(chǎn)品更新記錄產(chǎn)品定價(jià)快速上手開始使用快速上手案例介紹環(huán)境準(zhǔn)備創(chuàng)建鏡像倉(cāng)庫(kù) 概覽產(chǎn)品簡(jiǎn)介什么是AI訓(xùn)練服務(wù)交互式訓(xùn)練分布式訓(xùn)練分布式訓(xùn)練簡(jiǎn)介TensorFlow分布式訓(xùn)練MXNet分布式訓(xùn)練產(chǎn)品優(yōu)勢(shì)產(chǎn)品更新記錄產(chǎn)品定價(jià)快速上手開始使用UAI-Train快速上手-MNIST案例MNIST 介紹環(huán)境準(zhǔn)備創(chuàng)建...
摘要:第一個(gè)深度學(xué)習(xí)框架該怎么選對(duì)于初學(xué)者而言一直是個(gè)頭疼的問(wèn)題。簡(jiǎn)介和是頗受數(shù)據(jù)科學(xué)家歡迎的深度學(xué)習(xí)開源框架。就訓(xùn)練速度而言,勝過(guò)對(duì)比總結(jié)和都是深度學(xué)習(xí)框架初學(xué)者非常棒的選擇。 「第一個(gè)深度學(xué)習(xí)框架該怎么選」對(duì)于初學(xué)者而言一直是個(gè)頭疼的問(wèn)題。本文中,來(lái)自 deepsense.ai 的研究員給出了他們?cè)诟呒?jí)框架上的答案。在 Keras 與 PyTorch 的對(duì)比中,作者還給出了相同神經(jīng)網(wǎng)絡(luò)在不同框...
摘要:幸運(yùn)的是,這些正是深度學(xué)習(xí)所需的計(jì)算類型。幾乎可以肯定,英偉達(dá)是目前執(zhí)行深度學(xué)習(xí)任務(wù)較好的選擇。今年夏天,發(fā)布了平臺(tái)提供深度學(xué)習(xí)支持。該工具適用于主流深度學(xué)習(xí)庫(kù)如和。因?yàn)榈暮?jiǎn)潔和強(qiáng)大的軟件包擴(kuò)展體系,它目前是深度學(xué)習(xí)中最常見的語(yǔ)言。 深度學(xué)習(xí)初學(xué)者經(jīng)常會(huì)問(wèn)到這些問(wèn)題:開發(fā)深度學(xué)習(xí)系統(tǒng),我們需要什么樣的計(jì)算機(jī)?為什么絕大多數(shù)人會(huì)推薦英偉達(dá) GPU?對(duì)于初學(xué)者而言哪種深度學(xué)習(xí)框架是較好的?如何將...
閱讀 3546·2023-04-25 20:09
閱讀 3745·2022-06-28 19:00
閱讀 3066·2022-06-28 19:00
閱讀 3092·2022-06-28 19:00
閱讀 3185·2022-06-28 19:00
閱讀 2886·2022-06-28 19:00
閱讀 3057·2022-06-28 19:00
閱讀 2642·2022-06-28 19:00