深度學習GPU基準測試徹底改變了我們解決複雜問題的方式,從圖像識別到自然語言處理。但是,在培訓這些模型時,通常依賴於高性能的GPU,將它們有效地部署在資源受限的環境中,例如邊緣設備或有限的硬件系統提出了獨特的挑戰。 CPU,廣泛可用且具有成本效益,通常是在這種情況下推斷的骨幹。但是,我們如何確保部署在CPU上的模型在不損害準確性的情況下提供最佳性能?
本文深入研究了對CPU的深度學習模型推斷的基準測試,重點介紹了三個關鍵指標:延遲,CPU利用率和內存利用率。使用垃圾郵件分類示例,我們探討了Pytorch,Tensorflow,Jax和ONNX運行時手柄推理工作負載等流行框架。最後,您將對如何衡量性能,優化部署並為資源受限環境中的基於CPU推斷的推理選擇正確的工具和框架有清晰的了解。
影響:最佳推理執行可以節省大量資金,並為其他工作量提供免費資源。
本文作為數據科學博客馬拉鬆的一部分發表。
推理速度對於用戶體驗和機器學習應用程序的運營效率至關重要。運行時優化在通過簡化執行來增強它方面起著關鍵作用。使用諸如ONNX運行時的硬件加速庫會利用針對特定體系結構的優化,減少延遲(每次推理時間)。
此外,輕巧的模型格式,例如ONNX最小化開銷,從而更快地加載和執行。優化的運行時間利用並行處理來在可用的CPU內核上分發計算並改善內存管理,從而確保更好的性能,尤其是在資源有限的系統上。這種方法使模型在保持準確性的同時更快,更有效。
為了評估模型的性能,我們專注於三個關鍵指標:
為了保持這項基準研究的重點和實用,我們做出了以下假設並設定了一些界限:
這些假設確保基準與使用資源受限硬件的開發人員和團隊相關,或者需要可預測的性能而沒有分佈式系統的複雜性。
我們將探討用於基準和優化CPU的深度學習模型推斷的基本工具和框架,從而提供了對其能力的見解,以在資源受限的環境中有效執行。
我們正在利用github codespace(虛擬機),以下配置:
所使用的包裝的版本如下,此主要包括五個深度學習推理庫:Tensorflow,Pytorch,Onnx Runtime,Jax和OpenVino:
!pip安裝numpy == 1.26.4 !pip安裝火炬== 2.2.2 !PIP安裝TensorFlow == 2.16.2 !pip安裝onnx == 1.17.0 !pip安裝onnxRuntime == 1.17.0! !pip安裝jaxlib == 0.4.30 !PIP安裝OpenVino == 2024.6.0 !pip安裝matplotlib == 3.9.3 !pip安裝matplotlib:3.4.3 !PIP安裝枕頭:8.3.2 !pip安裝psutil:5.8.0
由於模型推斷包括在網絡權重和輸入數據之間執行一些矩陣操作,因此它不需要模型培訓或數據集。對於我們的示例,我們模擬了標準分類用例。這模擬了常見的二進制分類任務,例如垃圾郵件檢測和貸款申請決策(批准或拒絕)。這些問題的二進制性質使它們是比較不同框架模型性能的理想選擇。該設置反映了現實世界中的系統,但使我們能夠將重點放在跨框架的推理性能上,而無需大型數據集或預訓練的模型。
樣本任務涉及根據一組輸入功能預測給定樣本是垃圾郵件(貸款批准還是拒絕)。這個二進制分類問題在計算上是有效的,可以重點分析推理性能,而沒有多類分類任務的複雜性。
為了模擬現實世界電子郵件數據,我們生成了隨機輸入。這些嵌入模仿垃圾郵件過濾器可能處理的數據類型,但避免了對外部數據集的需求。該模擬輸入數據允許在不依賴任何特定外部數據集的情況下進行基準測試,這是測試模型推理時間,內存使用情況和CPU性能的理想選擇。另外,您可以使用圖像分類,NLP任務或任何其他深度學習任務來執行此基準測試過程。
模型選擇是基準測試的關鍵步驟,因為它直接影響了從分析過程中獲得的推理性能和見解。如上一節所述,對於這項基準測試研究,我們選擇了標準分類用例,其中涉及確定給定的電子郵件是否是垃圾郵件。此任務是一個直接的兩類分類問題,它在計算上有效,但為跨框架進行比較提供了有意義的結果。
分類任務的模型是為二進制分類設計的饋電神經網絡(FNN)(垃圾郵件與垃圾郵件)。它由以下層組成:
self.fc1 = torch.nn.linear(200,128)
self.fc2 = torch.nn.linear(128,64) self.fc3 = torch.nn.linear(64,32) self.fc4 = torch.nn.linear(32,16) self.fc5 = torch.nn.linear(16,8) self.fc6 = torch.nn.linear(8,1)
self.sigmoid = torch.nn.sigmoid()
該模型對於分類任務很簡單,但有效。
在我們的用例中用於基準測試的模型體系結構圖如下所示:
該工作流旨在比較使用分類任務的多個深度學習框架(Tensorflow,Pytorch,Onnx,Jax和OpenVino)的推理性能。該任務涉及使用隨機生成的輸入數據並根據每個框架進行基準測試以測量預測所花費的平均時間。
為了開始基準測試深度學習模型,我們首先需要導入實現無縫集成和性能評估的基本Python軟件包。
進口時間 導入操作系統 導入numpy作為NP 導入火炬 導入TensorFlow作為TF 來自TensorFlow.keras導入輸入 導入OnnxRuntime AS Ort 導入matplotlib.pyplot作為PLT 從PIL導入圖像 導入psutil 導入JAX 導入jax.numpy作為jnp 來自OpenVino.runtime Import Core 導入CSV
os.environ [“ cuda_visible_devices”] =“ -1”#disable gpu os.environ [“ tf_cpp_min_log_level”] =“ 3” #suppress tensorflow log
在此步驟中,我們隨機生成用於垃圾郵件分類的輸入數據:
我們使用Numpy生成Randome數據,以作為模型的輸入功能。
#Generate虛擬數據 input_data = np.random.rand(1000,200).stype(np.float32)
在此步驟中,我們從每個深度學習框架(Tensorflow,Pytorch,Onnx,Jax和OpenVino)定義NetWrok體系結構或設置模型。每個框架都需要一種特定的方法來加載模型並將其設置為推斷。
Pytorchmodel類(Torch.nn.Module): def __init __(自我): 超級(pytorchmodel,self).__ init __() self.fc1 = torch.nn.linear(200,128) self.fc2 = torch.nn.linear(128,64) self.fc3 = torch.nn.linear(64,32) self.fc4 = torch.nn.linear(32,16) self.fc5 = torch.nn.linear(16,8) self.fc6 = torch.nn.linear(8,1) self.sigmoid = torch.nn.sigmoid() def向前(self,x): x = torch.relu(self.fc1(x)) x = torch.relu(self.fc2(x)) x = torch.relu(self.fc3(x)) x = torch.relu(self.fc4(x)) x = torch.relu(self.fc5(x)) x = self.sigmoid(self.fc6(x)) 返回x #創建Pytorch模型 pytorch_model = pytorchmodel()
tensorflow_model = tf.keras.Sequeential([[ 輸入(Shape =(200,)), tf.keras.layers.dense(128,激活='relu'), tf.keras.layers.dense(64,activation ='relu'), tf.keras.layers.dense(32,activation ='relu'), tf.keras.layers.dense(16,activation ='relu'), tf.keras.layers.dense(8,activation ='relu'), tf.keras.layers.dense(1,激活='Sigmoid') ))) tensorflow_model.compile()
def jax_model(x): x = jax.nn.relu(jnp.dot(x,jnp.ones((200,128))))))) x = jax.nn.relu(jnp.dot(x,jnp.ones(((128,64)))))))) x = jax.nn.relu(jnp.dot(x,jnp.ones((64,32)))))))) x = jax.nn.relu(jnp.dot(x,jnp.ones((32,16)))))))) x = jax.nn.relu(jnp.dot(x,jnp.ones((16,8)))))) x = jax.nn.sigmoid(jnp.dot(x,jnp.ones((8,1))))))) 返回x
#將Pytorch型號轉換為ONNX dummy_input = torch.randn(1,200) onnx_model_path =“ model.onnx” TORCH.ONNX.EXPORT( pytorch_model, dummy_input, onnx_model_path, export_params = true, opset_version = 11, input_names = ['input'], output_names = ['輸出'], dynamic_axes = {'input':{0:'batch_size'},'output':{0:'batch_size'}}} ) onnx_session = ort.inferencesession(onnx_model_path)
#OpenVino模型定義 core = core() OpenVino_model = core.Read_model(model =“ model.onnx”) compiled_model = core.compile_model(openvino_model,device_name =“ cpu”)
該功能通過採用三個參數來執行跨不同框架的基準測試:prection_function,input_data和num_runs。默認情況下,它執行1000次,但可以根據要求增加。
def benchmark_model(prection_function,input_data,num_runs = 1000): start_time = time.time() process = psutil.process(os.getPid()) cpu_usage = [] memory_usage = [] 對於_範圍(num_runs): preditive_function(input_data) cpu_usage.append(process.cpu_percent()) memory_usage.append(process.memory_info()。rss) end_time = time.time() avg_latency =(end_time -start_time) / num_runs avg_cpu = np.mean(cpu_usage) avg_memory = np.Mean(Memory_usage) /(1024 * 1024)#轉換為MB 返回avg_latency,avg_cpu,avg_memory
現在我們已經加載了模型了,現在該基於每個框架的性能進行基準測試了。基準測試過程對生成的輸入數據執行推斷。
#基準Pytorch模型 def pytorch_predict(input_data): pytorch_model(torch.tensor(input_data))) pytorch_latency,pytorch_cpu,pytorch_memory = benchmark_model(lambda x:pytorch_predict(x),input_data)
#基準TensorFlow模型 def tensorflow_predict(input_data): tensorflow_model(input_data) tensorflow_latency,tensorflow_cpu,tensorflow_memory = benchmark_model(lambda x:tensorflow_predict(x),input_data)
#基準JAX模型 def jax_predict(input_data): jax_model(jnp.array(input_data)) jax_latency,jax_cpu,jax_memory = benchmark_model(lambda x:jax_predict(x),input_data)
#基準ONNX模型 def onnx_predict(input_data): #批量的過程輸入 對於i在範圍內(input_data.shape [0]): single_input = input_data [i:i 1]#提取單輸入 onnx_session.run(none,{onnx_session.get_inputs()[0] .name:single_input}) onnx_latency,onnx_cpu,onnx_memory = benchmark_model(lambda x:onnx_predict(x),input_data)
#基準OpenVino模型 DEF OPENVINO_PREDICT(INPUT_DATA): #批量的過程輸入 對於i在範圍內(input_data.shape [0]): single_input = input_data [i:i 1]#提取單輸入 compiled_model.infer_new_request({0:single_input}) OpenVINO_LATENCY,OPENVINO_CPU,OPENVINO_MEMORY = BENCHMARK_MODEL(LAMBDA X:OPENVINO_PREDICT(X),INPUT_DATA)
在這裡,我們討論了前面提到的深度學習框架的性能基準測試結果。我們將它們進行比較 - 延遲,CPU使用和內存使用情況。我們包含了表格數據和圖,以進行快速比較。
框架 | 潛伏期(MS) | 相對延遲(與Pytorch) |
Pytorch | 1.26 | 1.0(基線) |
張量 | 6.61 | 〜5.25× |
JAX | 3.15 | 〜2.50× |
onnx | 14.75 | 〜11.72× |
Openvino | 144.84 | 〜115× |
見解:
框架 | CPU使用(%) | 相對CPU用法 1 |
Pytorch | 99.79 | 〜1.00 |
張量 | 112.26 | 〜1.13 |
JAX | 130.03 | 〜1.31 |
onnx | 99.58 | 〜1.00 |
Openvino | 99.32 | 1.00(基線) |
見解:
框架 | 內存(MB) | 相對內存使用(與Pytorch) |
Pytorch | 〜959.69 | 1.0(基線) |
張量 | 〜969.72 | 〜1.01× |
JAX | 〜1033.63 | 〜1.08× |
onnx | 〜1033.82 | 〜1.08× |
Openvino | 〜1040.80 | 〜1.08–1.09× |
見解:
這是比較深度學習框架表現的情節:
在本文中,我們提出了一個全面的基準工作流程,以評估突出的深度學習框架的推理性能 - Tensorflow,Pytorch,pytorch,Onnx,Jax和OpenVino-使用垃圾郵件分類任務作為參考。通過分析關鍵指標,例如延遲,CPU使用和記憶消耗,結果突出了框架與其對不同部署方案的適用性之間的權衡。
Pytorch表現出最平衡的性能,在低潛伏期和有效的內存使用方面表現出色,使其非常適合對潛伏期敏感的應用,例如實時預測和建議系統。 TensorFlow提供了一種中間地面解決方案,具有中等程度的資源消耗。 JAX展示了高計算吞吐量,但以增加CPU利用率為代價,這可能是資源受限環境的限制因素。同時,ONNX和OpenVino的潛伏期滯後,OpenVino的性能尤其受到硬件加速度的阻礙。
這些發現強調了將框架選擇與部署需求保持一致的重要性。無論是針對速度,資源效率還是特定的硬件進行優化,理解權衡取捨對於在現實世界中的有效模型部署至關重要。
A. Pytorch的動態計算圖和有效的執行管道允許低延節推斷(1.26 ms),使其適合於推薦系統和實時預測等應用。
Q2。是什麼影響了OpenVino在這項研究中的表現?答:OpenVino的優化是為Intel硬件設計的。沒有這種加速度,與其他框架相比,它的延遲(144.84 ms)和內存使用情況(1040.8 MB)的競爭力較低。
Q3。如何為資源受限環境選擇一個框架?答:對於僅CPU的設置,Pytorch是最有效的。 TensorFlow是適度工作負載的強大替代方法。除非可以接受較高的CPU利用率,否則避免使用JAX之類的框架。
Q4。硬件在框架性能中起什麼作用?答:框架性能在很大程度上取決於硬件兼容性。例如,OpenVino在Intel CPU上具有特定於硬件的優化,而Pytorch和Tensorflow則在各種設置中持續執行。
Q5。基準測試結果是否會因複雜模型或任務而有所不同嗎?答:是的,這些結果反映了一個簡單的二進制分類任務。性能可能會隨複雜的架構(例如Resnet或NLP或其他人)等任務而變化,這些框架可能會利用專業的優化。
本文所示的媒體不由Analytics Vidhya擁有,並由作者酌情使用。
以上是深度學習CPU基準的詳細內容。更多資訊請關注PHP中文網其他相關文章!