- 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
Hacker News yorumları
Daha güçlü çıktı kısıtlamaları gerekiyorsa llama.cpp, GBNF destekliyor
https://github.com/ggerganov/llama.cpp/blob/master/grammars/...
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
İ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
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
\n ile önceden doldurupgö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: 5098Sonuç
{"amount": 190, "balance": 5098, "category": "Shopping", "place": "Fresh Mart"}olduGerç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
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
İ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
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
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
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
Ç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
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ü
Gelecek yıl topluluk PR’leriyle daha iyi ilgilenip onları merge edebilmeyi umuyorum
Hâlâ oobabooga kullanıyorum. exlv2 desteği sayesinde çift 3090 üzerinde çok daha verimli çıkarım yapmak mümkün
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
outlinesile karşılaştırıldığında ne gibi ek değer sunduğunu merak ediyorumhttps://www.souzatharsis.com/tamingLLMs/notebooks/structured...
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
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ğlayabilirElbette 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