신경망 추론의 메모리 트래픽 — 학습서

02a · 전체 네트워크 트래픽 — 66 MB가 쌓이는 과정

목차

02장에서 대표 블록 두 개를 분해했다. 이제 같은 셈을 MobileNet-v2의 모든 부분에 적용한다. bottleneck 블록 17개에 앞쪽 stem 합성곱, 마지막 1×1 합성곱, 분류기 전결합층을 더한 전체다. 한 블록씩 트래픽을 세어 늘어놓으면, 활성값과 가중치 중 누가 어디서 트래픽을 지배하는지가 모델 깊이를 따라 드러난다.

02a.1 블록별 트래픽 — 깊이를 따라 역전된다

다음은 모든 블록과 레이어의 가중치·활성값 트래픽이다(FP32, batch 1). 같은 모양을 반복하는 블록은 한 줄로 묶었다.

블록 입력 해상도 채널 (입력→출력) t 가중치 활성값
stem 3×3 s2 224 3→32 3.4 KB 2,156 KB 2,159 KB
b1 112 32→16 1 3.1 KB 5,488 KB 5,491 KB
b2 112 16→24 6 18.4 KB 12,838 KB 12,856 KB
b3 56 24→24 6 32.1 KB 8,232 KB 8,264 KB
b4 56 24→32 6 36.6 KB 4,802 KB 4,839 KB
b5–b6 28 32→32 6 54.8 KB 2,744 KB 2,799 KB
b7 28 32→64 6 78.8 KB 1,617 KB 1,696 KB
b8–b10 14 64→64 6 205.5 KB 1,372 KB 1,578 KB
b11 14 64→96 6 253.5 KB 1,298 KB 1,552 KB
b12–b13 14 96→96 6 452.2 KB 2,058 KB 2,510 KB
b14 14 96→160 6 596.2 KB 1,207 KB 1,803 KB
b15–b16 7 160→160 6 1,234 KB 857.5 KB 2,091 KB
b17 7 160→320 6 1,834 KB 826.9 KB 2,661 KB
final 1×1 7 320→1280 1,600 KB 306.2 KB 1,906 KB
classifier FC 1280→1000 5,000 KB 8.9 KB 5,009 KB

(b3은 02장의 블록 A, b15는 블록 B와 같은 모양이다. 표의 KB 단위 합이 그 장의 8,264 KB·2,091 KB와 맞는지 확인해 보면 셈이 일관됨을 알 수 있다.)

표를 위에서 아래로 읽으면 한 가지 흐름이 보인다. 위쪽 고해상도 블록에서는 활성값이 크고, 아래쪽 저해상도 블록으로 갈수록 가중치가 점점 커진다. b2에서 활성값이 12.8 MB로 가장 크고, classifier FC에서는 가중치가 5 MB인데 활성값은 9 KB뿐이다. 분류기는 극단적인 가중치 지배다. 파라미터 128만 개를 읽는데 활성값은 거의 없다. 이런 레이어가 가중치 지배 memory-bound 분류기(classifier head)의 전형이다.

다음 그림은 이 표를 누적 막대로 그린 것이다. 막대 하나가 한 블록이고, 아래가 가중치, 위가 활성값이다.

MobileNet-v2 블록별 메모리 트래픽. 초기(위쪽) 블록은 활성값(주황)이, 후기 블록과 분류기는 가중치(파랑)가 트래픽을 지배한다.
그림 1. MobileNet-v2 블록별 메모리 트래픽. 초기(위쪽) 블록은 활성값(주황)이, 후기 블록과 분류기는 가중치(파랑)가 트래픽을 지배한다.

왼쪽 초기 블록들은 주황(활성값)이 막대를 거의 다 채우고, 오른쪽으로 갈수록 파랑(가중치)이 자란다. 트래픽의 두 항이 네트워크 깊이를 따라 역전된다.

광고 · Advertisements

02a.2 해상도 밴드로 묶어 보기 — 활성값의 발원지

블록을 해상도별로 묶으면 활성값이 어디서 나오는지가 더 또렷해진다. 같은 해상도에서 도는 블록들의 가중치와 활성값을 각각 더한 표다.

해상도 밴드 가중치 합 활성값 합 활성값 ÷ 가중치
112×112 21.5 KB 18,326 KB 852×
56×56 68.6 KB 13,034 KB 190×
28×28 188.2 KB 7,105 KB 38×
14×14 2,371 KB 10,737 KB 4.5×
7×7 4,301 KB 2,542 KB 0.59×

해상도가 절반씩 줄수록(픽셀 수는 4분의 1씩) 활성값은 줄고 가중치는 는다. 112×112 밴드에서는 활성값이 가중치의 852배다. 7×7 밴드에서는 0.59배로, 처음으로 가중치가 더 크다. 활성값 비가 852배에서 0.59배로 뒤집히는 이 흐름이 곧 트래픽 성격의 역전이다.

가장 중요한 수치 하나. 초기 두 밴드(112×112와 56×56)만으로 활성값이 30.62 MB다. 이것은 bottleneck 블록들의 활성값 합 기준으로 약 60%에 해당한다. 다시 말해, 활성값 트래픽의 발원지는 모델 앞쪽의 고해상도 레이어다. 그런데 그 앞쪽 레이어들은 가중치가 거의 없다. 112×112 밴드의 가중치는 21.5 KB뿐이다. 파라미터가 가장 적은 곳에서 트래픽이 가장 크다.

해상도 밴드별 트래픽. 해상도가 절반씩 줄수록 활성값(주황)은 줄고 가중치(파랑)는 는다. 초기 두 밴드가 전체 활성값의 큰 몫을 차지한다.
그림 2. 해상도 밴드별 트래픽. 해상도가 절반씩 줄수록 활성값(주황)은 줄고 가중치(파랑)는 는다. 초기 두 밴드가 전체 활성값의 큰 몫을 차지한다.

세로 축이 로그 스케일이라 값의 큰 차이가 한 화면에 담긴다. 각 밴드 위의 비율 숫자가 활성값이 가중치의 몇 배인지 보여 준다.

02a.3 전체 합계 — 가벼운 모델의 무거운 트래픽

모든 항을 더하면 전체 트래픽이 나온다.

항목 FP32 (4 byte) 비고
총 파라미터 3.47 M 문헌의 ~3.4 M과 일치
총 MAC 301 M 문헌의 ~300 M과 일치
가중치 트래픽 13.24 MB 파라미터 수 × 4 byte
활성값 트래픽 52.94 MB 중간 텐서 읽기+쓰기
전체 트래픽 66.18 MB
가중치 : 활성값 20% : 80%
전체 연산강도 4.3 MAC/byte

손으로 센 총 파라미터 3.47 M개와 총 MAC 301 M번이 공개 문헌의 약 3.4 M, 약 300 M과 맞는다. 셈이 옳다는 증거다.

핵심은 세 수치다. 가중치를 다 합쳐도 13.24 MB인데, 활성값은 52.94 MB로 그 4배다. 전체 66.18 MB 중 활성값이 80%를 차지한다. "파라미터 3.4 M개에 곱셈 300 M번인 가벼운 모델"이 메모리에서는 한 번 추론에 66 MB를 옮긴다.

이 66 MB가 왜 문제인지 감을 잡으려면 대역폭과 비교해 보면 된다. 메모리 대역폭이 25.6 GB/s인 칩이라면, 66 MB를 옮기는 데에만 약 2.6 ms가 든다(66 MB ÷ 25.6 GB/s). 이것은 연산 시간이 아니라 데이터를 옮기는 시간만이다. 연산기가 아무리 빨라도 이 시간은 줄지 않는다. 연산강도 4.3 MAC/byte가 칩 ridge보다 한참 낮으니 그렇다. 이것이 memory-bound의 정량적 뿌리다. 자세한 판정은 05장 roofline에서 한다.

여기까지가 첫 질문의 답이다. 메모리 트래픽은 가중치 읽기와 활성값 읽기·쓰기의 합이고, MobileNet-v2에서는 활성값이 80%를 차지하며, 그 활성값은 앞쪽 고해상도 레이어에서 나온다. 다음 장은 두 번째 질문으로 넘어간다. inverted residual 블록에서 트래픽이 왜 늘어나는가.

광고 · Advertisements
이 시리즈 전체 챕터

학습경로 의존맵 보기 →