카타고 Vulkan Backend 개발기 1편
Katago
2016년 알파고 쇼크를 맞이한지 벌써 10주년이 된 해다. 이후 2018년부터 알파고 제로 논문을 구현한 오픈소스 GTP 모델들이 등장하기 시작했고, 여타 바둑 서비스들도 자체적인 인공지능 바둑 모델을 선보였다. 취업 준비를 한참 하던 2018년도 Leela Zero가 거의 유일한 무료로 이용 가능한 AI 바둑 백엔드였고 프로기사들은 중국의 예후바둑에서 제공하는 절예를 상대로 바둑을 두곤 했다.
그러다 취업 이후에 2020년 즈음해서 Katago라는 새로운 오픈소스 바둑 AI가 등장했고, 그 동안 엄청나게 강해져서 현존하는 바둑 AI는 대부분이 Katago 또는 거기서 포크된 변종들이 차지하고 있다. ㅁㅁ
쉬는 동안 인공지능 관련으로 오픈소스에 기여를 좀 해보고 싶었는데, Leela Zero는 프로젝트가 중단되었고 포크된 프로젝트 Sai도 개발 중단 상태
그러다보니 Katago까지 가게되었다.
Katago의 지원 백엔드
현재 카타고는 공식적으로 5개의 백엔드를 지원한다.
- Eigen
- CPU 백엔드로 AVX512 와 같은 벡터 유닛들을 활용한 라이브러리 Eigen을 이용한다.
- CUDA
- 명실상부 업계의 GPGPU 표준. cudnn 등을 활용해서 구현되어있다.
- OpenCL
- 이제는 사실상 크로노스 그룹의 버려진 자식 OpenCL 백엔드. clblas를 이용하여 구현되어있다.
- TensorRT
- Nvidia 의 추론 최적화 런타임을 이용한 백엔드도 존재한다. 16비트 부동 소수점 자료형과 8비트 정수 연산을 이용한다는데 가려져있으니 알 수 없다.
- Metal
- Apple 기기 전용으로 Metal 과 애플 자체적으로 개발한 추론 가속 라이브러리를 이용하여 구현되었다.
뭐 사실상 있을건 이미 다 있는 상태인데 없는걸 따져보자면
- AMD 의 Rocm
- Intel의 SyCL 두개 정도 되겠다.
1은 풀리퀘스트를 보니 구현한 사람은 있는데 머지가 안된 상태 같고, 2는 없다. 하지만 굳이 공부하거나 할 가치는 없다보니 패스.
Katago 백엔드 구조의 한계
Katago의 백엔드에는 아쉬운 점이 존재하는데, 서로 다른 제조사의 그래픽 카드를 활용하는데 제약이 존재한다는 점이다. 기본적으로 소스코드 내 neuralnet/nninterface.h 에 정의된 구조체 몇개와 함수를 구현하면 컴파일 타임에 매개변수로 전달된 매크로 변수를 가지고 위 5가지 백엔드 중 하나를 선택하는 방식이다.
보드의 상태가 주어지면 몬테카를로 탐색 트리를 위해 위 nninterface.h 에 구현된 ComputeHandle을 GPU마다 할당하고 후보수를 각각의 핸들에 던져주고 탐색을 하는 방식이라 CUDA, TensorRT를 이용하려면 전부 Nvidia GPU 애플은 어차피 폐쇄되어 비슷한 상황이고 멀티 벤더 사용자는 OpenCL이 유일한 답이된다.
그런데 사실상 OpenCL은 도태된 상태다. 2.0에서 거하게 삽질을 하고, 3.0에서는 1.2의 기능들과 몇가지 개선점만 Core Profile로 편입되고 나머지 2.0 피쳐가 확장으로 이용할 수 있게 한 정도이고 공식적으로 GPU 벤더에서 제공하는 AI 가속 코어들을 이용할 방법이 없다.
재미있는 점은 clblas 에 MMA/WMMA 관련 코드들이 존재한다는 점인데 확인해보니 PTX 코드를 직접 인라인으로 박아놨더라...... Nvidia 아니면 사실상 큰 의미가 없는 상태
개선점이 딱 이것밖에 안보였다. 멀티 벤더를 지원할 수 있는 백엔드. 그리고 AI 가속 코어들을 이용할 수 있는
답은 하나였다.
Vulkan
Vulkan은 공식적으로 1.2 버전부터 VK_KHR_cooperative_matrix 라는 확장을 활성화 하면 행렬곱 연산 유닛을 직접적으로 활용하는 것이 가능하다. 물론 벤더가 지원을 해야하지만 아예 없는 OpenCL보다야 낫지않은가?
그 외에도 subgroup 관련 커맨드들을 활용하여 공유 메모리를 이용하는 것보다 빠르게 Wavefront, Warp 단위로 직접적인 처리를 강요할 수 있는 확장 역시 존재한다. 또한 float16 사용과 Int8 등 사용 여부도 확장을 통해 결정할 수 있으니 최선의 선택이다.
문제는...?
Vulkan을 이용한다고 다 해결되는건 아니고 결국 쉐이더 코드를 작성해야 하는데 현업에서 GLSL을 사용해본 결과 그냥 HLSL을 쓰는게 장기적으론 더 좋다고 느껴졌고.... 새로운 쉐이더 언어를 하나 배우는 것과 AI 가속 커널들의 구현을 좀 살펴보니 예전 YOLO 초기모델들에서 타일 기반 행렬곱과 컨볼루션 이용한 정도랑은 비교가 되지 않을 정도로 많은 최적화 구현이 있어 그걸 이해하는 작업이 필요하다.
개발하면서 중간중간 해당 관련 알고리즘들이 포스팅 될 듯 하다.