Vector Databases

LanceDB لـ RAG متعدد الوسائط: تخزين واستعلام أزواج الصور والنصوص

كانت أنظمة توليد المعزز بالاسترجاع (RAG) تركز بشكل كبير على النصوص حتى وقت قريب. ومع ذلك، تتطلب تطبيقات الذكاء الاصطناعي الحديثة بشكل متزايد القدرة على الاسترجاع والاستدلال على البيانات المرئية والنصية في نفس الوقت. هنا يأتي دور RAG متعدد الوسائط. بينما تواجه قواعد البيانات المتجهية التقليدية صعوبة في تعقيد إدارة أنواع البيانات الكبيرة والحمولات الثنائية الضخمة، يقدم LanceDB حلاً تخزينياً عمودياً متيناً مصمماً خصيصاً لأحمال عمل الذكاء الاصطناعي.

في هذا الدليل، سنستكشف كيفية الاستفادة من LanceDB لتخزين واستعلام أزواج الصور والنصوص بكفاءة. سنوضح كيفية التعامل مع توليد التضمينات، وإدخال البيانات، ومنطق الاسترجاع المطلوب لنظام متعدد الوسائط.

لماذا LanceDB للبيانات متعددة الوسائط؟

LanceDB هو قاعدة بيانات متجهية مفتوحة المصدر وصديقة للمطورين تستخدم تنسيق Lance. على عكس قواعد البيانات القائمة على الصفوف، تم تحسين Lance للوصول العشوائي والملفات الثنائية الكبيرة، مما يجعله مثالياً لتخزين الصور جنباً إلى جنب مع تضميناتها المتجهية. تشمل المزايا الرئيسية ما يلي:

  • تخزين بدون عمليات تشغيل: يعمل مدمجاً داخل تطبيقك، مما يقلل من تعقيد البنية التحتية.
  • تصفية فعالة: يدعم التصفية بناءً على البيانات الوصفية إلى جانب التشابه المتجهي، وهو أمر حاسم لتضييق نطاق نتائج البحث حسب الفئة أو التاريخ أو المصدر.
  • دعم الكائنات الكبيرة: يتعامل مع البيانات الثنائية الكبيرة (مثل الصور) بشكل أصلي دون اعتماد على تخزين blob خارجي في العديد من السيناريوهات.

الإعداد والتثبيت

للبدء، تحتاج إلى تثبيت LanceDB ونموذج تضمين متعدد الوسائط. في هذا المثال، سنستخدم transformers مع نموذج CLIP لتوليد التضمينات.


# Install dependencies
pip install lancedb transformers torch pillow

الخطوة 1: توليد التضمينات متعددة الوسائط

أساس RAG متعدد الوسائط هو محاذاة الصور والنصوص في نفس الفضاء المتجهي. نستخدم نموذج CLIP لتوليد التضمينات لكل من الصور واستعلامات النص. عند البحث، يمكنك الاستعلام بالنص للعثور على صور ذات صلة، أو العكس.


import torch
from transformers import CLIPProcessor, CLIPModel
from PIL import Image
import base64
import numpy as np

# Load CLIP model
model_name = "openai/clip-vit-base-patch32"
processor = CLIPProcessor.from_pretrained(model_name)
model = CLIPModel.from_pretrained(model_name)

def get_image_embedding(image_path):
    """Generate embedding for an image."""
    image = Image.open(image_path)
    inputs = processor(images=image, return_tensors="pt")
    with torch.no_grad():
        outputs = model.get_image_features(**inputs)
    return outputs.cpu().numpy().flatten()

def get_text_embedding(text):
    """Generate embedding for a text query."""
    inputs = processor(text=text, return_tensors="pt", padding=True)
    with torch.no_grad():
        outputs = model.get_text_features(**inputs)
    return outputs.cpu().numpy().flatten()

الخطوة 2: إدخال أزواج الصور والنصوص

سنقوم بإنشاء جدول في LanceDB يخزن بيانات الصورة (مشفرة كـ Base64 للمحمولية في هذا المثال، على الرغم من أن البايتات الخام مفضلة للأداء)، والتسمية التوضيحية، والتضمين المتجهي.


import lancedb
import uuid

# Initialize database
db = lancedb.connect("./multimodal_db")

# Create a table if it doesn't exist
# Note: In production, you might store image bytes directly or use URIs
table = db.open_table("images") if db.table_names() else db.create_table("images", mode="create")

# Sample data
sample_data = [
    {
        "id": str(uuid.uuid4()),
        "caption": "A golden retriever playing in a park",
        "image_data": open("dog.jpg", "rb").read(), # Read image bytes
        "vector": get_image_embedding("dog.jpg"),
    },
    {
        "id": str(uuid.uuid4()),
        "caption": "A cozy library with bookshelves",
        "image_data": open("library.jpg", "rb").read(),
        "vector": get_image_embedding("library.jpg"),
    }
]

# Add data to the table
table.add(sample_data)

الخطوة 3: إجراء البحث متعدد الوسائط

قوة RAG متعدد الوسائط تكمن في الاسترجاع عبر الوسائط. قد يكتب المستخدم "اعثر لي على صور للكلاب"، وينبغي أن يعيد النظام الصور الأكثر تشابهاً بصرياً بناءً على استعلام النص.


def search_images(text_query, top_k=5):
    """Search for images based on a text query."""
    # Generate embedding for the text query
    query_vector = get_text_embedding(text_query)
    
    # Perform vector search with metadata filter
    # Here we simply search by vector similarity
    results = table.search(query_vector).limit(top_k).to_pandas()
    
    # Decode image data for display (optional)
    for idx, row in results.iterrows():
        print(f"Result {idx}: {row['caption']}")
        # In a real app, you'd decode row['image_data'] and display it
        # img = Image.open(io.BytesIO(row['image_data']))
        
    return results

# Execute search
results = search_images("cute dog playing outside")
print(results[['id', 'caption', '_distance']])

الخاتمة

يوفر LanceDB مساراً سلساً لبناء تطبيقات RAG متعددة الوسائط من خلال تبسيط تخزين واسترجاع أنواع البيانات المعقدة. من خلال محاذاة تضمينات النص والصورة في فضاء متجهي مشترك، يمكن للمطورين إنشاء تجارب بحث بديهية تفهم العلاقة بين مظهر الشيء ووصفه. ومع انتشار النماذج متعددة الوسائط بشكل أكبر، ستكون الأدوات مثل LanceDB ضرورية لإدارة البنية التحتية للبيانات الأساسية.

Share: