【TF/Guide筆記】 10. GPU
????用戶(hù)可以限制GPU上的內(nèi)存使用,但這個(gè)限制并不是所謂的“優(yōu)化”,畢竟,如果有明顯能節(jié)省的內(nèi)存,框架干嘛非等你打開(kāi)開(kāi)關(guān)再去優(yōu)化它呢。
????tf提供了兩種限制內(nèi)存的方法,第一個(gè)是打開(kāi)增長(zhǎng)模式(set_memory_growth),我理解的是,一張計(jì)算圖上前后涉及很多的Variable,你可以指定當(dāng)一個(gè)Variable用完之后就析構(gòu)掉。這個(gè)優(yōu)化在默認(rèn)情況下不做,是因?yàn)橛?jì)算圖是batch級(jí)運(yùn)行的,需要重復(fù)跑很多次,如果Variable被析構(gòu)了,下次跑到這兒還得申請(qǐng)回來(lái),帶來(lái)額外開(kāi)銷(xiāo),所以需要用戶(hù)去做權(quán)衡。
????另一種方式是嚴(yán)格的限制內(nèi)存,可以虛擬一張GPU然后在上面運(yùn)行,給虛擬的GPU分配一個(gè)上限,那從外面來(lái)看你怎樣都不會(huì)超過(guò)這個(gè)值,只不過(guò)當(dāng)你真的必須要用更多的時(shí)候,程序就只能掛了。
????不得不說(shuō)虛擬device是個(gè)不錯(cuò)的東西,不僅能控制內(nèi)存,還可以在開(kāi)發(fā)環(huán)境模擬分布式。
????個(gè)人推測(cè),當(dāng)一個(gè)Variable的存放位置和計(jì)算圖的執(zhí)行device不一致的時(shí)候,計(jì)算圖會(huì)自動(dòng)連接一個(gè)fetch op,從另一個(gè)GPU也好,從CPU也好,甚至是另一臺(tái)機(jī)器上的device,對(duì)fetch op來(lái)說(shuō)都是一樣的,這樣底層實(shí)現(xiàn)的接口就會(huì)很統(tǒng)一,只需要根據(jù)兩頭的device和配置的協(xié)議選擇對(duì)應(yīng)op就行了。不過(guò)這樣的話,fetch的一方還好說(shuō),存Variable的那邊得有一個(gè)線程專(zhuān)門(mén)執(zhí)行fetch指令吧,那這個(gè)任務(wù)是在什么時(shí)候啟動(dòng)的就不一定了,而且難道說(shuō)worker上有完整的一套類(lèi)似ps的邏輯?
????在最后肯定還會(huì)有個(gè)類(lèi)似push的op,將改動(dòng)后的Variable放回ps,結(jié)合coordinator分發(fā)任務(wù)的模式來(lái)看,用戶(hù)很容易可以自己把一個(gè)計(jì)算圖拆分成很多段任務(wù),然后不斷的扔給worker去跑,把上游step的結(jié)果傳給下游,它應(yīng)該自己會(huì)找到對(duì)應(yīng)的Variable,也就是存在ps上的中間結(jié)果。這主要是為了應(yīng)對(duì)模型非常復(fù)雜,Variable多到本地跑一個(gè)step都存不下的情況。
????關(guān)于TPU,我去搜了一下這東西的工作原理,有一篇發(fā)布在谷歌云上的介紹寫(xiě)的還是蠻詳細(xì)的,給我的直觀感受是,這個(gè)東西也沒(méi)有想象中的那么技術(shù)壟斷。
????它內(nèi)部針對(duì)機(jī)器學(xué)習(xí)所做的優(yōu)化在論文里都有詳細(xì)的說(shuō)明,比如用8位整數(shù)代替浮點(diǎn)運(yùn)算,比如增加指令集,哪怕是不大好懂的脈動(dòng)陣列,感覺(jué)這些只要有硬件足夠扎實(shí)的人來(lái)當(dāng)設(shè)計(jì)師,咱們抄個(gè)作業(yè)應(yīng)該還是蠻容易的,迭代個(gè)兩三次,哪怕只有TPU八成的水平也足夠了,至少不是絕對(duì)的被壟斷了。目前華為似乎就有這種專(zhuān)門(mén)為AI研發(fā)的芯片,看來(lái)也不必太過(guò)悲觀。
????關(guān)于TPU這一節(jié)的文檔,在使用接口上跟GPU沒(méi)什么區(qū)別,但它反復(fù)強(qiáng)調(diào)了加速問(wèn)題。
????由于TPU跑起來(lái)實(shí)在是太快,以至于你的代碼可能沒(méi)法高效的使用它的硬件性能,例如他說(shuō)你單次的文件讀取至少要達(dá)到100M,最好一張計(jì)算圖直接運(yùn)行他100個(gè)batch,別一個(gè)一個(gè)的往上提交任務(wù)。
????文章里還介紹了一點(diǎn),由于TPU在設(shè)計(jì)上就是單線程的,所以它的運(yùn)行邏輯是非??煽氐?,coordinator可以非常準(zhǔn)確的計(jì)算出跑完當(dāng)前任務(wù)所需的時(shí)間,也就能夠更精準(zhǔn)的往TPU里喂任務(wù),保證TPU始終處在高效運(yùn)行的狀態(tài),減少整體任務(wù)的時(shí)間。但我相信這種優(yōu)化是在用戶(hù)端做的,比如一個(gè)熟練使用tf的人用各種trick來(lái)高效得到一個(gè)AlphaGo,而不是說(shuō)你隨手寫(xiě)個(gè)代碼框架就能給優(yōu)化成非常吊的樣子。