2 puan yazan GN⁺ 2023-11-14 | 1 yorum | WhatsApp'ta paylaş
  • Python merkezli çıkarım yığınlarının büyük bağımlılıklarını ve dağıtım yükünü azaltmak için, Rust+Wasm Llama2 uygulaması 2 MB’lık bir ikili dosya olarak paketlenip çeşitli cihazlarda çalıştırılıyor
  • Uygulama, llama.cpp’nin Wasm’a uyarlanmış bir biçimi; GGUF model dosyası, WasmEdge’in GGML eklentisi ve WASI NN API ile yerel donanım hızlandırmasından yararlanıyor
  • Örnek, Llama-2-7B-Chat GGUF 5-bit kuantize modeli kullanıyor; düşük maliyetli bir M2 MacBook’ta yaklaşık 25 token/s, Nvidia A10G’de yaklaşık 50 token/s performans gösteriyor
  • WasmEdge çalışma zamanı konteyner araçlarıyla birlikte kullanılabildiği için aynı Wasm ikili dosyasını uç cihazlara, şirket içi ortamlara ve buluta dağıtmak kolaylaşıyor
  • GGML araçları halihazırda kullanılabilir durumda, ancak erken aşamada; daha fazla donanım ve işletim sistemi eklentisi, llama.cpp ayar desteği ve birden çok Wasm uyumlu dil için WASI NN API desteği hâlâ yapılacak işler arasında

Rust+Wasm ile Llama2 çıkarımı çalıştırma

  • Rust+Wasm yığını, yapay zeka çıkarımında Python’a alternatif olarak kullanılabilir
    • Rust+Wasm uygulamaları Python’a kıyasla 1/100 boyutta ve 100 kat hızlı olabilir; aynı ikili kod, değişiklik gerektirmeden farklı ortamlarda donanım hızlandırmasından yararlanabilir
  • Second State, Llama2 model çıkarımını yerel hıza yakın çalıştıran basit bir Rust programı oluşturdu
    • Wasm’a derlenmiş ikili uygulama 2 MB
    • Bu Wasm uygulaması, heterojen donanım hızlandırıcılarına sahip cihazlar arasında taşınabilir
    • WasmEdge çalışma zamanı, bulut ortamlarında güvenli bir yürütme ortamı sağlar
    • WasmEdge, farklı cihazlarda taşınabilir uygulamaları orkestre etmek ve çalıştırmak için konteyner araçlarıyla birlikte kullanılabilir

llama.cpp ve GGUF temeli

  • Bu çalışma, Georgi Gerganov tarafından geliştirilen llama.cpp üzerine kuruludur
  • Orijinal C++ programı Wasm’da çalışacak şekilde uyarlanmıştır
  • Model dosyaları GGUF biçimini kullanır

Çalıştırma adımları

  • Linux veya Mac cihazda WasmEdge ve GGML eklentisini kurun
curl -sSf https://raw.githubusercontent.com/WasmEdge/WasmEdge/… | bash -s -- --plugins wasmedge_rustls wasi_nn-ggml
  • Önceden derlenmiş Wasm uygulamasını indirin
curl -LO https://github.com/LlamaEdge/LlamaEdge/…
  • Örnek, Llama2 7B chat-tuned modelinin 5-bit weights ile kuantize edilmiş GGUF dosyasını kullanır
curl -LO https://huggingface.co/second-state/Llama-2-7B-Chat-GGUF/…
  • Wasm çıkarım uygulamasını WasmEdge ile çalıştırıp GGUF modelini verdiğinizde etkileşimli olarak soru girebilirsiniz
wasmedge --dir .:. --nn-preload default:GGML:AUTO:Llama-2-7b-chat-hf-Q5_K_M.gguf llama-chat.wasm

Model ayarları ve performans örnekleri

  • llama-chat.wasm, modelle etkileşim şeklini komut satırı seçenekleriyle yapılandırır
    • --ctx-size: istem bağlamı boyutu, varsayılan 512
    • --n-predict: tahmin edilecek token sayısı, varsayılan 1024
    • --n-gpu-layers: GPU’da çalıştırılacak katman sayısı, varsayılan 100
    • --batch-size: istem işleme batch boyutu, varsayılan 512
    • --temp: örnekleme sıcaklığı, varsayılan 0.8
    • --repeat-penalty: tekrar eden token cezası, varsayılan 1.1
    • --prompt-template: llama-2-chat, codellama-instruct, mistral-instruct-v0.1, chatml, deepseek-chat, deepseek-coder vb. desteklenir
    • --log-stat: istatistik çıktısı
  • Bağlam uzunluğu 2048, yanıt üst sınırı 512 token ve istatistik çıktısı belirtilen çalıştırma örneği şöyledir
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
  • Düşük maliyetli bir M2 MacBook’ta LLM yanıtı varsayılan olarak akış şeklinde yazdırılır ve yaklaşık 25 token/s hızında üretilir
    • Günlük örneğinde eval time bazında 82 çalıştırmada 25.64 token/s kaydedilmiştir
    • kv self size 1024.00 MB, compute buffer total size 630.14 MB olarak gösterilir
  • Nvidia A10G donanımında yaklaşık 50 token/s hızında çalışır
    • CUDA GPU hızlandırması kullanılır ve 35/35 katman GPU’ya offload edilir
    • VRAM kullanımı model için 4474.93 MB, bağlam için 1648.02 MB, toplam 6122.95 MB olarak gösterilir
    • eval time bazında 83 çalıştırmada 50.55 token/s kaydedilmiştir

OpenAI uyumlu API sunucusu ve LLM uygulamaları

  • Rust ve WasmEdge ile geliştirilmiş OpenAI uyumlu API sunucusu da sunuluyor
  • Bu sunucu ile flows.network gibi OpenAI uyumlu geliştirici araçları kullanarak LLM ajanları ve uygulamaları oluşturabilirsiniz
  • İlgili açıklama Build a super lightweight AI agent içinde yer alıyor

Python çıkarım yığınının sınırları

  • Llama2 gibi LLM’ler genellikle Python tabanlı PyTorch, Tensorflow ve JAX framework’leriyle eğitilir
  • Ancak yapay zeka hesaplamasının yaklaşık %95’ini oluşturan çıkarım uygulamalarında Python’un dezavantajlı olduğu düşünülüyor
  • Python paketleri, karmaşık bağımlılıklar nedeniyle kurulumu ve kullanımı zorlaştırabilir
  • Python veya PyTorch Docker imajları çoğunlukla birkaç GB’dan onlarca GB’a kadar büyüyebilir; bu da uç sunucularda veya cihazlarda yapay zeka çıkarımı için ciddi yük oluşturur
  • Python, C, C++ ve Rust gibi derlenen dillere göre çok yavaştır; en fazla 35.000 kat yavaş olabilir
  • Gerçek iş yüklerinin çoğu, Python sarmalayıcılarının altındaki yerel paylaşımlı kütüphanelere devredilir
    • Bu yapı demolar için iyidir, ancak iş gereksinimlerine göre içini değiştirmeyi zorlaştırdığı düşünülür
  • Yerel kütüphanelere yüksek bağımlılık ve karmaşık bağımlılık yönetimi, cihazlara özgü donanım yeteneklerinden yararlanan Python yapay zeka programlarının taşınabilirliğini azaltır
  • LLM araç zincirinde yaygın kullanılan Python paketlerinin pydantic sürüm gereksinimleri yüzünden birbiriyle çakıştığı durumlar da vardır
    • llama-cpp-python, pydantic 2.0.1 gerektirir ve <=2.0 ile çalışmaz
    • fastapi ve chromadb, pydantic 1.9.2 gerektirir ve >=2.0 ile çalışmaz

Rust+Wasm’ın avantajları

  • Rust+Wasm yığını; cihazlar, uç bulut, şirket içi sunucular ve genel bulutları kapsayan birleşik bir bulut bilişim altyapısı olarak kullanılabilir
  • Yapay zeka çıkarım uygulamalarında Python yığınına güçlü bir alternatif olabilir
  • Ultra hafif

    • Çıkarım uygulaması, tüm bağımlılıklarıyla birlikte 2 MB
    • Tipik bir PyTorch konteynerinin boyutunun %1’inden daha küçük
  • Hızlı yürütme

    • Ön işleme, tensör hesaplamaları ve son işleme genelinde yerel C/Rust hızına ulaşabilir
  • Taşınabilirlik

    • Aynı Wasm bytecode uygulaması başlıca bilişim platformlarında çalışır
    • Heterojen donanım hızlandırmasını da destekler
  • Kolay kurulum, geliştirme ve dağıtım

    • Karmaşık bağımlılıklar azalır
    • Dizüstü bilgisayarda standart araçlarla tek bir Wasm dosyası derleyip farklı ortamlara dağıtabilirsiniz
  • Güvenlik ve buluta hazır olma

    • Wasm çalışma zamanı, güvenilmeyen kullanıcı kodunu izole edecek şekilde tasarlanmıştır
    • Konteyner araçlarıyla yönetilebilir ve bulut yerel platformlara dağıtılabilir

Rust çıkarım programının yapısı

  • Demo çıkarım programı Rust ile yazılmış ve Wasm’a derlenmiştir
  • Temel Rust kaynak kodu yaklaşık 40 satırdır
  • Rust programı şu rolleri üstlenir
    • Kullanıcı girdisini yönetme
    • Konuşma geçmişini izleme
    • Metni Llama2 chat template’e dönüştürme
    • WASI NN API kullanarak çıkarımı çalıştırma
  • Kendiniz derlemek için Rust derleyicisini ve wasm32-wasi derleme hedefini kurun
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup target add wasm32-wasi
  • Ardından kaynak projeyi indirip cargo ile Wasm dosyasını derleyin
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 .

Bulut ve uç dağıtım

  • Wasm bytecode dosyası olduğunda, WasmEdge çalışma zamanını destekleyen her cihaza dağıtabilirsiniz
  • Mevcut GGML eklentisi generic Linux ve Ubuntu Linux’u destekler
    • x86 ve ARM CPU
    • Nvidia GPU
    • Apple M1/M2/M3
  • WasmEdge GGML eklentisi, llama.cpp temelinde cihazın donanım hızlandırmasını otomatik kullanır
    • Nvidia GPU varsa kurulum programı CUDA için optimize edilmiş GGML eklentisini otomatik kurar
    • Mac OS için GGML eklentisi, M1/M2/M3’ün yerleşik neural processing engine üzerinde çıkarım iş yükünü çalıştırmak için Metal API’yi kullanır
    • Linux CPU derlemesi, AVX ve SIMD gibi modern CPU hesaplama yeteneklerini otomatik algılayıp kullanmak için OpenBLAS kullanır
  • Bu yaklaşım, performanstan ödün vermeden heterojen yapay zeka donanımları ve platformları arasında taşınabilirlik sağlamayı hedefler

Gelecek çalışmalar

  • WasmEdge GGML araçları şu anda kullanılabilir ve bulut yerel müşteriler tarafından kullanılıyor olsa da hâlâ erken aşamada
  • Katkı yapılabilecek alanlar şunlardır
    • Daha fazla donanım ve işletim sistemi platformu için GGML eklentileri ekleme
      • TPU, ARM NPU, Linux ve Windows üzerindeki özel yapay zeka çiplerine ilgi var
    • Daha fazla llama.cpp ayarını destekleme
      • Şu anda yalnızca bazı ayar seçenekleri Wasm’dan GGML eklentisine aktarılabiliyor
      • Hedef, GGML’in sunduğu tüm seçenekleri desteklemek
    • Diğer Wasm uyumlu dillerde WASI NN API desteği
      • Go, Zig, Kotlin, JavaScript, C ve C++ için ilgi var

LLM dışı model desteği

  • WasmEdge ve WASI NN; hafif, hızlı, taşınabilir ve güvenli bir Python alternatifi olarak LLM dışındaki popüler yapay zeka modellerine dayalı çıkarım uygulamaları da geliştirebilir
  • mediapipe-rs, Google mediapipe Tensorflow model ailesi için Rust+Wasm API sağlar
  • WasmEdge YOLO, YOLOv8 PyTorch modelini ele alan bir Rust+Wasm API projesidir
  • WasmEdge ADAS demo, Intel OpenVINO modeliyle otonom araçlarda yol segmentasyonu yapan bir örnektir
  • WasmEdge Document AI, OCR ve belge işleme model aileleri için Rust+Wasm API sağlayacaktır
  • WasmEdge ile ilgili tartışmalar ve katkılar WasmEdge Discord üzerinden yapılabilir

1 yorum

 
GN⁺ 2023-11-14
Hacker News yorumları
  • Rust ve WASM güzel, ama koda bakınca temel bir Rust komut satırı betiğinden ibaret, 150 satır
    Ağır işi, modeli WASI-NN backend’ine devreden tek bir satır yapıyor; burada bunu WasmEdge runtime’ı sağlıyor
    Ancak WasmEdge Rust değil C++ ve bu durumda Rust’ın sağladığı avantaj neredeyse yok; backend Python gibi başka dillerden de çağrılabilir

    • Burada Rust’ın sağladığı avantaj paketleme ve dağıtım gibi görünüyor
      Python ve PyTorch’u son kullanıcının çift tıklayıp çalıştırabileceği bir biçimde paketlemek hâlâ neredeyse berbat durumda; gerçek yüksek performanslı kod iki tarafta da C++ olsa da, o C++’a birkaç komut göndermek için 2 GB’tan fazla veri ve on binlerce dosya dağıtmak yerine işi tek bir 2 MB çalıştırılabilir dosyayla bitirebiliyorsanız bunun anlamı var
  • Harika bir çalışma. Yine de denemek isteyenlerin hâlâ büyük boyutlu ağırlık dosyasını indirmesi gerekiyor
    Özünde tamamen taşınabilir ve bağımlılıksız llama.cpp’yi 2 MB’a indirmiş gibi
    Bir uygulama geliştiricisiyseniz, çıkarım motorunu dağıtılabilir dosyanın içine paketlemenin en kolay yolu bu olabilir. Ağırlıklar zaten taşınabilir ve gerektiğinde indirilebilir; gerçekten sabitlemek isteyeceğiniz kısım çıkarım motoru

    • Başlığa 2 MB wasm yazmak daha faydalı olurdu
      Dediğiniz gibi ağırlıklar bu boyutu gölgede bırakıyor
    • Benim makinemde llama.cpp’nin derlediği main dosyası 1,2 MB
      2 MB boyutu tek başına pek etkileyici değil; asıl mesele wasm’i hedefleyerek daha taşınabilir olması, yoksa özellikle daha sıkıştırılmış değil
  • Bu sonuçta llama.cpp’yi sarmalayan bir şey değil mi? Açıkçası x.cpp’yi sarmalayan projelerden epey yoruldum
    Son 6 aydır Rust + WebGPU makine öğrenimi framework’ü geliştiriyorum ve GG’nin yaptığı işin ne kadar müthiş olduğunu hemen fark ettim
    Hâlâ erken aşamada ama buradan görebilirsiniz:
    https://www.ratchet.sh/
    https://github.com/FL33TW00D/whisper-turbo

    • Neyin etkileyici olduğunu biraz daha açıklayabilir misin? Bu alanı hiç bilmediğim için değerini doğru anlamakta zorlanıyorum
    • Başkasının işini küçümseyip aynı yorumda kendi işini mi tanıttın? Etik açıdan ciddi şekilde dönüp bakmak gerekiyor
    • GG kim?
  • Bunun dayandığı wasm-nn, yani https://github.com/WebAssembly/wasi-nn, rastgele parçaları tedarikçi uygulamasına gönderen bir öneri. API de fiilen girdi ayarlama, hesaplama, çıktı ayarlama seviyesinde
    Bu yüzden hiç taşınabilir değil
    Bunun çalışmasının nedeni, llama.cpp’de zaten uygulanmış soyutlamaya yaslanması. gguf modelini farklı donanım hedeflerine eşleyen o kodu WasmEdge’in aynen aldığı burada görülebiliyor: https://github.com/WasmEdge/WasmEdge/tree/master/plugins/was...
    Dolayısıyla “geliştiriciler binding’leri kullanarak yüksek seviyeli dillerde makine öğrenimi uygulamaları yazıp WebAssembly’ye derleyebilir ve WasmEdge gibi wasi-nn destekli runtime’larda çalıştırabilir” tarzındaki açıklama tamamen yanlış. Gerçekte bunu yapamazsınız
    Bu ne taşınabilir, ne sandbox, ne de bir donanım soyutlama katmanı
    wasm binary’si olsa bile ancak kullandığınız runtime sürümü tesadüfen gereken belirli ggml backend’ini uyguladıysa çalışabilir; böyle bir gereklilik hiç olmadığı için çoğu zaman muhtemelen çalışmayacaktır
    Çalışsa bile sonuçta llama.cpp’nin ggml kodunu çağırdığı için güvenlik o kütüphane kadar olur
    Yazıda “taşınabilirlik” ve “Rust” fazla vurgulanıyor, ama gerçekte ikisinin de avantajı pek ortaya çıkmıyor
    Yeni bir donanımda WASI runtime’ı olduğunu varsaysak, modeli çalıştırabilir misiniz? GPU desteği var mı? Yanıt şu olur: “O platformda llama.cpp’nin GPU desteğiyle derlenip derlenmediğini, kullandığınız runtime’da ggml eklentisi olup olmadığını, onun içinde doğru ggml sürümünün vendoring yapılıp yapılmadığını kontrol edin. Yoksa olmaz”
    O zaman WASI’yi neden kullanıyoruz ki?
    Çapraz platform GPU desteğinin zor olduğu doğru, ama bu epey saçma görünüyor
    WebGPU’nun “GPU’ya binary parçaları atarsınız; mevcut donanıma uygun bir parçaysa belki bir şey çizer” gibi çalıştığını hayal edin; bu yapı tam olarak buna benziyor

    • Açıklama için teşekkürler. WASM’de GPU desteğinin nereden geldiğini merak ediyordum
    • Güvenlik açısından etkilerini de biraz daha ayrıntılı açıklayabilir misin?
  • Bunu iPhone’da çevrimdışı çalıştırabilir miyiz? Öyleyse çekim durumundan bağımsız olarak temel bir internet araması benzeri şeyler için kullanılabilir, kamp yaparken işe yarayabilir

    • Çeşitli Linux, Mac, Windows tabanlı cihazlarda çalışabilir; Raspberry Pi ve çoğu dizüstü bilgisayar/sunucu da buna dahil
      Ancak modelin kendisini yüklemek için hâlâ birkaç GB bellek gerekiyor
    • Bu projeyi Pixel’de çalıştırmayı denedim. Bazı iPhone/iPad’lerde de çalışıyor gibi görünüyor
      [0] https://github.com/mlc-ai/mlc-llm
    • O amaç için Wikipedia’nın bir sürümünü indirmek büyük olasılıkla daha iyi olur. Entropi gibi sorunlar da var
    • Bu kullanım için belli ölçüde başarılı olmuş ticari bir iOS uygulaması yaptım
      Başta ggml ile yapmıştım, sonra mlc-llm’yi keşfedip onun üzerine port ettim
      [0]: https://apps.apple.com/us/app/private-llm/id6448106860
  • Akış içinde, edge’de Transformer mimarisini daha verimli ve hızlı çalıştırmanın daha fazla yolu ortaya çıkacaktır; ancak VRAM gereksinimi Rust ile çözülemeyeceği için sınıra yaklaşılıyor gibi görünüyor
    Yeterince büyük bir modeli yüklerken ana darboğaz tam da bu kısım
    “Küçük modeller daha iyi hale geliyor, Mistral ve Llama 2’ye bakın” denebilir; ama küçük modeller de kapasite sınırına yaklaşıyor. 7 milyar parametrenin içine sığdırılabilecek bilginin bir sınırı var
    Bu yapay zeka yaklaşımının AGI’ye götüreceğini sanmıyorum. Fazla verimsiz hissettiriyor

    • Küçük modellerde bile MoE sistemleri ya da LoRA’yı dinamik olarak yükleme gibi yöntemlerle hâlâ epey alan olduğunu düşünüyorum
  • “Mac OS için GGML eklentisi, çıkarım işlerini M1/M2/M3’ün yerleşik sinir ağı işleme motorunda çalıştırmak için Metal API’yi kullanır” açıklaması doğru değil gibi
    GGML’in Metal API’yi kullanması, M1/2/3’ün GPU’sunda çalıştığı anlamına gelir; Neural Engine’de çalıştığı anlamına gelmez
    Elbette bu kendi başına da iyi bir şey, ama kesin konuşmak gerekirse durum bu

  • Çekirdek kütüphaneyi saran wrapper’ın başka bir dil kullanması yüzünden projenin diğer çözümlerden boyutu 1/100’e indirmiş ya da hızı 100~35000 kat artırmış gibi anlatan clickbait pazarlamadan hoşlanmıyorum
    Diğer çözümlerin etrafında birikmiş araçları ve topluluk uzmanlığını da tamamen yok sayıyor
    Öncelikle bu proje llama.cpp[1] tabanlı ve birkaç GB’lık model dosyalarını GPU/CPU’ya yükleyip çalıştırma gibi ağır işi llama.cpp hallediyor
    Çıkarım hızı wrapper seçimiyle sınırlı değildir; Go, Python, Node, Rust wrapper’ları da var, llama.cpp doğrudan da kullanılabilir
    İkili dosya boyutu da o kadar önemli değil. Yaygın kuantize model dosyaları 5GB~40GB aralığında ve güçlü GPU ya da 16~64GB RAM’e sahip bir makine gerekiyor
    [1] https://github.com/ggerganov/llama.cpp

  • Boyutun büyük kısmı sonuçta eğitilmiş model ağırlıklarıysa, doğruluk kaybetmeden boyutu nasıl birkaç mertebe küçültebilirler?

    • Doğruluk kaybı olmadan boyutu küçültmenin zor olduğunu düşünüyorum. Ancak kuantize GGUF harika
      Burada sözü edilen 2MB, model hariç program boyutunu ifade ediyor gibi görünüyor. wasm ve llama.cpp çalıştıran bir Rust sunucusuyla llama.cpp’yi çalıştırma yöntemi gibi
      Küçük llama.cpp/examples/serverı sevdiğim için FreeChat’e gömüyorum; ama araç seçeneklerinin artması her zaman iyi
      Kontrol ettim, gömdüğüm arm64/x86 çalıştırılabilir dosyası şu an 4.2MB. FreeChat 12.1MB, ama varsayılan model yaklaşık 3GB olduğu için 2MB farkı pek önemsemiyorum
      [0]: https://github.com/ggerganov/llama.cpp/tree/master/examples/...
    • Modelin kendisinin, yani eğitilmiş ağırlıkların boyutunu doğruluk kaybı olmadan birkaç mertebe küçültmekten söz ediliyorsa, bu ayrı ve zor bir problem
      Bu yazı çıkarım uygulamasının boyutunu 100 kat küçültmeyi ele alıyor
  • Bunu llama.cpp’yi doğrudan kullanmak yerine neden kullanayım, bilmiyorum

    • İpucu: Rust’ta yeniden yaz ekonomisinin para birimi, gerçekten bir şey çalıştırmak değildir
    • llama.cpp genellikle işletim sistemi ve mimariye göre Windows, macOS, Linux vb. için ayrı ayrı derlenmek zorunda olduğundan taşınabilirliği düşüktür
      Yazıda, heterojen donanım hızlandırıcılara sahip cihazlarda donanım hızlandırmasından yararlandığı da açıklanıyor
      Bu, wasm’e derlenmiş bir programın farklı cihazlarda GPU ya da özel yapay zeka çipi gibi çeşitli donanım kaynaklarını verimli kullanabileceği anlamına gelir
      Doğrudan C++ ile uygulanırsa benzer performans için her donanım türüne ayrı optimizasyon ya da sürüm gerekebilir