Cứ vài tháng một lần, cộng đồng mã nguồn mở lại cho ra đời một framework AI mới. Hầu hết chúng chỉ là các lớp bọc (wrap) Python xung quanh các nhân (kernel) C++ nặng nề, hoặc chúng chồng chất các lớp trừu tượng cao đến mức chỉ riêng runtime đã nặng hơn cả các mô hình mà chúng phục vụ. CatAI đi theo hướng ngược lại. Đây là một engine AI thuần túy được viết hoàn toàn bằng C++, được xây dựng từ nền tảng toán học tensor trở lên. Mục tiêu không phải là tạo ra thêm một lớp vỏ thân thiện bao quanh PyTorch. Mục tiêu là kiểm soát từng byte bộ nhớ và từng chu kỳ tính toán, bắt đầu từ ranh giới phần cứng.

Tại sao lại cần thêm một engine khác?

Nếu bạn đã từng triển khai bất cứ thứ gì lên môi trường production, bạn đã biết nỗi đau đó. Hãy thử đưa một stack deep-learning tiêu chuẩn vào một container và xem dung lượng image phình to lên đến hàng gigabyte. Các dependency xung đột lẫn nhau. Trình thông dịch Python làm tăng độ trễ. Bộ điều phối (dispatcher) điều hướng các toán tử (ops) đến CUDA hoặc CPU tạo ra những overhead tinh vi, thứ mà việc profiling trở nên bất khả thi khi nó bị ẩn sâu trong hàng tá framework lồng nhau. Đối với các thiết bị edge, robot nhúng, hoặc các backend nhạy cảm với độ trễ, cái "thuế" đó là có thật. Một engine C++ thuần túy sẽ loại bỏ trung gian. Nó giao tiếp trực tiếp với hệ điều hành và silicon, không có garbage collection, không có global interpreter lock, và không có các bước serialization phức tạp giữa các ngôn ngữ.

CatAI coi đây là một tính năng, chứ không phải một sự thỏa hiệp. Dự án đang được viết lại từ đầu bằng C++ vì tác giả muốn quyết định chính xác cách các tensor tồn tại trong RAM, cách chúng di chuyển qua các phân cấp cache, và cách các kernel được lập lịch trên các luồng (threads). Đó không phải là sự khổ dâm. Đó là cách duy nhất để đảm bảo hành vi có thể dự đoán được khi bạn đang cố gắng vắt kiệt hiệu năng từ phần cứng hạn chế.

"Từ đầu" thực sự có nghĩa là gì

Trong hầu hết các framework hiện đại, toán học tensor được xử lý thông qua các lời gọi hàm không minh bạch (opaque calls) vào các thư viện của nhà cung cấp như cuDNN, oneMKL, hoặc MPS. Điều này hoàn toàn hợp lý để đẩy nhanh tốc độ phát hành, nhưng nó che giấu cơ chế vận hành của các thao tác. CatAI đang tự viết các toán học tensor cốt lõi và các bố cục bộ nhớ (memory layouts) của riêng mình. Điều đó có nghĩa là thiết kế các cấu trúc dữ liệu cơ bản chứa các mảng đa chiều, lựa chọn cách tính toán strides và offsets, và quyết định xem nên lưu trữ dữ liệu theo định dạng row-major, column-major, hay các định dạng tiled tùy chỉnh tùy thuộc vào mô hình truy cập (access pattern).

Đây là công việc hệ thống chuyên sâu. Khi bạn tự tay viết một kernel nhân ma trận, bạn sẽ ngừng nghĩ về torch.matmul và bắt đầu nghĩ về các dòng cache L1, áp lực thanh ghi (register pressure), và loop tiling. Bạn quyết định xem nên block cho các tile 32x32 hay 64x64 dựa trên độ rộng SIMD của CPU mục tiêu. Bạn căn chỉnh các vùng cấp phát theo ranh giới 64-byte để các lệnh load AVX-512 không vượt quá các dòng cache. Bạn đặt câu hỏi liệu std::vector có phải là container phù hợp để lưu trữ tensor hay không, hoặc liệu một arena allocator tùy chỉnh có mang lại tính cục bộ (locality) tốt hơn và không gây phân mảnh (zero fragmentation) trên toàn bộ đồ thị suy luận (inference graph) hay không.

Bố cục bộ nhớ cũng quan trọng không kém. Một mảng n-chiều ngây thơ có thể giết chết hiệu năng nếu dữ liệu hình ảnh định dạng channels-last được truy cập theo mô hình channels-first. Trong CatAI, các bố cục này là những thành phần cốt lõi (first-class citizens), chứ không phải là những thứ được tính đến sau bởi một bộ tối ưu hóa đồ thị chạy vào thời điểm export.

Tư duy tối ưu hóa

Tối ưu hóa bare-metal nghe có vẻ giống như một thuật ngữ hào nhoáng cho đến khi bạn bắt đầu đếm từng nano giây. Nó có nghĩa là hợp nhất (fusing) các thao tác để các kết quả trung gian không bao giờ rời khỏi các thanh ghi CPU hoặc cache L1. Nó có nghĩa là triển khai một layer-norm theo sau bởi một GELU như một kernel duy nhất, giúp tiết kiệm toàn bộ một chu kỳ truy cập (round-trip) tới DRAM. Nó có nghĩa là tự viết thread pool của riêng bạn thay vì dựa vào các mặc định của OpenMP, bởi vì bạn biết khối lượng công việc của mình có tính bùng phát (bursty) và bạn không muốn runtime phải tạo (spawning) và kết hợp (joining) các luồng trong mỗi lượt forward pass.

Nó cũng có nghĩa là hiểu khi nào không nên viết assembly. Đôi khi trình biên dịch vector hóa một vòng lặp tốt hơn cả các hàm intrinsics được viết bằng tay. Kỷ luật ở đây là sự đo lường: profiling, đưa ra giả thuyết, thay đổi một biến số, và profiling lại. Engine này đang được xây dựng bởi những người yêu thích sự khổ luyện đó. Nếu bạn đã từng dành cả một buổi chiều để viết lại một vòng lặp convolution nhằm cắt giảm hai mili giây cho một batch, bạn đã hiểu văn hóa này.

Chúng tôi cần ai

Đây không phải là một màn trình diễn của một người. Xây dựng một backend từ con số không đòi hỏi những kỹ năng riêng biệt mà hiếm khi xuất hiện cùng lúc trong một bộ não. Nếu bạn đang đọc những dòng này và cân nhắc xem có nên tham gia hay không, đây là những vị trí bạn có thể phù hợp:

  • Các nhà phát triển C++ những người nắm vững các tiêu chuẩn hiện đại nhưng cũng biết khi nào các template gây ra sự phình to khi biên dịch (compilation bloat). Bạn nên thoải mái với con trỏ thô (raw pointers) khi cần thiết và con trỏ thông minh (smart pointers) khi phù hợp, và bạn cần quan tâm đến kích thước file nhị phân cũng nhiều như quan tâm đến syntax sugar.

  • Các chuyên gia Toán học những người có thể đạo hàm gradient của bước lan truyền ngược (backward-pass) cho các hàm kích hoạt phi tiêu chuẩn, lập luận về độ ổn định số học trong huấn luyện với độ chính xác hỗn hợp (mixed-precision training), và tối ưu hóa các thuật toán trước khi chúng trở thành mã nguồn. Nếu bạn có thể giải thích tại sao thủ thuật log-sum-exp lại quan trọng, bạn đang có tư duy phù hợp.

  • Các chuyên gia bộ nhớ cấp thấp những người luôn suy nghĩ về bộ cấp phát (allocators), lỗi trang (page faults) và cấu trúc NUMA. Engine này cần các vùng đệm bộ nhớ (memory pools) để thực thi đồ thị, các bộ đệm tạm (scratch buffers) cho các kernel, và các chiến lược để tái sử dụng bộ nhớ tensor qua các bước huấn luyện mà không gây rò rỉ hoặc phân mảnh.

  • Các kỹ sư hệ thống những người hiểu rõ một lời gọi hệ thống (syscall) đặt sai chỗ có thể làm đình trệ toàn bộ vòng lặp huấn luyện như thế nào. Lập lịch (Scheduling), I/O và các nguyên ngữ đồng bộ hóa (synchronization primitives) chính là chất keo gắn kết toán học lại với nhau.

Bạn không cần phải là một chuyên gia đẳng cấp thế giới trong cả bốn lĩnh vực. Hầu hết những người đóng góp sẽ bắt đầu bằng việc đảm nhận một kernel hoặc một bộ cấp phát và học hỏi những phần còn lại khi kiến trúc dần được củng cố.

Kiến trúc và Toán học Tùy chỉnh

Logic backend đang được xây dựng thông qua sự cộng tác, và điều đó bắt đầu từ những cuộc tranh luận về kiến trúc. Liệu engine sẽ sử dụng một đồ thị tính toán tĩnh (static computation graph), nơi toàn bộ mô hình được định nghĩa và tối ưu hóa trước khi chạy? Hay nó sẽ hỗ trợ thực thi tức thời (eager execution) với một "tape" để tự động vi phân (automatic differentiation)? Việc autodiff sẽ được biểu diễn như thế nào—nạp chồng toán tử (operator overloading), biến đổi mã nguồn (source transformation), hay một IR đồ thị (graph IR)? Những quyết định này sẽ định hình mọi thứ khác.

Toán học mạng thần kinh tùy chỉnh không chỉ đơn thuần là tái triển khai các lớp tiêu chuẩn. Nó có nghĩa là sự tự do để phát minh ra những lớp mới. Nếu bạn muốn một biến thể tích chập (convolution) với một sparse kernel phi tiêu chuẩn hoặc một hàm kích hoạt chưa có tên trong các tài liệu nghiên cứu, bạn chỉ cần viết các bước lan truyền tiến (forward) và lan truyền ngược (backward) bằng C++ và cắm trực tiếp chúng vào engine. Không có Python API nào để phải đối phó, cũng không cần đến monkey-patching. Toán học chính là mã nguồn, và mã nguồn chính là giao diện.

Cách thức tham gia

Nếu điều này thu hút bạn, bản phân tích chi tiết dự án và lộ trình hiện tại đã được tài liệu hóa cụ thể trong bài đăng trên Dev.to của tác giả. Bạn có thể đọc các chi tiết cụ thể, xem những gì đã được xây dựng cho đến nay và hiểu chính xác nơi cần sự giúp đỡ.

Chi tiết dự án: https://dev.to/banana_cool/building-a-native-c-ai-engine-catai-from-scratch-looking-for-collaborators-l8m

Ngoài ra còn có một nhóm Telegram dành cho bất kỳ ai muốn tham gia thảo luận, đặt câu hỏi hoặc theo dõi tiến độ mà chưa cần cam kết thực hiện một pull request ngay lập tức.

Cộng đồng: https://t.me/GyaanSetuAi

Bài học cốt lõi

Ngăn xếp AI hiện đại đã trở thành một hộp đen. Chúng ta đối xử với các framework như những thiết bị ma thuật: dữ liệu đưa vào, mô hình đưa ra, và chúng ta hy vọng sự thiếu minh bạch đó sẽ không gây rắc rối khi triển khai. CatAI từ chối sự thoải mái đó. Xây dựng theo cách này sẽ chậm hơn. Bạn sẽ phải viết nhiều mã hơn, gỡ lỗi nhiều lỗi segfault hơn và phải tư duy lại những giả định mà các framework cấp cao hơn đã che giấu khỏi bạn. Nhưng bạn cũng sẽ hiểu tại sao máy móc lại hoạt động theo cách nó đang làm. Trong một ngành công nghiệp mà mọi người đều đang chạy đua để trừu tượng hóa phần cứng, việc đi theo hướng ngược lại và tiếp cận trực tiếp phần cứng (touching the metal) mang lại giá trị thực sự. Sự hiểu biết đó là điều phân biệt giữa một người chỉ biết gọi API và một người xây dựng nên các hệ thống.