Все Изображения AI-генерированные автором бесплатно с NightCafe Studio - см. подкладку для ссылки.
Все Изображения AI-генерированные автором бесплатно с NightCafe Studio - см. подкладку для ссылки.
Все Изображения AI-генерированные автором бесплатно с NightCafe Studio - см. подкладку для ссылки.Эпоха высокопроизводительных вычислений была определена одним названием:Чудесная
ЧудеснаяПлатформа NVIDIA разблокировала мощность GPU, став де-факто стандартом.
Более десяти лет программирование GPU означало программирование в CUDA.
Это доминирование, однако, создало клетку, замкнув прогресс в одном продавце.
Это доминирование, однако, создало клетку, замкнув прогресс в одном продавце.
Это доминирование, однако, создало клетку, замкнув прогресс в одном продавце.Но сегодня, в середине 2025 года — все меняется.
Но сегодня, в середине 2025 года — все меняется.
The computing world is now undergoing a radical transformation towards heterogeneity.
Мы наблюдаем распространение специализированного аппаратного обеспечения:
-
Intel Gaudi Series:
Intel's Gaudi processors are designed specifically for deep learning training and inference, offering a competitive alternative to Nvidia's GPUs.
-
AMD Instinct MI Series:
AMD's MI series of GPUs is designed for high-performance computing and AI workloads, providing an alternative to Nvidia's data center GPUs.
-
Groq Tensor Streaming Processor (TSP):
Groq's TSP architecture is designed for low-latency inference and high throughput, particularly for large language models.
-
Google TPUs (Tensor Processing Units):
Google's TPUs are custom-designed chips optimized for machine learning workloads, particularly in Google's cloud infrastructure.
-
AWS Trainium:
AWS Trainium is a chip designed for machine learning training, offering high performance and cost-effectiveness.
И все больше и больше стартапов, которые строят персонализированные силиконовые чипы, появляются каждый день.
И все больше и больше стартапов, которые строят персонализированные силиконовые чипы, появляются каждый день.Этот новый, разнообразный ландшафт требует новой философии программирования.
Многоуровневое промежуточное представление (MLIR) и язык программирования Mojo
This is not just another competitor; they represent a fundamental paradigm shift.
Это революция в том, как мы проектируем, оптимизируем и развертываем программное обеспечение для любого оборудования.
This is a revolution in how we design, optimize, and deploy software for any hardware.
This article will deeply explore the architectural chasm between CUDA and MLIR.
- Мы будем использовать полные примеры рабочего кода, чтобы предоставить конкретное, практическое сравнение.
- Мы рассмотрим, почему MLIR является прорывом по сравнению со своим почетным предшественником, LLVM.
- Мы будем утверждать, что Mojo является превосходным долгосрочным решением.
- Мы проанализируем, почему этот новый стек является игровым преобразователем по цене и скорости.
Это воздействие распространяется на критические развивающиеся области, такие какGenerative AI, Quantum ComputingИ дажеBlockchain.
Мы также будем смотреть в будущее, охватываяmining ASICs,Neuromorphic Computing, иspecialized hardwareдля редких потоков данных, с которыми GPU плохо справляются.
Это история конца одной эпохи и начала новой.
Это история конца одной эпохи и начала новой.
Чтобы понять масштабы этой смены, мы должны сначалаunderstand the four key players.
1. CUDA: The Powerful, Proprietary Incumbent
Оригинальное название: CUDA: The Powerful, Proprietary IncumbentCUDA stands for Compute Unified Device Architecture.
Это параллельная вычислительная платформа и модель программирования NVIDIA.
Он позволяет разработчикам писать код, похожий на C++, называемый ядрами, которые работают на GPU NVIDIA.
CUDA's Strengths:
Сильные стороны куды:Its ecosystem of libraries is mature and unmatched:
- Mathematical Libraries:
- cuBLAS: For basic linear algebra subprograms (BLAS).
- cuRAND: For random number generation.
- cuFFT: For Fast Fourier Transforms.
- cuSPARSE: For sparse matrix operations.
- cuTENSOR: For tensor operations.
- cuSOLVER: For dense and sparse direct solvers.
- Parallel Algorithm Libraries:
- nvGRAPH: For graph algorithms.
- Thrust: For parallel algorithms and data structures.
- Communication Libraries:
- NVSHMEM: For partitioned global address space (PGAS) programming.
- NCCL: For multi-GPU and multi-node collective communication.
- Deep Learning Libraries:
- cuDNN: For deep neural network computations.
- TensorRT: For optimized deep learning inference.
- Riva: For conversational AI.
- DALI: For data loading and augmentation for deep learning.
Он обеспечивает прямой, низкий уровень контроля над аппаратным обеспечением, обеспечивая пиковую производительность для экспертов.
Его долгая история построила огромное сообщество с обширной документацией и поддержкой.
Its long history has built a massive community with vast documentation and support.
CUDA's Fatal Flaw: The Cage
Vendor Lock-In: CUDA code runs only on NVIDIA GPUs.
толькоЭто связывает разработчиков и целые отрасли к одному, дорогостоящему поставщику оборудования.
Это подавляет конкуренцию и ограничивает свободу выбора наилучшего оборудования для работы.
Двуязычная проблема: основная неразбериха в области ИИ и научных вычислений.
Исследователи разработали прототип на языке высокого уровня, таком как Python, из-за его простоты и скорости итерации.
Но для производства критический для производительности код должен быть полностью переписан на низком уровне C++/CUDA.
But for production, performance-critical code must be completely rewritten in low-level C++/CUDA.
Это создает болезненное и дорогостоящее отключение, замедляя путь от исследований до развертывания.
Сложность программирования :
CUDA является мощным, но известным образом сложным и сложным.
Разработчик вынужден быть
Ручной менеджер памяти, передающий данные между процессором (хостом) и GPU (устройством).
Разработчик также должен быть аппаратным планировщиком, управляющим блоками нитей, сетками и синхронизацией.
Эта сложность является крутой кривой обучения и частым источником тонких ошибок.
2. LLVM: The Foundation and Its "Semantic Gap”
LLVM: Фонд и его «семантический разрыв»Проект LLVM представляет собой совокупность модульных и многоразовых компиляционных технологий.
Его ядром является LLVM Intermediate Representation (IR), язык низкого уровня, похожий на сборку.
LLVM стал стандартом для современных компиляторов, особенно для процессоров.
Компилятор frontend (например, Clang для C++) переводит исходный код в LLVM IR.
Затем бак-энд LLVM оптимизирует этот IR и преобразует его в машинный код для конкретного процессора.
Эта модульность была революционной для своего времени.
Тем не менее, LLVM был разработан для CPU-центрированного мира.
Его IR слишком низкий для нового мира гетерогенного оборудования.
Он теряет важную информацию высокого уровня из исходного кода, проблема, известная как «семантический разрыв».
Например, при составлении модели TensorFlow теряется знание о том, что операция является Convolution.
LLVM IR видит только общий набор циклов и арифметических инструкций.
Это мешает компилятору выполнять мощные, специфические для домена оптимизации.
Он больше не понимает высокого уровня намерения программиста.
В этом суть «семантического разрыва».
И именно эту проблему решила MLIR.
It loses crucial high-level information from the source code, a problem known as the "semantic gap."
For example, when compiling a TensorFlow model, the knowledge that an operation is a Convolution is lost.
LLVM IR only sees a generic collection of loops and arithmetic instructions.
This prevents the compiler from performing powerful, domain-specific optimizations.
It no longer understands the programmer's high-level intent.
This is the essence of the “semantic gap problem.”
And this problem is what MLIR has Solved.
3. MLIR: The Universal Translator for Hardware
MLIR: Универсальный переводчик для аппаратного обеспеченияMLIR родился в Google из необходимости компилировать TensorFlow для CPU, GPU и их TPU.
Они поняли, что одного низкоуровневого IR LLVM недостаточно.
Прорыв MLIR - это унифицированная инфраструктура для определения и составления нескольких IR.
Эти компостируемые IR называются диалектами.
ДиалектыMLIR подобен универсальному переводчику, который умеет все, от концепций высокого уровня до деталей машин низкого уровня.
Диалект высокого уровня может непосредственно представлять конкретные понятия домена.
For example, a "TensorFlow dialect" has an operation for tf.conv2d.
A "Linear Algebra dialect" has an operation for linalg.matmul.
Это сохраняет критическую семантическую информацию, которую LLVM отбрасывает.
Это позволяет использовать мощную компиляторную стратегию, называемуюПостепенное снижение* * * *
Постепенное снижение
- Компилятор начинается с диалектного представления высокого уровня.
- Он выполняет оптимизацию на высоком уровне, специфическую для домена, на этом диалекте.
- Затем он постепенно «снижает» код через серию промежуточных диалектов.
- Каждый промежуточный диалект выполняет свои специфические оптимизации.
- Наконец, он достигает диалекта низкого уровня, как диалект LLVM IR, для окончательного генерации машинного кода.
This process preserves high-level context for as long as possible.
This enables vastly superior optimizations for any hardware target.
MLIR - это отсутствующая связь между языками высокого уровня и разнообразным кремнием.
MLIR - это отсутствующая связь между языками высокого уровня и разнообразным кремнием.
MLIR - это отсутствующая связь между языками высокого уровня и разнообразным кремнием.4. Mojo: The User-Friendly Face of MLIR's Power
Mojo: удобное для пользователя лицо силы MLIRЕсли MLIR - это мощный, сложный движок, то Mojo - это тонкий, интуитивный пользовательский интерфейс.
Mojo был создан Крисом Латнером, первоначальным архитектором LLVM и языка Swift.
Mojo был создан Крисом Латнером, первоначальным архитектором LLVM и языка Swift.
Он разработан с первых принципов, чтобы быть идеальным языком для эры MLIR.
В этом смысле это самый технологически продвинутый язык сегодня.
Даже Rust основан на LLVM и имеет все недостатки LLVM.
Even Rust is based on LLVM and has all of LLVM’s shortcomings.
Mojo является единственным основным языком программирования, основанным на MLIR.
Mojo is the only major programming language today based on MLIR.
Mojo's Key Features:
Суперкомплект Python
- Mojo стремится к полной совместимости с существующей экосистемой Python.
- Это свойство убийцы!
- Он позволяет разработчикам импортировать и использовать любую библиотеку Python, такую как NumPy, Pandas или Matplotlib.
- It completely bypasses the "cold start" problem that new languages face by tapping into Python's vast ecosystem.
Особенности программирования настоящих систем:
- В отличие от Python, Mojo является скомпилированным языком с сильным статическим шрифтом.
- Это устраняет целые классы ошибок и позволяет оптимизировать производительность на уровне C++.
- Он вводит современные концепции управления памятью, такие как владение и заимствование (от Rust) для безопасности памяти без перекрытия коллектора мусора.
Интеграция MLIR первого класса:
- Mojo раскрывает полную мощность MLIR непосредственно разработчику.
- Программисты могут писать питонический код высокого уровня для большинства своих приложений.
- Когда требуется максимальная производительность, они могут использовать конкретные диалекты MLIR и писать ядра низкого уровня.
- По сути, все это можно сделать в одном файле, на одном языке.
Моджо элегантно решает «проблему двух языков».
Mojo elegantly solves the "two-language problem."
Full Code Examples and Analysis
Полные примеры кода и анализТеория одна вещь, практика другая.
Следующие полные примеры рабочего кодекса -
Это покажет глубокие различия между двумя парадигмами.
Example 1: Matrix Multiplication
Пример 1: Умножение матрицыЭто «Здравствуйте, мир!» высокопроизводительных вычислений, и это ясно показывает основную философию каждой платформы.
The Full CUDA Implementation
Это полная, компилируемая программа CUDA для умножения матриц.
(включает в себя C++)
// Filename: matmul.cu
// To compile: nvcc matmul.cu -o matmul_cuda
#include <iostream>
#include <vector>
#include <cuda_runtime.h>
// Helper to check for CUDA errors
#define CUDA_CHECK(err) { \
cudaError_t err_code = err; \
if (err_code != cudaSuccess) { \
std::cerr << "CUDA Error: " << cudaGetErrorString(err_code) << " at line " << __LINE__ << std::endl; \
exit(EXIT_FAILURE); \
} \
}
// CUDA Kernel for Matrix Multiplication (Device Code)
__global__ void matrixMulKernel(float* C, const float* A, const float* B, int N) {
// Calculate the global row and column index of the element
int row = blockIdx.y * blockDim.y + threadIdx.y;
int col = blockIdx.x * blockDim.x + threadIdx.x;
// Boundary check to avoid accessing out-of-bounds memory
if (row < N && col < N) {
float p_value = 0.0f;
// Each thread computes one element of the result matrix C
for (int k = 0; k < N; ++k) {
p_value += A[row * N + k] * B[k * N + col];
}
C[row * N + col] = p_value;
}
}
// Main function (Host Code)
int main() {
const int N = 256;
const int size = N * N * sizeof(float);
// Step 1. Allocate host memory
std::vector<float> h_A(N * N);
std::vector<float> h_B(N * N);
std::vector<float> h_C(N * N);
// Initialize host matrices
for (int i = 0; i < N * N; ++i) {
h_A[i] = static_cast<float>(rand()) / RAND_MAX;
h_B[i] = static_cast<float>(rand()) / RAND_MAX;
}
// Step 2. Allocate device memory
float *d_A, *d_B, *d_C;
CUDA_CHECK(cudaMalloc((void**)&d_A, size));
CUDA_CHECK(cudaMalloc((void**)&d_B, size));
CUDA_CHECK(cudaMalloc((void**)&d_C, size));
// Step 3. Copy matrices from host to device
std::cout << "Copying data from host to device..." << std::endl;
CUDA_CHECK(cudaMemcpy(d_A, h_A.data(), size, cudaMemcpyHostToDevice));
CUDA_CHECK(cudaMemcpy(d_B, h_B.data(), size, cudaMemcpyHostToDevice));
// Step 4. Define kernel launch configuration
// Use 16x16 threads per block, a common choice
dim3 threadsPerBlock(16, 16);
// Calculate the number of blocks needed in each dimension
dim3 numBlocks((N + threadsPerBlock.x - 1) / threadsPerBlock.x, (N + threadsPerBlock.y - 1) / threadsPerBlock.y);
// Step 5. Launch the kernel on the device
std::cout << "Launching kernel..." << std::endl;
matrixMulKernel<<<numBlocks, threadsPerBlock>>>(d_C, d_A, d_B, N);
CUDA_CHECK(cudaGetLastError());
CUDA_CHECK(cudaDeviceSynchronize()); // Wait for the kernel to finish
// Step 6. Copy the result matrix back from device to host
std::cout << "Copying result from device to host..." << std::endl;
CUDA_CHECK(cudaMemcpy(h_C.data(), d_C, size, cudaMemcpyDeviceToHost));
// Step 7. Free device memory
CUDA_CHECK(cudaFree(d_A));
CUDA_CHECK(cudaFree(d_B));
CUDA_CHECK(cudaFree(d_C));
std::cout << "CUDA Matrix Multiplication finished successfully." << std::endl;
// (Optional: Add verification step here)
return 0;
}
Analysis of the CUDA Code:
Анализ кода CUDA:В коде доминирует котел и управление низким уровнем.
Шаги 1, 2, 3, 6 и 7 предназначены исключительно для управления памятью через границу CPU/GPU.
Это скучно, склонно к ошибкам и скрывает основной алгоритм.
ТЭ
Этот код фундаментально и постоянно связан с архитектурой аппаратного обеспечения NVIDIA.
Действительный алгоритм — три встроенных цикла — представляет собой крошечную долю общего кода.
Психическая ответственность программиста тратится на управление аппаратным обеспечением, а не на саму проблему.
The programmer's mental overhead is spent on hardware management, not on the problem itself.
The Full Mojo Implementation
The Full Mojo ImplementationЭта версия Mojo достигает того же результата с захватывающей простотой и мощью.
(Мужчина )
# Filename: matmul.mojo
# To run: mojo matmul.mojo
from memory import DType, Tensor
from random import rand
from time import now
fn matmul_naive(C: Tensor[DType.float32], A: Tensor[DType.float32], B: Tensor[DType.float32]):
"""A naive, high-level implementation of matrix multiplication."""
let N = A.dim(0)
let M = A.dim(1)
let P = B.dim(1)
for i in range(N):
for j in range(P):
var sum: Float32 = 0.0
for k in range(M):
sum += A.load(i, k) * B.load(k, j)
C.store(i, j, sum)
fn main():
let N = 256
# 1. Allocate and initialize tensors.
# Mojo's Tensor handles memory allocation automatically.
# The compiler will place it in the most appropriate memory space.
var A = Tensor[DType.float32](N, N)
var B = Tensor[DType.float32](N, N)
var C = Tensor[DType.float32](N, N)
for i in range(N):
for j in range(N):
A.store(i, j, rand[DType.float32]())
B.store(i, j, rand[DType.float32]())
print("Starting Mojo Matrix Multiplication...")
let start_time = now()
# 2. Call the function.
# The MLIR-based compiler optimizes this high-level code.
# It can automatically tile, vectorize, and parallelize this code
# for the target hardware (CPU, GPU, etc.).
matmul_naive(C, A, B)
let end_time = now()
let duration_ms = (end_time - start_time) / 1_000_000.0
print("Mojo Matrix Multiplication finished successfully.")
print("Execution time:", duration_ms, "ms")
# (Optional: Print a corner of the result matrix to verify)
print("Result C[0,0]:", C.load(0,0))
}
И это все!
The Mojo Approach is Far Superior
Подход Mojo намного вышеProgrammability and Focus:
- Код Mojo чист и напрямую выражает алгоритм.
- Программист фокусируется на том, что (математика), а не на том, как (передача памяти).
- Нет ручной cudaMalloc, cudaMemcpy или cudaFree.
- Весь этот класс ошибок исчез.
Абстракция с выступлением:
- Простые гнездящиеся петли – это не то, что выполняется.
- The MLIR-based compiler performs sophisticated transformations.
- Это превращает этот простой код в высокооптимизированное ядро.
- Он может автоматически применять плитку, векторизацию и параллелизацию.
- Программист может добавлять подсказки (например, @vectorize или @parallelize) для руководства компилятором, добиваясь контроля без сложности.
Portability (The Ultimate Advantage):
- Это решающий момент.
- Тот же файл matmul.mojo можно перекомпилировать для запуска на NVIDIA GPU, AMD GPU, Intel CPU с AVX512 или Google TPU.
- Логика остается прежней; компиляторный резерв меняется.
- The CUDA code would require a complete, costly rewrite for each new hardware target.
- Mojo предлагает «переносимость производительности», нарушая блокировку поставщика и предотвращая будущее кода.
MLIR-based Mojo is undeniably set to replace LLVM-based CUDA, and developers will enjoy the change!
MLIR-based Mojo is undeniably set to replace LLVM-based CUDA, and developers will enjoy the change!
For more on Mojo, refer to the article below:
Example 2: Gen AI and the Transformer Attention Mechanism
Пример 2: генный ИИ и механизм внимания трансформаторовМеханизм «внимания» является сердцем таких моделей, как GPT-4, и является основным вычислительным барьером.
Оптимизировать его критически важно.
Optimizing it is critical.
The CUDA Implementation (Conceptual FlashAttention)
FlashAttention is a landmark algorithm that manually and expertly orchestrates data movement between the GPU's slow main memory (HBM) and its fast on-chip memory (SRAM) to reduce bottlenecks.
Реальный код — это тысячи строк длиной и невероятно сложным.
The real code is thousands of lines long and incredibly complex.
Ссылки на компоненты полной реализации алгоритма приведены ниже:
https://github.com/Dao-AILab/flash-attention/blob/main/csrc/flash_attn/src/flash_fwd_kernel.h
https://github.com/Dao-AILab/flash-attention/blob/main/csrc/flash_attn/flash_api.cpp
Together, they are almost 3000 lines long.
The repository contains thousands of files.
Кривая обучения и кривая набора обоих являются крутыми.
A simplified version (AI-generated) is given below:
(включает в себя C++)
// This is a simplified conceptual view of a FlashAttention-style CUDA kernel.
// The actual implementation is far more complex.
template<typename Kernel_traits>
__global__ void flash_attention_fwd_kernel(Flash_fwd_params params) {
// 1. Incredibly complex setup code
// Calculates dozens of pointers and indices for HBM and shared memory (SRAM)
const int block_row_idx = blockIdx.x;
const int head_idx = blockIdx.y;
// ... many more calculations ...
// 2. Explicitly allocate shared memory tiles for Q, K, V
// The developer must manage this limited resource manually.
extern __shared__ char smem[];
float* sQ = (float*)smem;
float* sK = sQ + kTileM * kTileK;
float* sV = sK + kTileN * kTileK;
// 3. Main loop over the sequence, manually loading blocks
for (int k_block_idx = 0; k_block_idx < params.k_num_blocks; ++k_block_idx) {
// Manually orchestrate asynchronous loads from HBM into SRAM
// to hide memory latency. This is extremely difficult to get right.
load_qkv_block_from_hbm(params, ...);
__syncthreads(); // Hard synchronization barrier
// Manually perform matrix multiplication in fast SRAM
compute_sram_matmul(sQ, sK, ...);
// Recompute softmax "online" to avoid writing the huge intermediate
// attention score matrix back to slow HBM. This is the core trick.
compute_online_softmax(...);
__syncthrows();
// Update the output block
update_output_block(sV, ...);
}
// 4. Manually write the final output block back to HBM
store_output_to_hbm(params, ...);
}
Analysis of the CUDA/FlashAttention Approach:
Analysis of the CUDA/FlashAttention Approach:- Это шедевр ручной, аппаратно-специфической инженерии.
- Он достигает невероятной производительности, обращаясь с GPU как с ручной программируемой машиной.
- This makes the code virtually unreadable, unmaintainable, and unportable.
- Только немногие эксперты мирового класса могут писать или изменять такой код.
- Он представляет собой пик производительности в закрытой экосистеме, но также и пик сложности и жесткости.
The Conceptual Mojo Implementation
The Conceptual Mojo ImplementationВерсия Mojo выражает то же самоеАлгоритмическая идея (tiling, online softmax) at a high level, delegating the hardware orchestration to the MLIR compiler.
(Мужчина )
from memory import DType, Tensor
from algorithm import parallelize
struct AttentionParams:
var is_causal: Bool
# ... other model parameters
# This function is a high-level, portable description of the FlashAttention algorithm.
fn flash_attention[T: DType](Q: Tensor[T], K: Tensor[T], V: Tensor[T], params: AttentionParams) -> Tensor[T]:
# Define problem dimensions from input tensors
let num_batches = Q.dim(0)
let num_heads = Q.dim(2)
let seqlen_q = Q.dim(1)
let seqlen_k = K.dim(1)
# Define tunable tiling parameters. The compiler can use these as hints.
alias BLOCK_M: Int = 128
alias BLOCK_N: Int = 64
# The output tensor
var O = Tensor[T](Q.dims)
# The @parallelize decorator tells the compiler to map this function
# over the available hardware parallelism (e.g., CUDA thread blocks or CPU cores).
@parallelize(num_batches * num_heads)
fn compute_head(batch_idx: Int, head_idx: Int):
# Define per-worker accumulators. The compiler will map these
# to the fastest available memory (e.g., registers or SRAM).
var o_i = Tensor[T](seqlen_q, V.dim(3))
var l_i = Tensor[T](seqlen_q) # Stores the denominator of the softmax
var m_i = Tensor[T](seqlen_q) # Stores the max of each row for stable softmax
o_i.zero()
l_i.fill(0.0)
m_i.fill(-50000.0) # Negative infinity
# Loop over blocks of the Key/Value sequence
for j in range(0, seqlen_k, BLOCK_N):
# 1. Load tiles of K and V.
# The compiler is responsible for generating the optimal code
# to move this data from main memory to fast memory.
let k_j = K.load_tile[BLOCK_N](batch_idx, j, head_idx)
let v_j = V.load_tile[BLOCK_N](batch_idx, j, head_idx)
# Loop over blocks of the Query sequence
for i in range(0, seqlen_q, BLOCK_M):
# 2. Load tile of Q.
let q_i = Q.load_tile[BLOCK_M](batch_idx, i, head_idx)
# 3. Compute attention scores for the tile. This is a simple matmul.
let s_ij = q_i @ k_j.transpose()
# Causal masking for decoder models like GPT
if params.is_causal:
# Algorithmic logic, no hardware specifics
apply_causal_mask(s_ij, i, j)
# 4. Perform the "online softmax" update.
# This is pure mathematical logic, not memory management.
let m_ij = row_max(s_ij)
let p_ij = exp(s_ij - m_ij)
let l_ij = row_sum(p_ij)
let m_new = max(m_i, m_ij)
let l_new = exp(m_i - m_new) * l_i + exp(m_ij - m_new) * l_ij
# Update output tile
o_i = (l_i / l_new * exp(m_i - m_new)) * o_i + (exp(m_ij - m_new) / l_new) * (p_ij @ v_j)
# Update softmax stats
l_i = l_new
m_i = m_new
# 5. Store the final output. The compiler manages the write-back.
O.store_tile(batch_idx, head_idx, o_i)
compute_head()
return O
Один файл
Менее 100 мест.
Без мозговых зависимостей.
Конечно, это всего лишь алгоритм, но в хранилище тот же алгоритм взял почти 3000 LOC с CUDA!
Of course, this is just the algorithm, but in the repository, the same algorithm took nearly 3000 LOC with CUDA!
Теперь вы понимаете разницу:
So now you understand the difference:
Mojo is Game-Changing for AI:
Mojo меняет игру для AI:Separation of Concerns:
- Код Mojo описывает алгоритм.
- Код CUDA описывает ручную реализацию аппаратного обеспечения.
- Это глубокая разница.
- Программист Mojo может сосредоточиться на улучшении алгоритма:
- While the MLIR compiler focuses on mapping it to silicon.
Research Velocity and Maintainability:
- Исследователь искусственного интеллекта может легко понять и изменить этот код Mojo, чтобы проверить новую идею.
- Изменение кода CUDA было бы массовым, трудоемким инженерным проектом, требующим редкого набора навыков.
- Это значительно ускоряет цикл исследований и разработок.
Hardware Freedom:(Наиболее важные из них)
- Этот код Mojo не связан с NVIDIA.
- It can be compiled to run on:
- AMD GPUs
- Google TPUs
- Intel Gaudi
- Custom AI chips.
- Any architecture there is!
- MLIR's dialects can be extended to support any new hardware:
- Создание кода Mojo действительно будущего.
Это нарушит монополию NVIDIA на высокопроизводительный ИИ и снизит затраты.
This breaks the NVIDIA monopoly on high-performance AI and will drive down costs.
Specialized Hardware and Future Domains
Специализированное оборудование и будущие доменыОграничения модели CUDA становятся еще более очевидными, когда мы смотрим за пределы традиционных плотных рабочих нагрузок на будущее вычислений.
The limitations of the CUDA model become even more apparent when we look beyond traditional dense workloads to the future of computing.
MLIR/Mojo предназначен для этого будущего.
MLIR/Mojo is designed for this future.
Blockchain, Mining, and ASICs
Блокчейн, майнинг и ASICБлокчейн Proof-of-Work, такой как Bitcoin, требует огромной мощности хаширования.
Цель состоит в том, чтобы найти «нонс», который, когда хешируется с другими данными, производит результат ниже определенной цели.
Это поиск грубой силы, идеальный для параллельного оборудования.
Первоначально майнеры использовали процессоры, а затем GPU для их превосходного параллелизма.
The CUDA code for a SHA-256 miner is low-level, focused on bitwise and integer operations.
Однако для стабильного, неизменного алгоритма, такого как SHA-256, конечным аппаратным обеспечением является ASIC.
However, for a stable, unchanging algorithm like SHA-256, the ultimate hardware is an ASIC.
An ASIC (Application-Specific Integrated Circuit) is a chip designed for one single purpose - to implement an algorithm in hardware.
ASIC (Application-Specific Integrated Circuit) - это чип, предназначенный для одной цели - для реализации алгоритма в аппаратном обеспечении.
An SHA-256 ASIC has the hashing logic literally baked into the silicon.
It is thousands of times more power-efficient than a GPU for that one task.
This is where the CUDA story ends, but the MLIR/Mojo story gets even more interesting.
Здесь заканчивается история CUDA, но история MLIR/Mojo становится еще более интересной.Процесс проектирования чипа называется High-Level Synthesis (HLS).
Инструменты HLS превращают описание алгоритма на высоком уровне в язык описания оборудования низкого уровня (например, Verilog или VHDL), используемый для изготовления чипа.
MLIR, через проекты, такие как CIRCT (Circuit IR для компиляторов и инструментов), предназначен для того, чтобы быть основой следующего поколения HLS.
MLIR, through projects like CIRCT (Circuit IR for Compilers and Tools), is designed to be the backbone of next-generation HLS.
- Разработчик может написать алгоритм хаширования в Mojo.
- Для GPU-майнинга они бы сочиняли его, используя GPU-бак-энд.
- Для создания ASIC они могли составить точно такой же Mojo-код, используя HLS backend.
- Инфраструктура MLIR снизит логику Mojo высокого уровня в Verilog.
Это объединяет весь стек, от программного обеспечения высокого уровня до индивидуального силиконового дизайна.
It allows for rapid prototyping and deployment of new algorithms onto the most efficient hardware possible, be it a GPU or a brand new ASIC.
Куда не ответить на этот вопрос.
Куда не ответить на этот вопрос.
It is a software-only solution for a single vendor's programmable hardware.
Neuromorphic Computing and Sparse Data
Нейроморфные вычисления и сбережение данныхГрафические процессоры NVIDIA являются мастерами SIMT: Single Instruction, Multiple Thread.
NVIDIA GPUs are masters of SIMT: Single Instruction, Multiple Thread.
Это означает, что они невероятно эффективны, когда тысячи нитей выполняют одну и ту же инструкцию на разных данных (например, умножение матрицы).
Однако они очень неэффективны при рабочих нагрузках с тяжелым разветвлением или нерегулярным доступом к данным.
Это объясняется «дивергентностью порога».
Если нити в группе ( "варп") занимают разные ветви изложения if/else, аппарат должен выполнять оба пути последовательно, при этом нити в неактивном пути просто отключены.
If threads in a group (a "warp") take different branches of an if/else statement, the hardware must execute both paths serially, with threads in the inactive path simply turned off.
ОбаЭто убивает производительность для многих важных проблем.
Neuromorphic Computing:
Это мозговая вычислительная парадигма.
Neuromorphic chips, like Intel's Loihi, are not based on clocks and dense matrix math.
Они движутся событиями.
They are event-driven.
«Нейроны» стреляют только тогда, когда их потенциал входа пересекает порог.
Эти пики путешествуют в другие «синапсы», которые затем могут вызвать огонь других нейронов.
Это чрезвычайно скудный, тяжелый и асинхронный процесс.
Попытка имитировать это на GPU ужасно неэффективна из-за постоянного расхождения нитей.
Trying to simulate this on a GPU is horrifically inefficient due to constant thread divergence.
MLIR является идеальным решением для этого.
MLIR является идеальным решением для этого.
MLIR является идеальным решением для этого.
- В MLIR может быть создан «невроморфный диалект».
- Этот диалект имел бы первоклассные операции для Spike, Synapse, NeuronUpdate.
- Разработчик мог бы написать нейроморфный алгоритм в Mojo, используя эти концепции высокого уровня.
- Компилятор MLIR, с резервным кодом для конкретного нейроморфного чипа, как Loihi, перевел бы эти концепции в врожденные, на события направленные инструкции чипа.
Это позволяет создать портативную модель программирования высокого уровня для совершенно нетрадиционной формы вычислений.
The CUDA model is not relevant in this domain.
The CUDA model is not relevant in this domain.
Sparse and Graph Data:
Спарс и графические данные:Многие реальные проблемы включают в себя скудные данные: социальные сети, системы рекомендаций и научные симуляции.
Представлять их как плотные матрицы — пустая трата.
Представлять их как плотные матрицы — пустая трата.
Обработка их на GPU приводит к нерегулярным образцам доступа к памяти, что побеждает оптимизацию слияния памяти GPU и снижает производительность.
Again, MLIR provides the answer.
- «Диалект графа» или «Диалект скудного тензора» может представлять эти структуры данных в родном виде.
- The compiler can then apply specialized optimizations for handling sparsity.
- Например, он может перенастроить узлы для улучшения локализации памяти или использовать сжатые форматы хранения.
-
Это позволяет высокоуровневому алгоритму, написанному в Mojo, эффективно компилировать редкие данные на любом оборудовании.
This allows a high-level algorithm written in Mojo to be efficiently compiled for sparse data on any hardware.
Это то, что сегодня чрезвычайно трудно.
И рядом с невозможным с CUDA.
И рядом с невозможным с CUDA.
Quantum Computing Simulation
Квантовая компьютерная симуляцияSimulating a quantum computer on a classical computer is essential for developing and testing quantum algorithms.
Наиболее распространенным методом является симуляция векторов состояния.
Состояние квантовой системы N-кубитов представлено вектором 2^N комплексных чисел.
For just 50 qubits, this vector has 2^50 (over a quadrillion) elements, requiring petabytes of memory.
For just 50 qubits, this vector has 2^50 (over a quadrillion) elements, requiring petabytes of memory.
Квантовый алгоритм — это последовательность «ворот».
Каждый шлюз эквивалентен умножению вектора массивного состояния на очень большую, очень скудную матрицу.
Это рабочая нагрузка, которая как вычислительно-интенсивная, так и связанная с пропускной способностью памяти.
NVIDIA инвестировала здесь большие средства в свою библиотеку cuQuantum, высокопроизводительное решение, основанное на CUDA.
cuQuantum очень быстрый на GPU NVIDIA, но он имеет классические ограничения CUDA:
- Включение поставщика: ваша квантовая симуляция связана с аппаратным обеспечением NVIDIA.
- Оптимизация низкого уровня: компилятор видит только умножения матрицы-вектора.
- Нет доменного преимущества: он не имеет оптимизации для квантовой механики, основываясь на LLVM (семантический пробел).
The MLIR/Mojo Advantage for Quantum Simulation:
Преимущества MLIR/Mojo для квантовой симуляции:Подход MLIR обеспечивает гораздо более высокий уровень интеллекта в компиляторе.
- «Квантовый диалект» можно определить в MLIR.
- Этот диалект не будет представлять ворота как матрицы; он будет представлять их как их квантовые объекты: Hadamard, CNOT, Toffoli.
- Разработчик напишет свою квантовую схему в Mojo, используя эти объекты высокого уровня.
- Компилятор MLIR может затем выполнять квантовые оптимизации, прежде чем будут созданы какие-либо матрицы.
Например, компилятор знает, что применение порта Hadamard (H) дважды подряд является операцией идентификации и может быть полностью устранено.
Он бы знал, что определенные последовательности ворот могут быть «соединены» в единые, более эффективные ворота.
Например, компилятор знает, что применение порта Hadamard (H) дважды подряд является операцией идентификации и может быть полностью устранено.
Он бы знал, что определенные последовательности ворот могут быть «соединены» в единые, более эффективные ворота.
Это целый класс оптимизации, который невидим для компилятора CUDA, который видит только общие матрицы, благодаря LLVM.
This is an entire class of optimization that is invisible to the CUDA compiler, which only sees generic matrices, thanks to LLVM.
После выполнения этих алгебраических упрощений высокого уровня компилятор MLIR затем снизил упрощенную схему в оптимизированную последовательность матричных операций для целевого аппаратного обеспечения.
Поскольку все это построено на MLIR, одна и та же квантовая схема высокого уровня, написанная в Mojo, может быть составлена для работы на NVIDIA GPU, AMD GPU или CPU-кластере.
Because this is all built on MLIR, the same high-level quantum circuit written in Mojo could be compiled to run on an NVIDIA GPU, an AMD GPU, or a CPU cluster.
This provides both higher performance (due to smarter optimization) and complete hardware freedom.
Nvidia инвестирует значительные средства в квантовое оборудование и программное обеспечение.
Но его платформа CUDA-Q по-прежнему основана на LLVM.
Mojo на основе MLIR может не только предложить передовую оптимизацию - он также предлагает более простое программирование.
MLIR-based Mojo can not just offer advanced optimization - it also offers simpler programming.
Final Verdict: Today vs. The Inevitable Future
Оригинальное название: Today vs. The Inevitable FutureThe Verdict Today (2025):
Приговор сегодня (2025):- Куда - король холма, и холм большой.
- Его зрелая экосистема, обширные библиотеки и огромное сообщество являются мощными активами.
- Для команды, которая уже инвестировала в оборудование NVIDIA и нуждается в немедленной доставке продукта, CUDA является прагматичным выбором.
- Инерция десятилетия господства — это мощная сила.
- Мохо еще молод.
- Ее экосистема растет с невероятной скоростью, но она еще не может соответствовать чистой широте проверенных в боях библиотек CUDA.
The Verdict for the Long Run:
Приговор за долгое время:- Будущее будет гетерогенным.
- Это не догадка, это реальность.
- Появление на заказ силикона ИИ и возобновленная конкуренция от AMD и Intel сделали блокировку поставщиков неприемлемым деловым и техническим риском.
- Проблемы будущего — скудные данные, нейроморфный ИИ, добыча блокчейна и квантовые вычисления — не вписываются в жесткую модель SIMT сегодняшних GPU.
- MLIR является единственной существующей архитектурой, поддерживаемой отраслью, предназначенной для решения этой проблемы.
- Его принятие Google, Apple, Intel, AMD и ARM является четким сигналом о его центральной роли в будущем компиляторов.
- Моджо является единственным языком, созданным (пока) для использования этой силы.
Мохо :
- Решение проблемы двуязычия
- Сочетание функциональности с производительностью
- Представляет собой портал для всей экосистемы MLIR.
Переход от CUDA к миру, основанному на MLIR, будет постепенным, но неизбежным.
Это фундаментальный сдвиг от закрытой модели, ориентированной на аппарат, к открытому будущему, определяемому программным обеспечением.
Недостатки Mojo
- Mojo все еще находится в разработке.
- У него пока нет даже классов.
- Его сторонние библиотеки немногочисленны, но растут с невероятной скоростью.
- Он имеет приложения везде, где используется Python, но он должен эволюционировать с Python.
- Весь язык еще не является открытым исходным кодом, хотя эксперты говорят, что это скоро изменится.
- Он не поддерживает Windows (пока).
- И для этого требуется портирование на Android, iOS и Edge IOT-системы.
Но будет ли он победителем в долгосрочной перспективе?
I believe it will, and developers will be happier with Mojo than CUDA.
Заключение
CUDA построил впечатляющий дворец современных высокопроизводительных вычислений.
CUDA built the impressive palace of today's high-performance computing.
Но это и есть клетка.
But it is a cage.
MLIR и Mojo передают каждому разработчику ключ, чтобы разблокировать его и построить будущее на любом фундаменте.
MLIR and Mojo are handing every developer the key to unlock it and build the future on any foundation they choose.
И этот фонд предназначен для MLIR и Mojo.
И этот фонд предназначен для MLIR и Mojo.
The simplest reason - the budget.
и бюджет .Вот почему, если только Nvidia не пилот, и вскоре:
Это будет конец доминирования Nvidia - если они также не примут MLIR!
This will be the end of the dominance of Nvidia - unless they embrace MLIR as well!
Референции
Official Project Pages
- MLIR (Multi-Level Intermediate Representation)
- Text description: The official homepage for the MLIR project, hosted by LLVM. This is the canonical source for documentation, talks, and the project's overall mission statement.
- https://mlir.llvm.org/
- Mojo Programming Language
- The official documentation for the Mojo programming language from Modular, the company that created it. This is the primary resource for learning the language.[2]
- https://docs.modular.com/mojo/
- NVIDIA CUDA Toolkit
- The official portal from NVIDIA for downloading the CUDA Toolkit, which includes the compilers, libraries, and tools necessary for CUDA development.
- https://developer.nvidia.com/cuda-toolkit
- LLVM Compiler Infrastructure Project
- The main homepage for the LLVM project, which provides an overview of the entire ecosystem, including Clang, LLDB, and other sub-projects. MLIR is a part of this larger project.
- https://llvm.org/
- Chris Lattner's Homepage
- The personal homepage of Chris Lattner, the creator of LLVM, Clang, Swift, MLIR, and Mojo. It provides his work history and links to his talks and papers, offering direct insight into the creation of these technologies.
- https://nondot.org/sabre/
AI and Attention Mechanism (FlashAttention)
- FlashAttention Original Paper (arXiv)
- The original scientific paper, "FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness," which introduced the algorithm. This is the primary source for understanding the technical details and performance benefits.
- https://arxiv.org/abs/2205.14135
- FlashAttention-2 Paper (arXiv)
- The follow-up paper describing FlashAttention-2, which details further optimizations for parallelism and work partitioning to achieve even greater speedups on modern GPUs.
- https://arxiv.org/abs/2307.08691
- FlashAttention GitHub Repository
- The official GitHub repository containing the source code for the FlashAttention and FlashAttention-2 CUDA kernels.
- https://github.com/Dao-AILab/flash-attention
Quantum Computing Simulation
- NVIDIA cuQuantum Official Page
- NVIDIA's official product page for the cuQuantum SDK, outlining its features for accelerating quantum computing simulations on GPUs.
- https://developer.nvidia.com/cuquantum
- NVIDIA cuQuantum Documentation
- The detailed technical documentation for the cuQuantum SDK, providing a high-level overview and API references for the libraries.
- https://docs.nvidia.com/cuda/cuquantum/index.html
Specialized Hardware (Neuromorphic & ASICs)
- Intel Neuromorphic Computing Overview
- Intel's official overview of their neuromorphic computing research, which discusses the goals of the program and the Loihi research chips.
- https://www.intel.com/content/www/us/en/research/neuromorphic-computing.html
- CIRCT (Circuit IR Compilers and Tools) Project
- The official homepage for the CIRCT project, an LLVM/MLIR incubator looking to apply compiler technology to hardware design, including High-Level Synthesis (HLS) for FPGAs and ASICs.
- https://circt.llvm.org/
- CIRCT GitHub Repository
- The official GitHub repository for the CIRCT project, containing the source code, dialects, and tools for hardware compiler design.
- https://github.com/llvm/circt
Google AI Studio была использована для обозначения и исследования этой статьи. Вы можете найти ее здесь:
Google AI Studio была использована для обозначения и исследования этой статьи. Вы можете найти ее здесь:
Все фотографии были созданы автором с помощью NightCafe Studio бесплатно, доступны по ссылке ниже:
Все фотографии были созданы автором с помощью NightCafe Studio бесплатно, доступны по ссылке ниже:
https://creator.nightcafe.studio/