몇 달마다 오픈소스 커뮤니티에서는 새로운 AI 프레임워크가 탄생합니다. 대부분은 무거운 C++ 커널을 Python 바인딩으로 감싸거나, 추상화 계층을 너무 높게 쌓아서 런타임 자체의 무게가 서빙하는 모델보다 더 무겁습니다. CatAI는 정반대의 방향으로 나아갑니다. CatAI는 텐서 연산부터 시작하여 전체를 C++로 작성한 네이티브 AI 엔진입니다. 목적은 PyTorch 위에 또 하나의 친숙한 스킨을 입히는 것이 아닙니다. 목적은 하드웨어 경계부터 시작하여 메모리의 모든 바이트와 연산의 모든 사이클을 직접 제어하는 것입니다.

왜 또 다른 엔진이 필요한가?

무언가를 프로덕션 환경에 배포해 본 적이 있다면, 그 고통을 이미 알고 있을 것입니다. 표준 딥러닝 스택을 컨테이너에 넣으면 이미지가 수 기가바이트로 부풀어 오르는 것을 보게 됩니다. 의존성들이 서로 충돌합니다. Python 인터프리터는 지연 시간(latency)을 추가합니다. 연산을 CUDA나 CPU로 라우팅하는 디스패처는 미세한 오버헤드를 발생시키며, 이는 수많은 중첩된 프레임워크 속으로 사라지면 프로파일링하는 것이 불가능해집니다. 엣지 디바이스, 임베디드 로보틱스, 또는 지연 시간에 민감한 백엔드에서 이러한 비용(tax)은 실질적인 문제입니다. 순수 C++ 엔진은 중간 매개체를 제거합니다. 가비지 컬렉션, 글로벌 인터프리터 락(GIL), 언어 간의 복잡한 직렬화 과정 없이 운영체제 및 실리콘과 직접 통신합니다.

CatAI는 이를 타협이 아닌 기능(feature)으로 취급합니다. 이 프로젝트를 C++로 처음부터(from scratch) 작성하는 이유는, 텐서가 RAM에 어떻게 상주하고, 캐시 계층을 통해 어떻게 이동하며, 커널이 스레드 간에 어떻게 스케줄링되는지를 정확히 결정하고 싶기 때문입니다. 이것은 가학적인 행위가 아닙니다. 제한된 하드웨어에서 성능을 극한으로 끌어올릴 때 동작의 예측 가능성을 보장할 수 있는 유일한 방법입니다.

"From Scratch"가 실제로 의미하는 것

대부분의 현대적인 프레임워크에서 텐서 연산은 cuDNN, oneMKL, MPS와 같은 벤더 라이브러리에 대한 불투명한(opaque) 호출로 처리됩니다. 빠른 배포를 위해서는 매우 합리적이지만, 연산의 메커니즘을 숨기게 됩니다. CatAI는 자체적인 핵심 텐서 연산과 메모리 레이아웃을 작성합니다. 이는 다차원 배열을 담는 근본적인 데이터 구조를 설계하고, 스트라이드(stride)와 오프셋(offset) 계산 방식을 선택하며, 액세스 패턴에 따라 데이터를 row-major, column-major 또는 사용자 정의 타일(tiled) 형식으로 저장할지 결정하는 것을 의미합니다.

이것은 심도 있는 시스템 작업입니다. 행렬 곱셈(matrix-multiply) 커널을 직접 작성할 때, 여러분은 torch.matmul 관점에서 생각하는 것을 멈추고 L1 캐시 라인, 레지스터 압박(register pressure), 루프 타일링(loop tiling)에 대해 생각하기 시작합니다. 대상 CPU의 SIMD 너비에 따라 32x32 타일로 블록화할지, 64x64 타일로 할지 결정합니다. AVX-512 로드가 캐시 라인을 넘지 않도록 할당을 64바이트 경계에 맞춥니다. 텐서 저장을 위해 std::vector가 적절한 컨테이너인지, 아니면 사용자 정의 아레나 할당자(arena allocator)가 전체 추론 그래프(inference graph)에 걸쳐 더 나은 지역성(locality)과 제로 단편화(zero fragmentation)를 제공할지 고민합니다.

메모리 레이아웃 또한 매우 중요합니다. channels-last 방식의 이미지 데이터에 channels-first 패턴으로 접근하면 단순한 n차원 배열은 성능을 망가뜨릴 수 있습니다. CatAI에서 이러한 레이아웃은 내보내기(export) 시점에 실행되는 그래프 최적화기에 의해 처리되는 사후 고려 사항이 아니라, 일급 시민(first-class citizens)입니다.

최적화 마인드셋

베어메탈(bare-metal) 최적화는 나노초를 세기 시작하기 전까지는 그저 유행어처럼 들립니다. 이는 중간 결과가 CPU 레지스터나 L1 캐시를 벗어나지 않도록 연산을 융합(fusing)하는 것을 의미합니다. 이는 layer-norm 다음에 GELU가 오는 과정을 단일 커널로 구현하여 DRAM으로의 전체 왕복(round-trip)을 절약하는 것을 의미합니다. 또한 워크로드가 간헐적(bursty)이라는 것을 알고, 매 포워드 패스(forward pass)마다 런타임이 스레드를 생성하고 결합(join)하는 것을 원치 않기 때문에 OpenMP 기본값에 의존하는 대신 직접 스레드 풀을 작성하는 것을 의미합니다.

또한 언제 어셈블리를 작성하지 말아야 하는지를 이해하는 것도 의미합니다. 때로는 컴파일러가 직접 작성한 인트린직(intrinsics)보다 루프를 더 잘 벡터화하기도 합니다. 핵심 원칙은 측정입니다: 프로파일링하고, 가설을 세우고, 변수를 하나 바꾸고, 다시 프로파일링하는 것입니다. 이 엔진은 그러한 고된 작업을 즐기는 사람들에 의해 구축되고 있습니다. 배치(batch)에서 2밀리초를 줄이기 위해 오후 내내 컨볼루션(convolution) 루프를 다시 작성해 본 적이 있다면, 여러분은 이미 이 문화를 이해하고 있는 것입니다.

우리가 찾는 인재

이것은 혼자서 할 수 있는 일이 아닙니다. 백엔드를 무에서 유로 구축하려면 한 사람의 머릿속에서 거의 겹치지 않는 독특한 기술들이 필요합니다. 이 글을 읽으며 합류를 고민하고 있다면, 여러분이 적합할 수 있는 분야는 다음과 같습니다:

  • C++ developers who know modern standards but also know when templates cause compilation bloat. You should be comfortable with raw pointers when necessary and smart pointers when appropriate, and you should care about binary size as much as syntax sugar.

  • Math experts who can derive backward-pass gradients for non-standard activations, reason about numerical stability in mixed-precision training, and optimize algorithms before they become code. If you can explain why a log-sum-exp trick matters, you are in the right mental space.

  • Low-level memory specialists who think about allocators, page faults, and NUMA topology. The engine needs memory pools for graph execution, scratch buffers for kernels, and strategies for reusing tensor storage across training steps without leaking or fragmenting.

  • Systems engineers who understand how a misplaced syscall can stall an entire training loop. Scheduling, I/O, and synchronization primitives are the glue that holds the math together.

You do not need to be a world-class specialist in all four areas. Most contributors will start by owning one kernel or one allocator and learning the rest as the architecture solidifies.

Architecture and Custom Math

The backend logic is being built collaboratively, and that starts with architecture debates. Will the engine use a static computation graph, where the entire model is defined and optimized before runtime? Or will it support eager execution with a tape for automatic differentiation? How will autodiff be represented—operator overloading, source transformation, or a graph IR? These decisions shape everything else.

Custom neural net math means more than reimplementing standard layers. It means the freedom to invent new ones. If you want a convolution variant with a non-standard sparse kernel or an activation function that has no name in the literature, you write the C++ forward and backward passes and plug them directly into the engine. There is no Python API to fight, no monkey-patching required. The math is the code, and the code is the interface.

How to Get Involved

If this resonates, the full project breakdown and current roadmap are documented in detail on the author’s Dev.to post. You can read the specifics, see what has been built so far, and understand exactly where help is needed.

Project details: https://dev.to/banana_cool/building-a-native-c-ai-engine-catai-from-scratch-looking-for-collaborators-l8m

There is also a Telegram group for anyone who wants to hang out, ask questions, or follow progress without committing to a pull request immediately.

Community: https://t.me/GyaanSetuAi

The Real Takeaway

The modern AI stack has become a black box. We treat frameworks like magic appliances: data goes in, model comes out, and we hope the opacity does not bite us at deployment. CatAI rejects that comfort. It is slower to build this way. You will write more code, debug more segfaults, and rethink assumptions that higher-level frameworks hide from you. But you will also understand why the machine behaves the way it does. In an industry where everyone is racing to abstract away the hardware, there is real value in going the other direction and touching the metal. That understanding is what separates someone who calls APIs from someone who builds systems.