Dec 30, 2023
MUHAMMAD GHIFARY
Inti dari algoritma/komputasi deep learning merupakan rangkaian operasi aljabar matriks dan vektor. Operasi aljabar akan semakin efisien apabila dieksekusi secara paralel. Inilah yang coba dieksploitasi oleh berbagai perangkat keras seperti GPU dan TPU untuk mengakselerasi komputasi deep learning.
Pada tahun 2020, Apple mengeluarkan Silicon atau System-on-a-chip (SoC) seri “M” produksi sendiri yang mengintegrasikan berbagai komponen penyusun komputer pada satu IC. SoC tersebut merupakan pengganti dari perangkat komputasi berbasis Intel yang selama ini digunakan pada seluruh produk Apple.
Untuk seri M1 Pro, Silicon tersebut dilengkapi dengan GPU (14 - 16 cores) dan juga Neural engine (16 cores) yang merupakan komponen-komponen khusus dirancang untuk mengoptimalkan komputasi paralel — seri-seri di atasnya memliki spesifikasi yang lebih tinggi. Tentunya ini kabar gembira bagi para tukang oprek AI pengguna Mac OS.
Kekuatan komputasi perangkat keras GPU tidak serta merta langsung bisa dinikmati tanpa keberadaan semacam driver atau API framework. Apple sekaligus menyediakan API framework yang dinamai Metal Performance Shaders (MPS) untuk memanfaatkan sumber daya komputasi paralel pada SoC seri M. Hal ini seperti hubungan antara GPU dari NVIDIA dengan Cuda framework.
Sejak tahun 2022, PyTorch mulai versi 1.12 akhirnya dilengkapi dengan backend MPS. Hal ini memungkinkan graf komputasi PyTorch untuk dipetakan pada MPS Graph yang mengoptimalkan komputasi pada GPU dan Neural engine. Ketika pertama kali launching, dilaporkan bahwa PyTorch dengan MPS mampu mempercepat pelatihan berbagai model deep learning hingga ~8x lipat dibandingkan dengan CPU.

Per Desember 2023, PyTorch sudah mencapai versi 2.1.2 dimana sudah terjadi banyak peningkatan optimisasi komputasi MPS. Untuk dapat menggunakan backend MPS cukup dengan instalasi / upgrade dengan cara standar:
# MPS acceleration is available on MacOS 12.3+
pip3 install --upgrade torch torchvision torchaudio
Kode di bawah ini mengecek dan mengidentifikasi keberadaan device “mps” pada PyTorch — device “cpu” akan otomatis terpilih apabila “mps” tidak tersedia:
device = (
"mps"
if torch.backends.mps.is_available()
else "cpu"
)
Saya coba membandingkan kecepatan komputasi antara CPU dengan MPS pada mesin Apple M1 Pro, dimulai dengan skenario komputasi sederhana perkalian matriks-vektor berikut ini.
m = 3000 # vector / matrix dimension
a_cpu = torch.rand(m, device="cpu")
B_cpu = torch.rand((m, m), device="cpu")
a_mps = torch.rand(m, device="mps")
B_mps = torch.rand((m, m), device="mps")
print("[vec @ mat] cpu: ", timeit.timeit(lambda: B_cpu @ a_cpu, number=100))
print("[vec @ mat] mps: ", timeit.timeit(lambda: B_mps @ a_mps, number=100))
Kode di atas menginstansiasi 2 vektor dan matriks masing-masing pada device “cpu” dan “mps” dimana $m$ mendefinisikan dimensi dari vektor dan matriks tersebut: $\mathbf{a} \in \mathbb{R}^m$, $\mathbf{B}\in \mathbb{R}^{m \times m}$. Kemudian dilakukan operasi perkalian matriks dan vektor $\mathbf{B} \mathbf{a}$.
Dengan mencoba beberapa nilai dimensi $m$, didapatkan grafik waktu komputasi terhadap dimensi berikut ini:

CPU vs MPS