하드웨어 아키텍처를 설계할 때, 처음에는 ‘특정 워크로드에 알맞은 최적의 해가 있을 것’이라 생각하기 쉽다. 물론 알고리즘이 정해져있다면 어느정도 맞는 말이다. 하지만 NPU에게는 전혀 아니다.

NPU에게 워크로드란 딥러닝 알고리즘을 의미한다. 하지만 딥러닝 알고리즘은 성숙한 알고리즘이 아니다. 매일매일 새로운 연산 레이어가 탄생하고 죽어가길 반복한다. 연산 레이어는 약간의 튜닝만으로도 성능이 천차만별이기 때문에 변종도 수없이 탄생한다.

좋은 NPU를 만든다는 것은, 곧 유연한 NPU를 만든다는 것이고, 이는 사실상 General-purpose 프로세서를 만든다는 말과 동일하다. General-purpose 프로세서는 다양한 알고리즘을 돌려야하기 때문에, 아주 다양한 기능을 지원해야하고, 그래서 매우 복잡하다. 알고리즘마다 최적의 인터커넥트의 구조, SRAM의 크기와 대역폭, PE 배열 방식, 연산기는 다르다. 즉, 아키텍처링은 하나의 최적해가 존재하지 않는 NP-hard 문제이다.

그리고 프로세서란 소프트웨어 스택의 도움없이는 돌멩이에 불과하다. 간단한 알고리즘을 가속하는 하드웨어라면 커맨드 단위로 알고리즘을 제어하면 되니, 소프트웨어 스택은 복잡하지 않다. 몇 개의 CSR만으로 알고리즘을 동작시킬 수 있다. 하지만 딥러닝 알고리즘을 하드웨어 커맨드로 매핑하는 것은 수 십개의 lowering 패스를 거쳐야하고, 여러 개의 intermediate representation을 지나야 한다.

DianNao 시리즈에서 시작한 초창기 NPU는 단순히 Convolution 연산 가속기에 불과했다. 당시 딥러닝 알고리즘은 CNN이 전부였고, CNN의 가장 큰 병목은 Convolution 연산이었다. 이를 가속하면 충분했고, 여기에 LUT를 함께 엮어 activation 도 가속해주면 금상첨화였다. 이때까지만 하더라도 몇 개의 CSR 만으로 알고리즘을 간단히 동작시킬 수 있는 하드웨어였다. 하지만 Depth-wise Conv2D 와 같은 적은 채널을 연산해야하는 변종이 나타나더니, 기존 NPU를 바보로 만들었다. 이전만 하더라도 긴 채널을 병렬처리 하는 것으로 Convolution 연산을 가속했는데, 갑작스럽게 적은 채널을 잘 연산하도록 지원해야 하는 것이다. 그리고는 Transformer가 나타났다. Attention layer에는 기존 Dense 연산도 있었지만, 동적으로 생성되는 Q/K/V 행렬의 GEMM 연산도 있어 data-reuse를 어렵게 만들었다. Data-reuse를 잘 지원하는 것으로 높은 에너지 효율성을 달성했던 구세대 NPU들은 더 이상 빛을 발하지 못했다.


딥러닝 알고리즘과 함께 NPU의 세대교체가 점차 일어나던 시기. 이때가 나는 NPU 업계에 처음 들어가게 되었다. 당시 우리 회사는 Transformer를 지원하기 위해 프로그래머블한 NPU를 만들고 싶어했고, RISC-V 벡터 확장을 도입했다. 이때까지만해도 나는 NPU의 큰 그림은 보지 못했고, RISC-V ISA 스펙을 준수하는 프로세서를 개발하는데 몰입해있었다. 벡터 프로세서 개발이 메인이었고, 스칼라 프로세서는 유지 및 보수, 그리고 약간의 성능 향상에 기여를 했었다. 석사를 마치고 막 들어온 신입에게는 RISC-V ISA 스펙을 이해하고 이를 RTL로 반영하는 것은 어렵지만 상당히 흥미로운 일이었다.

하지만 좀 더 도전적인 일을 찾고자 이직을 했다.

모든 것은 완전히 맨땅에서부터 시작했다. 보통 기업에 들어가면 어느 정도 다져진 초석 위에 이미 정해진 프로세스대로 벽돌을 쌓아올리는 일 정도를 수행하지만, 여기는 달랐다. 모든게 처음이다.

난 NPU 개발을 했었지만, NPU에 대해서 아무것도 모른단걸 깨달았다. 그리고 하드웨어 개발 프로세스에 대해서도 무지렁이였다. 학부 때 배운게 있었으나, 실무에서 적용할 수 있을만큼 이해가 깊지 않았다.

어디서부터 손을 대야 할지 막막했다.

NPU 논문들을 정독하고, 업계 자료들을 찾아보고, 미친듯이 공부했다. 하지만 실험실에서 쏟아져 나오는 아키텍처 연구들이 으레 그렇듯, 반 이상이 거짓이고 실험 재현은 거의 불가능하다.

위에서는 당장 데이터를 달라고 말을 하는데, 아무런 인프라도 없는 상황에서 데이터를 줄 형편이 안됐다. 그래서 일단은 지금 당장 데이터를 줄 수 없다고 설득하기 위해 ASIC 디자인 프로세스를 토대로 차근차근 설명했다. 일단 스펙부터 정의하고, 그리고 나서 기능 정의하고 시뮬레이터를 만들어야지만 데이터를 줄 수 있다고 말했다. 하지만 전혀 받아들여지지 않았다. 연차가 낮은 나에게 신뢰도 없었을테고, 나도 NPU에 대해서는 그리 잘 알지 못했으니 말이다.

그래서 일단 오픈소스 시뮬레이터부터 시작했다. NVIDIA의 Timeloop, ARM의 SCALE-Sim 등을 찾았다. 하지만 이들 시뮬레이터는 딥러닝 알고리즘 단계에서 실험을 해볼 수 있다. 즉, 시뮬레이터의 추상 단계가 너무 높다. 알고리즘 단계에서의 성능 측정을, 그것도 두루뭉실한 아키텍처에서 하다보니 결과에 신뢰도가 너무 떨어진다. 나 스스로도 실험 결과가 너무 의심스러웠고, 결과를 전달하면서도 찝찝했다.

그렇게 시간을 의미없이 보내다가, 도저히 안되겠다 싶어서 프로그래밍 모델부터 시작해서 하나하나 다시 조사하기 시작했다. 이를 토대로 하나하나 설득하는 과정을 거쳐 겨우 내가 원하던 방향대로 시뮬레이터 개발을 처음부터 착수하는 것을 결정받았다.

먼저, ‘지원할 기능’을 ISA 레벨로 정의해 기능 스펙의 초안을 잡았고, 이를 검증할 function simulator를 빠르게 구현하는 중이다. 외부 메모리 모델과 스크래치패드 모델을 구현했고, 레지스터 파일과 CSR 등도 모두 구현한 상태이다.

이제 어셈블리 수준에서 딥러닝 연산 커널을 구현해, 정의한 기능들로 알고리즘을 동작시킬 수 있는지 검증해나가는 단계이다.

어느 정도 방향이 잡히고 나니, 설계 범위가 한결 명확해졌다. 무작정 그리드 탐색(grid sweep)을 돌리던 과거와 달리, 이제는 ‘이 기능이 빠지면 이 알고리즘이 동작하지 않는다’는 기준 하나로도 실험 지점을 대폭 줄일 수 있었다.


실무적 접근법

어차피 하드웨어 아키텍처링은 NP-hard 문제이다. 최적해는 존재하지 않고, 모든 것은 트레이드-오프이다.

내 경험 상, 실제 개발팀에서는 다음과 같은 흐름을 권장한다. 사실 이 흐름은 기본적인 ASIC Design Flow에 크게 벗어나 있지는 않고, 많은 교육 자료에서 이 flow를 권장하지만, 실무에서 이를 적용하려면 (특히나 설득 대상자가 ASIC 개발자가 아니라면) 상당히 많은 설득 과정이 필요하다.

  1. 최소 기능 MVP 프로토타입 제작
    • ISA와 메모리 트랜잭션 인터페이스에 꼭 필요한 명령어만 모아, 간단한 하드웨어 모델 또는 FPGA 기반 프로토타입을 빠르게 만든다.
    • 소프트웨어 팀과 통합해 early feedback loop를 가동한다.
  2. 단계별 시뮬레이터 전략
    • Function simulator 단계에서는 순수 기능 호환성만 확인하고,
    • Performance simulator 단계에서는 마이크로아키텍처 수준의 성능 예측을 수행하며,
    • 최종적으로 FPGA나 ASIC 프로토타입 위에 실제 소프트웨어를 올려 전체 워크로드 성능을 검증한다.
  3. 휴리스틱 DSE(Design-Space Exploration)
    • 완전 탐색이 불가능한 NP-hard 문제라는 점을 인정하고, 간단한 휴리스틱(rule-of-thumb)으로 탐색 범위를 먼저 좁힌 뒤, 다양한 방법(e.g. GA, Bayesian Opt. 등의 메타휴리스틱)을 적용해 near-optimal 해를 찾는다.
  4. 반복과 피드백
    • 각 단계에서 드러난 병목과 사용성 이슈를 function/performance simulator에 즉시 반영하고, 프로토타입을 소프트웨어 팀이 다시 테스트하도록 한다.
    • 이 과정을 짧은 스프린트 단위로 계속 돌려야만, 설계 완성도를 높일 수 있다.

하드웨어 아키텍처링은 하나의 정답을 찾아가는 작업이 아니다. 중요한 건 ‘어느 지점까지 기능을 정의할 것인지’, ‘어떻게 빠르게 피드백을 돌릴 것인지’, 그리고 ‘어떤 휴리스틱으로 탐색 범위를 줄일 것인지’다. 이 세 가지를 중심에 두고 function simulator → performance simulator → 프로토타입의 순서로 단계별 개발을 반복하면, NP-hard 문제 속에서도 실무에 맞는 충분히 좋은 해결책을 찾아낼 수 있다.

Leave a comment