###### tags: `深度學習` # 深度學習系統與平行計算技術 ## 作業說明 - [link](https://drive.google.com/file/d/1rurBVTwFeYXbUAntIPpJ3u-IIX2c8Tte/view?usp=sharing) ## HackMD 版本 - [深度學習系統與平行計算技術](https://hackmd.io/@jonec76/dlspc-hw2) ## 學生資料 學號:P76091129 姓名:王子源 系級:資工所碩一 ## 實驗說明 作業採用的架構如下 - Framework: PyTorch - Dataset: [small-food-11.zip](https://drive.google.com/drive/folders/1Sj3hK6AbMv_cfsPxIQkXg8GLhRUEb3Ks?usp=sharing) (為了能夠快速實驗,本次作業使用較小的 dataset。) ## 實驗環境: - 硬體 - CPU: Intel(R) Core(TM) i7 CPU 860 * 8 - GPU: GeForce GTX 1660 - Memory: 16 GB - 軟體 - OS: Ubuntu 18.04 - Python 3.6.9 / PyTorch 1.7 ## 實驗步驟 - 程式說明 參考[ 官方網站 ](https://pytorch.org/tutorials/recipes/recipes/profiler.html) 的介紹,本次作業使用 `PyTorch` 內建的 profiling 函式。 ```py=1 import torch.autograd.profiler as profiler ``` 使用方法如下,在程式碼裡頭插入幾行偵測分析的程式碼,而這次作業是針對 training 階段做分析 ```py=1 with profiler.profile(record_shapes=True) as prof: with profiler.record_function("model_training"): train_pred = model(data[0].cuda()) ``` 接著在訓練完之後將結果印出 ```py=1 print(prof.key_averages(group_by_input_shape=True).table(sort_by="cpu_time_total", row_limit=10)) ``` - 實驗數據 首先,先來比較一下有無 gpu 的時間差別 ![](https://i.imgur.com/Sjyx0ge.png =300x200) 接著,看到 gpu 的各 epoch 時間紀錄,這邊是使用 `cpu_time_total` 作為排序。 ![](https://i.imgur.com/Zc0MUc0.png =300x200) 可以看到在 epoch=0 的時候,花了比其他 epoch 多更多的時間,這是為什麼呢?將該 epoch 細項印出 ![](https://i.imgur.com/sSToQTC.png) 圖中 Self CPU 和 CPU total 最大的差別,就在於 Self CPU 計算的項目是該函式使用 CPU 的時間(不包括呼叫到其他函式的時間),但後者是包括該函式所呼叫的所有子函式花費的時間。 觀察後發現,在此 epoch 的 `addmm` (矩陣相乘) 此函式佔了 81% 左右的 cpu 使用率。在其他的 epoch 的 `addmm` 並沒有耗費如此多的時間,但這是否是 torch 的某種最佳化方法目前還沒有結論。 接著看整體 training 的各個函式分佈比例,這邊使用了 ```py=1 prof.export_chrome_trace(out) ``` 來輸出 `.json` 檔案,結果如下: ![](https://i.imgur.com/yaUbcqo.png) 可以看到在執行過程時,程式將不同的 task 分配給不同的 CPU 做處理,而在整個 training 的過程中,CPU=1 的 `to` 這個函式花了非常多的時間,也就是將 tensor 轉移到 gpu 上面,CPU=2 在跑的部分是 backward 調整參數的部分,花費的時間相對少了很多。 接著觀察單個 epoch 的時間分析,此 training model 是由 5 次的 convolution 以及一次的 fully connected 所組成,從下圖可以分別看出每層所花的時間細節: ![](https://i.imgur.com/An927FQ.png) 將各層時間以折線圖方式呈現: ![](https://i.imgur.com/2Lpe49s.png =300x200) 可以看出每層因為 input size 的變化,而有計算時間上的減少。 透過分析,可以看到在 `to` 的函式、做 convolution 時的第一層 layer 會花費很高的時間成本,可能透過資料或者處理器平行化的方式加以改善。