- Untuk mengurangi dependensi besar dan beban deployment dari stack inferensi yang berpusat pada Python, aplikasi Llama2 Rust+Wasm dikemas sebagai biner 2MB dan dijalankan di berbagai perangkat
- Implementasinya merupakan bentuk llama.cpp yang disesuaikan untuk Wasm, serta memanfaatkan akselerasi perangkat keras lokal melalui file model GGUF, plugin GGML WasmEdge, dan API WASI NN
- Contohnya menggunakan model kuantisasi 5-bit Llama-2-7B-Chat GGUF, dengan kinerja sekitar 25 tokens/s pada MacBook M2 kelas murah dan sekitar 50 tokens/s pada Nvidia A10G
- Runtime WasmEdge dapat digunakan bersama alat kontainer, sehingga memudahkan deployment biner Wasm yang sama ke perangkat edge, on-premise, dan cloud
- Alat GGML sudah dapat digunakan, tetapi masih pada tahap awal; dukungan plugin untuk lebih banyak perangkat keras/OS, konfigurasi llama.cpp, dan dukungan API WASI NN di berbagai bahasa yang kompatibel dengan Wasm masih tersisa
Menjalankan inferensi Llama2 dengan Rust+Wasm
- Stack Rust+Wasm dapat digunakan sebagai alternatif Python untuk inferensi AI
- Dibandingkan Python, aplikasi Rust+Wasm bisa berukuran 1/100, 100 kali lebih cepat, dan memanfaatkan akselerasi perangkat keras di berbagai lingkungan tanpa perubahan pada kode biner yang sama
- Second State membuat program Rust sederhana yang menjalankan inferensi model Llama2 pada kecepatan native
- Aplikasi biner yang dikompilasi ke Wasm berukuran 2MB
- Aplikasi Wasm ini portabel di perangkat dengan akselerator perangkat keras yang heterogen
- Runtime WasmEdge menyediakan lingkungan eksekusi yang aman di lingkungan cloud
- WasmEdge dapat digunakan bersama alat kontainer untuk mengorkestrasi dan menjalankan aplikasi portabel di berbagai perangkat
Berbasis llama.cpp dan GGUF
Prosedur menjalankan
- Instal WasmEdge dan plugin GGML di perangkat Linux atau Mac
curl -sSf https://raw.githubusercontent.com/WasmEdge/WasmEdge/… | bash -s -- --plugins wasmedge_rustls wasi_nn-ggml
- Unduh aplikasi Wasm yang sudah dibangun sebelumnya
curl -LO https://github.com/LlamaEdge/LlamaEdge/…
- Contoh ini menggunakan file GGUF dari model Llama2 7B yang telah di-tune untuk chat dan dikuantisasi dengan 5-bit weights
curl -LO https://huggingface.co/second-state/Llama-2-7B-Chat-GGUF/…
- Jalankan aplikasi inferensi Wasm dengan WasmEdge dan berikan model GGUF, lalu Anda bisa memasukkan pertanyaan secara interaktif
wasmedge --dir .:. --nn-preload default:GGML:AUTO:Llama-2-7b-chat-hf-Q5_K_M.gguf llama-chat.wasm
Konfigurasi model dan contoh performa
llama-chat.wasm mengatur cara interaksi model melalui opsi command line
--ctx-size: ukuran konteks prompt, default 512
--n-predict: jumlah token yang akan diprediksi, default 1024
--n-gpu-layers: jumlah layer yang dijalankan di GPU, default 100
--batch-size: ukuran batch pemrosesan prompt, default 512
--temp: temperatur sampling, default 0.8
--repeat-penalty: penalti token berulang, default 1.1
--prompt-template: mendukung llama-2-chat, codellama-instruct, mistral-instruct-v0.1, chatml, deepseek-chat, deepseek-coder, dan lain-lain
--log-stat: keluaran statistik
- Berikut contoh eksekusi dengan panjang konteks 2048, maksimum 512 token respons, dan keluaran statistik diaktifkan
wasmedge --dir .:. --nn-preload default:GGML:AUTO:Llama-2-7b-chat-hf-Q5_K_M.gguf llama-chat.wasm -c 2048 -n 512 --log-stat
- Pada MacBook M2 kelas murah, respons LLM secara default di-streaming dan dihasilkan pada sekitar 25 tokens/s
- Contoh log mencatat 25.64 tokens/s berdasarkan
eval time dalam 82 kali eksekusi
kv self size ditampilkan sebagai 1024.00MB, dan compute buffer total size sebagai 630.14MB
- Pada perangkat Nvidia A10G, berjalan pada sekitar 50 tokens/s
- Menggunakan akselerasi CUDA GPU dan melakukan offload 35/35 layer ke GPU
- Penggunaan VRAM ditampilkan sebagai model 4474.93MB, konteks 1648.02MB, total 6122.95MB
- Mencatat 50.55 tokens/s berdasarkan
eval time dalam 83 kali eksekusi
Server API kompatibel OpenAI dan aplikasi LLM
- Tersedia juga server API kompatibel OpenAI yang dibuat dengan Rust dan WasmEdge
- Dengan server ini, Anda dapat membuat agen dan aplikasi LLM menggunakan alat pengembang kompatibel OpenAI seperti flows.network
- Penjelasan terkait tersedia di Build a super lightweight AI agent
Keterbatasan stack inferensi Python
- LLM seperti Llama2 biasanya dilatih dengan framework berbasis Python seperti PyTorch, Tensorflow, dan JAX
- Namun, untuk aplikasi inferensi yang mencakup sekitar 95% komputasi AI, Python dinilai kurang menguntungkan
- Paket Python dapat menjadi sulit diatur dan digunakan karena dependensi yang kompleks
- Image Docker Python atau PyTorch biasanya bisa membesar hingga beberapa GB atau puluhan GB, sehingga menjadi beban besar untuk inferensi AI di server atau perangkat edge
- Python jauh lebih lambat daripada bahasa terkompilasi seperti C, C++, dan Rust, bahkan bisa hingga 35.000 kali lebih lambat
- Sebagian besar workload nyata didelegasikan ke shared library native di bawah wrapper Python
- Struktur ini dianggap baik untuk demo, tetapi sulit memodifikasi bagian dalamnya agar sesuai dengan kebutuhan bisnis tertentu
- Ketergantungan tinggi pada library native dan pengelolaan dependensi yang rumit menurunkan portabilitas program AI Python dalam memanfaatkan kemampuan perangkat keras tiap perangkat
- Ada juga kasus paket Python yang umum di toolchain LLM saling bertabrakan karena persyaratan versi
pydantic
llama-cpp-python mensyaratkan pydantic 2.0.1 dan tidak berjalan pada <=2.0
fastapi dan chromadb mensyaratkan pydantic 1.9.2 dan tidak berjalan pada >=2.0
Keunggulan Rust+Wasm
- Stack Rust+Wasm dapat digunakan sebagai infrastruktur komputasi cloud terpadu yang mencakup perangkat, edge cloud, server on-premise, dan public cloud
- Untuk aplikasi inferensi AI, ini bisa menjadi alternatif kuat bagi stack Python
-
Sangat ringan
- Aplikasi inferensi hanya 2MB termasuk semua dependensinya
- Kurang dari 1% ukuran kontainer PyTorch pada umumnya
-
Eksekusi cepat
- Dapat memberikan kecepatan native C/Rust di seluruh tahap prapemrosesan, komputasi tensor, dan pascapemrosesan
-
Portabilitas
- Aplikasi bytecode Wasm yang sama berjalan di platform komputasi utama
- Juga mendukung akselerasi perangkat keras heterogen
-
Mudah dikonfigurasi, dikembangkan, dan di-deploy
- Dependensi kompleks berkurang
- Satu file Wasm dapat dibangun di laptop dengan alat standar lalu di-deploy ke berbagai lingkungan
-
Aman dan siap cloud
- Runtime Wasm dirancang untuk mengisolasi kode pengguna yang tidak tepercaya
- Dapat dikelola dengan alat kontainer dan di-deploy ke platform cloud-native
Struktur program inferensi Rust
- Program inferensi demo ditulis dalam Rust dan dikompilasi ke Wasm
- Kode sumber Rust inti panjangnya sekitar 40 baris
- Program Rust menjalankan peran berikut
- Mengelola input pengguna
- Melacak riwayat percakapan
- Mengubah teks ke template chat Llama2
- Menjalankan inferensi menggunakan API WASI NN
- Untuk membangun sendiri, instal compiler Rust dan target kompilasi
wasm32-wasi
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup target add wasm32-wasi
- Setelah itu, unduh proyek sumber dan bangun file Wasm dengan
cargo
git clone https://github.com/second-state/llama-utils
cd llama-utils/chat/
cargo build --target wasm32-wasi --release
cp target/wasm32-wasi/release/llama-chat.wasm .
Deployment cloud dan edge
- Jika sudah memiliki file bytecode Wasm, Anda dapat men-deploy-nya ke semua perangkat yang mendukung runtime WasmEdge
- Saat ini plugin GGML mendukung generic Linux dan Ubuntu Linux
- CPU x86 dan ARM
- GPU Nvidia
- Apple M1/M2/M3
- Plugin WasmEdge GGML secara otomatis memanfaatkan akselerasi perangkat keras perangkat berdasarkan llama.cpp
- Jika ada GPU Nvidia, installer akan otomatis memasang plugin GGML yang dioptimalkan untuk CUDA
- Plugin GGML untuk Mac OS menggunakan Metal API untuk menjalankan workload inferensi pada neural processing engine bawaan M1/M2/M3
- Build CPU Linux menggunakan OpenBLAS untuk mendeteksi dan memanfaatkan fitur komputasi CPU modern seperti AVX dan SIMD secara otomatis
- Pendekatan ini bertujuan memperoleh portabilitas lintas perangkat keras dan platform AI yang heterogen tanpa mengorbankan performa
Pekerjaan selanjutnya
- Alat WasmEdge GGML saat ini sudah dapat digunakan dan dipakai pelanggan cloud-native, tetapi masih berada pada tahap awal
- Area yang bisa dikontribusikan meliputi
- Menambahkan plugin GGML untuk lebih banyak perangkat keras dan platform OS
- Ada minat pada TPU, ARM NPU, dan chip AI khusus di Linux serta Windows
- Dukungan untuk lebih banyak konfigurasi llama.cpp
- Saat ini hanya sebagian opsi konfigurasi yang bisa diteruskan dari Wasm ke plugin GGML
- Tujuannya adalah mendukung semua opsi yang disediakan GGML
- Dukungan API WASI NN di bahasa lain yang kompatibel dengan Wasm
- Ada minat pada Go, Zig, Kotlin, JavaScript, C, dan C++
Dukungan model selain LLM
- WasmEdge dan WASI NN juga dapat digunakan untuk membangun aplikasi inferensi berbasis model AI populer di luar LLM sebagai alternatif Python yang ringan, cepat, portabel, dan aman
- mediapipe-rs menyediakan API Rust+Wasm untuk keluarga produk model Tensorflow mediapipe dari Google
- WasmEdge YOLO adalah proyek API Rust+Wasm untuk menangani model PyTorch YOLOv8
- WasmEdge ADAS demo adalah contoh yang melakukan segmentasi jalan untuk kendaraan otonom dengan model Intel OpenVINO
- WasmEdge Document AI direncanakan menyediakan API Rust+Wasm untuk keluarga model OCR dan pemrosesan dokumen
- Diskusi dan kontribusi terkait WasmEdge dapat dilakukan di WasmEdge Discord
1 komentar
Komentar Hacker News
Rust dan WASM memang bagus, tetapi kalau melihat kodenya, itu pada dasarnya hanya skrip command-line Rust 150 baris
Pekerjaan berat ditangani oleh satu baris yang menyerahkan model ke backend WASI-NN, yang di sini disediakan oleh runtime WasmEdge
Namun WasmEdge ditulis dalam C++, bukan Rust, dan dalam kasus ini manfaat Rust hampir tidak ada; backend-nya juga bisa dipanggil dari bahasa lain seperti Python
Membundel Python dan PyTorch menjadi bentuk yang bisa dijalankan pengguna akhir dengan double-click sampai sekarang masih nyaris berantakan, dan meski kode berperforma tinggi yang sesungguhnya di kedua sisi sama-sama C++, kalau bisa cukup dengan satu executable 2MB alih-alih mendistribusikan lebih dari 2GB dan puluhan ribu file hanya untuk mengirim beberapa perintah ke C++ itu, maka itu ada artinya
Pekerjaan yang hebat. Namun orang yang ingin mencobanya tetap harus mengunduh file bobot yang berukuran besar
Pada dasarnya ini membuat llama.cpp yang sepenuhnya portabel dan tanpa dependensi menjadi 2MB
Kalau Anda pengembang aplikasi, ini mungkin cara termudah untuk memaketkan inference engine ke dalam file yang bisa didistribusikan. Bobotnya sendiri sudah portabel dan bisa diunduh saat diperlukan, jadi bagian yang benar-benar ingin Anda kunci adalah inference engine-nya
Seperti yang dikatakan, ukuran bobotnya jauh mendominasi
mainyang dibangun llama.cpp berukuran 1,2MBUkuran 2MB itu sendiri tidak terlalu mengesankan; poin utamanya adalah menargetkan wasm sehingga menjadi lebih portabel, bukan berarti secara khusus lebih terkompresi
Bukankah ini pada akhirnya hanya membungkus llama.cpp? Sejujurnya saya sudah cukup lelah dengan proyek-proyek yang membungkus
x.cppSelama 6 bulan terakhir saya mengembangkan framework machine learning Rust + WebGPU, dan saya segera menyadari betapa hebatnya pekerjaan GG
Masih tahap awal, tetapi bisa dilihat di sini:
https://www.ratchet.sh/
https://github.com/FL33TW00D/whisper-turbo
wasi-nn yang menjadi dependensi ini, yaitu https://github.com/WebAssembly/wasi-nn, adalah proposal dengan cara mengirim chunk arbitrer ke implementasi vendor. API-nya pun pada dasarnya hanya sebatas mengatur input, menghitung, dan mengatur output
Jadi ini sama sekali tidak portabel
Alasan ini bisa berjalan adalah karena bergantung pada abstraksi yang sudah diimplementasikan di llama.cpp. Di sini terlihat WasmEdge mengambil begitu saja kode yang memetakan model gguf ke berbagai target hardware: https://github.com/WasmEdge/WasmEdge/tree/master/plugins/was...
Karena itu, penjelasan seperti “pengembang dapat menggunakan binding untuk menulis aplikasi machine learning dalam bahasa tingkat tinggi, mengompilasinya ke WebAssembly, lalu menjalankannya di runtime yang mendukung wasi-nn seperti WasmEdge” sepenuhnya keliru. Dalam praktiknya, itu tidak bisa dilakukan
Ini tidak portabel, bukan sandbox, dan bukan lapisan abstraksi hardware
Walau Anda punya binary wasm, itu hanya bisa berjalan jika versi runtime yang dipakai kebetulan mengimplementasikan backend ggml tertentu yang dibutuhkan, dan karena sama sekali tidak ada keharusan untuk itu, besar kemungkinan biasanya tidak demikian
Kalaupun bisa, pada akhirnya itu memanggil kode ggml milik llama.cpp, jadi keamanannya bergantung pada library tersebut
Tulisan itu terlalu menekankan “portabilitas” dan “Rust”, tetapi pada kenyataannya keunggulan keduanya tidak benar-benar terlihat
Dengan asumsi ada runtime WASI di hardware baru, apakah modelnya bisa dijalankan? Apakah ada dukungan GPU? Jawabannya menjadi “coba periksa apakah llama.cpp bisa dikompilasi dengan dukungan GPU di platform itu, apakah runtime yang Anda pakai punya plugin ggml, dan apakah versi ggml yang sesuai sudah di-vendor di dalamnya. Kalau tidak, ya tidak bisa”
Kalau begitu, untuk apa sebenarnya memakai WASI?
Memang dukungan GPU lintas platform itu sulit, tetapi ini terlihat cukup tidak masuk akal
Bayangkan kalau WebGPU bekerja dengan cara seperti “lemparkan chunk binary ke GPU, lalu kalau chunk itu cocok dengan hardware saat ini, mungkin saja sesuatu akan tergambar”; inilah kira-kira strukturnya
Bisakah ini dijalankan offline di iPhone? Kalau bisa, sepertinya berguna saat berkemah karena bisa dipakai seperti pencarian internet dasar tanpa bergantung pada sinyal
Namun untuk memuat modelnya sendiri tetap dibutuhkan memori beberapa GB
[0] https://github.com/mlc-ai/mlc-llm
Awalnya dibuat dengan ggml, lalu kemudian saya menemukan mlc-llm dan mem-port-nya berdasarkan itu
[0]: https://apps.apple.com/us/app/private-llm/id6448106860
Dalam alurnya, mungkin akan ada lebih banyak cara untuk menjalankan arsitektur transformer di edge dengan lebih efisien dan cepat, tetapi kebutuhan VRAM tidak bisa diselesaikan dengan Rust, jadi rasanya sudah mendekati batas
Saat memuat model yang cukup besar, bottleneck utamanya memang bagian ini
Bisa saja dikatakan “model kecil makin bagus, lihat Mistral dan llama 2”, tetapi model kecil pun sedang mendekati batas kapasitas. Ada batas pada jumlah informasi yang bisa dimasukkan ke dalam 7 miliar parameter
Saya tidak merasa pendekatan AI seperti ini akan mengarah ke AGI. Rasanya terlalu tidak efisien
Penjelasan bahwa “plugin GGML untuk Mac OS menggunakan Metal API untuk menjalankan pekerjaan inferensi di mesin pemrosesan neural bawaan M1/M2/M3” tampaknya tidak akurat
Bahwa GGML menggunakan Metal API berarti ia berjalan di GPU M1/2/3, bukan berarti berjalan di Neural Engine
Tentu saja itu sendiri sudah bagus, tetapi secara ketat begitulah maksudnya
Saya tidak suka pemasaran clickbait yang seolah mengatakan sebuah proyek mengurangi ukuran menjadi 1/100 atau meningkatkan kecepatan 100–35000 kali dibanding solusi lain hanya karena wrapper yang membungkus pustaka inti memakai bahasa lain
Ini juga sepenuhnya mengabaikan alat dan keahlian komunitas yang sudah terbentuk di sekitar solusi lain
Pertama-tama, proyek ini berbasis llama.cpp[1], dan pekerjaan berat berupa memuat file model berukuran beberapa GB ke GPU/CPU lalu menjalankannya ditangani oleh llama.cpp
Kecepatan inferensi tidak dibatasi oleh pilihan wrapper; ada wrapper Go, Python, Node, dan Rust, dan llama.cpp juga bisa digunakan langsung
Ukuran biner juga tidak begitu penting. File model terkuantisasi yang umum berada di kisaran 5GB~40GB, dan dibutuhkan mesin dengan GPU kuat atau RAM 16~64GB
[1] https://github.com/ggerganov/llama.cpp
Jika sebagian besar ukurannya pada akhirnya adalah bobot model yang telah dilatih, bagaimana ukurannya bisa dikurangi beberapa orde besaran tanpa kehilangan akurasi?
Angka 2MB yang dimaksud di sini tampaknya merujuk pada ukuran program di luar model. Sepertinya ini adalah cara menjalankan llama.cpp melalui server Rust yang menjalankan wasm dan llama.cpp
Saya menyukai
llama.cpp/examples/serveryang kecil dan meng-embed-nya di FreeChat, tetapi bertambahnya pilihan alat selalu merupakan hal baikSetelah dicek, file executable arm64/x86 yang saya embed saat ini berukuran 4,2MB. FreeChat berukuran 12,1MB, tetapi model bawaannya sekitar 3GB, jadi saya tidak terlalu memedulikan selisih 2MB
[0]: https://github.com/ggerganov/llama.cpp/tree/master/examples/...
Tulisan ini membahas pengurangan ukuran aplikasi inferensi sebesar 100 kali
Saya tidak mengerti alasan memakai ini alih-alih langsung memakai llama.cpp
Tulisan itu juga menjelaskan pemanfaatan akselerasi hardware pada perangkat yang memiliki akselerator hardware heterogen
Ini berarti program yang dikompilasi ke wasm dapat menggunakan berbagai sumber daya hardware seperti GPU atau chip AI khusus secara efisien di berbagai perangkat
Jika diimplementasikan langsung dengan C++, untuk mendapatkan performa serupa mungkin diperlukan optimasi atau versi terpisah untuk tiap jenis hardware