- Tulisan ini menjelaskan upaya dan desain untuk mengompilasi lebih dulu (AOT) kode Python murni menjadi berkas eksekusi lintas platform, dengan penjelasan berbasis contoh kasus
- Ide intinya bukan membuat JIT baru atau menulis ulang dalam C++, melainkan menghasilkan kernel yang dioptimalkan melalui pipeline symbolic tracing → IR → pembuatan kode C++ → kompilasi multi-target
- Anotasi tipe PEP 484 digunakan untuk menyemai propagasi tipe, dan pembuatan kode AI dipakai untuk mengimplementasikan ratusan operator C++ secara otomatis agar mencakup pemanggilan library yang luas seperti Numpy, OpenCV, dan PyTorch
- Untuk fungsi Python yang sama, berbagai jalur implementasi dibuat dan didistribusikan dalam jumlah besar, lalu strategi optimasi performa empiris digunakan untuk memilih varian tercepat lewat telemetri pengukuran nyata
- Tujuannya adalah menyediakan binary portabel yang kecil dan cepat tanpa bergantung pada container, sebagai unit distribusi yang bisa berjalan di mana saja hingga mencakup server, desktop, mobile, dan web
Foreword
- Kesederhanaan dan produktivitas Python adalah keunggulan, tetapi ada batasan performa dan portabilitas pada workload berbeban tinggi
- Artikel oleh kontributor tamu Yusuf Olokoba ini memperkenalkan desain kompilator untuk membuat berkas eksekusi yang cepat dan portabel sambil tetap mempertahankan Python asli
- Pendekatan ini berupaya mencapai optimasi kernel dengan menyusun pipeline tanpa menambahkan JIT atau menulis ulang total ke C++
Introduction
- Tujuannya adalah mengompilasi Python tanpa modifikasi secara AOT penuh agar berjalan tanpa interpreter, cepat mendekati C/C++, dan dapat dijalankan di semua platform
- Berbeda dari upaya yang sudah ada seperti Jython, RustPython, Numba, PyTorch, dan Mojo, pendekatan ini memilih transformasi kode dan pembuatan kernel alih-alih mengganti bahasa atau runtime
- Fungsi Python hasil kompilasi ini sudah digunakan di ribuan perangkat setiap bulan
Containers Are the Wrong Way to Distribute AI
- Dalam deployment dunia nyata, container membawa payload berlebihan seperti interpreter, package, dan snapshot OS, sehingga menimbulkan startup yang lambat dan batasan portabilitas
- Alternatifnya adalah berkas eksekusi mandiri yang hanya berisi model, yang menawarkan ukuran lebih kecil, startup lebih cepat, dan kemampuan berjalan di server, desktop, mobile, dan web
- Intinya adalah mengubah unit distribusi dari snapshot OS menjadi binary yang dapat dieksekusi sendiri
Arm64, Apple, and Unity: How It All Began
- Saat transisi Apple ke arm64, kasus Unity yang mengubah CIL ke C++ dengan IL2CPP sehingga bisa dikompilasi ke semua target dijadikan acuan
- Gagasan yang sama kemudian diterapkan ke Python untuk mewujudkan visi jalur kode yang bisa berjalan di mana saja
Sketching Out a Python Compiler
- Desain tingkat tinggi terdiri dari tahap input Python → symbolic trace (IR) → pembuatan C++ → kompilasi multi-target
- Alasan tidak langsung menuju object code dari IR dan memilih C++ sebagai artefak perantara adalah agar dapat memanfaatkan sebanyak mungkin jalur akselerasi seperti CUDA, MLX, TensorRT, dan AMX
- Tujuannya adalah mendapatkan desain yang mudah diperluas sehingga jalur optimal per perangkat keras mudah disisipkan
Building a Symbolic Tracer for Python
- Tracing awal berbasis PyTorch FX memiliki keterbatasan karena memerlukan eksekusi dan hanya terbatas pada operasi PyTorch
- Sebagai gantinya, dibangun symbolic tracer berbasis parsing AST yang mengubah control flow dan analisis pemanggilan ke IR
- Saat ini tracer tersebut menyediakan fitur seperti analisis statis, evaluasi parsial, dan pengamatan nilai live berbasis sandbox
Lowering to C++ via Type Propagation
- Untuk menjembatani dynamic typing Python ke static typing C++, digunakan propagasi tipe
- Jika tipe argumen input diketahui, maka tipe variabel perantara dapat diinferensikan secara deterministik berdasarkan definisi operator
- Setiap operasi Python dipetakan ke implementasi C++ yang sesuai, sambil menyebarkan tipe ke seluruh fungsi
Seeding the Type Propagation Process
- Anotasi tipe PEP 484 digunakan sebagai seed untuk propagasi tipe
- Ini memang bertentangan dengan prinsip tidak memodifikasi kode asli, tetapi dianggap sebagai kompromi yang dapat diterima demi antarmuka yang ringkas dan kompatibilitas
- Selain itu, diberlakukan batasan seperti pembatasan jumlah tipe pada signature fungsi untuk menjamin antarmuka konsumsi yang sederhana
Building a Library of C++ Operators
- Tidak semua fungsi perlu diimplementasikan langsung dalam C++; hanya operasi leaf yang tidak bisa ditrace yang memerlukan implementasi manual/otomatis
- Karena banyak kode Python tersusun dari kombinasi sejumlah kecil operasi dasar, himpunan operator yang perlu dicakup relatif kecil
- Dengan pembuatan kode berbasis LLM serta infrastruktur constraint, pengujian, dan conditional compilation, implementasi ratusan fungsi dari Numpy, OpenCV, dan PyTorch berhasil diotomatisasi
Performance Optimization via Exhaustive Search
- Berangkat dari pelajaran bahwa optimasi performa selalu bersifat empiris, semua varian implementasi dihasilkan lalu dibandingkan lewat pengukuran nyata untuk memilih yang terbaik
- Contoh: di Apple Silicon, hanya untuk resize saja dapat dibuat berbagai jalur seperti Accelerate, vImage, Core Image, dan Metal, lalu banyak binary dengan fungsi yang sama didistribusikan
- Dengan telemetri terperinci, latensi tiap jalur dikumpulkan, lalu model statistik dipakai untuk memprediksi dan memilih varian tercepat
- Dampaknya bagi pengguna adalah pengalaman eksekusi yang secara otomatis makin cepat seiring waktu
Designing a User Interface for the Compiler
- Untuk membuat pengalaman developer sedekat mungkin dengan tanpa kurva belajar, dekorator PEP 318
@compile dipilih sebagai antarmuka
- CLI menggunakan dekorator tersebut sebagai entry point untuk menelusuri graf kode dependensi dan melakukan kompilasi
- Argumen dekorator menerima tag, description, sandbox, metadata untuk mendukung reproduksi lingkungan dan penentuan backend seperti ONNXRuntime, TensorRT, CoreML, IREE, QNN, dan lainnya
Closing Thoughts
- Fitur seperti exception, lambda, recursion, dan class masih didukung sebagian atau belum didukung, dan khususnya tipe kompleks serta tipe orde tinggi masih memerlukan perluasan propagasi tipe
- Pengalaman debugging juga menjadi tantangan karena kompilasi teroptimasi mengurangi informasi simbol sehingga pelacakan menjadi lebih sulit
std::span, concepts, dan coroutines di C++20 menjadi fondasi utama, sementara std::generator, <stdfloat>, dan <stacktrace> di C++23 diharapkan berkontribusi pada streaming, half/bfloat16, dan pelacakan exception
- Tujuan akhirnya adalah menetapkan unit distribusi yang memungkinkan workload AI seperti embedding dan deteksi untuk berjalan di mana saja, melalui berkas eksekusi yang kecil, cepat, dan aman tanpa container
1 komentar
Kupikir ini seperti APE, tapi ternyata bukan.