2 पॉइंट द्वारा GN⁺ 2023-11-14 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • Python-केंद्रित inference stack की भारी dependencies और deployment burden घटाने के लिए, Rust+Wasm Llama2 app को 2MB binary के रूप में package कर कई devices पर चलाया गया
  • implementation, llama.cpp को Wasm के अनुकूल बनाए गए रूप में है, और GGUF model file, WasmEdge के GGML plugin, तथा WASI NN API के साथ local hardware acceleration का उपयोग करता है
  • उदाहरण में Llama-2-7B-Chat GGUF 5-bit quantized model का उपयोग है, और low-cost M2 MacBook पर लगभग 25 tokens/s, Nvidia A10G पर लगभग 50 tokens/s performance दिखती है
  • WasmEdge runtime को container tools के साथ इस्तेमाल किया जा सकता है, जिससे वही Wasm binary edge devices, on-premises और cloud पर deploy करना आसान होता है
  • GGML tools पहले से उपलब्ध हैं, लेकिन शुरुआती चरण में हैं; इसलिए अधिक hardware/OS plugins, llama.cpp settings support, और कई Wasm-compatible languages में WASI NN API support अभी बाकी है

Rust+Wasm से Llama2 inference चलाना

  • Rust+Wasm stack को AI inference में Python के विकल्प के रूप में इस्तेमाल किया जा सकता है
    • Rust+Wasm apps Python की तुलना में 1/100 size और 100 गुना speed दे सकते हैं, और वही binary code बदले बिना कई environments में hardware acceleration का उपयोग कर सकता है
  • Second State ने Llama2 model inference को native speed पर चलाने वाला एक सरल Rust program बनाया है
    • Wasm में compile किया गया binary app 2MB का है
    • यह Wasm app heterogeneous hardware accelerators वाले devices पर portable है
    • WasmEdge runtime cloud environments में secure execution environment देता है
    • WasmEdge को container tools के साथ इस्तेमाल करके कई devices पर portable apps को orchestrate और run किया जा सकता है

llama.cpp और GGUF पर आधारित

  • यह काम Georgi Gerganov द्वारा बनाए गए llama.cpp पर आधारित है
  • मूल C++ program को Wasm में चलाने के लिए adapt किया गया
  • Model files GGUF format का उपयोग करती हैं

चलाने की प्रक्रिया

  • Linux या Mac device पर WasmEdge और GGML plugin install करें
curl -sSf https://raw.githubusercontent.com/WasmEdge/WasmEdge/… | bash -s -- --plugins wasmedge_rustls wasi_nn-ggml
  • pre-built Wasm app download करें
curl -LO https://github.com/LlamaEdge/LlamaEdge/…
  • उदाहरण Llama2 7B chat-tuned model को 5-bit weights में quantize किए गए GGUF file का उपयोग करता है
curl -LO https://huggingface.co/second-state/Llama-2-7B-Chat-GGUF/…
  • WasmEdge से Wasm inference app चलाकर और GGUF model पास करके interactive तरीके से सवाल input किए जा सकते हैं
wasmedge --dir .:. --nn-preload default:GGML:AUTO:Llama-2-7b-chat-hf-Q5_K_M.gguf llama-chat.wasm

Model settings और performance examples

  • llama-chat.wasm command-line options से model interaction का तरीका configure करता है
    • --ctx-size: prompt context size, default 512
    • --n-predict: predict किए जाने वाले tokens की संख्या, default 1024
    • --n-gpu-layers: GPU पर चलाए जाने वाले layers की संख्या, default 100
    • --batch-size: prompt processing batch size, default 512
    • --temp: sampling temperature, default 0.8
    • --repeat-penalty: repeated token penalty, default 1.1
    • --prompt-template: llama-2-chat, codellama-instruct, mistral-instruct-v0.1, chatml, deepseek-chat, deepseek-coder आदि support
    • --log-stat: statistics output
  • Context length 2048, maximum response 512 tokens, और statistics output specify करने वाला run example यह है
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
  • low-cost M2 MacBook पर LLM response default रूप से streaming output में आता है और लगभग 25 tokens/s पर generate होता है
    • log example में eval time के आधार पर 82 runs में 25.64 tokens/s दर्ज हुआ
    • kv self size 1024.00MB और compute buffer total size 630.14MB दिखाया गया
  • Nvidia A10G machine पर यह लगभग 50 tokens/s पर चलता है
    • CUDA GPU acceleration का उपयोग करता है और 35/35 layers को GPU पर offload करता है
    • VRAM usage model 4474.93MB, context 1648.02MB, कुल 6122.95MB दिखाया गया
    • eval time के आधार पर 83 runs में 50.55 tokens/s दर्ज हुआ

OpenAI-compatible API server और LLM apps

  • Rust और WasmEdge से बना OpenAI-compatible API server भी दिया गया है
  • इस server का उपयोग करके flows.network जैसे OpenAI-compatible developer tools से LLM agents और apps बनाए जा सकते हैं
  • संबंधित explanation Build a super lightweight AI agent में है

Python inference stack की सीमाएँ

  • Llama2 जैसे LLM आम तौर पर Python-based frameworks PyTorch, Tensorflow, JAX से train किए जाते हैं
  • लेकिन AI computing के लगभग 95% हिस्से यानी inference applications में Python को नुकसानदेह माना जाता है
  • Python packages complex dependencies के कारण setup और use में मुश्किल हो सकते हैं
  • Python या PyTorch Docker images आमतौर पर कई GB या दसियों GB तक बढ़ सकते हैं, जिससे edge servers या devices पर AI inference में burden बढ़ता है
  • Python, C, C++, Rust जैसी compiled languages से बहुत धीमा है और अधिकतम 35,000 गुना धीमा हो सकता है
  • असली workloads का अधिकांश हिस्सा Python wrapper के नीचे native shared libraries को delegate होता है
    • यह structure demos के लिए अच्छा है, लेकिन business-specific needs के हिसाब से internals बदलना मुश्किल माना जाता है
  • Native libraries पर high dependency और complex dependency management, device-specific hardware capabilities का उपयोग करने वाले Python AI programs की portability घटाते हैं
  • LLM toolchain में आम तौर पर इस्तेमाल होने वाले Python packages के pydantic version requirements आपस में conflict करने के cases भी हैं
    • llama-cpp-python को pydantic 2.0.1 चाहिए और यह <=2.0 पर काम नहीं करता
    • fastapi और chromadb को pydantic 1.9.2 चाहिए और ये >=2.0 पर काम नहीं करते

Rust+Wasm के फायदे

  • Rust+Wasm stack को devices, edge cloud, on-premises servers और public cloud को cover करने वाले unified cloud computing infrastructure के रूप में इस्तेमाल किया जा सकता है
  • AI inference applications में यह Python stack का मजबूत विकल्प बन सकता है
  • बेहद lightweight

    • inference application सभी dependencies सहित 2MB का है
    • सामान्य PyTorch container size के 1% से कम
  • तेज़ execution

    • preprocessing, tensor computation और postprocessing में native C/Rust speed मिल सकती है
  • Portability

    • वही Wasm bytecode application प्रमुख computing platforms पर चलता है
    • heterogeneous hardware acceleration भी support करता है
  • Setup, development और deployment में आसानी

    • complex dependencies कम होती हैं
    • laptop पर standard tools से single Wasm file build करके कई environments में deploy किया जा सकता है
  • Safety और cloud readiness

    • Wasm runtime untrusted user code को isolate करने के लिए design किया गया है
    • इसे container tools से manage कर cloud-native platforms पर deploy किया जा सकता है

Rust inference program structure

  • demo inference program Rust में लिखा गया है और Wasm में compile किया गया है
  • core Rust source code करीब 40 lines का है
  • Rust program ये भूमिकाएँ निभाता है
    • user input manage करना
    • conversation history track करना
    • text को Llama2 chat template में बदलना
    • WASI NN API का उपयोग करके inference चलाना
  • सीधे build करने के लिए Rust compiler और wasm32-wasi compilation target install करें
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup target add wasm32-wasi
  • इसके बाद source project download करें और cargo से Wasm file build करें
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 .

Cloud और edge deployment

  • Wasm bytecode file होने पर इसे WasmEdge runtime support करने वाले किसी भी device पर deploy किया जा सकता है
  • मौजूदा GGML plugin generic Linux और Ubuntu Linux support करता है
    • x86 और ARM CPU
    • Nvidia GPU
    • Apple M1/M2/M3
  • WasmEdge GGML plugin llama.cpp के आधार पर device के hardware acceleration का automatic उपयोग करता है
    • Nvidia GPU होने पर installer CUDA-optimized GGML plugin अपने-आप install करता है
    • Mac OS के लिए GGML plugin Metal API का उपयोग करके M1/M2/M3 के built-in neural processing engine पर inference workload चलाता है
    • Linux CPU build OpenBLAS का उपयोग करके AVX, SIMD जैसी आधुनिक CPU compute capabilities को automatic detect और use करता है
  • यह approach performance sacrifice किए बिना heterogeneous AI hardware और platforms के बीच portability हासिल करने का तरीका है

आगे का काम

  • WasmEdge GGML tools अभी usable हैं और cloud-native customers इस्तेमाल कर रहे हैं, लेकिन अभी भी early stage में हैं
  • contribution के संभावित areas ये हैं
    • अधिक hardware और OS platforms के लिए GGML plugins जोड़ना
      • TPU, ARM NPU, Linux और Windows के special AI chips में interest है
    • अधिक llama.cpp settings support करना
      • फिलहाल कुछ ही settings options Wasm से GGML plugin तक pass किए जा सकते हैं
      • लक्ष्य GGML द्वारा दिए जाने वाले सभी options support करना है
    • अन्य Wasm-compatible languages में WASI NN API support
      • Go, Zig, Kotlin, JavaScript, C, C++ में interest है

LLM के अलावा models का support

  • WasmEdge और WASI NN, LLM के अलावा popular AI models पर आधारित inference apps भी lightweight, fast, portable और secure Python alternative के रूप में बना सकते हैं
  • mediapipe-rs Google mediapipe Tensorflow model family के लिए Rust+Wasm API देता है
  • WasmEdge YOLO YOLOv8 PyTorch model को handle करने वाला Rust+Wasm API project है
  • WasmEdge ADAS demo Intel OpenVINO model से autonomous vehicles के road segmentation करने का example है
  • WasmEdge Document AI OCR और document processing model family के लिए Rust+Wasm API provide करेगा
  • WasmEdge से जुड़ी discussions और contributions WasmEdge Discord पर की जा सकती हैं

1 टिप्पणियां

 
GN⁺ 2023-11-14
Hacker News की राय
  • Rust और WASM अच्छे हैं, लेकिन कोड देखें तो यह बस एक बुनियादी Rust command-line script की 150 lines है
    भारी काम मॉडल को WASI-NN backend को सौंपने वाली एक line करती है, और यहाँ उसे WasmEdge runtime उपलब्ध कराता है
    लेकिन WasmEdge Rust नहीं, C++ है, और इस मामले में Rust से मिलने वाला फायदा लगभग नहीं है; backend को Python जैसी दूसरी भाषाओं से भी call किया जा सकता है

    • यहाँ Rust का फायदा bundling और deployment लगता है
      Python और PyTorch को ऐसे रूप में bundle करना, जिसे end user double-click करके चला सके, आज भी लगभग अव्यवस्थित है। असली high-performance code दोनों तरफ C++ ही है, लेकिन उस C++ को कुछ commands भेजने के लिए 2GB से ज्यादा और हजारों files deploy करने के बजाय अगर एक 2MB executable file से काम हो जाए, तो उसका मतलब है
  • शानदार काम है। हालांकि इसे आजमाने वालों को अब भी बड़े size वाली weights file download करनी होगी
    मूल रूप से यह पूरी तरह portable और dependency-free llama.cpp को 2MB में बनाने जैसा है
    अगर आप app developer हैं, तो deploy की जा सकने वाली file के अंदर inference engine package करने का यह सबसे आसान तरीका हो सकता है। weights पहले से portable हैं और जरूरत पड़ने पर download किए जा सकते हैं, इसलिए जिस हिस्से को सच में fix करना है, वह inference engine है

    • title में 2MB का wasm लिखना शायद ज्यादा मददगार होगा
      जैसा कहा गया, weights उस size को बहुत पीछे छोड़ देते हैं
    • मेरी machine पर llama.cpp द्वारा build की गई main file 1.2MB है
      2MB का size अपने-आप में खास impressive नहीं है; मुख्य बात यह है कि wasm को target करने से यह ज्यादा portable बनता है, यह कोई खास तौर पर ज्यादा compressed नहीं है
  • क्या यह आखिरकार llama.cpp का wrapper ही नहीं है? सच कहूँ तो x.cpp को wrap करने वाले projects से मैं काफी थक गया हूँ
    पिछले 6 महीनों से मैं Rust + WebGPU machine learning framework develop कर रहा हूँ, और जल्दी ही समझ आ गया कि GG का काम कितना जबरदस्त है
    अभी शुरुआती stage में है, लेकिन यहाँ देखा जा सकता है:
    https://www.ratchet.sh/
    https://github.com/FL33TW00D/whisper-turbo

    • क्या आप और बता सकते हैं कि इसमें आपको क्या impressive लगा? मैं इस field को बिल्कुल नहीं जानता, इसलिए इसकी value ठीक से समझना मुश्किल है
    • क्या आपने दूसरे के काम को कमतर बताते हुए उसी comment में अपना काम promote किया? इस पर नैतिक रूप से गंभीरता से सोचने की जरूरत है
    • GG कौन है?
  • जिस wasm-nn पर यह निर्भर है, यानी https://github.com/WebAssembly/wasi-nn, वह arbitrary chunks को vendor implementation को भेजने के तरीके का proposal है। API भी असल में input set करने, compute करने और output set करने भर की है
    इसलिए यह बिल्कुल portable नहीं है
    यह चल इसलिए रहा है क्योंकि यह llama.cpp में पहले से implemented abstraction पर निर्भर है। gguf models को अलग-अलग hardware targets पर map करने वाला वही code WasmEdge ने जस का तस ले लिया है, जैसा यहाँ दिखता है: https://github.com/WasmEdge/WasmEdge/tree/master/plugins/was...
    इसलिए “developer bindings का इस्तेमाल करके high-level languages में machine learning apps लिख सकते हैं, WebAssembly में compile कर सकते हैं और WasmEdge जैसे wasi-nn support वाले runtime पर चला सकते हैं” जैसी बात पूरी तरह गलत है। असल में आप ऐसा नहीं कर सकते
    यह न portable है, न sandbox है, और न hardware abstraction layer है
    wasm binary होने पर भी यह तभी चलेगी जब इस्तेमाल हो रहे runtime version ने संयोग से जरूरी खास ggml backend implement किया हो; इसकी कोई requirement नहीं है, इसलिए ज्यादातर cases में शायद ऐसा नहीं होगा
    अगर चल भी जाए, तो आखिरकार यह llama.cpp के ggml code को call कर रहा है, इसलिए safety उतनी ही है जितनी उस library की
    article में “portability” और “Rust” पर बहुत जोर है, लेकिन असल में दोनों में से किसी का भी फायदा अच्छी तरह दिखाई नहीं देता
    मान लें किसी नए hardware पर WASI runtime है, तो क्या model चल सकता है? GPU support है? जवाब होगा: “जाँचिए कि उस platform पर llama.cpp GPU support के साथ compile होता है या नहीं, आपके runtime में ggml plugin है या नहीं, और उसमें सही version का ggml vendored है या नहीं। नहीं तो नहीं चलेगा”
    तो फिर WASI का इस्तेमाल आखिर क्यों करें?
    cross-platform GPU support मुश्किल है, यह सही है, लेकिन यह काफी बेतुका लगता है
    कल्पना करें कि WebGPU का तरीका ऐसा होता: “GPU पर binary chunk फेंक दें; अगर वह chunk मौजूदा hardware के लिए सही हुआ तो शायद कुछ draw कर दे।” यह structure बिल्कुल वैसा ही है

    • explanation के लिए धन्यवाद। सोच रहा था कि WASM में GPU support कहाँ से मिलता है
    • security के लिहाज से असर को भी थोड़े विस्तार से समझा सकते हैं?
  • क्या इसे iPhone पर offline चलाया जा सकता है? ऐसा हो तो reception की परवाह किए बिना basic internet search जैसा इस्तेमाल किया जा सकेगा, camping के समय काम आ सकता है

    • यह कई Linux, Mac, Windows आधारित devices पर चल सकता है और इसमें Raspberry Pi या ज्यादातर laptops/servers भी शामिल हैं
      हालांकि model खुद load करने के लिए अब भी कुछ GB memory चाहिए
    • मैंने इस project को Pixel पर चलाकर देखा है। कुछ iPhone/iPad पर भी चलता लगता है
      [0] https://github.com/mlc-ai/mlc-llm
    • उस use case के लिए Wikipedia का edition download करना शायद बेहतर होगा। entropy जैसी समस्याएँ भी हैं
    • उस use case के लिए मैंने कुछ हद तक सफल commercial iOS app बनाया था
      शुरुआत में ggml से बनाया था, फिर mlc-llm मिला और उसे उसी पर port कर दिया
      [0]: https://apps.apple.com/us/app/private-llm/id6448106860
  • प्रवाह को देखते हुए edge पर Transformer architecture को ज़्यादा efficient और तेज़ चलाने के तरीके आगे और आएंगे, लेकिन VRAM requirement Rust से हल नहीं हो सकती, इसलिए लगता है कि यह सीमा के करीब पहुंच रहा है
    पर्याप्त बड़ा model चलाते समय मुख्य bottleneck यही हिस्सा होता है
    “छोटे model बेहतर होते जा रहे हैं, Mistral और llama 2 को देखिए” कहा जा सकता है, लेकिन छोटे model भी capacity limit के करीब पहुंच रहे हैं। 7 अरब parameters में डाली जा सकने वाली जानकारी की एक सीमा होती है
    नहीं लगता कि AI का यह approach AGI तक ले जाएगा। यह बहुत inefficient लगता है

    • छोटे models में भी MoE systems या LoRA को dynamically load करने जैसे तरीकों से अभी काफी गुंजाइश है, ऐसा मुझे लगता है
  • “Mac OS के लिए GGML plugin, Metal API का उपयोग करके M1/M2/M3 के built-in neural network processing engine पर inference tasks चलाता है” वाला वर्णन सही नहीं लगता
    GGML का Metal API इस्तेमाल करना मतलब M1/2/3 के GPU पर चलना है, Neural Engine पर चलना नहीं
    बेशक यह अपने-आप में अच्छा है, लेकिन strictly कहें तो बात यही है

    • यह बिल्कुल मामूली nitpick नहीं है। https://github.com/ggerganov/llama.cpp/discussions/336 में GPU से आगे बढ़कर सीधे Neural Engine इस्तेमाल करना शुरू से ही worth it है या नहीं, इस पर कुछ बिखरी हुई चर्चा है
  • मुझे ऐसी clickbait marketing पसंद नहीं, जिसमें core library के wrapper के दूसरी language में लिखे होने भर से project को दूसरे solutions की तुलना में size 1/100 करने या speed 100~35000x बढ़ाने जैसा बताया जाता है
    यह दूसरे solutions के आसपास बने tools और community expertise को भी पूरी तरह ignore करता है
    सबसे पहले, यह project llama.cpp[1] पर आधारित है, और कई GB वाले model files को GPU/CPU पर load करके चलाने वाला भारी काम llama.cpp संभालता है
    inference speed wrapper चुनने से limited नहीं होती; Go, Python, Node, Rust wrappers भी हैं और llama.cpp को directly भी इस्तेमाल किया जा सकता है
    binary size भी इतना महत्वपूर्ण नहीं है। आम quantized model files 5GB~40GB range में होते हैं, और strong GPU या 16~64GB RAM वाली machine चाहिए होती है
    [1] https://github.com/ggerganov/llama.cpp

  • अगर size का बड़ा हिस्सा आखिरकार trained model weights ही है, तो accuracy खोए बिना size को कई orders of magnitude तक कैसे घटाया जा सकता है?

    • मुझे लगता है कि accuracy loss के बिना size घटाना मुश्किल है। हालांकि quantized GGUF शानदार है
      यहां बताए गए 2MB से model को छोड़कर program size का मतलब लगता है। ऐसा लगता है कि wasm और llama.cpp चलाने वाले Rust server से llama.cpp चलाने का तरीका है
      मुझे छोटा llama.cpp/examples/server पसंद है, इसलिए उसे FreeChat में embed कर रहा हूं, लेकिन tool choices और बढ़ना हमेशा अच्छा है
      check करने पर, जो arm64/x86 executable मैं embed करता हूं वह अभी 4.2MB है। FreeChat 12.1MB है, लेकिन default model लगभग 3GB का है, इसलिए 2MB के फर्क की मुझे ज्यादा चिंता नहीं
      [0]: https://github.com/ggerganov/llama.cpp/tree/master/examples/...
    • अगर बात model itself, यानी trained weights के size को accuracy loss के बिना कई orders of magnitude घटाने की है, तो वह एक अलग और कठिन समस्या है
      यह लेख inference app size को 100x घटाने की बात करता है
  • समझ नहीं आता कि इसे llama.cpp सीधे इस्तेमाल करने के बजाय क्यों इस्तेमाल किया जाए

    • hint: Rewrite-it-in-Rust economy की currency असल में कुछ चलाना नहीं है
    • llama.cpp को आम तौर पर operating system और architecture के हिसाब से Windows, macOS, Linux आदि के लिए अलग-अलग compile करना पड़ता है, इसलिए portability कम होती है
      लेख में यह भी बताया गया है कि heterogeneous hardware accelerators वाले devices पर hardware acceleration का फायदा उठाया जाता है
      इसका मतलब है कि wasm में compile किया गया program कई devices पर GPU या special AI chips जैसे अलग-अलग hardware resources को efficiently इस्तेमाल कर सकता है
      सीधे C++ में implement करने पर, similar performance पाने के लिए हर hardware type के लिए अलग optimization या version की जरूरत पड़ सकती है