3-qism · Kengaytirilgan imkoniyatlar·07-bob
Embeddings: matnni vektorga aylantirish
Matnning ma'nosini raqamlar ro'yxatiga aylantirish, o'xshashlikni o'lchash, oddiy semantik qidiruv qurish va vektor bazalarga kirish.
"Til modeli qanday ishlaydi" bobida token haqida gapirgan edik — matn raqamga aylanishining birinchi bosqichi. Embedding — shu g'oyaning davomi: butun bir gap yoki paragrafni bitta uzun raqamlar ro'yxatiga (vektorga) aylantirish, va shu vektor gapning ma'nosini o'zida tashiydi.
1. Nega bu foydali: ma'no bo'yicha qidiruv#
Oddiy qidiruv (masalan, SQL'dagi LIKE '%kalitso'z%') faqat aynan bir
xil harflar ketma-ketligini topadi. Agar foydalanuvchi "pulni
qaytarish" haqida yozsa-yu, sizning bazangizda "mablag'ni qaytarish" deb
yozilgan bo'lsa, oddiy qidiruv buni topolmaydi — so'zlar boshqacha.
Embedding bilan bu ikki gap vektor makonida yaqin joylashadi, chunki ularning ma'nosi bir xil. Model harflarga emas, ma'noga qaraydi.
response = client.embeddings.create(
model="text-embedding-3-small",
input="Mahsulot uchun to'lagan pulimni qaytarib berishingiz mumkinmi?",
)
vektor = response.data[0].embedding
print(len(vektor)) # masalan, 1536 ta raqam
print(vektor[:5]) # [0.0023, -0.0091, 0.0145, ...]2. Bir nechta matnni birdan yuborish#
Bitta so'rovda bir nechta matnning embeddingini olish mumkin — bu bitta- bitta yuborishdan tezroq va samaraliroq:
response = client.embeddings.create(
model="text-embedding-3-small",
input=[
"Yetkazib berish 2-3 ish kunini oladi.",
"Mahsulotni 14 kun ichida qaytarish mumkin.",
"To'lov karta yoki naqd pul orqali amalga oshiriladi.",
],
)
vektorlar = [item.embedding for item in response.data]
print(len(vektorlar)) # 3 — har bir matn uchun bitta vektor3. O'xshashlikni o'lchash: kosinus o'xshashligi#
Ikki vektor qanchalik "yaqin" ekanini o'lchash uchun kosinus o'xshashligi (cosine similarity) ishlatiladi — natija -1 dan 1 gacha, qancha katta bo'lsa, shuncha o'xshash:
import numpy as np
def oxshashlik(v1, v2):
v1, v2 = np.array(v1), np.array(v2)
return np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2))
gap1 = client.embeddings.create(model="text-embedding-3-small", input="Pulni qaytarib bering").data[0].embedding
gap2 = client.embeddings.create(model="text-embedding-3-small", input="Mablag'ni qaytarishni so'rayman").data[0].embedding
gap3 = client.embeddings.create(model="text-embedding-3-small", input="Bugun ob-havo juda issiq").data[0].embedding
print(oxshashlik(gap1, gap2)) # ~0.7-0.9 — mavzu bir xil
print(oxshashlik(gap1, gap3)) # ~0.1-0.3 — mavzu boshqatext-embedding-3 oilasidagi vektorlar normallashtirilgan — bu
amaliy jihatdan degani, kosinus o'xshashlik o'rniga oddiy **nuqta
ko'paytmasi (dot product)**dan foydalanish ham bir xil natija beradi va
biroz tezroq hisoblanadi:
def tez_oxshashlik(v1, v2):
return np.dot(v1, v2) # normallashtirilgan vektorlar uchun kosinusga teng4. Amaliy misol: mini semantik qidiruv#
Kichik hujjatlar to'plamida qidirish qanday ishlashini ko'raylik:
hujjatlar = [
"Yetkazib berish 2-3 ish kunini oladi.",
"Mahsulotni 14 kun ichida qaytarish mumkin, agar o'ram buzilmagan bo'lsa.",
"To'lov karta yoki naqd pul orqali amalga oshiriladi.",
"Kafolat muddati — bir yil, ishlab chiqaruvchi nuqsoni uchun.",
]
# Har bir hujjat uchun vektorni oldindan hisoblab qo'yamiz
hujjat_vektorlari = [
client.embeddings.create(model="text-embedding-3-small", input=h).data[0].embedding
for h in hujjatlar
]
def qidir(savol, top_n=1):
savol_vektor = client.embeddings.create(model="text-embedding-3-small", input=savol).data[0].embedding
baholar = [oxshashlik(savol_vektor, hv) for hv in hujjat_vektorlari]
eng_yaqin = sorted(zip(baholar, hujjatlar), reverse=True)[:top_n]
return eng_yaqin
natija = qidir("Sotib olgan narsamni orqaga qaytarsam bo'ladimi?")
print(natija)
# → [(0.71, "Mahsulotni 14 kun ichida qaytarish mumkin, agar o'ram buzilmagan bo'lsa.")]E'tibor bering: savolda "qaytarish" so'zi bor, hujjatda ham bor — lekin "sotib olgan narsam" va "mahsulot" so'zma-so'z bir xil emas. Embedding ularni baribir bog'ladi, chunki ma'no yaqin.
5. dimensions parametri — vektorni kichraytirish#
text-embedding-3 modellari yana bir foydali imkoniyat beradi: to'liq
o'lchamdagi vektor o'rniga, kerak bo'lsa kichikroq vektor so'rash
mumkin — bu saqlash joyini va hisoblash tezligini yaxshilaydi, aniqlikda
kichik yo'qotish evaziga:
response = client.embeddings.create(
model="text-embedding-3-small",
input="Namuna matn",
dimensions=256, # standart 1536 o'rniga, faqat 256 o'lchamli vektor
)
print(len(response.data[0].embedding)) # 2566. Production'da: nima uchun vektor baza kerak#
Yuqoridagi misol 4 ta hujjat bilan ishlaydi. 40,000 ta hujjat bo'lsa-chi? Har bir qidiruvda 40,000 marta kosinus hisoblash — sekin va qimmat. Shu uchun production tizimlar vektor bazalar (Pinecone, Weaviate, pgvector, Qdrant) ishlatadi — ular millionlab vektor orasidan eng yaqinlarini millisekundlarda topadigan maxsus indekslash algoritmlaridan foydalanadi.
7. Model tanlash: o'lcham va narx#
| Model | Vektor o'lchami | Qachon tanlash |
|---|---|---|
text-embedding-3-small | 1536 | Aksariyat vazifalar uchun yetarli, arzon |
text-embedding-3-large | 3072 | Yuqori aniqlik kerak bo'lganda, ko'p tilli murakkab matnlarda |
8. Nima noto'g'ri ketishi mumkin#
| Belgi | Sabab | Yechim |
|---|---|---|
| Qidiruv natijasi mantiqsiz | Savol va hujjat vektorlari turli modelda hisoblangan | Bitta modeldan izchil foydalaning |
| O'xshashlik hamma narsaga yuqori chiqadi | Matn juda qisqa yoki umumiy (masalan, bitta so'z) | Kontekstliroq, to'liqroq gaplar bilan ishlang |
| Katta hujjatlar to'plamida qidiruv sekin | Har safar barcha vektorlar bilan solishtirilmoqda | Vektor bazaga o'ting (pgvector, Pinecone va h.k.) |
| Xarajat kutilganidan yuqori | Har bir qidiruvda hujjat vektorlari qaytadan hisoblanmoqda | Hujjat vektorlarini bir marta hisoblab, saqlab qo'ying — faqat savol vektori har safar yangi hisoblanadi |
Mini FAQ qidiruv tizimi quring
O'zingiz tanlagan sohada (masalan, onlayn do'kon, universitet qabul komissiyasi) 8-10 ta tez-tez so'raladigan savol va ularning javoblarini yozing. Foydalanuvchi savolni har xil so'zlar bilan yozganda ham (masalan, "narxi qancha" o'rniga "qimmatmi") to'g'ri javobni topa oladigan mini qidiruv funksiyasini yarating.
Maslahatni ko'rsatish
8-10 ta savol-javob juftligidan iborat kichik FAQ ro'yxati yozing. Har bir savolning embeddingini oldindan hisoblab, lug'atda saqlang. Foydalanuvchi so'rovi kelganda, eng yaqin 2 ta savolni top_n=2 bilan qaytaring.