# 多執行緒測試說明(Python Flask)
## 測試方向
1. 使用 CPE 內的高通 AI-Chip 執行推論
2. 測試高通 AI-Chip 同時多執行緒的推論速度
3. 比較與 Nvidia-RTX4060 的推論速度
## 測試模型種類
1. LEDA _ AutoEncoder
2. LEDA _ Classification
3. YOLOv8 _ Classification
4. YOLOv8 _ ObjectDetection
5. YOLOv8 _ Segmentation
## 測試設備
1. CPE & 高通 AI-Chip
2. Nvidia - RTX4060
## 多執行緒測試方法(Python Flask)
### 方法與步驟
* 原本推論測試程式為 Python,要達成同時多執行緒執行有一定難度,無法快速測試出結果。
* Python Flask 是一種輕量級 Web 應用架構,提供從 URL 到 Python 函數之間得連結。可以拿來寫網頁應用或是 API。
* 由於此次測試重點在於推論時間,其引用的模型與測試集皆相同,我們只須考慮如何讓多個模型同時跑起來即可。用到的就是 URL 與 Python 函數的串接,將原本程式改成 Flask server,再撰寫一個 client 同時呼叫多個函式即可達成多線程執行的目的。
### 安裝 Python Flask
#### python3 & pip 環境版本確認
* 如果系统中只安装了Python2 --> 只能使用pip。
* 如果系统中只安装了Python3 --> 可以使用pip也可以使用python3,二者是相同的。
* 如果系统中同时安装了Python2和Python3 --> pip默認给Python2用。
* sudo的python的環境與anaconda不同,須注意自己在哪個環境下。
```
sudo python3 -V # 檢查 Python3 版本
sudo pip -V # 檢查 pip 環境
sudo python3 -m pip install # 可以確保pip install是安裝到正確的python3路徑
```
#### 安裝 Python Flask
```
sudo python3 -m pip install flask # 安裝flask
```
如果遇到有關blinker相關錯誤,請重新安裝blinker。
```
ERROR: Cannot uninstall 'blinker'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.
sudo -H pip install --ignore-installed -U blinker # 安裝blinker
```
#### 在程式中啟動 Flask
```python=
from flask import Flask
app = Flask(__name__) # 初始化Flask
# 告訴 Flask,哪個 URL 應該觸發我們的函式。
# 斜線代表的就是根目錄,可以疊加。
@app.route("/")
# 例如: 新增一個 /hello 的位址
# 當收到 URL (http://127.0.0.1:5000/hello) 會觸發hello function
@app.route("/hello")
def hello():
return "Hello, World!"
if __name__ == '__main__':
app.run(debug=True, port=5000) # 啟動 Flask 應用程式
```
#### 將原本推論腳本改成 API 形式(以 leda_ae.py 為例)
1. 將原本main底下的程式碼改成某個flask的route
```python=
@app.route('/leda_ae', methods=['POST'])
def init():
parser = argparse.ArgumentParser()
parser.add_argument("--model", required=True, help="your fp16 model dir.")
parser.add_argument(
"--img", default=str("images/bus.jpg"), help="Path to input image."
)
parser.add_argument(
"--count",
type=int,
default=3,
help="Count to run. -1 for loop",
)
args = parser.parse_args()
run(args.model, args.img, args.count)
```
2. 將main改成啟動flask
```python=
if __name__ == '__main__':
app.run(debug=True, port=5000) # 啟動 Flask 應用程式
```
3. 撰寫另一個python client的程式
```python=
import requests
if __name__ == '__main__':
url = "http://127.0.0.1:8000/seg_v8"
response = requests.post(url)
print(response)
```
## CPE測試步驟
1. 在終端機輸入指令,要注意自己的檔案位置,會導致指令些許不同。
`sudo python3 flask/leda_ae_flask_5000.py --model model/leda_ae`

2. 確認自己的url,並修改python client程式。
3. 再開一個終端機執行client端的程式。`sudo python3 flask/flask_test.py`
4. 如果有對正確的url發送請求,server端程式底下對應的函式會開始執行。

5. 高通 Ai-chip 多開時會有調用問題,如下圖

## CUDA測試方法(RTX-4060)
### 利用GPU推論方法
#### 於 python 內安裝 onnxruntime-gpu
1. 依cuda, cudnn下載對應onnxruntime-gpu版本
版本對照:https://onnxruntime.ai/docs/execution-providers/CUDA-ExecutionProvider.html
```
pip install onnxruntime-gpu==1.16.0
```
2. 於 cmd 依序輸入以下指令測試
```
python
import onnxruntime
onnxruntime.get_device()
onnxruntime.get_available_providers()
```
如果輸出結果為以下則代表安裝成功
```
'GPU'
['TensorrtExecutionProvider', 'CUDAExecutionProvider', 'CPUExecutionProvider']
```
#### 程式測試
1. 下載LEDA提供的資源庫(.zip)
連結:http://leda-office.synology.me:30000/LEDA/qualcomm-ai-chip/src/branch/onnxruntime
2. 依本地環境補足缺少的資源庫
```
pip install (缺少的資源庫 EX:onnx)
```
3. 依照 README 執行指令即可
## 測試常見問題
### 常見問題1__找不到 zlibwapi.dll 檔案位置
程式報錯如下:
```
use CUDAExecutionProvider
Could not locate zlibwapi.dll. Please make sure it is in your library path!
```
這是因為 C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.7\bin 內缺少了zlibwapi.dll導致
*註:網路上會建議你去Nvidia官網下載檔案,但現在官網已經不提供下載了*
* STEP1:在 C:\Program Files 搜尋 zlibwapi.dll
* STEP2:找到檔案位置後,複製一份至 C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.x\bin 資料夾內
重新整理後,再執行一次程式應該就不會報錯了。
### 常見問題2__無法用cuda執行程式
## 測試結果
### CPE(單執行/雙執行/九執行)
***YOLO_OD吃的資源比較多,一次請求吃兩個處理器,所以最多只能測4線程**
| 模型名稱 | 推論秒數(ms) | 前後處理秒數(ms) | 推論FPS |
| ------------------------ | ----------------- | ------------------ | --------- |
| LEDA _ AutoEncoder | 2.08 / 2.17 / 3.86 | 0.72 / 0.80 / 2.9 | 357 / 710 / 1335|
| LEDA _ Classification | 0.89 / 0.95 / 2.93 | 0.44 / 0.52 / 1.55 | 751 / 1354 / 2031|
| YOLOv8 _ Classification | 1.59 / 1.77 / 4.56 | 0.52 / 0.67 / 1.57 | 474 / 818 / 1472|
| YOLOv8 _ ObjectDetection | 19.73 / 21.9 / 25.4 | 5.23 / 9.65 /11.5 | 40 / 63 / 108|
| YOLOv8 _ Segmentation | 38.13 / 50.28 / 102.1 | 28.58 / 41.85 / 158.72 | 15 / 22 / 34.5 |
### RTX4060_Laptop(單執行/雙執行/多執行(同時發送10個請求)
| 模型名稱 | 推論秒數(ms) | 前後處理秒數(ms) | 推論FPS |
| ------------------------ | --------------------- | ---------------------- | --------------- |
| LEDA _ AutoEncoder | 1.45 / 1.45 / 2.30 | 0.90 / 1.00 / 2.49 | 425 / 816 / 2090 |
| LEDA _ Classification | 1.41 / 1.27 / 2.37 | 0.11 / 0.16 / 0.43 | 657 / 1398 / 3590 |
| YOLOv8 _ Classification | 3.74 / 3.40 / 7.24 | 14.79 / 15.45 / 29.3 | 53 / 106 / 270 |
| YOLOv8 _ ObjectDetection | 10.27 / 11.83 / 40.61 | 20.12 / 21.59 / 45.84 | 32 / 60 / 110 |
| YOLOv8 _ Segmentation | 12.81 / 21.35 / 40.79 | 62.14 / 56.66 / 105.71 | 13 / 24 / 60 |
## 結論
### 高通 AI-Chip 硬體調用極限
運算單元的調用問題,因為這些推論都是比較簡單的,照理來說是不太可能佔用太多資源,結論比較像是只有兩個運算單元可以調用,就算他們彼此都還有多餘算力。進一步確認要想辦法找到可以知道AI chip的資源佔用監控,就可以更加確定這個結論是否正確。(YOLOv8-OD 一次會調用兩個晶片?)
### LEDA 自主研發模型
不論是在 NVIDIA 或是 AI-Chip,與 YOLOv8 比較推論速度有明顯的提升。
### 高通 AI-Chip vs NVIDIA
高通優勢在cls模型下速度優於nv,但硬體資源調用還是nv佔優勢,在多執行緒的情況下高通無法完全釋放他的算力。