windows下A卡、I卡跑AI的救星:DirectML煉丹指南

摘要:當(dāng)今硬件,N卡獨(dú)占AI鰲頭,而為了防止用戶拿普通游戲卡用于AI用途,英偉達(dá)很貼心地削弱了40系顯卡的顯存規(guī)格。本該給48G才能充分發(fā)揮核心優(yōu)勢(shì)的4090只給了24G,還取消了所有非計(jì)算卡的NVLINK。
So NVIDIA...
AMD這邊7900XTX擁有得天獨(dú)厚的24G顯存,理論計(jì)算速度在4070ti至4080,但價(jià)格僅為7k出頭,那么,如果我手上的是一張7900xtx,我是否可以用它來進(jìn)行AI訓(xùn)練,來節(jié)約一定的成本呢?
又或者我手上有一張A77016G,目前性價(jià)比極高的16G顯卡,單精度能跑到P100的兩倍,我能拿它來煉丹嗎?
更有甚至,我用的是爾英的筆記本核心桌面主板,CUDA0位置上的卡已經(jīng)在跑了,但我這還有個(gè)96EU的核顯,我這有個(gè)雞哥的無界14給了7840HS,核顯單精度性能快9Tflops了,能頂一張P10,那么我該怎么利用這些核顯扛起我們煉丹的大旗呢?
在lx端,有opencl,是torch官方支持的硬件接口,windows端,則由微軟提供的DML來提供這條計(jì)算速度起飛的“跑道”。本教程將通過英特爾核顯UHD620作為例子,以展示通過DML進(jìn)行模型訓(xùn)練的環(huán)境配置。
關(guān)鍵詞:GPU加速、AI訓(xùn)練、DML
第1章 設(shè)備配置要求
1.1 顯卡選擇
? ? ? 對(duì)于顯卡類型的選擇,在windows環(huán)境下,一張符合微軟DirectX標(biāo)準(zhǔn)的顯卡顯然是使用DML接口煉丹的充分必要條件,目前市面上大多數(shù)顯卡都符合該標(biāo)準(zhǔn),都可以作為DML的煉丹卡。
? ? ? 在不確定自己的顯卡是否支持DML時(shí),可下載gpuz:GPU-Z Graphics Card GPU Information Utility (techpowerup.com)
? ? ? 安裝并進(jìn)入軟件后,如下所示:

? ? ? ?下方DirctML前面的方框中打勾,說明這張顯卡可以進(jìn)行接下來的DML配置,以參與到模型訓(xùn)練中。
? ? ? ?對(duì)于一些低計(jì)算能力的顯卡,如果想比較其性能與CPU相比誰勝誰負(fù),可參考:關(guān)于CPU的浮點(diǎn)運(yùn)算能力計(jì)算 - 簡書 (jianshu.com),因此,對(duì)目前常見的CPU,沒有必要為了所謂的“快一點(diǎn)”而特意選配一些老古董級(jí)別的顯卡。而且,由于DML接口需要CPU進(jìn)行邏輯性的處理,使用DML時(shí),“顯卡偷U”的現(xiàn)象很明顯,因此進(jìn)行DML加速的顯卡最好要比CPU強(qiáng)。
?1.2 內(nèi)存選擇
? ? ? 對(duì)于使用核顯或者有計(jì)劃超顯存使用顯卡的DML用戶,內(nèi)存應(yīng)盡量大,頻率應(yīng)盡量高,由于DML接口由windows操作系統(tǒng)直接進(jìn)行調(diào)度,因此通過該辦法可以使用“共享GPU內(nèi)存”來擴(kuò)增顯存,提高吞吐量,綜合顯存帶寬由顯存和內(nèi)存的使用部分加權(quán)乘以各自的等效帶寬而來,因此,有使用高頻內(nèi)存的必要。內(nèi)存的選擇至少應(yīng)該大于8G以保證操作系統(tǒng)正常運(yùn)行,同時(shí),如果需要“小馬拉大車”,還應(yīng)大于顯存容量+8G。
第2章 環(huán)境配置
2.1 python版本選擇
? ? ??目前,pytorch_directml支持的最大python版本為3.10,本教程選擇該版本python作為解釋器使用。
? ? ? 在anaconda環(huán)境下,可以通過輸入:
conda create?-n 此次填寫環(huán)境名字 python==3.10.x(x為任意版本,視需要而定,但通常來講,一個(gè)大版本內(nèi)的python區(qū)別不大)
指令來創(chuàng)建環(huán)境。
2.2 pytorch_directml版本選擇
? ? ? 進(jìn)入微軟torch下的DirectML倉庫,以獲得torch_dircetml:DirectML/PyTorch at master · microsoft/DirectML · GitHub
? ? ??

其中,1.13版本以后的torch需要搭配0.1.13+的torch_directml,1.8以下的需要搭配1.8.0a0的torch_directml。這兩個(gè)版本前者作為一個(gè)獨(dú)立的三方包,提供一個(gè)torch和一個(gè)torch_directml,torch版本視下載的torch_directml而定,0.2.0版本附帶的是2.0.0+cpu版本的torch。(細(xì)心的你可能已經(jīng)發(fā)現(xiàn)了torch_directml版本和torch版本間的關(guān)系)
后者則默認(rèn)附帶一個(gè)魔改版的1.8.0的torch。
第3章 使用方法與效果
3.1 使用方法
? ? ? ?對(duì)于1 .8 版本的torch_directml:
? ???? 查找dml設(shè)備是否可用:torch.dml.is_available()
? ?? ? 查找dml設(shè)備名稱:torch.dml.device_name(),括號(hào)內(nèi)填寫設(shè)備序號(hào)
? ? ? ?調(diào)用dml設(shè)備:torch.dml.device(),括號(hào)內(nèi)填寫設(shè)備序號(hào)
? ? ? ?對(duì)于1.13之后的版本:
? ? ? ?查找dml設(shè)備是否可用:torch_directml.is_available()
? ???? 查找dml設(shè)備名稱:torch_directml.device_name(),括號(hào)內(nèi)填寫設(shè)備序號(hào)
? ? ? ?調(diào)用dml設(shè)備:torch_directml.device(),括號(hào)內(nèi)填寫設(shè)備序號(hào)
3.2 使用案例
#如下為python代碼
import torch_directml
import torch
import time
a=torch.randn(40000000,1).cpu()
b=torch.randn(40000000,1).cpu()
t0=time.time()
c=a*b
print(c)
print(time.time()-t0)
a=a.to(dtype=torch.float32,device=torch_directml.device(1))
b=b.to(dtype=torch.float32,device=torch_directml.device(1))
t1=time.time()
d=a*b
print(d)
print(time.time()-t1)
#代碼結(jié)尾
運(yùn)行效果:

由于UHD620單精度性能僅有384GFlops,低于8250U短時(shí)睿頻的435.2GFlops,且需要調(diào)用雙倍內(nèi)存來處理設(shè)備化的數(shù)組與等待DML接口處理和相應(yīng),內(nèi)存也到達(dá)了這臺(tái)電腦的瓶頸,因此,這顆核顯比CPU慢。將數(shù)組大小擴(kuò)大至80000000*2后,核顯跟cpu用時(shí)的比例進(jìn)一步下降:

計(jì)算時(shí)的系統(tǒng)狀態(tài):
