Dari Python ke Silicon: Penjelasan Mengenai Tumpukan Pengiraan AI
Apa sebenarnya yang berlaku apabila anda menjalankan model AI dalam PyTorch?
Ramai pengamal AI tidak pernah perlu memikirkan perkara ini. Mereka mereka bentuk dan melatih model menggunakan rangka kerja tahap tinggi dan tahu bahawa pengiraan berlaku pada GPU, tetapi mereka jarang perlu memikirkan bagaimana ia berfungsi di bawah permukaan.
Ini kerana rangka kerja ini, seperti PyTorch, menyediakan antara muka yang mudah digunakan untuk berinteraksi dengan GPU. Tetapi untuk menjadikan ini mungkin, terdapat lapisan demi lapisan perisian untuk menterjemahkan kod ini menjadi arahan yang boleh difahami oleh cip fizikal. Lapisan-lapisan ini dipanggil “timbunan pengkomputeran AI”, dan penyedia perkakasan masing-masing mempunyai versi mereka sendiri - CUDA untuk NVIDIA dan ROCm untuk AMD.
Dalam pos ini, kami akan membuka lapisan abstraksi dalam tumpukan pengkomputeran ini. Kami akan membina setiap lapisan dari GPU fizikal sehingga kepada rangka kerja tahap tinggi seperti PyTorch, sambil menonjolkan komponen yang sepadan dalam ekosistem NVIDIA dan AMD.
Lapisan 0: Perkakasan (Asas)
Di bahagian paling bawah timbunan, kami mempunyai komponen fizikal: GPU itu sendiri (contohnya, NVIDIA H200 atau AMD Instinct MI300X).
Komponen ini bernilai kerana ia sangat cekap dalam melakukan pendaraban matriks. Ini adalah operasi matematik yang menjadi asas kepada banyak model AI, seperti LLM. Untuk mengira satu pendaraban matriks, sebuah komputer perlu melakukan berbilion-bilion pendarabaan biasa (seperti 2 x 3), yang dipanggil “pendarabaan skalar.”
Orang dahulu biasa melakukan operasi ini pada CPU (Unit Pemprosesan Pusat), yang sering dirujuk sebagai "otak" komputer. Tetapi pada tahun 2012, satu model yang dipanggil AlexNet menunjukkan bahawa jenis komponen perkakasan yang berbeza yang dipanggil GPU (Unit Pemprosesan Grafik) sebenarnya lebih sesuai untuk tugas pendaraban matriks ini.
CPU pintar tetapi bersiri. Mereka direka untuk melakukan tugas kompleks satu demi satu dengan sangat cepat. GPU 'bodoh' tetapi besar. Mereka mempunyai beribu-ribu 'teras' yang boleh memproses operasi mudah secara selari.
GPU boleh melakukan banyak operasi ringkas (kotak hijau) secara selari, membawa kepada peningkatan kecekapan yang sangat tinggi berbanding CPU yang mesti melakukan operasi ini secara berurutan
“Operasi mudah” ini yang boleh dilakukan GPU dengan cekap termasuk pendaraban skalar, perkara tepat yang menggerakkan pendaraban matriks (dan oleh itu model AI). Jadi GPU jauh lebih cekap dalam melatih dan menjalankan model AI berbanding CPU.
Kekangan adalah GPU mempunyai halangan bahasa. Ia tidak memahami bahasa pengaturcaraan seperti Python, C++, atau bahkan Assembly. Ia hanya memahami kod mesin tertentu (Architecture Set Arahan atau ISA) yang direka untuk cip tersebut.
Untuk merapatkan jurang ini, kita memerlukan perisian.
Lapisan 1: Pemacu Kernel
Mula-mula, amaran istilah: Dalam AI, anda akan kerap mendengar perkataan “kernel”. Lapisan ini, Pemacu Kernel, merujuk kepada Pemacu Kernel sistem operasi. Ini berbeza dengan “GPU Compute Kernel”, yang akan kita bincangkan dalam Lapisan 4.
Pemandu Kernel adalah modul dalam kernel sistem anda yang berfungsi sebagai jambatan antara GPU fizikal anda dan komputer anda. Ia adalah lapisan pertama dalam tumpukan ini yang berada dalam ekosistem CUDA (disebut “coo-dah”) dan ROCm (disebut “rock-um”).
Secara fizikal, GPU anda bersambung ke papan induk melalui PCIe. Pemacu Kernel adalah komponen perisian yang menghantar data pergi balik melalui sambungan fizikal itu, membolehkan sistem operasi komputer anda (seperti MacOS, Windows 11, Ubuntu, dan lain-lain) untuk berkomunikasi dengan perisian tegar GPU. Pemacu Kernel beroperasi dalam “mod kernel” dengan keistimewaan tertinggi, yang diperlukan untuk menguruskan memori, penggunaan kuasa, dan suhu GPU melalui sambungan ini.
(sumber
Yang penting, Pemacu Kernel adalah satu-satunya lapisan yang bercakap terus dengan GPU. Setiap lapisan di atasnya mesti menghantar mesejnya melalui Pemacu Kernel.
Lapisan 2: Masa Larian Sistem
Bergerak satu langkah ke atas, kita sampai ke Runtime Sistem. Anggaplah lapisan ini sebagai Pengawal Trafik Udara bagi sistem CPU + GPU yang digabungkan, yang dianggap sebagai satu unit pengiraan yang bersatu.
Sistem Runtime bertindak sebagai penjadual kerja. Ia mencipta ‘pek’ arahan, menyusunnya ke dalam barisan, dan menghantarnya ke GPU. Ia juga menunggu GPU memberi isyarat balik, ‘Hei, saya sudah siap dengan kerja itu’.
Kita memerlukan Lapisan 2 kerana Lapisan 1, Pemacu Kernel, hanya berurusan dengan komunikasi langsung dengan GPU. Tidak masuk akal untuk setiap program individu yang ingin menggunakan GPU cuba berkomunikasi dengannya secara langsung. Sistem Runtime bertindak sebagai pengawal pusat yang mengatur semua kerja yang perlu dilakukan pada GPU supaya Pemacu Kernel boleh menumpukan pada berkomunikasi dengan GPU untuk menyelesaikan setiap tugasan individu.
Runtime Sistem ROCm dipanggil ROCr. Ia melaksanakan satu standard terbuka yang dipanggil “Heterogeneous System Architecture” (HSA). Standard ini mentakrifkan bagaimana sistem unit pengiraan heterogen (seperti gabungan CPU dan GPU) harus berfungsi bersama sebagai satu unit.
CUDA tidak mempunyai padanan tepat, tetapi yang paling hampir adalah CUDA Driver API, iaitu API proprietari yang melaksanakan fungsi yang serupa (walaupun ia juga boleh dianggap sebahagian daripada lapisan seterusnya kerana anda boleh membuat pengaturcaraan terus dengannya).
Lapisan 3: Antara Muka Pengaturcaraan
Lapisan 3 adalah di mana jurutera perisian yang menulis kod untuk GPU sebenar mula berinteraksi dengan tumpukan, yang mereka lakukan melalui Antara Muka Pengaturcaraan untuk ekosistem mereka.
Membuat program GPU secara langsung menggunakan kod mesin adalah tidak praktikal bagi manusia. Untuk menyelesaikan masalah ini, pengeluar menyediakan lanjutan C++ yang membolehkan pembangun menulis kod konvensional yang kemudian boleh dikompilkan menjadi kod mesin untuk GPU.*
Terdapat dua sambungan C++ seperti ini:
- NVIDIA menggunakan CUDA C++, ini adalah standard industri dan telah menjadi piawaian selama lebih sedekad
- AMD menggunakan HIP (Antara Muka Pengkomputeran Heterogen untuk Kebolehpindahan)
Sekarang secara teknikal, setara dengan HIP adalah gabungan kedua-dua CUDA C++ dan CUDA Runtime API bersama-sama, yang biasanya dirujuk hanya sebagai “CUDA”. Kedua-dua HIP dan CUDA pada dasarnya hanyalah C++, tetapi mereka menyediakan kata kunci dan fungsi tambahan untuk keupayaan penting yang berkaitan dengan pengaturcaraan GPU, seperti:
- Peruntukan: Menyimpan memori pada GPU
- Pergerakan: Memindahkan data dari CPU ke GPU
- Pelaksanaan: Melancarkan pengiraan pada GPU
Apabila anda menjalankan program yang ditulis dalam HIP atau CUDA (antara muka pengaturcaraan), arahan berkaitan GPU ini diserahkan kepada Runtime Sistem (Lapisan 2)**, yang bertanggungjawab memastikan ia dilaksanakan.
Garis menjadi sedikit kabur antara dua ekosistem pada lapisan 2 dan 3 - mereka tidak setara secara langsung pada lapisan ini. Sebagai contoh, ROCr adalah infrastruktur murni dan tidak boleh diprogram secara langsung oleh pembangun, manakala API Pemacu CUDA mendedahkan fungsi yang boleh anda program dengan menggunakan CUDA C++. Tetapi, perincian ini tidak penting bagi kebanyakan pembangun.
Apa yang penting adalah untuk memahami (1) bahawa ROCm dan CUDA (ekosistem) berbeza dari segi seni bina, dan yang lebih penting (2) bahawa apabila orang berkata “CUDA”, mereka boleh merujuk sama ada kepada antara muka pengaturcaraan CUDA C++ bersama dengan CUDA Runtime API, atau kepada keseluruhan ekosistem CUDA.
Catatan tentang Keserasian
AMD membuat pilihan strategik dengan HIP, yang dikeluarkan beberapa tahun selepas CUDA. AMD mereka HIP agar kelihatan hampir sama seperti CUDA. Ini membolehkan pembangun memindahkan kod CUDA ke HIP dengan perubahan yang minimum. AMD juga menyediakan alat yang dipanggil hipify untuk mengautomasikan terjemahan ini. HIP direka untuk menjadi mudah alih yang bermakna ia boleh dijalankan sama ada pada GPU AMD dan pada GPU NVIDIA.
CUDA tidak boleh sentiasa dipindahkan ke HIP kerana perpustakaan ROCm belum begitu matang, jadi sama ada CUDA anda boleh ditukar kepada HIP bergantung pada kes penggunaan anda yang tertentu. Jurang ini semakin mengecil, tetapi NVIDIA masih mempunyai kelebihan dalam bidang terpilih (seperti Pengkomputeran Kuantum). Walau bagaimanapun, untuk aplikasi AI arus perdana dan pengkomputeran saintifik standard, ekosistem AMD telah matang dengan ketara dan telah setara untuk banyak beban kerja.
* Catatan kaki: “disusun ke kod mesin” adalah satu penyederhanaan. Sebenarnya, program CUDA C++ dan HIP dibahagikan semasa disusun. Bahagian CPU kod disusun oleh penyusun C++ biasa sistem, dan bahagian GPU disusun oleh penyusun GPU dan disimpan dalam program sebagai blok data dalam program.
Apabila program dilaksanakan, ia berjalan pada CPU. Apabila bahagian GPU kod ditemui, CPU mewakilkan pelaksanaannya kepada GPU, menghantar sepanjang blok kod pra-kompilasi ke masa jalan GPU untuk mengurus pelaksanaan kod pada GPU.
** Nota Kaki: Untuk kesempurnaan, AMD menggunakan lapisan perantaraan yang dipanggil ROCclr (ROCm Common Language Runtime) antara HIP dan ROCr. Lapisan abstraksi ini membolehkan AMD menyokong pelbagai antara muka pengaturcaraan (HIP dan OpenCL) dengan runtime asas yang sama. Untuk memudahkan, kita menganggap ini sebagai sebahagian daripada sambungan HIP → ROCr.
Lapisan 4: Perpustakaan Matematik
Jika anda sedang membangunkan aplikasi AI, anda mungkin tidak menulis CUDA C++ atau HIP mentah untuk mendarab matriks. Itu seperti menulis enjin pangkalan data sendiri hanya untuk menyimpan alamat e-mel pengguna - tidak cekap dan mudah mengundang kesilapan.
Sebaliknya, anda menggunakan perpustakaan matematik - lapisan terakhir dalam tumpukan yang berada dalam ekosistem CUDA dan ROCm.
Ini adalah koleksi 'kernel pengkomputeran' yang dioptimumkan (program kecil yang dijalankan pada GPU) yang ditulis oleh pengeluar perkakasan itu sendiri. Ia dioptimumkan sepenuhnya untuk mendapatkan prestasi maksimum daripada perkakasan.
Kebanyakan pustaka ini mencerminkan satu sama lain merentas ekosistem:
| Jenis Operasi | NVIDIA (CUDA) | AMD (ROCm) |
|---|---|---|
| Algebra Linear Asas | cuBLAS, cuSPARSE | rocBLAS, rocSPARSE |
| Pembelajaran Mendalam | cuDNN | MIOpen |
| Penyelesai | cuSOLVER | rocSOLVER |
Apabila seorang penyelidik bercakap tentang “mengoptimumkan kernel,” mereka biasanya bercakap tentang menulis semula kod dalam perpustakaan ini supaya berjalan lebih pantas pada seni bina perkakasan tertentu.
Lapisan 5: Rangka Kerja AI
Akhirnya, kami sampai ke puncak susunan: Rangka Kerja AI.
Inilah tempat PyTorch, TensorFlow, dan JAX wujud, dan di sinilah kebanyakan pembangun AI bekerja. Rangka kerja ini menyederhanakan semua kerumitan yang baru kita bincangkan, menyediakan cara yang intuitif dan berorientasikan Python untuk membina model tanpa risau tentang pengagihan memori atau lebar jalur PCIe. Rangka kerja ini mempunyai versi backend yang berbeza, satu untuk CUDA dan satu untuk ROCm.
Tetapi kesederhanaan itu tidak menjejaskan kelajuan. Apabila anda menjalankan fungsi dalam PyTorch, ia kebanyakannya bertindak sebagai pembungkus yang memanggil terus perpustakaan Lapisan 4 yang sangat dioptimumkan. Jadi, apabila anda menggunakan rangka kerja, anda mendapatkan fleksibiliti dan kesederhanaan Python dengan prestasi kernel GPU yang dioptimumkan.
Rangka kerja ini membolehkan anda menulis kod 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 cuba menulis program sebegitu dalam arahan GPU yang bertaraf rendah dan mengelirukan:
// 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 Penuh
Untuk memvisualisasikan bagaimana semuanya bersambung, mari kita jejak satu arahan. Bayangkan anda menggunakan PyTorch pada mesin AMD dan anda menjalankan pendaraban matriks: torch.matmul().
- Python (Lapisan 5): Anda menjalankan arahan. Backend PyTorch diaktifkan.
- Perpustakaan Matematik (Lapisan 4): PyTorch memanggil
rocBLAS, meminta kernel pendaraban matriks. - Antara Muka Pengaturcaraan (Lapisan 3):
rocBLASmemanggil API HIP untuk melancarkan kernel itu. - Runtime Sistem (Lapisan 2): Runtime memasukkan tugasan ke dalam barisan dan menjadualkannya.
- Pemandu Kernel (Lapisan 1): Pemandu mengambil peket dan menghantarnya melalui bas PCIe.
- Perkakasan (Lapisan 0): Cip GPU menerima kod mesin dan melaksanakan matematik.
Keseluruhan susunan ini - dari Python hingga Silicon - adalah satu pencapaian kejuruteraan yang luar biasa. Ia merapatkan jurang antara logik manusia dan kuasa pengkomputeran mentah, membolehkan ledakan AI yang kita lihat hari ini.
Keseluruhan Tumpukan Pengiraan AI, dari perkakasan (hijau), melalui ekosistem CUDA dan ROCm (biru), sehingga rangka kerja AI (kuning)
Terima kasih kerana belajar bersama Komuniti Linux-Console.net.










