시스톨릭 어레이 구조, NPU와 TPU가 행렬 곱을 하는 법

시스톨릭 어레이 구조, NPU와 TPU가 행렬 곱을 하는 법

공항에서 승객은 체크인 카운터, 보안 검색대, 출국 심사, 탑승구를 정해진 순서로 지납니다. 각 단계의 직원은 자기 일만 반복하고 승객은 줄지어 한 단계씩 앞으로 움직이기 때문에, 한 승객이 보안 검색을 받는 동안 앞 승객은 출국 심사를, 뒤 승객은 체크인을 동시에 처리받죠.

이 구조는 NPU와 TPU의 핵심 회로와 닮았습니다. 이 글에서 다룰 시스톨릭 어레이(Systolic Array)는 작은 연산 유닛을 격자로 늘어놓고, 데이터가 심장 박동처럼 일정한 리듬으로 이웃 유닛을 따라 흐르며 곱셈과 덧셈이 이어지게 하는 구조입니다.

공항과 다른 점이 있습니다. 승객은 단계마다 서류를 새로 제출하지만, 이 구조에서는 한번 꺼낸 데이터가 이웃 유닛을 지나며 여러 번 쓰이고 중간 결과도 창고, 곧 메모리에 다녀오지 않고 옆 유닛으로 바로 넘어갑니다.

행렬 곱이 메모리 병목이 되는 이유

신경망의 한 층을 계산하는 일은 대부분 입력 행렬과 가중치 행렬의 곱입니다. 이 곱은 MAC(Multiply-Accumulate, 곱셈 누산)이라는 단순한 연산을 수없이 반복하는 일로, 연산 하나는 단순해도 개수가 압도적으로 많습니다.

문제는 연산보다 데이터 이동입니다. 일반적으로 칩 밖 메모리에서 데이터를 가져오는 에너지는 곱셈 한 번의 에너지보다 훨씬 큽니다. 그래서 MAC마다 메모리에서 두 피연산자를 새로 읽어 오면 전력과 시간이 대부분 메모리 접근에 쓰입니다.

다행히 행렬 곱에는 재사용의 여지가 큽니다. N × N 행렬 두 개를 곱하면 MAC은 N³번 일어나지만 입력 원소는 2N²개뿐이고, 각 원소가 N번씩 쓰입니다.

N이 256이라면 MAC은 256³ = 16,777,216번이고 읽어야 할 원소는 2 × 256² = 131,072개입니다. 이 많은 재사용을 칩 안에서 살려 내는 것이 이 구조의 출발점입니다.

시스톨릭 어레이 구조, PE 격자와 데이터가 흐르는 방향

어레이의 칸 하나를 PE(Processing Element, 처리 요소)라고 합니다. PE는 곱셈기와 덧셈기, 값을 잠시 담아 두는 레지스터로 이루어진 아주 작은 회로이고, 이런 PE를 가로세로로 수십에서 수백 개씩 깔아 둡니다.

널리 소개되는 배치에서는 가중치를 각 PE의 레지스터에 미리 올려 두고 움직이지 않게 합니다. 입력 값은 왼쪽에서 들어와 오른쪽 PE로 한 칸씩 전달되고, 곱셈 결과를 더한 부분합은 위에서 아래로 흘러 내려갑니다. 이렇게 가중치를 제자리에 두는 방식을 가중치 고정이라고 합니다.

메모리에 접근하는 곳은 어레이의 가장자리뿐입니다. 입력은 왼쪽 가장자리에서 넣고 결과는 아래쪽 가장자리에서 꺼내므로, 안쪽 PE들은 메모리를 거치지 않고 이웃끼리만 데이터를 주고받습니다. 배선이 이웃 사이로 짧게 제한된다는 점도 큰 장점입니다.

2×2 가상 예시로 따라가는 시스톨릭 어레이 계산

작은 예시로 흐름을 따라가 보겠습니다. 아래 행렬은 설명을 위해 임의로 정한 값이며, 곱 결과 C = A × W를 구합니다.

가상 예시, 곱할 두 행렬A = [[1, 2], [3, 4]]이고 행 하나가 입력 샘플 하나입니다. W = [[5, 6], [7, 8]]이고 각 PE에 값 하나씩 올려 둡니다.

직접 계산한 정답은 C = [[1×5 + 2×7, 1×6 + 2×8], [3×5 + 4×7, 3×6 + 4×8]] = [[19, 22], [43, 50]]입니다.

PE(0,0)은 5, PE(0,1)은 6, PE(1,0)은 7, PE(1,1)은 8을 담고 있다고 둡니다. 첫 번째 샘플 (1, 2)와 두 번째 샘플 (3, 4)가 차례로 들어오는데, 둘째 행의 PE에는 한 클록 늦게 넣어 시차를 줍니다. 이 시차 덕분에 위에서 내려온 부분합과 입력이 같은 순간에 만납니다.

클록 사이클별 계산

  1. 사이클 0에서 PE(0,0)이 1 × 5 = 5를 계산합니다.
  2. 사이클 1에서 PE(0,0)이 3 × 5 = 15, PE(0,1)이 1 × 6 = 6을 계산하고, PE(1,0)이 위에서 내려온 5에 2 × 7을 더해 19를 냅니다.
  3. 사이클 2에서 PE(0,1)이 3 × 6 = 18, PE(1,0)이 15 + 4 × 7 = 43, PE(1,1)이 6 + 2 × 8 = 22를 냅니다.
  4. 사이클 3에서 PE(1,1)이 18 + 4 × 8 = 50을 내며 마지막 결과가 나옵니다.

곱셈 8번이 4사이클에 끝났고, 같은 순간에 최대 3개의 PE가 일했습니다. 메모리 접근을 세어 보면 가중치 4개를 한 번씩 올리고, 입력 4개를 가장자리에서 한 번씩 읽고, 결과 4개를 한 번씩 쓰니 모두 12번입니다.

MAC마다 두 피연산자를 새로 읽는 방식이라면 읽기만 8 × 2 = 16번이 필요합니다. 2×2에서는 차이가 작지만 행렬이 커질수록 간격이 벌어지는데, 가중치와 입력과 결과가 각각 N²에 비례하는 접근으로 머무는 동안 MAC은 N³으로 늘어나기 때문입니다.

이 예시는 흐름을 이해하기 위한 단순화입니다. 실제 하드웨어는 레지스터 단수와 데이터 흐름 방식이 이보다 복잡합니다.

가중치 고정과 출력 고정, 무엇을 제자리에 둘까

이 구조는 무엇을 제자리에 두느냐에 따라 여러 변형이 있습니다. 앞의 예처럼 가중치를 두는 가중치 고정, 부분합을 PE 안에 쌓아 두고 입력과 가중치를 흘리는 출력 고정, 입력을 두는 입력 고정이 대표적입니다.

어느 쪽이 좋은지는 재사용하려는 데이터의 크기와 층의 모양에 달려 있습니다. 같은 가중치로 많은 입력을 연달아 처리한다면 가중치 고정이 유리하고, 부분합을 오래 쌓아야 한다면 출력 고정이 메모리 쓰기를 줄여 줍니다.

한계도 있습니다. 행렬이 어레이보다 작으면 놀게 되는 PE가 생기고, 어레이보다 크면 조각(타일)으로 나눠 반복해야 합니다. 값이 0인 곳이 많은 희소한 데이터에서도 곱셈을 그대로 수행하기 때문에 이득이 줄어듭니다.

흔한 오해는 시스톨릭 어레이만 있으면 NPU와 TPU가 모든 연산을 빠르게 처리한다는 생각입니다. 어레이는 행렬 곱 계열에서 이득이 크고, 활성화 함수나 정규화 같은 나머지 연산은 별도 유닛이 맡으므로 그 비중이 크면 전체 속도가 제한됩니다.

NPU와 TPU 안에서 어레이를 둘러싼 구성

NPU는 신경망 연산을 가속하는 칩이나 블록을 두루 부르는 이름이고, TPU는 Google이 만든 텐서 연산 가속기의 이름입니다. 두 이름은 층위가 다르지만, 행렬 곱 유닛으로 이 어레이를 쓰는 설계가 널리 알려져 있습니다. 모든 NPU가 이 구조인 것은 아닙니다.

어레이 주변에는 데이터를 대기시키는 온칩 SRAM 버퍼, 어레이 아래쪽에서 부분합을 모으는 누산기, 활성화 함수 같은 후처리를 맡는 유닛이 붙습니다. 버퍼가 데이터를 쉬지 않고 공급해야 PE가 놀지 않으므로, 어레이 크기만큼 버퍼와 대역폭 설계도 성능을 좌우합니다.

신경망 한 층을 처리하는 흐름

  1. 가중치를 DRAM에서 온칩 버퍼로 가져와 PE에 올립니다.
  2. 입력 활성값을 버퍼에서 읽어 어레이의 왼쪽 가장자리로 넣습니다.
  3. 부분합이 아래로 흐르며 누산기에 모입니다.
  4. 활성화 함수 같은 후처리를 거칩니다.
  5. 결과를 버퍼에 저장해 다음 층의 입력으로 재사용합니다.

곱셈기는 정밀도가 낮을수록 작고 에너지가 적습니다. 그래서 추론용으로는 8비트 정수 같은 낮은 정밀도를 쓰는 설계가 흔하고, 같은 면적에 PE를 더 많이 넣어 처리량을 높이는 선택으로 이어집니다.

메모리 접근 방식 비교 표

구분MAC마다 메모리에서 읽는 방식시스톨릭 어레이 방식
데이터 이동피연산자를 연산마다 메모리에서 가져옴데이터가 이웃 PE로 흘러가며 재사용됨
메모리 접근 규모N × N 곱에서 MAC 수에 비례하는 N³ 수준가장자리 입출력만 쓰는 N² 수준
배선메모리와 연산기 사이의 긴 연결이웃 PE 사이의 짧은 연결
잘 맞는 연산불규칙한 접근, 분기가 많은 코드규칙적인 행렬 곱과 합성곱
약점메모리 대역폭과 에너지 부담크기가 어긋난 행렬에서 낮은 이용률
놓치기 쉬운 점어레이가 있으면 모든 연산이 빨라진다는 오해, 이득은 규칙적인 행렬 곱에 집중됩니다.

핵심 정리

이 구조는 행렬 곱의 높은 재사용성을 PE 격자의 이웃 전달로 살려, 메모리 접근을 연산 수보다 훨씬 적게 유지합니다. 가중치를 제자리에 두고 입력과 부분합을 흘려 보내는 방식이 대표적이고, 2×2 예시에서는 곱셈 8번이 4사이클에 끝났습니다. 시스톨릭 어레이를 이해할 때는 어떤 데이터를 제자리에 두고 어떤 데이터를 흘리는지부터 구분해 보는 것이 좋습니다.

공항의 직원이 쉬지 않고 일해야 줄이 막히지 않듯, 이 구조의 성능은 PE를 놀리지 않는 데 달려 있습니다. 어레이 크기와 맞지 않는 행렬이 들어오면 비어 있는 카운터가 생기는 것과 같아서, 행렬을 조각내는 방식과 버퍼 설계가 함께 중요해집니다.

면접 대비 질문

면접 대비 질문시스톨릭 어레이가 메모리 접근을 줄이는 원리를 가중치 고정 방식을 예로 설명하고, 이 구조의 한계를 말해 보세요.

[답변 포인트] 행렬 곱은 MAC 수가 N³인데 입력 원소는 N²개뿐이라 재사용 여지가 크다는 점에서 시작합니다. 가중치를 PE에 올려 두고 입력은 가로로, 부분합은 세로로 흘려 보내면 메모리 접근이 어레이 가장자리의 입출력으로 한정되고, 이웃 PE 사이의 짧은 배선만 쓴다는 점을 연결합니다. 한계로는 행렬 크기가 어레이와 맞지 않을 때의 낮은 이용률, 타일링 비용, 희소 데이터에서의 낭비, 활성화 함수 같은 비행렬 연산이 병목이 될 수 있다는 점과 버퍼 대역폭 설계의 중요성까지 덧붙이면 좋습니다.