- Respons model lokal kini bisa dibatasi agar sesuai dengan JSON Schema, sehingga beban parsing pascapemrosesan berkurang dan hasil ekstraksi data menjadi lebih konsisten
- Pengguna dapat meminta output terstruktur dengan cara yang sama di cURL, Python, dan JavaScript dengan mengirimkan skema ke parameter
format
- Di Python, penggunaan Pydantic, dan di JavaScript, Zod, memudahkan penghubungan definisi skema dan validasi respons di level kode
- Contohnya mencakup pengembalian dan validasi informasi negara, teks tentang hewan peliharaan, serta hasil analisis gambar
llama3.2-vision ke dalam field JSON yang telah ditentukan
- Jika membutuhkan hasil yang stabil, disarankan menambahkan “return as JSON” ke prompt dan menurunkan temperature ke 0
Membatasi respons model dengan JSON Schema
- Ollama mendukung output terstruktur yang membatasi hasil model agar mengikuti format JSON Schema tertentu
- Library Ollama untuk Python dan JavaScript juga telah diperbarui untuk mendukung output terstruktur
- Fitur ini dapat digunakan untuk tugas-tugas berikut
- Mem-parsing data dari dokumen
- Mengekstrak data dari gambar
- Menstrukturkan respons model bahasa
- Mendapatkan keandalan dan konsistensi yang lebih tinggi dibanding JSON mode
Instalasi dan cara pemanggilan
- Anda perlu mengunduh versi terbaru Ollama
- Library Python dapat diperbarui ke versi terbaru dengan perintah berikut
pip install -U ollama
- Library JavaScript dapat diinstal dengan perintah berikut
npm i ollama
- Saat meminta output terstruktur, kirimkan skema ke parameter
format pada permintaan cURL atau library Python/JavaScript
Mengirim JSON Schema dengan cURL
- Contoh cURL mengirim permintaan ke
http://localhost:11434/api/chat, dengan model disetel ke llama3.1 dan stream ke false
- Pada
format, masukkan skema objek yang memiliki name, capital, dan languages
name: string
capital: string
languages: array string
- Ketiga field ditandai sebagai
required
- Respons akan dikembalikan dalam format JSON Schema yang disertakan dalam permintaan
{
"capital": "Ottawa",
"languages": [
"English",
"French"
],
"name": "Canada"
}
Menggunakan library Python dan JavaScript
-
Python
- Ollama Python library mengirimkan skema sebagai objek JSON ke parameter
format
- Skema dapat diteruskan sebagai
dict, dan cara yang direkomendasikan adalah melakukan serialisasi dengan model_json_schema() dari Pydantic
- Contohnya mendefinisikan model
Country dengan field name, capital, dan languages, lalu memvalidasi respons dengan Country.model_validate_json()
country = Country.model_validate_json(response.message.content)
- Output contoh mengembalikan
Canada, Ottawa, English, dan French sesuai field yang telah didefinisikan
-
JavaScript
- Ollama JavaScript library mengirimkan skema sebagai objek JSON ke parameter
format
- Skema dapat diteruskan sebagai
object, dan cara yang direkomendasikan adalah menggunakan Zod bersama zodToJsonSchema()
- Contohnya mendefinisikan skema
Country sebagai objek Zod, lalu mem-parsing body respons dengan JSON.parse() dan memvalidasinya dengan Country.parse()
const country = Country.parse(JSON.parse(response.message.content));
Mengekstrak data dari teks dan gambar
-
Ekstraksi teks hewan peliharaan
- Output terstruktur dapat digunakan untuk mengambil informasi yang dibutuhkan dari teks
- Contohnya mendefinisikan model Pydantic
Pet dan PetList untuk mengembalikan informasi hewan peliharaan dalam struktur JSON
Pet: name, animal, age, color, favorite_toy
PetList: array pets
- Teks masukan berisi informasi tentang dua ekor kucing
- Luna: usia 5 tahun, bulu abu-abu, menyukai yarn
- Loki: usia 2 tahun, berwarna hitam, menyukai tennis balls
- Output divalidasi sebagai daftar objek
Pet sesuai skema yang didefinisikan
-
Deskripsi gambar dengan model vision
- Output terstruktur dapat digunakan bersama model vision
- Contohnya menganalisis gambar dengan
llama3.2-vision dan mengembalikan hasil yang sesuai dengan skema ImageDescription
- Skema tersebut mencakup field berikut
summary
objects
scene
colors
time_of_day
setting
text_content
- Contoh permintaan menginstruksikan analisis objek, adegan, warna, dan teks yang dapat dideteksi dari gambar
- Pada opsi,
temperature disetel ke 0 untuk menghasilkan output yang lebih deterministik
- Output contoh merangkum pemandangan pantai dengan pohon palem, lalu mengembalikan objek
tree dan beach, warna, waktu, serta pengaturan luar ruang dalam field terstruktur
Menggunakan API yang kompatibel dengan OpenAI
- Contoh yang kompatibel dengan OpenAI mengatur klien
OpenAI dengan base_url="http://localhost:11434/v1" dan api_key="ollama"
- Gunakan
client.beta.chat.completions.parse() untuk mengirim model Pydantic PetList ke response_format
- Pada respons, periksa
completion.choices[0].message, dan jika ada parsed, tampilkan hasil yang telah diparse
- Jika ada
refusal, tampilkan respons penolakan, dan openai.LengthFinishReasonError ditangani sebagai kasus ketika token terlalu banyak
Pengaturan output stabil dan rencana ke depan
- Untuk mendefinisikan skema respons, disarankan menggunakan Pydantic di Python atau Zod di JavaScript
- Menambahkan “return as JSON” ke prompt dianjurkan agar model memahami permintaan
- Jika menginginkan output yang lebih deterministik, setel temperature ke 0
- Rencana ke depan mencakup hal-hal berikut
- Eksposur logits untuk controlled generation
- Peningkatan performa dan akurasi output terstruktur
- Akselerasi GPU untuk sampling
- Dukungan format tambahan di luar JSON Schema
1 komentar
Komentar Hacker News
Jika memerlukan pembatasan output yang lebih kuat, llama.cpp mendukung GBNF
https://github.com/ggerganov/llama.cpp/blob/master/grammars/...
Sekilas rasanya model kemungkinan membuat JSON lebih baik daripada format lain karena jauh lebih sering melihat JSON
Ini kabar baik
Saat membuat data CSV, saya sempat memikirkan bagaimana menyusun prompt umum tanpa frasa yang tidak perlu seperti "Here is your data" atau "Please note blah blah" di awal atau akhir, jadi senang karena sekarang kita bisa mendefinisikan format pengembalian yang diinginkan secara tepat dan langsung mengirim structured output ke CSV
Jika tidak, hasilnya mungkin secara teknis berbentuk CSV tetapi tidak bermakna. Model sebenarnya mungkin sedang mencoba menulis jawaban berbentuk paragraf, tetapi token sampler memilih token berprobabilitas rendah yang sebenarnya tidak terlalu ingin dikeluarkan model
\n dan membuatnya berhenti diBerfungsi. Saya memasukkan kalimat berikut ke gemma2:2b dan JSON yang diinginkan keluar
You have spent 190 at Fresh Mart. Current balance: 5098Hasilnya adalah
{"amount": 190, "balance": 5098, "category": "Shopping", "place": "Fresh Mart"}Benar-benar mengesankan. Ini memang salah satu fitur yang saya inginkan
Alasan ollama bagus adalah karena ia memberi kesan LLM bisa dipakai seperti program UNIX lain, dan membuat LLM terasa cocok secara alami di lingkungan UNIX
Tapi saya penasaran apakah ada yang sudah berhasil menjalankannya dengan baik di AMD GPU. Katanya lebih sulit, tetapi saya ingin mendukung kompetitor saat membeli kartu tahun depan
Saya mengalokasikan 16GB shared memory lewat BIOS pada mini PC dengan 780M, dan hasilnya berjalan cukup baik
Saya penasaran dampak pembatasan seperti ini terhadap kualitas output LLM
Dalam beberapa kasus, kalau kualitas output lebih tinggi, saya mungkin akan memilih mem-parsing Markdown atau teks biasa
Pertama, gunakan model yang lebih berat dan bahasa alami untuk menangani penalaran dalam bagian-bagian Markdown serta memberikan jawaban akhir dalam bahasa alami. Jika memungkinkan, beri label yang jelas dengan header Markdown
Kedua, gunakan model yang lebih murah dan cepat untuk mengubah jawaban itu menjadi format structured output, agar bisa dikonsumsi oleh bagian pipeline yang non-LLM
Pada dasarnya ini membuat batas yang rapi di sekitar bagian bahasa alami yang ambigu dengan mode JSON schema, dan membuat LLM berperan sebagai preprocessor yang menangkap outputnya sendiri ke dalam format yang berguna
Anda juga perlu memberi tahu model tentang skemanya. Jika tidak, masalah tokenisasi aneh akan lebih sering muncul
Misalnya, jika skema mengharapkan key JSON
"foobarbaz"dan tokenisasi BPE standar adalah["foobar", "baz"], maka token mask yang dibuat library constrained output saat ini bisa mengizinkan model memilih di antara"f","foo","foobar". Jika model memilih"foo", constraint lalu memaksa token berikutnya misalnya"bar"dan"baz". Akibatnya model melihat["foo", "bar", "baz"], bukan["foobar", "baz"], dan itu membingungkan [0]Jika prompt memberi tahu model bahwa
"foobarbaz"adalah salah satu key dalam skema, model biasanya akan lebih memilih"foobar"daripada"foo"[0] Pada model terbaru, token-token itu memang saling terkait karena normalisasi, tetapi tidak identik
Ini sangat bergantung pada apakah LLM dan prompt-nya memang sejak awal cukup mungkin menghasilkan respons JSON. Makin keras Anda memaksa arah LLM, makin kecil kemungkinan ia menghasilkan input yang normal
Pada model kecil, Anda lebih cepat mencapai tepi ruang yang masih punya daya prediksi bermakna, lalu output mulai mendekati noise acak
Ini bukan pengukuran yang ketat, hanya kesan setelah menghabiskan banyak waktu di berbagai proyek LLM. Saya belum mencoba alat khusus ini, tetapi ollama sebelumnya juga bisa menjamin output JSON dengan teknik yang tampaknya mirip, dan saya pernah mengerjakan sesuatu yang mirip jsonformer untuk oobabooga, runtime tool LLM lain, bersama seorang rekan
Semoga jika perubahan seperti itu masuk, generasi terstruktur yang umum dan tidak terbatas pada JSON juga bisa menjadi mungkin
Memang mudah menghabiskan banyak token, tetapi jika pekerjaan yang ingin dilakukan memang layak dengan biayanya, ini bisa didorong cukup jauh. Mungkin bukan kualitas absolut terbaik, tetapi alat yang bisa memberi level 95% tanpa banyak usaha tetap layak ada di kotak peralatan
Saya penasaran apakah ini bisa dipakai pada model apa pun yang didukung
Di hardware saya, hanya model 1B~3B yang bisa berjalan stabil, jadi saya bertanya
Pada model kecil hasilnya mungkin naik turun, tetapi meminta "kembalikan x sebagai JSON" cenderung membantu akurasi
PR untuk fitur ini sempat terbuka hampir 1 tahun
Agak disayangkan para maintainer terlalu diam
Saya berharap tahun depan bisa lebih baik dalam meninjau dan me-merge PR komunitas
Masih pakai oobabooga. Berkat dukungan exlv2, inferensi jadi jauh lebih efisien di dual 3090
Kalau tidak salah, exl2 memang lebih cepat, tetapi terutama pada kedalaman bit rendah, kuantisasi gptq tampaknya dulu lebih baik dari sisi akurasi
Penasaran nilai tambah apa yang ada dibandingkan
outlineshttps://www.souzatharsis.com/tamingLLMs/notebooks/structured...
Berdasarkan riset terbaru terkait outlines/xgrammar, saya berharap bisa memperbarui sampling agar mendukung lebih banyak format, meningkatkan akurasi, dan memperbaiki performa
Penasaran apakah ada cara terbaik untuk memberikan input terstruktur ke LLM
Misalnya, memasukkan 100 kalimat lalu meminta model mengklasifikasikan masing-masing dengan beberapa cara. Menerima data terstruktur itu mudah, tetapi cara saya menambahkan nomor baris di depan terasa agak kasar
Namun dalam kasus ini, yang terbaik adalah memberikan kalimat satu per satu agar model tidak bingung
Jika prompt disusun dalam bentuk
"Klasifikasikan kalimat berikut. Aturannya adalah ..."+ kalimat, Anda bisa memanfaatkan cache prefiks, sehingga performanya bahkan bisa lebih baik daripada menanyakannya sekaligusTentu saja, ini hanya memungkinkan jika ada cache prefiks dan Anda tidak dikenai biaya per token input. Saat ini sebagian besar penyedia memungkinkan penggunaan dengan biaya lebih rendah jika Anda menyatakan ingin memakai cache prefiks