aidoc.uz

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 vektor

3. 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 boshqa

text-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 teng

4. 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))  # 256

6. 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.

Sizning kodingiz
Savolni vektorga aylantiradi, natijani modelga uzatadi
Vektor baza
Millionlab vektor orasidan eng yaqinlarini tezkor topadi
OpenAI Embeddings API
Matnni vektorga aylantiradi

7. Model tanlash: o'lcham va narx#

ModelVektor o'lchamiQachon tanlash
text-embedding-3-small1536Aksariyat vazifalar uchun yetarli, arzon
text-embedding-3-large3072Yuqori aniqlik kerak bo'lganda, ko'p tilli murakkab matnlarda

8. Nima noto'g'ri ketishi mumkin#

BelgiSababYechim
Qidiruv natijasi mantiqsizSavol va hujjat vektorlari turli modelda hisoblanganBitta modeldan izchil foydalaning
O'xshashlik hamma narsaga yuqori chiqadiMatn juda qisqa yoki umumiy (masalan, bitta so'z)Kontekstliroq, to'liqroq gaplar bilan ishlang
Katta hujjatlar to'plamida qidiruv sekinHar safar barcha vektorlar bilan solishtirilmoqdaVektor bazaga o'ting (pgvector, Pinecone va h.k.)
Xarajat kutilganidan yuqoriHar bir qidiruvda hujjat vektorlari qaytadan hisoblanmoqdaHujjat vektorlarini bir marta hisoblab, saqlab qo'ying — faqat savol vektori har safar yangi hisoblanadi
Amaliy topshiriq

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.