Product
Optimium은 AI 개발자들을 위한 강력한 추론 엔진으로, 최적의 AI 모델을 쉽고 빠르게 배포할 수 있도록 지원합니다. AI 모델의 연산 속도를 가속하기 위해 저희는 고성능 컴퓨팅을 위한 새로운 언어 Nadya를 직접 개발하였고, 이를 Optimium에 적극 활용하고 있습니다. 오늘은 에너자이가 자체 개발한 ‘Nadya’라는 언어에 대해 자세히 설명하겠습니다.
Sewoong Moh
2024년 4월 2일
안녕하세요. AI 추론 최적화 엔진을 만들고 있는 Optimium 팀의 모세웅(Sewoong Moh)입니다. 이전 게시물에서 말씀드린 것처럼 Optimium은 AI 개발자들을 위한 강력한 추론 엔진으로, 최적의 AI 모델을 쉽고 빠르게 배포할 수 있도록 지원합니다. AI 모델의 연산 속도를 가속하기 위해 저희는 고성능 컴퓨팅을 위한 새로운 언어 Nadya를 직접 개발하였고, 이를 Optimium에 적극 활용하고 있습니다. MADE BY ENERZAi. 오늘은 에너자이가 자체 개발한 ‘Nadya’라는 언어에 대해 자세히 설명하겠습니다.
이전 내용을 잠시 복습하고 넘어갈까요? AI 모델 배포를 위해 Optimium을 활용하는 것의 대표적인 장점들은 아래와 같습니다!
추론 최적화를 위한 소모되는 불필요한 시간을 아낄 수 있습니다.
배포 일정에 쫓겨 AI 모델은 한 땀 한 땀 수동으로 최적화할 필요 없이, Optimium을 통해 자동으로 최적 배포를 위한 모델의 추론 최적화를 수행할 수 있습니다.
기존 프레임워크와 높은 호환성을 자랑합니다.
다양한 프레임워크에서 사용할 수 있는 기본적인 연산자를 지원하고, 설계상 추가로 필요한 연산자가 있다면 언제든 쉽게 확장 가능합니다.
지원되는 Architecture 범위 내에선 제조사에 상관없이 유연한 지원이 가능합니다.
현재 지원하는 마이크로 아키텍처 (x86/x64/Arm) 범위 내에서는 공급업체/브랜드에 관계없이 어디에서나 작동합니다.
Optimium이 다른 State-of-the-art 추론 엔진들보다 압도적인 성능을 제공할 수 있는 것은 주어진 타겟 하드웨어에 맞춰 자동으로 코드를 생성하고 최적화할 수 있기 때문입니다. 이러한 과정은 범용적인 목적으로 만들어진 기존 프로그래밍 언어(ex. Python 혹은 C++)로 구현 불가능한 부분이기 때문에, 저희는 Optimium만을 위한 새로운 프로그래밍 언어 Nadya를 직접 개발했습니다. Nadya는 간단하게 작성할 수 있으면서도 자동 코드 생성을 언어 레벨에서 지원하고, 다양한 타겟 하드웨어에 맞는 최적화 파이프라인을 내장하고 있습니다.
Nadya가 강력한 이유 1 : Metaprogramming
Metaprogramming이란 프로그램이 스스로 프로그램을 짤 수 있도록 하는 것을 의미합니다. 쉽게 말해, 개발자가 직접 실제로 돌아갈 코드를 프로그래밍하는 것이 아닌, 앞으로 실행될 코드를 생성하는 프로그램을 만듭니다. Python도 일부 Metaprogramming과 비슷한 기능인 Decorator이나 Metaclass가 있습니다. C++의 경우에도 템플릿이나 매크로를 통한 Metaprogramming 기능이 일부 지원되지만, 대규모 데이터를 다루거나 복잡한 코드를 생성하고자 하면 제한적인 기능 때문에 매우 복잡해져서 사실상 사용이 어렵습니다.
하지만, Nadya는 설계부터 이러한 Metaprogramming을 쉽게 지원할 수 있도록 많은 노력을 기울였습니다. Nadya를 사용하면 특별히 복잡한 기능을 배울 필요가 없이 개발자가 일반적인 데이터를 다루듯이 아주 쉽게 코드 생성을 할 수 있습니다. 따라서 Nadya는 지금까지 그 어떤 프로그래밍 언어도 지원하지 못하는 아주 강력하고 유연한 Metaprogramming을 지원할 수 있게 되었습니다.
💡 <Metaprogramming>
· 객체를 생성하지 않더라도 타입에 어떠한 값을 부여할 수 있고, 또 그 타입들을 가지고 연산을 할 수 있습니다.· 컴파일 타임에 정적으로 계산되는 부분을 미리 계산할 수 있어 프로그램 실행 속도를 향상할 수 있다는 장점이 있습니다.
· 하지만 컴파일 타임에 연산하는 것이기 때문에 디버깅이 불가능하여 메타 프로그래밍으로 작성된 코드는 버그를 찾는 것이 매우 어렵습니다.
그렇다면 Metaprogramming이 Optimium의 성능 최적화에 왜 중요할까?
복잡한 Metaprogramming을 거치지 않고 그냥 짜면 안 되느냐는 질문이 있을 수도 있습니다. 물론 그래도 되지만, 그렇다면 개발자는 훨씬 더 긴 코드를, 여러 번 만들어야 할 것입니다. 대부분의 컴퓨터는 입맛이 아주 까다로워서 빠르게 동작하는 프로그램의 형태가 각자 다릅니다. 같은 행렬 연산 알고리즘이라고 하더라도, 스마트폰에 많이 사용되는 Arm 기반 칩에서 빠르게 동작하는 코드, Intel 칩에서 잘 동작하는 코드는 각자 다릅니다. 심지어 같은 Intel이나 Arm 기반 칩이더라도, 종류나 세대에 따라 달라지기도 합니다. 이렇게 모든 경우의 수를 고려하려면 정말로 많은 코드를 짜야 합니다. 실제로 TensorFlow Lite 등 기존 추론 엔진의 경우 레이어 1개를 최적화하기 위해 정말 많은 종류의 알고리즘을 하드웨어별로 다르게 제작합니다.
하지만 Nadya와 같은 Metaprogramming이 가능하다면 이야기가 달라집니다. 컴파일 시간에 이미 어느 하드웨어에서 실행될지 알 수 있으므로 해당 하드웨어에 맞게 코드를 생성하기만 하면 추가적인 수고로움을 줄일 수 있습니다. 따라서 Metaprogramming을 사용한 100줄의 Nadya 프로그램은 다른 프로그래밍 언어로 만들어진 1,000줄 ~ 10,000줄의 코드보다 뛰어난 성능을 낼 수 있습니다. 바로 이러한 장점 때문에 저희 팀은 효율을 극대화하여 적은 인원이지만 많은 개발자가 참여한 기존의 추론 엔진보다 더 수준 높은 최적화를 할 수 있었습니다.
Optimium은 Nadya의 Metaprogramming을 이용해 다양한 방법으로 코드를 생성하여 여러분의 하드웨어에서 가장 빠르게 동작하는 구현을 찾아냅니다. 이렇게 해서 나온 프로그램은 여러분의 컴퓨터 상황에 맞춰 만들어지게 됩니다. 그러면 여러분의 컴퓨터는 마치 기성품 운동화만 신다가 맞춤 제작된 수제 운동화를 신은 마라톤 선수처럼 더 빠르고 효율적으로 프로그램을 실행하게 됩니다. 이것이 Optimium이 하드웨어의 스펙과 종류에 구애받지 않고 우수한 성능을 제공하는 이유입니다.
Metaprogramming을 손쉽게 활용하기 위한 Nadya의 노력
Metaprogramming을 위해 컴파일 시간에 실행되는 코드와 실제로 컴파일이 끝난 후 실행되는 코드 사이에 차이가 거의 존재하지 않습니다. 심지어 Metaprogramming을 통해 생성된 코드를 그대로 다시 컴파일 시간에 실행할 수도 있습니다.
매우 직관적인 방법으로 프로그램에서의 표현 식을 값처럼 다룰 수 있습니다. 서로 합성을 할 수도 있고, 함수 인자로 넘길 수도 있습니다.
표현식 내부에 다른 표현식을 넣어서 보다 직관적으로 구성할 수 있습니다.
Nadya가 강력한 이유 2: 스마트한 컴파일러 최적화 파이프라인
Nadya가 Metaprogramming을 통하여 코드를 생성하여도 실행이 되기 위해선 컴퓨터가 읽을 수 있는 기계어로 바꾸어야 합니다. 이 과정은 컴파일러가 해줍니다. 하지만 Nadya는 단순하게 1 대 1 매칭하는 단순한 방식으로 코드를 컴파일하지 않습니다. Nadya에서는 아래와 같이 다양한 파이프라인들을 통하여 컴파일이 진행됩니다.
1.자동 병렬화
Nadya 컴파일러는 스스로 Loop을 분석해 병렬화해도 문제가 없는지 판단하는 기능이 있습니다.
개발자의 컴퓨터 상황(Multi Core 사용 가능 여부, 전력 이슈 존재 여부 등)이 병렬화가 가능한 환경일 때엔 아래의 코드처럼 “attr[Parallel : true]” 을 주어서 자동 병렬화를 사용할 수 있습니다.