2 puan yazan GN⁺ 2024-12-09 | 1 yorum | WhatsApp'ta paylaş
  • Yerel model yanıtları JSON Schema ile sınırlandırılabiliyor; böylece son işlemde ayrıştırma yükü azalıyor ve veri çıkarma sonuçları daha tutarlı hale geliyor
  • Kullanıcılar cURL, Python ve JavaScript'te format parametresi ile şemayı ileterek aynı şekilde yapılandırılmış çıktı isteyebiliyor
  • Python'da Pydantic, JavaScript'te Zod ile birlikte kullanıldığında, şema tanımı ile yanıt doğrulamayı kod seviyesinde bağlamak kolaylaşıyor
  • Örneklerde ülke bilgileri, evcil hayvan metni ve llama3.2-vision görüntü analizi sonuçları belirlenmiş JSON alanlarıyla döndürülüyor ve doğrulanıyor
  • Kararlı sonuçlar gerekiyorsa, prompt içine “return as JSON” eklenmesi ve temperature değerinin 0'a düşürülmesi öneriliyor

JSON Schema ile model yanıtlarını sınırlandırma

  • Ollama, model çıktılarının belirli bir JSON Schema biçimine uymasını zorunlu kılan yapılandırılmış çıktıları destekliyor
  • Ollama Python ve JavaScript kütüphaneleri de yapılandırılmış çıktıyı destekleyecek şekilde güncellendi
  • Bu özellik şu işler için kullanılabiliyor
    • Belgelerden veri ayrıştırma
    • Görüntülerden veri çıkarma
    • Dil modeli yanıtlarını yapılandırma
    • JSON mode'a göre daha yüksek güvenilirlik ve tutarlılık sağlama

Kurulum ve çağırma yöntemi

  • En güncel Ollama sürümünün indirilmesi gerekiyor
  • Python kütüphanesi şu komutla en güncel sürüme yükseltiliyor
pip install -U ollama
  • JavaScript kütüphanesi şu komutla kuruluyor
npm i ollama
  • Yapılandırılmış çıktı isterken, cURL isteğinde veya Python·JavaScript kütüphanelerinde format parametresine şema aktarılıyor

cURL ile JSON Schema gönderme

  • cURL örneği http://localhost:11434/api/chat adresine istek gönderiyor; model olarak llama3.1, stream olarak false ayarlanıyor
  • format içine name, capital, languages alanlarına sahip bir nesne şeması konuluyor
    • name: string
    • capital: string
    • languages: string dizisi
    • Üç alan da required olarak belirtiliyor
  • Yanıt, isteğe dahil edilen JSON Schema biçiminde dönüyor
{
  "capital": "Ottawa",
  "languages": [
    "English",
    "French"
  ],
  "name": "Canada"
}

Python ve JavaScript kütüphanelerini kullanma

  • Python

    • Ollama Python library, şemayı JSON nesnesi olarak format parametresine iletiyor
    • Şema dict olarak verilebiliyor; önerilen yöntem ise Pydantic'in model_json_schema() çıktısını serileştirmek
    • Örnekte Country modeli içinde name, capital, languages alanları tanımlanıyor ve yanıt Country.model_validate_json() ile doğrulanıyor
country = Country.model_validate_json(response.message.content)
  • Örnek çıktı, Canada, Ottawa, English, French değerlerini tanımlı alanlara uygun biçimde döndürüyor
  • JavaScript

    • Ollama JavaScript library, şemayı JSON nesnesi olarak format parametresine iletiyor
    • Şema object olarak verilebiliyor; önerilen yöntem ise Zod ve zodToJsonSchema() kullanmak
    • Örnekte Country şeması Zod nesnesi olarak tanımlanıyor, yanıt gövdesi JSON.parse() ile ayrıştırıldıktan sonra Country.parse() ile doğrulanıyor
const country = Country.parse(JSON.parse(response.message.content));

Metin ve görüntüden veri çıkarma

  • Evcil hayvan metninden çıkarım

    • Yapılandırılmış çıktı, metinden gerekli bilgileri çıkarmak için kullanılabiliyor
    • Örnekte Pet ve PetList Pydantic modelleri tanımlanarak evcil hayvan bilgileri JSON yapısında döndürülüyor
      • Pet: name, animal, age, color, favorite_toy
      • PetList: pets dizisi
    • Girdi metninde iki kedinin bilgisi yer alıyor
      • Luna: 5 yaşında, gri tüylü, yarn seviyor
      • Loki: 2 yaşında, siyah, tennis balls seviyor
    • Çıktı, tanımlanan şemaya uygun Pet nesneleri listesi olarak doğrulanıyor
  • Vizyon modeliyle görüntü açıklama

    • Yapılandırılmış çıktı, vizyon modeli ile birlikte de kullanılabiliyor
    • Örnekte llama3.2-vision ile bir görüntü analiz ediliyor ve sonuç ImageDescription şemasına uygun biçimde döndürülüyor
    • Şemada şu alanlar yer alıyor
      • summary
      • objects
      • scene
      • colors
      • time_of_day
      • setting
      • text_content
    • Örnek istek, görüntüdeki nesnelerin, sahnenin, renklerin ve algılanabilen metnin analiz edilmesini istiyor
    • Seçeneklerde temperature 0 olarak ayarlanıp daha deterministik çıktı kullanılıyor
    • Örnek çıktı, sahildeki palmiye ağaçları sahnesini özetliyor; tree ve beach nesnelerini, renkleri, günün zamanını ve dış mekân ayarını yapılandırılmış alanlarda döndürüyor

OpenAI uyumlu API kullanımı

  • OpenAI uyumlu örnekte OpenAI istemcisi base_url="http://localhost:11434/v1"; ve api_key="ollama" ile yapılandırılıyor
  • client.beta.chat.completions.parse() kullanılarak response_format içine Pydantic modeli olan PetList aktarılıyor
  • Yanıtta completion.choices[0].message kontrol ediliyor; parsed varsa ayrıştırılmış sonuç yazdırılıyor
  • refusal varsa reddetme yanıtı yazdırılıyor, openai.LengthFinishReasonError ise token sayısının fazla olduğu durum olarak ele alınıyor

Kararlı çıktı ayarları ve gelecek planları

  • Yanıt şeması tanımında Python için Pydantic, JavaScript için Zod kullanılması öneriliyor
  • Modelin isteği anlamasına yardımcı olmak için prompt'a “return as JSON” eklenmesi tavsiye ediliyor
  • Daha deterministik çıktı istenirse temperature değeri 0 olarak ayarlanıyor
  • Gelecek planları şunlar
    • Kontrollü üretim için logits erişimi
    • Yapılandırılmış çıktının performansını ve doğruluğunu iyileştirme
    • Sampling için GPU hızlandırma
    • JSON Schema'nın ötesinde ek biçim desteği

1 yorum

 
GN⁺ 2024-12-09
Hacker News yorumları
  • Daha güçlü çıktı kısıtlamaları gerekiyorsa llama.cpp, GBNF destekliyor
    https://github.com/ggerganov/llama.cpp/blob/master/grammars/...

    • Görünüşe göre zaten tam da bunu kullanıyorlar
    • Rastgele gramerler için çıktı kalitesinin tatmin edici olup olmadığını merak ediyorum
      Yüzeysel bakınca, modeller JSON’u çok daha fazla gördüğü için JSON üretmekte diğer biçimlere göre daha iyi olacaklarmış gibi geliyor
    • Hangi açıdan daha güçlü olduğunu merak ediyorum
  • İyi haber
    CSV verisi oluştururken başında sonunda "Here is your data" ya da "Please note blah blah" gibi gereksiz ifadeler olmadan sıradan bir prompt’u nasıl kurmam gerektiğini düşünüyordum; artık istenen dönüş biçimini tam olarak tanımlayıp yapılandırılmış çıktıyı doğrudan CSV’ye aktarabilmek sevindirici

    • Yine de prompt’un doğru bağlama girmesi için CSV oluşturma talimatını eklemek gerekiyor
      Aksi halde teknik olarak CSV biçiminde ama anlamsız bir çıktı gelebilir. Model aslında paragraf biçiminde bir yanıt yazmaya çalışmış, token sampler ise modelin pek söylemek istemediği düşük olasılıklı token’ları seçmiş olabilir
    • Çoğu durumda çıktının başlangıcını \n ile önceden doldurup gördüğünde durdurmak bu sorunu engelleyebilir
  • Çalışıyor. gemma2:2b modeline aşağıdaki cümleyi verdim ve istediğim JSON geldi
    You have spent 190 at Fresh Mart. Current balance: 5098
    Sonuç {"amount": 190, "balance": 5098, "category": "Shopping", "place": "Fresh Mart"} oldu

    • Oldukça tutarsız bir JSON, ama çok küçük bir modelse ve üstelik gemma ise beklenebilir
  • Gerçekten şaşırtıcı. Aslında istediğim özelliklerden biriydi
    ollama’nın iyi yanı, LLM’leri başka UNIX programları gibi kullanıyormuş hissi vermesi ve LLM’in UNIX’e doğal biçimde aitmiş gibi hissettirmesi
    Ancak AMD GPU üzerinde sorunsuz çalıştırabilen var mı merak ediyorum. Daha zor olduğunu duydum ama gelecek yıl kart alırken rakibi desteklemek istiyorum

    • Mümkün. Entegre GPU’da bile oluyor
      780M’li bir mini PC’de BIOS üzerinden 16 GB paylaşımlı bellek ayırdım; oldukça iyi çalıştı
  • Bu tür kısıtlamaların LLM çıktı kalitesi üzerinde nasıl bir etkisi olduğunu merak ediyorum
    Bazı durumlarda çıktı kalitesi daha yüksek olacaksa Markdown ya da düz metin ayrıştırmayı tercih etmek isterim

    • OpenAI modellerini kullanırken, ek token maliyetini karşılayabiliyorsanız iki geçişli strateji çok iyi çalışıyordu
      İlk geçişte ağır bir model ve doğal dil kullanıp akıl yürütmeyi Markdown bölümleriyle ele aldırıyor ve nihai doğal dil yanıtını verdiriyorduk. Mümkünse Markdown başlıklarıyla net biçimde etiketliyorduk
      İkinci geçişte ise daha ucuz ve hızlı bir modelle bu yanıtı, hattın LLM olmayan kısmının tüketebileceği yapılandırılmış çıktı biçimine dönüştürüyorduk
      Temelde JSON şema moduyla muğlak doğal dil kısımlarının etrafına temiz sınırlar koyuyor ve LLM’in kendi çıktısını kullanışlı bir biçimde yakalayan bir ön işlemci gibi davranmasını sağlıyorduk
    • Modelin JSON çıktısı için ne kadar ince ayarlandığına bağlı
      Ayrıca modele şemayı bildirmek gerekiyor. Bildirmezseniz garip tokenizasyon sorunları daha çok ortaya çıkıyor
      Örneğin şema JSON anahtarı olarak "foobarbaz" bekliyorsa ve standart BPE tokenizasyonu ["foobar", "baz"] ise, mevcut kısıtlı çıktı kütüphanelerinin ürettiği token maskesi modelin "f", "foo", "foobar" arasından seçim yapmasına izin verebilir. Model "foo"yu seçerse kısıt bir sonraki token olarak örneğin "bar" ve "baz"ı zorunlu kılar. Böylece model ["foobar", "baz"] yerine ["foo", "bar", "baz"] görür ve kafası karışır [0]
      Prompt’ta "foobarbaz"ın şema anahtarlarından biri olduğunu model bilirse genellikle "foo" yerine "foobar"ı tercih eder
      [0] Modern modellerde normalizasyon nedeniyle bu token’lar birbirleriyle ilişkili olsa da aynı şey değildir
    • Duruma göre değişir ama akıl yürütme açısından olumsuz etkisi var; çoğu durumda fark çok büyük değildi
      LLM’in ve prompt’un zaten JSON yanıtı üretme olasılığı olup olmadığına çok bağlı. LLM’i ne kadar zorla yönlendirirseniz, normal bir girdi üretme olasılığı o kadar düşer
      Küçük modellerde, anlamlı öngörü gücü olan alanın sınırına daha çabuk ulaşıp çıktı rastgele gürültüye benzemeye başlar
      Katı bir ölçüm değil; birçok LLM projesine çok zaman harcadıktan sonra sezgisel bir değerlendirme. Bu belirli araçları henüz denemedim ama ollama daha önce de benzer bir teknik gibi görünen bir yöntemle JSON çıktısını garanti edebiliyordu; ayrıca bir iş ortağıyla başka bir LLM çalışma zamanı aracı olan oobabooga için jsonformer benzeri bir şey üzerinde de çalışmıştık
    • İlgili araştırmaları takip etmeyi sürdürüyorum. Sampling genelini hem hız hem doğruluk açısından iyileştirmek için inceliyorum
      Bu tür değişiklikler geldiğinde yalnızca JSON’la sınırlı olmayan genel yapı üretiminin de mümkün olmasını umuyorum
    • instructor gibi araçların kullanışlılığı konusunda tamamen yanılmış olabileceğimi söyleyebilirim
      Çok token harcamak kolay, ama yapmaya çalıştığınız şey bu maliyeti haklı çıkarıyorsa epey güçlü şekilde ilerleyebilirsiniz. Mutlak en yüksek kalite olmasa bile, çabasızca %95 düzeyi elde ettiren bir araç, araç kutusuna koymaya kesinlikle değer
  • Desteklenen herhangi bir modelle kullanılabiliyor mu merak ediyorum
    Donanımımda yalnızca 1B~3B modelleri istikrarlı çalıştırabildiğim için soruyorum

    • Blog yazısının yazarıyım. Herhangi bir modeli kullanabilmeniz gerekir
      Küçük modellerde sonuçlar dalgalanabilir ama “x’i JSON olarak döndür” diye istemek doğruluğa yardımcı olma eğilimindeydi
  • Bu özellikle ilgili PR neredeyse 1 yıl açık kaldı
    Bakımcıların bu kadar sessiz kalması biraz üzücüydü

    • Yazının yazarı ve bakımcılardan biriyim. Katılıyorum. Bakımcılar geç yanıt verdi ve genel olarak daha fazla katkıyı teşvik etmek istiyoruz
      Gelecek yıl topluluk PR’leriyle daha iyi ilgilenip onları merge edebilmeyi umuyorum
    • Havanın şirket merkezli bir yola gittiği görülüyor; bu yüzden her şeye o mercekten ve kâr maksimizasyonu açısından bakıyor gibiler
    • Ben de bunu birlikte geliştirmeye katkı vermek istemiştim ama konuşma aniden kesildi
  • Hâlâ oobabooga kullanıyorum. exlv2 desteği sayesinde çift 3090 üzerinde çok daha verimli çıkarım yapmak mümkün

    • Bir süredir ooba’ya bakmadım; exl2 ve q3k_s gibi heterojen olmayan nicemleme yöntemlerinin durumunu merak ediyorum
      Hatırladığım kadarıyla exl2 daha hızlı olsa da, özellikle düşük bit derinliklerinde gptq nicemleme doğruluk açısından daha iyi gibiydi
  • outlines ile karşılaştırıldığında ne gibi ek değer sunduğunu merak ediyorum
    https://www.souzatharsis.com/tamingLLMs/notebooks/structured...

    • Blogun yazarıyım. Mevcut uygulama llama.cpp GBNF kullanılarak hızlıca hayata geçirilebildi. Şu anki en büyük ek değer, özelliğin yayınlanmış olması
      outlines/xgrammar üzerine son araştırmalara dayanarak, daha fazla biçimi desteklemek, doğruluğu artırmak ve performansı iyileştirmek için örneklemenin güncellenebileceğini umuyorum
  • LLM’ye yapılandırılmış girdi sağlamanın en iyi yolu var mı, merak ediyorum
    Örneğin 100 cümle verip her birini birden fazla şekilde sınıflandırmasını istemek gibi. Yapılandırılmış veri almak kolay, ama satır numaralarını başa eklediğim yöntem bana kaba geliyor

    • Modeller Markdown, JSON ve çeşitli programlama dilleriyle eğitildiği için bunlardan biri işe yarayacaktır
      Ancak bu durumda modelin kafasının karışmaması için cümleleri tek tek vermek en iyisi
      İstemi "Aşağıdaki cümleyi sınıflandır. Kurallar ..." + cümle biçiminde kurgularsanız önek önbelleğinden yararlanabilirsiniz; bu da tek seferde sorgulamaktan daha iyi performans sağlayabilir
      Elbette bu, önek önbelleği olduğunda ve giriş token’ı başına ücret alınmadığında mümkün olan bir yöntem. Günümüzde çoğu sağlayıcı, önek önbelleğini kullanmak istediğinizi belirtirseniz daha düşük maliyetle kullanmanıza izin veriyor