Birkaç hafta önce Google'ın Gemma Geliştirici Günü'ne katıldım. Google'ın Gemma adlı en yeni LLM modellerinin yeteneklerini, taşınabilirliğini ve açıklığını tanıttığı bir gün.
Bu modeller, Üretken Yapay Zeka için heyecan verici yeni bir aşamayı sunuyor. Yerel cihazlara kurulabilecek kadar küçük modeller, yine de ilgi çekici ve yararlı bir deneyim sağlayabilir.
Mobile AI'a bakıp ilham alarak günü terk edeli uzun zaman oldu . Bu modelleri bir Android Uygulamasında denediğimde ne olacağını görmeye karar verdim.
Gemma'ya kolay ama yeni bir meydan okuma sunmak istedim. Simon Says oyununu oynuyorum.
Kurallar basit. Bir oyuncu Simon olacak. Rolleri diğer oyunculara gerçekleştirmeleri gereken görevleri vermektir. Simon rolünü oynayan oyuncu, görevi vermeden önce "Simon diyor" demelidir.
Üç ekranlı bir uygulama oluşturdum. Gemma'nın iletişim kurabileceği ve görev verebileceği bir giriş ekranı, bir talimat ekranı ve bir sohbet ekranı.
Sohbet ekranının oluşturulmasını hızlandırmak için Meyta Taliti'nin bu blog gönderisini son derece yararlı buldum.
Oluşturulan ekranlarla bir sonraki görevim Gemma'yı entegre etmekti. Bunun için MediaPipe adında öğrendiğim bir dizi araca güvendim.
MediaPipe , AI modellerini Android, iOS ve web'deki uygulamalara entegre etmeyi basitleştirmeyi amaçlayan bir araç koleksiyonudur. MediaPipe ile ihtiyaçlarınıza bağlı olarak birçok seçeneğiniz var.
Hızlı bir şekilde başlamak istiyorsanız MediaPipe, yapay zeka modellerine başvurabilmeniz için Görevler adlı bir API sağlar. Bu API'ler Görme, Metin ve Ses gibi farklı alanlara ayrılmıştır.
MediaPipe ayrıca uygulamalarınıza yerleştirilebilecek önceden eğitilmiş modellerden oluşan bir koleksiyon da sağlar. Yine hızlı başlamak için faydalıdır.
Daha özel bir şeye ihtiyacınız varsa ve sıfırdan bir model oluşturmak istemiyorsanız MediaPipe, Model Maker adlı bir araç sağlar. Model Maker, mevcut bir makine öğrenimi modelini yeniden eğitmek ve ona yeni veriler sağlamak için Transfer Öğrenimi adı verilen bir süreci kullanır. Bu yaklaşımın faydası zamandan tasarruf sağlaması ve yeni bir model oluşturmak için daha az eğitim verisi gerektirmesidir.
Model Maker da bu işlem sayesinde oluşturulan modelin boyutunu küçültebilir. Bu sürecin modelin mevcut bilgilerinin bir kısmını “unutmasına” neden olduğunu unutmayın.
MediaPipe'ın son aracı, özel modellerinizi değerlendirmek ve ayarlamak için kullanılan bir web uygulaması olan MediaPipe Studio'dur . Modellerinizi kıyaslamak ve dağıtımdan önce ne kadar iyi çalıştıklarını anlamak istiyorsanız kullanışlıdır.
İhtiyaçlarımız için MediaPipe için yeni bir API olan LLM Interfence API'sinden yararlanacağız. Bu, Gemma ile iletişim kurmamıza ve yanıt almamıza olanak tanır.
MediaPipe'ı kullanmak için önce onu uygulamaya derece bağımlılığı olarak eklemeniz gerekir:
implementation ("com.google.mediapipe:tasks-genai:0.10.11")
Daha sonra LlmInference
örneğini yaratırsınız. Gemma ile iletişim kurmak için kullandığınız nesne budur:
val llmInference = LlmInference.createFromOptions( context, LlmInference.LlmInferenceOptions.builder() .setModelPath("/data/local/tmp/llm/gemma-2b-it-cpu-int8.bin") .build() )
.setModelPath
kullanılarak ayarlanan yolu not etmek önemlidir. Burası Gemma modelinin cihazda bulunduğu yerdir. Kullanılan Gemma modelinin gemma-2b
versiyonları olması da önemlidir. 7b
sürümleri henüz MediaPipe tarafından desteklenmiyor; bunun ne anlama geldiğine daha sonra değineceğiz. Şimdilik modeli indirelim.
Gemma'yı Kaggle'dan indirebilirsiniz. Veri Bilimcileri ve Makine Öğrenimine adanmış bir web sitesi. Modelleri indirebilmeniz için önce bir hesap oluşturmanız ve Kullanım Şartları ve Koşullarını kabul etmeniz gerekir. Gemma sayfasına buradan ulaşabilirsiniz.
Bu gönderiyi takip ediyorsanız TensorFlow Lite
sekmesi altında modelin yalnızca gemma-2b-it-cpu
sürümlerini indirmeyi unutmayın. gemma-2b-it-gpu
versiyonlarını denerseniz kendi başınızasınız.
Model indirildikten sonra. Modeli .setModelPath
ayarlanan yola aktarmak için Android Studio'daki Device Explorer'ı kullanın. Yolu veya model adını değiştirdiyseniz yol adını güncellediğinizden emin olun.
Model içe aktarıldıktan sonra .generateResponse
yöntemini kullanarak istemleri Gemma'ya aktarmaya başlayabilirsiniz. Simon Says'ı oynaması için Gemma'ya ilettiğim istemin bir örneği:
private const val SimonSaysPrompt = """ You are a Simon in a game of Simon Says. Your objective is to ask the player to perform tasks. For every task you give, you must prefix it with the words "Simon says". You must not ask the player to do anything that is dangerous, unethical or unlawful. Do not try to communicate with the player. Only ask the player to perform tasks. """ val gemmaResponse = llmInference.generateResponse(SimonSaysPrompt)
Daha önce Yüksek Lisans kullandıysanız ve İstem Mühendisliği konusunda temel bir anlayışa sahipseniz, bu size tanıdık gelecektir. Tedbirli davranmak için bilgi istemine ihtiyati talimatlar ekledim. Simon'un kullanıcıdan şüpheli bir şey yapmasını istemesini istemiyoruz!
Bunu bir cihazda çalıştırmayı denerseniz birkaç şey olabilir:
Uygulamanın yanıt vermesi ve sonunda yanıt vermesi kısa bir süre alabilir.
Uygulama çökebilir. Logcat'e baktığınızda MediaPipe'ın modeli bulamadığı mesajlarını göreceksiniz. Doğru model yolunu ayarladınız mı?
Uygulama çökebilir. Logcat'e bakarsanız, birçok yerel kod günlüğü ve belleğin geri dönüştürülmesiyle ilgili bilgileri görebilirsiniz.
Deneyimim ikinci ve üçüncü kategoriye girdi. Her şeyi doğru şekilde kurduysanız ve yüksek özelliklere sahip bir fiziksel cihaz kullanıyorsanız, kendi deneyimleriniz farklılık gösterebilir.
Eğer bu şeylerin eterine sahip değilseniz. Emulator aracılığıyla kullanılabilen RAM miktarını artıran başka bir seçenek daha var.
Mevcut RAM miktarının arttırılması genellikle belleğin yoğun olduğu ortamlarda yardımcı olur, peki belleğe ihtiyaç duyan bir LLM neden farklı olsun ki? Bunu yapmak için Android öykünücümün kullandığı RAM miktarını özelleştirdim.
Mevcut bir emülatörünüz varsa RAM alanının devre dışı olduğunu fark edebilirsiniz. Cihaz Yöneticisinde sağındaki üç noktaya tıklayarak mevcut RAM miktarını hala güncelleyebilirsiniz.
Diskte Göster'e tıklayın ve ardından config.ini ve hardware-qemu.ini dosyalarını bir metin düzenleyicide açın. Her dosyadaki hw.ramSize
değerlerini değiştirin. Bana bunun nasıl yapılacağına dair cevap verdiğiniz için bu Yığın Taşması sorusuna teşekkür ederim.
Alternatif olarak, Android Studio'da Aygıt Yöneticisi'ne gidip Sanal Aygıt Oluştur'a ve ardından Yeni Donanım Profili'ne tıklayarak özel bir öykünücü oluşturabilirsiniz. Özelleştirme seçeneklerinin bir parçası olarak RAM miktarını seçebilirsiniz.
Nispeten iyi çalışacak 8 GB RAM buldum. Ben de şansımı 22GB RAM ile denedim. Beklediğim kadar olmasa da hız açısından biraz daha iyi performans gösteriyor.
Öykünücünün geri kalanı akıcı bir şekilde çalıştığından Gemma belleğe yüklendiğinde bir yerde bir darboğaz olduğundan şüpheleniyorum. Belki bir yerde yapılabilecek bir iyileştirme.
MediaPipe ile uyumlu Gemma modelleri gemma-2b
versiyonlarıdır. 2b
2 milyar parametre anlamına gelir. Modelin çalışmasını sağlamak için birlikte çalışan parametrelerin miktarı.
Bunlar, Gemma'ya bir soru sorduğunuzda birbirleri arasındaki bağlantıları ve çıkarımları sağlamak için eğitim sırasında model içerisinde belirlenen değerlerdir.
Ayrıca 7 milyar parametre kullanan bir gemma-7b
koleksiyonu da bulunmaktadır. Ancak bunlar MediaPipe tarafından desteklenmemektedir. Belki bir gün!
Yüksek Lisans söz konusu olduğunda parametreler hakkında daha fazla bilgi edinmek istiyorsanız bu sayfayı tavsiye ederim.
2 milyar parametreli bir modelin mobil cihaza yüklenip çalıştırılması etkileyici bir başarıdır. Peki ne kadar iyi çalışıyor? Hadi bulalım.
gemma-2b-it-cpu-int4
4 bitlik bir LLM'dir. Bu, model tarafından kullanılan her parametrenin 4 bitlik bir bellek boyutuna sahip olduğu anlamına gelir. Buradaki fayda, modelin toplam boyutunun daha küçük olmasıdır, ancak her parametre için bellek boyutunun azaltılması, modelin doğruluğunun ve kalitesinin de etkileneceği anlamına gelir.
Peki gemma-2b-it-cpu-int4
nasıl performans gösteriyor? Dürüst olmak gerekirse o kadar da iyi değil. Yukarıdaki istemi kullanarak ve ona genel sorular sorarak Simon Says'ı oynama girişimlerimin birkaç ekran görüntüsünü burada bulabilirsiniz.
Yanıtlar beklenmedikti ve modelin Simon Says oyununa benzer bir şey yapmasını sağlamak sinir bozucuydu. Farklı bir konuya sapılacak ve yanlış bilgi halüsinasyonuna yol açacaktı.
Halüsinasyonlar , yüksek lisans öğrencilerinin yalanları ve gerçek olmayan şeyleri sanki gerçekmiş gibi konuştuğu bir phoenema'dır. Yukarıdaki örneği ele alalım, Mars'a 60 dakikada 60 mil hızla gidebileceğiniz doğru değil. Henüz değil. 😃
Ayrıca bağlam farkındalığı eksikliği de vardı. Bu, daha önce bir konuşmada bahsettiğim bir şeyi hatırlayamadığı anlamına geliyor. Bunun nedeni muhtemelen modelin sınırlı boyutundan kaynaklanmaktadır.
Bir süre sonra bu modelden vazgeçip daha büyük olan 8 bitlik modeli denemeye karar verdim.
gemma-2b-it-cpu-int8
8 bitlik bir LLM'dir. Boyutu 4 bitlik kardeşine göre daha büyüktür. Yani daha doğru olabilir ve daha kaliteli yanıtlar sağlayabilir. Peki burada sonuç ne oldu?
Bu model, Simon Says'ın fikrini hemen kavrayarak Simon rolünü üstlendi. Ne yazık ki o da bağlam farkındalığı eksikliğinden muzdaripti.
Buna karşı koymak için, modeli her seferinde Simon Says kurallarıyla yeniden yönlendirmem ve onu bir görev sağlamasını isteyen başka bir komut istemiyle birleştirmem gerekiyordu.
Görev istemleri, Gemma'ya aktarılmak üzere bir listeden rastgele seçilir ve bu, sorulan görevlerde bir miktar çeşitlilik sağlar.
Aşağıda olup bitenlere bir örnek verilmiştir:
private const val SimonSaysPrompt = """ You are a Simon in a game of Simon Says. Your objective is to ask the player to perform tasks. For every task you give, you must prefix it with the words "Simon says". You must not ask the player to do anything that is dangerous, unethical or unlawful. Do not try to communicate with the player. Only ask the player to perform tasks. """ private const val MovePrompt = SimonSaysPrompt + """ Give the player a task related to moving to a different position. """ private const val SingASongPrompt = SimonSaysPrompt + """ Ask the player to sing a song of their choice. """ private const val TakePhotoPrompt = SimonSaysPrompt + """ Give the player a task to take a photo of an object. """ private val prompts = listOf( MovePrompt, SingASongPrompt, TakePhotoPrompt ) val prompt = prompts.random() val response = llmInference.generateResponse(prompt)
Ara sıra karakter dışı görünen eğri bir top tepkisi veriyor. Bunu modelin boyutuna indiriyorum. Bunun yalnızca v1 olduğunu da dikkate almakta fayda var.
Bilgi istemleri kesin olarak belirlendikten sonra, yalnızca istemlere güvenmenin ve kullanıcı girdisini dikkate almamanın yararlı olduğunu gördüm. Model bağlam farkındalığından yoksun olduğundan, kullanıcı girişi Simon Says'ı oynamayı bırakıp bunun yerine girdiye yanıt vermesine neden oluyor.
Bu kadar hileyi eklemek tatmin edici bir sonuç değildi ama Gemma'nın Simon Says'ı oynamaya devam etmesi gerekiyordu.
Peki Gemma Simon Says'ı bir Android cihazda oynayabilir mi? “Bir nevi yardımla” diyeceğim.
Gemma 2b'nin 4 bit versiyonunun daha sezgisel yanıt verdiğini görmek isterim. Gemma 2b bağlamını her istekte yeniden yönlendirme ihtiyacını ortadan kaldırmak için bilinçli hale getirmek ve kullanıcı girişine dikkat etmek de yardımcı olacaktır.
Yalnızca tek bir istem gerektiren basit istekler için. Gemma 2b'nin bu görevleri rahatça yerine getirebildiğini görebiliyorum.
Bunların modellerin v1'i olduğunu da akılda tutmakta fayda var. Mobil bir işletim sistemi üzerinde çalışıp çalışmaları etkileyici bir başarıdır!
Mobil cihazlarda Yüksek Lisans'ın geleceği ne olacak? Gördüğüm iki engel var. Donanım sınırlamaları ve pratik kullanım durumları.
Sanırım bu modelleri yalnızca üst düzey cihazların etkin bir şekilde çalıştırabileceği bir noktadayız. Akla gelen cihazlar Tensor G yongalarına sahip Pixel 7 veya Pixel 8 serisi telefonlar ve Neural Engine yongasına sahip Apple iPhone'dur.
Bu tür özelliklerin orta sınıf telefonlara kadar filtrelendiğini görmemiz gerekiyor.
Retrieval Augmented Generation'dan faydalanan cihaz yüksek lisans eğitimlerinden ilginç fikirler gelebilir. Yüksek Lisans'ların yanıtlar sağlarken ek bağlam elde etmek için harici veri kaynaklarıyla iletişim kurmasına yönelik bir teknik. Bu, performansı artırmanın etkili bir yolu olabilir.
İkinci engel ise pratik kullanım senaryoları bulmaktır. Cihazların internet üzerinden daha güçlü LLM'lerle iletişim kurabilmesine rağmen bunların sınırlı olduğunu düşünüyorum. Örneğin OpenAI'den GPT-4'ün bir trilyondan fazla parametreyi desteklediği söyleniyor!
Bu modellerin mobil cihazlara dağıtılmasının maliyetinin, onları bulutta barındırmaktan daha ucuz hale geleceği bir zaman gelebilir. Maliyet düşürme bugünlerde çok popüler olduğundan, bunun geçerli bir kullanım durumu olduğunu görebiliyorum.
Ayrıca, hiçbir bilginin cihazınızın sınırlarını aşmadığı, kendi kişisel LLM'nize sahip olmanın gizlilik avantajları da vardır. Gizliliğe duyarlı uygulama kullanıcılarına hitap edecek faydalı bir avantaj.
Bahse girerim, LLM'lerin cihazda düzenli olarak konuşlandırılmasına hala birkaç yıl uzaktayız.
Gemma'yı mobil bir cihazda kendiniz denemek istiyorsanız işte size yardımcı olacak bazı kaynaklar:
Gemma : Resmi Gemma web sitesi , karşılaştırmalar, hızlı başlangıç kılavuzları ve Google'ın sorumlu Üretken Yapay Zeka geliştirme yaklaşımına ilişkin bilgiler de dahil olmak üzere çok sayıda bilgi içerir.
MediaPipe : MediaPipe'ın, kendisi hakkında daha fazla bilgi edinebileceğiniz ve nasıl kullanılacağını öğrenebileceğiniz kendi Google Geliştirici bölümü vardır. Kesinlikle okunması tavsiye edilir.
Google Geliştirici Grubu Discord'u : Google Geliştirici Grubu Discord'unun Üretken Yapay Zeka'ya özel kanalları vardır. Benzer düşüncelere sahip insanlarla sohbet etmek için #gemma, #gemini ve #ml kanallarına göz atın.
Simons Uygulamayı Söyledi: Bu blog gönderisinin örnek kodunu kopyalayıp çalıştırın ve onu çalışırken görün. Ayrıca MediaPipe'tan Görüntü Sınıflandırma Görevinin kullanımını da içerir. Kurulum talimatları README'de bulunmaktadır.
Bir GÇ iş parçacığından LLM çıkarımının çağrılmasından bahsetmek için 23/03/24 güncellendi
Bu yazıyı yazdıktan sonra gemma'ya seslenmenin bir dosya üzerinde okuma/yazma işlemi olduğu aklıma geldi. .generateResponse()
yöntemini bir GÇ iş parçacığına taşımak, gemma belleğe yüklendiğinde meydana gelen büyük sarsıntıyı önleyecektir:
suspend fun sendMessage(): String { return withContext(Dispatchers.IO) { val prompt = prompts.random() llmInference.generateResponse(prompt) } }
Ayrıca burada görünür.