Dari Python ke Silicon: Menjelaskan Tumpukan Komputasi AI
Apa yang sebenarnya terjadi ketika Anda menjalankan model AI di PyTorch?
Banyak praktisi AI tidak pernah perlu memikirkan hal ini. Mereka merancang dan melatih model menggunakan kerangka kerja tingkat tinggi dan tahu bahwa perhitungannya terjadi di GPU, tetapi mereka jarang perlu memikirkan bagaimana ini bekerja di balik layar.
Ini karena framework seperti PyTorch menyediakan antarmuka yang mudah digunakan untuk berinteraksi dengan GPU. Namun, untuk membuat ini memungkinkan, ada lapisan demi lapisan perangkat lunak yang menerjemahkan kode ini menjadi instruksi yang dapat dipahami oleh chip fisik. Lapisan-lapisan ini disebut “AI compute stack”, dan penyedia perangkat keras masing-masing memiliki versi mereka sendiri - CUDA untuk NVIDIA dan ROCm untuk AMD.
Dalam postingan ini, kita akan membuka lapisan-lapisan abstraksi dalam tumpukan komputasi ini. Kita akan membangun setiap lapisan dari GPU fisik hingga ke kerangka kerja tingkat tinggi seperti PyTorch, menyoroti komponen yang sesuai dari ekosistem NVIDIA dan AMD.
Lapisan 0: Perangkat Keras (Dasar)
Di bagian paling bawah tumpukan, kita memiliki komponen fisik: GPU itu sendiri (misalnya, NVIDIA H200 atau AMD Instinct MI300X).
Komponen-komponen ini berharga karena sangat efisien dalam melakukan perkalian matriks. Ini adalah operasi matematika yang menjadi dasar banyak model AI, seperti LLM. Untuk menghitung satu perkalian matriks, sebuah komputer perlu melakukan miliaran perkalian reguler (seperti 2 x 3), yang disebut "perkalian skalar."
Orang-orang dulu melakukan operasi ini pada CPU (Central Processing Unit), yang sering disebut sebagai 'otak' dari sebuah komputer. Namun pada tahun 2012, sebuah model bernama AlexNet menunjukkan bahwa jenis komponen perangkat keras yang berbeda, yang disebut GPU (Graphical Processing Unit), sebenarnya lebih cocok untuk tugas perkalian matriks ini.
CPU itu cerdas tapi bersifat berurutan. Mereka dirancang untuk melakukan tugas kompleks satu per satu dengan sangat cepat. GPU itu “bodoh” tapi masif. Mereka memiliki ribuan “inti” yang dapat memproses operasi sederhana secara paralel.
GPU dapat melakukan banyak operasi sederhana (kotak hijau) secara paralel, sehingga menghasilkan peningkatan efisiensi yang sangat tinggi dibandingkan CPU yang harus melakukan operasi ini secara berurutan
Operasi "sederhana" ini yang bisa dilakukan GPU dengan efisien termasuk perkalian skalar, hal yang sama persis yang mendasari perkalian matriks (dan dengan demikian model AI). Jadi GPU jauh lebih efisien dalam melatih dan menjalankan model AI dibandingkan CPU.
Batasannya adalah GPU memiliki hambatan bahasa. GPU tidak memahami bahasa pemrograman seperti Python, C++, atau bahkan Assembly. GPU hanya memahami kode mesin tertentu (Instruction Set Architecture atau ISA) yang dirancang untuk chip tersebut.
Untuk menjembatani kesenjangan ini, kita membutuhkan perangkat lunak.
Lapisan 1: Driver Kernel
Pertama, peringatan jargon: Dalam AI, Anda akan sering mendengar kata “kernel”. Lapisan ini, Kernel Driver, mengacu pada Driver Kernel sistem operasi. Ini berbeda dari “GPU Compute Kernel,” yang akan kita bahas di Lapisan 4.
Driver Kernel adalah modul di dalam kernel sistem Anda yang bertindak sebagai jembatan antara GPU fisik Anda dan komputer Anda. Ini adalah lapisan pertama dari tumpukan ini yang berada di dalam ekosistem CUDA (diucapkan “coo-dah”) dan ROCm (diucapkan “rock-um”).
Secara fisik, GPU Anda terhubung ke motherboard melalui PCIe. Kernel Driver adalah komponen perangkat lunak yang mengirim data bolak-balik melalui koneksi fisik tersebut, memungkinkan sistem operasi komputer Anda (seperti MacOS, Windows 11, Ubuntu, dll.) untuk berkomunikasi dengan firmware GPU. Kernel Driver beroperasi dalam “mode kernel” dengan hak istimewa tertinggi, yang dibutuhkan untuk mengelola memori, konsumsi daya, dan suhu GPU melalui koneksi ini.
Penghubung putih dan merah yang Anda lihat di atas adalah slot PCIe. Inilah tempat Anda mencolokkan GPU Anda ke motherboard komputer, dan sambungan di mana Kernel Driver berkomunikasi dengan GPU (sumber)
Yang paling penting, Kernel Driver adalah satu-satunya lapisan yang berbicara langsung dengan GPU. Setiap lapisan di atasnya harus melewatkan pesannya melalui Kernel Driver.
Lapisan 2: Waktu Eksekusi Sistem
Dengan naik satu tingkat, kita mencapai System Runtime. Anggap lapisan ini sebagai Pengatur Lalu Lintas Udara untuk sistem CPU + GPU yang digabungkan, diperlakukan sebagai satu unit komputasi terpadu.
Runtime Sistem bertindak sebagai penjadwal pekerjaan. Ia membuat "paket" perintah, mengaturnya ke dalam antrian, dan mengirimkannya ke GPU. Ia juga menunggu GPU memberi sinyal kembali, "Hei, saya sudah selesai dengan pekerjaan itu".
Kita membutuhkan Lapisan 2 karena Lapisan 1, Driver Kernel, hanya berfokus pada komunikasi langsung dengan GPU. Tidak masuk akal jika setiap program individu yang ingin menggunakan GPU mencoba berkomunikasi dengannya secara langsung. System Runtime bertindak sebagai pengendali pusat yang mengatur semua pekerjaan yang perlu dilakukan pada GPU sehingga Driver Kernel bisa fokus pada berkomunikasi dengan GPU untuk menyelesaikan pekerjaan tertentu.
Runtime Sistem ROCm disebut ROCr. Ini mengimplementasikan standar terbuka yang disebut “Arsitektur Sistem Heterogen” (HSA). Standar ini mendefinisikan bagaimana sistem dari unit komputasi heterogen (seperti gabungan CPU dan GPU) harus bekerja sama sebagai satu kesatuan.
CUDA tidak memiliki padanan tepat, tetapi yang paling mendekati adalah CUDA Driver API, yang merupakan API kepemilikan yang melakukan fungsi serupa (meskipun juga dapat dianggap sebagai bagian dari lapisan berikutnya karena Anda bisa memprogram langsung dengannya).
Lapisan 3: Antarmuka Pemrograman
Lapisan 3 adalah tempat para insinyur perangkat lunak yang menulis kode untuk GPU benar-benar mulai berinteraksi dengan tumpukan, yang mereka lakukan melalui Antarmuka Pemrograman untuk ekosistem mereka.
Membuat program GPU langsung dengan kode mesin tidak praktis bagi manusia. Untuk mengatasinya, vendor menyediakan ekstensi C++ yang memungkinkan pengembang menulis kode konvensional yang kemudian dapat dikompilasi menjadi kode mesin untuk GPU.*
Ada dua ekstensi C++ seperti ini:
- NVIDIA menggunakan CUDA C++, ini adalah standar industri yang telah digunakan selama lebih dari satu dekade
- AMD menggunakan HIP (Antarmuka Komputasi Heterogen untuk Portabilitas)
Secara teknis, yang setara dengan HIP adalah kombinasi dari keduanya CUDA C++ dan CUDA Runtime API bersama-sama, yang biasanya hanya disebut sebagai “CUDA”. Baik HIP maupun CUDA pada dasarnya hanyalah C++, tetapi keduanya menyediakan kata kunci dan fungsi tambahan untuk kemampuan penting yang berkaitan dengan pemrograman GPU, seperti:
- Alokasi: Memesan memori di GPU
- Pergerakan: Memindahkan data dari CPU ke GPU
- Eksekusi: Menjalankan perhitungan di GPU
Ketika Anda menjalankan program yang ditulis dalam HIP atau CUDA (antarmuka pemrograman), perintah-perintah terkait GPU ini diserahkan ke System Runtime (Lapisan 2)**, yang bertugas memastikan mereka dijalankan.
Garis antara kedua ekosistem di lapisan 2 dan 3 agak kabur - mereka tidak langsung setara di lapisan ini. Misalnya, ROCr adalah infrastruktur murni dan tidak bisa langsung diprogram oleh pengembang, sementara CUDA Driver API menyediakan fungsionalitas yang bisa Anda program menggunakan CUDA C++. Namun, detail ini tidak terlalu penting bagi kebanyakan pengembang.
Yang penting adalah memahami (1) bahwa ROCm dan CUDA (ekosistem) berbeda secara arsitektural, dan yang lebih penting (2) bahwa ketika orang mengatakan “CUDA ”, mereka bisa merujuk baik pada antarmuka pemrograman CUDA C++ bersama dengan CUDA Runtime API, atau pada seluruh ekosistem CUDA.
Catatan tentang Kompatibilitas
AMD membuat pilihan strategis dengan HIP, yang dirilis beberapa tahun setelah CUDA. AMD merancang HIP agar terlihat hampir sama persis dengan CUDA. Ini memungkinkan pengembang untuk memindahkan kode CUDA ke HIP dengan perubahan yang minim. AMD bahkan menyediakan alat bernama hipify untuk mengotomatiskan terjemahan ini. HIP dirancang agar portabel, yang berarti dapat dijalankan baik di GPU AMD maupun di GPU NVIDIA.
CUDA tidak selalu bisa dipindahkan ke HIP karena pustaka ROCm belum se-matang itu, jadi apakah CUDA Anda bisa dikonversi ke HIP tergantung pada kasus penggunaan Anda. Kesenjangan ini sedang menutup, tetapi NVIDIA masih memegang keuntungan di bidang tertentu (seperti Komputasi Kuantum). Namun, untuk aplikasi AI mainstream dan komputasi ilmiah standar, ekosistem AMD telah berkembang pesat dan telah mencapai kesetaraan untuk banyak beban kerja.
* Catatan kaki: “dikompilasi ke kode mesin” adalah penyederhanaan. Sebenarnya, program CUDA C++ dan HIP dibagi saat dikompilasi. Bagian kode CPU dikompilasi oleh compiler C++ normal sistem, dan bagian GPU dikompilasi oleh compiler GPU dan disimpan dalam program sebagai blok data dalam program.
Ketika program dijalankan, program tersebut berjalan di CPU. Ketika bagian kode GPU ditemui, CPU mendelegasikan eksekusinya ke GPU, mengirimkan blok kode yang telah dikompilasi sebelumnya ke runtime GPU agar GPU bisa mengelola eksekusi kode tersebut.
** Catatan kaki: Untuk kelengkapan, AMD menggunakan lapisan perantara yang disebut ROCclr (ROCm Common Language Runtime) antara HIP dan ROCr. Lapisan abstraksi ini memungkinkan AMD mendukung beberapa antarmuka pemrograman (HIP dan OpenCL) dengan runtime yang sama. Untuk kesederhanaan, kami menganggap ini sebagai bagian dari koneksi HIP → ROCr.
Lapisan 4: Perpustakaan Matematika
Jika Anda sedang membangun aplikasi AI, besar kemungkinan Anda tidak menulis CUDA C++ atau HIP mentah untuk mengalikan matriks. Itu akan seperti menulis mesin database sendiri hanya untuk menyimpan alamat email seorang pengguna - tidak efisien dan rawan kesalahan.
Sebagai gantinya, Anda menggunakan perpustakaan matematika - lapisan terakhir dalam tumpukan yang berada dalam ekosistem CUDA dan ROCm.
Ini adalah kumpulan "compute kernels" yang dioptimalkan (program kecil yang dijalankan di GPU) yang ditulis oleh vendor perangkat keras itu sendiri. Mereka dioptimalkan secara maksimal untuk memaksimalkan kinerja perangkat keras.
Kebanyakan dari perpustakaan ini saling mencerminkan di berbagai ekosistem:
| Tipe Operasi | NVIDIA (CUDA) | AMD (ROCm) |
|---|---|---|
| Aljabar Linear Dasar | cuBLAS, cuSPARSE | rocBLAS, rocSPARSE |
| Pembelajaran Mendalam | cuDNN | MIOpen |
| Pemecah | cuSOLVER | rocSOLVER |
Ketika seorang peneliti membicarakan tentang "mengoptimalkan kernel," mereka biasanya berbicara tentang menulis ulang kode di dalam perpustakaan ini agar berjalan lebih cepat pada arsitektur perangkat keras tertentu.
Lapisan 5: Kerangka AI
Akhirnya, kita sampai di puncak tumpukan: Kerangka Kerja AI.
Inilah tempat PyTorch, TensorFlow, dan JAX berada, dan tempat sebagian besar pengembang AI bekerja. Framework ini mengabstraksi semua kompleksitas yang baru saja kita bahas, menyediakan cara yang intuitif dan Pythonic untuk membangun model tanpa khawatir tentang alokasi memori atau bandwidth PCIe. Framework ini memiliki berbagai versi backend mereka, satu untuk CUDA dan satu untuk ROCm.
Namun kesederhanaan itu tidak mengorbankan kecepatan. Saat Anda menjalankan sebuah fungsi di PyTorch, itu sebagian besar berperan sebagai wrapper yang memanggil ke perpustakaan Layer 4 yang sangat dioptimalkan. Jadi, ketika Anda menggunakan sebuah framework, Anda mendapatkan fleksibilitas dan kesederhanaan Python dengan kinerja kernel GPU yang dioptimalkan.
Kerangka kerja ini memungkinkan Anda menulis kode yang mudah dibaca seperti ini:
import torch
# 1. define the device (the GPU)
device = torch.device('cuda')
# 2. Create two random matrices on the GPU
A = torch.randn(1024, 1024, device=device)
B = torch.randn(1024, 1024, device=device)
# 3. Perform the calculation (Matrix Multiplication)
C = torch.matmul(A, B)
print(f"Calculation complete. Result shape: {C.shape}")Daripada mencoba menulis program semacam itu dengan instruksi GPU tingkat rendah yang membingungkan:
// Address // Hex Encoding // Disassembly (Operation)
/*0000*/ 0x00005a0000057ab9 IMAD.MOV.U32 R1, RZ, RZ, c[0x0][0x28]
/*0010*/ 0x0000980000000a00 IMAD.MOV.U32 R0, RZ, RZ, c[0x0][0x20]
/*0020*/ 0x0000020000027a02 MOV R2, c[0x0][0x0]
/*0030*/ 0x3800000000025910 IMAD.WIDE.U32 R2, R2, R0, c[0x0][0x0]
/*0040*/ 0x0000580000000a00 IMAD.MOV.U32 R0, RZ, RZ, c[0x0][0x24]
/*0050*/ 0x0000000002037202 IADD3 R3, R2, c[0x0][0x0], RZ
/*0060*/ 0x0001940003027981 LDG.E.SYS R2, [R2]
/*0070*/ 0x0000020000007200 IADD3 R0, R0, 0x1, RZ
/*0080*/ 0x000000000000794d STG.E.SYS [R2], R0
/*0090*/ 0x0000000000007943 EXITRingkasan: Jejak Lengkap
Untuk memvisualisasikan bagaimana semua ini terhubung, mari kita lacak satu perintah. Bayangkan Anda menggunakan PyTorch di mesin AMD dan Anda menjalankan perkalian matriks: torch.matmul().
- Python (Lapisan 5): Anda menjalankan perintah. Backend PyTorch aktif.
- Perpustakaan Matematika (Lapisan 4): PyTorch memanggil
rocBLAS, meminta kernel perkalian matriks. - Antarmuka Pemrograman (Lapisan 3):
rocBLASmemanggil API HIP untuk menjalankan kernel tersebut. - Waktu Eksekusi Sistem (Lapisan 2): Runtime mengantri pekerjaan dan menjadwalkannya.
- Driver Kernel (Lapisan 1): Driver mengambil paket dan mengirimkannya melalui bus PCIe.
- Perangkat Keras (Lapisan 0): Silicon GPU menerima kode mesin dan menjalankan perhitungannya.
Seluruh tumpukan ini - dari Python hingga Silicon - adalah prestasi teknik yang luar biasa. Ini menjembatani kesenjangan antara logika manusia dan kekuatan komputasi murni, memungkinkan ledakan AI yang kita saksikan saat ini.
Tumpukan Komputasi AI lengkap, dari perangkat keras (hijau), melalui ekosistem CUDA dan ROCm (biru), hingga kerangka kerja AI (kuning)
Terima kasih telah belajar bersama Komunitas Linux-Console.net.










