Performance Evaluation

모델 변환 성능을 높이기 위한 모니터링 방법

Performance Evaluation 기능이 필요한 이유는 다음과 같습니다.

rknn으로 모델을 변환하거나, 경량화를 진행했을 때 성능이 형편없어졌다고 하면 (대부분 그렇지만) 우리는 어디가 문제인지 알아야 합니다.

예를 들어, 모델의 inference time이 너무 길 때 어느 레이어에서 시간과 자원을 많이 소모하고 있는지 layer by layer로 분석해야 할 필요가 있습니다.

Performance Evaluation

Performance Evaluation 기능은 각각의 레이어에서 얼마만큼의 시간이 소요되었는지 알려줍니다. 이전 챕터에서 다뤘던 Depth Anything을 예시로 계속 진행해 보도록 하겠습니다.

하단의 코드 역시 rknn이 설치되어 있는 Ubuntu 컴퓨터에 adb 모드로 오렌지 파이를 연결하고 실행하는 것을 권장합니다.

import numpy as np
import cv2
from rknn.api import RKNN

if __name__ == '__main__':

    # Create RKNN object
    rknn = RKNN(verbose=True)

    # Pre-process config
    print('--> Config model')
    rknn.config(
        mean_values=[[0.485*255, 0.456*255, 0.406*255]],  
        std_values=[[0.229*255, 0.224*255, 0.225*255]],
        quant_img_RGB2BGR=True, 
        target_platform='rk3588')
    print('done')

    # load rknn model
    print('--> Load rknn model')
    ret = rknn.load_rknn('depth_anything_vits_OP19.rknn')
    if ret != 0:
        print('Load rknn model failed!')
        exit(ret)
    print('done')

    # Set inputs
    img = cv2.imread('front.jpg')
    img = np.expand_dims(img, 0)

    print('--> List devices')
    rknn.list_devices()

    # Init runtime environment
    print('--> Init runtime environment')
    ret = rknn.init_runtime(target='rk3588', perf_debug=True, eval_mem=True, core_mask=RKNN.NPU_CORE_0_1_2)
    if ret != 0:
        print('Init runtime environment failed!')
        exit(ret)
    print('done')

    print('--> Get sdk version')
    sdk_version = rknn.get_sdk_version()
    print(sdk_version)

    # eval perf
    print('--> Eval perf')
    rknn.eval_perf()

    # eval perf
    print('--> Eval memory')
    rknn.eval_memory()

    # Inference
    print('--> Running model')
    outputs = rknn.inference(inputs=[img], data_format=['nhwc'])
    np.save('./depth_anything_eval_perf.npy', outputs[0])
    # show_outputs(outputs)
    print('done')

    rknn.release()

rknn.eval_perf() 함수를 실행하면 다음과 같은 txt 파일이 생성됩니다.

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
                                                                         Network Layer Information Table                                                                               
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ID   OpType           DataType Target InputShape                               OutputShape            Cycles(DDR/NPU/Total)    Time(us)     MacUsage(%)          WorkLoad(0/1/2)      RW(KB)       FullName        
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1    InputOperator    FLOAT16  CPU    \                                        (1,3,480,640)          0/0/0                    3            \                    0.0%/0.0%/0.0%       0            InputOperator:image
2    Conv             FLOAT16  NPU    (1,3,480,640),(384,3,14,14),(384)        (1,384,67,90)          324681/28374528/28374528 12600        7.03/7.03/7.03       33.3%/33.3%/33.3%    2977         Conv:/patch_embed/proj/Conv_stride_split
3    Conv             FLOAT16  NPU    (1,384,67,90),(1,384,1,1)                (1,384,34,45)          245492/9216/245492       332          0.12/0.12/0.12       35.3%/32.4%/32.4%    4523         Conv:/patch_embed/proj/Conv_select
4    Reshape          FLOAT16  NPU    (1,384,34,45),(4)                        (1,384,1,1530)         99354/0/99354            1            \                    0.0%/0.0%/0.0%       1147         Reshape:/patch_embed/Reshape_output_0_rs
5    Concat           FLOAT16  NPU    (1,384,1,1),(1,384,1,1530)               (1,384,1,1531)         99418/0/99418            195          \                    33.3%/33.3%/33.3%    1148         Concat:/Concat_1
6    Add              FLOAT16  NPU    (1,384,1,1531),(1,384,1,1531)            (1,384,1,1531)         149126/0/149126          206          \                    33.3%/33.3%/33.3%    2296         Add:/Add        
7    exNorm           FLOAT16  NPU    (1,384,1,1531),(1,384,1,1),...           (1,384,1,1531)         99548/0/99548            1134         \                    100.0%/0.0%/0.0%     1151         exNorm:/blocks.0/norm1/LayerNorm
8    Conv             FLOAT16  NPU    (1,384,1,1531),(1152,384,1,1),(1152)     (1,1152,1,1531)        236433/1327104/1327104   827          53.32/53.32/53.32    33.3%/33.3%/33.3%    2016         Conv:/blocks.0/attn/qkv/MatMul_2conv
9    Reshape          FLOAT16  CPU    (1,1152,1,1531),(4)                      (3,6,64,1531)          0/0/0                    3476         \                    0.0%/0.0%/0.0%       3444         Reshape:/blocks.0/attn/Reshape_output_0_squeeze_1_nd_/blocks.0/attn/Transpose
10   Transpose        FLOAT16  CPU    (3,6,64,1531)                            (6,64,3,1531)          0/0/0                    14819        \                    0.0%/0.0%/0.0%       3444         Transpose:/blocks.0/attn/Transpose_output_0_tp_4/blocks.0/attn/Gather_3_2slice_2split
```

여기서 주의 깊게 보아야 할 항목들은 다음과 같습니다.

  • DDRCycles (Double Data Rate)

    • 메모리 접근에 필요한 사이클 수 (데이터를 DDR RAM에서 읽거나 쓰는 데 소요되는 사이클)

    • 높은 DDR 사이클은 메모리 병목 현상을 의미할 수 있음

  • NPUCycles

    • NPU에서 실제 연산을 수행하는 데 필요한 사이클 수

  • Time

  • MacUsage (MAC : Multiply-Accumulate)

    • a*b+c

    • NPU에서 제공하는 MAC 유닛의 사용률

    • 100%에 가까울 수록 해당 레이어가 NPU의 MAC 리소스를 효율적으로 사용하고 있다는 의미

    • 높은 MAC usage : 추가적인 최적화 필요 없음

    • 낮은 MAC usage : 추가적인 최적화 여지 있음

  • WorkLoad

  • RW

따라서 DDR 사이클이 높은 레이어는 메모리를 최적화하고, NPU 사이클이 높은 레이어는 연산을 최적화하거나 Quantization을 할 필요가 있습니다. Total Cycle이 높은 레이어가 주요한 관찰 대상입니다.

eval_perf로 생성되는 텍스트 파일 하단에 레이어 순위가 적혀 있으니 이를 참고하시면 좋을 것 같습니다.

---------------------------------------------------------------------------------------------------
                                 Operator Time Consuming Ranking Table            
---------------------------------------------------------------------------------------------------
OpType             CallNumber   CPUTime(us)  GPUTime(us)  NPUTime(us)  TotalTime(us)  TimeRatio(%)  
---------------------------------------------------------------------------------------------------
exSDPAttention     12           0            0            556747       556747         38.64%        
Resize             6            406682       0            0            406682         28.22%        
Transpose          12           240229       0            0            240229         16.67%        
Reshape            29           81356        0            16           81372          5.65%         
Conv               49           0            0            57195        57195          3.97%         
ConvExGelu         12           0            0            37473        37473          2.60%         
exNorm             28           0            0            30351        30351          2.11%         
Split              12           0            0            7569         7569           0.53%         
ConvRelu           9            0            0            6054         6054           0.42%         
Mul                24           0            0            5070         5070           0.35%         
Add                25           0            0            4003         4003           0.28%         
ConvTranspose      2            0            0            2898         2898           0.20%         
ConvAdd            10           0            0            2878         2878           0.20%         
Relu               8            0            0            1305         1305           0.09%         
Slice              4            0            0            839          839            0.06%         
Concat             1            0            0            195          195            0.01%         
OutputOperator     1            80           0            0            80             0.01%         
InputOperator      1            3            0            0            3              0.00%         
---------------------------------------------------------------------------------------------------

Last updated