170 avläsningar

Hur man bygger Live Image Search med Vision Model och Query med naturligt språk

förbi LJ7m2025/05/22
Read on Terminal Reader

För länge; Att läsa

I den här bloggen kommer vi att bygga live-bildsökning och fråga det med naturligt språk. Till exempel kan du söka efter "en elefant", eller ett "söt djur" med en lista över bilder som input. Vi kommer att använda multimodal inbäddningsmodell för att förstå och inbäddning av bilden, och bygga ett vektorindex för effektivt hämtning. Vi kommer att använda CocoIndex för att bygga indexflödet.
featured image - Hur man bygger Live Image Search med Vision Model och Query med naturligt språk
LJ HackerNoon profile picture
0-item
1-item

I den här bloggen kommer vi att bygga live-bildsökning och fråga den med naturligt språk. Till exempel kan du söka efter "en elefant", eller ett "söt djur" med en lista över bilder som input.

Vi kommer att använda multimodal inbäddningsmodell för att förstå och inbäddning av bilden, och bygga en vektorindex för effektiv återvinning. Vi kommer att använda CocoIndex för att bygga indexeringsflödet, det är en ultra-presterande realtidsdatatransformationsramverk. Under körning kan du lägga till nya filer till mappen och det bara bearbetar ändrade filer och kommer att indexeras inom en minut.

Det skulle betyda mycket för oss om du kunde släppa en stjärna påCocoIndex på GitHubOm denna tutorial är till hjälp.


tekniker

CocoIndex

CocoIndexär en ultra-presterande realtidsdatatransformationsram för AI.

Klipp ViT-L/14

Klipp ViT-L/14är en kraftfull vision-språkmodell som kan förstå både bilder och texter. Den är utbildad för att anpassa visuella och textuella representationer i ett delat inbäddningsutrymme, vilket gör den perfekt för vår bildsökning.

I vårt projekt använder vi CLIP för att:

  1. Generera inbäddningar av bilderna direkt
  2. Konvertera naturliga språk sökfrågor till samma inbäddningsutrymme
  3. Aktivera semantisk sökning genom att jämföra frågeinbäddningar med rubrikinbäddningar

Qdrant

Qdrantär en högpresterande vektordatabas. Vi använder den för att lagra och fråga in inbäddningarna.

snabba

snabbaär en modern, snabb (högpresterande), webbram för att bygga API med Python 3.7+ baserat på standard Python typ tips.

Förutsättningar

  • Installera Postgres. CocoIndex använder Postgres för att hålla reda på data linje för incrementell bearbetning.
  • Installation av Qdrant.

Definiera indexering flöde

Flödesdesign

flow design

Flödesdiagrammet illustrerar hur vi kommer att bearbeta vår kodbas:

  1. Läs bildfiler från det lokala filsystemet
  2. Använd CLIP för att förstå och bädda in bilden
  3. Spara inbäddningarna i en vektordatabas för hämtning

1 Inkludera bilderna

@cocoindex.flow_def(name="ImageObjectEmbedding")
def image_object_embedding_flow(flow_builder: cocoindex.FlowBuilder, data_scope: cocoindex.DataScope):
    data_scope["images"] = flow_builder.add_source(
        cocoindex.sources.LocalFile(path="img", included_patterns=["*.jpg", "*.jpeg", "*.png"], binary=True),
        refresh_interval=datetime.timedelta(minutes=1)  # Poll for changes every 1 minute
    )
    img_embeddings = data_scope.add_collector()

flow_builder.add_sourcekommer att skapa en tabell med underfält (filenameochcontent) kan vi hänvisa till denDokumentationFör mer detaljer.

ingestion

Bearbeta varje bild och samla in informationen.

2.1 Infoga bilden med CLIP

@functools.cache
def get_clip_model() -> tuple[CLIPModel, CLIPProcessor]:
    model = CLIPModel.from_pretrained(CLIP_MODEL_NAME)
    processor = CLIPProcessor.from_pretrained(CLIP_MODEL_NAME)
    return model, processor

den@functools.cacheI det här fallet säkerställer det att vi bara laddar CLIP-modellen och processorn en gång.

@cocoindex.op.function(cache=True, behavior_version=1, gpu=True)
def embed_image(img_bytes: bytes) -> cocoindex.Vector[cocoindex.Float32, Literal[384]]:
    """
    Convert image to embedding using CLIP model.
    """
    model, processor = get_clip_model()
    image = Image.open(io.BytesIO(img_bytes)).convert("RGB")
    inputs = processor(images=image, return_tensors="pt")
    with torch.no_grad():
        features = model.get_image_features(**inputs)
    return features[0].tolist()

embed_imageär en anpassad funktion som använder CLIP-modellen för att konvertera en bild till en vektorinbäddning. Den accepterar bilddata i byteformat och returnerar en lista över flytande punktsnummer som representerar bildens inbäddning.

Funktionen stöder caching genomcacheparameter. När den är aktiverad lagrar utföraren funktionens resultat för återanvändning under vidare bearbetning, vilket är särskilt användbart för beräkningsintensiva operationer.Dokumentation.

Sedan kommer vi att bearbeta varje bild och samla in informationen.

with data_scope["images"].row() as img:
    img["embedding"] = img["content"].transform(embed_image)
    img_embeddings.collect(
        id=cocoindex.GeneratedField.UUID,
        filename=img["filename"],
        embedding=img["embedding"],
    )



2.3 Samla in inbäddningarna

Exportera inbäddningarna till ett bord i Qdrant.

img_embeddings.export(
    "img_embeddings",
    cocoindex.storages.Qdrant(
        collection_name="image_search",
        grpc_url=QDRANT_GRPC_URL,
    ),
    primary_key_fields=["id"],
    setup_by_user=True,
)

Sök efter index

Bädda in frågan med CLIP, som kartlägger både text och bilder i samma inbäddningsutrymme, vilket möjliggör cross-modal likhetssökning.

def embed_query(text: str) -> list[float]:
    model, processor = get_clip_model()
    inputs = processor(text=[text], return_tensors="pt", padding=True)
    with torch.no_grad():
        features = model.get_text_features(**inputs)
    return features[0].tolist()

Definiera en FastAPI Endpoint/searchsom utför semantisk bildsökning.

@app.get("/search")
def search(q: str = Query(..., description="Search query"), limit: int = Query(5, description="Number of results")):
    # Get the embedding for the query
    query_embedding = embed_query(q)
    
    # Search in Qdrant
    search_results = app.state.qdrant_client.search(
        collection_name="image_search",
        query_vector=("embedding", query_embedding),
        limit=limit
    )
    

Detta söker Qdrant-vektordatabasen för liknande inbäddningar. Returnerar toppenlimitResultatet

# Format results
out = []
for result in search_results:
    out.append({
        "filename": result.payload["filename"],
        "score": result.score
    })
return {"results": out}

Denna slutpunkt möjliggör semantisk bildsökning där användare kan hitta bilder genom att beskriva dem i naturligt språk, snarare än med exakta nyckelord matcher.

Ansökan

Snabbt eld

app = FastAPI()
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
# Serve images from the 'img' directory at /img
app.mount("/img", StaticFiles(directory="img"), name="img")

FastAPI applikationsinstallation med CORS middleware och statisk fil som serverar appen är konfigurerad till:

  • Tillåta korsförfrågningar från alla ursprung
  • Servera statiska bildfiler från 'img' katalogen
  • Hantera API-ändpunkter för bild sökfunktionalitet
@app.on_event("startup")
def startup_event():
    load_dotenv()
    cocoindex.init()
    # Initialize Qdrant client
    app.state.qdrant_client = QdrantClient(
        url=QDRANT_GRPC_URL,
        prefer_grpc=True
    )
    app.state.live_updater = cocoindex.FlowLiveUpdater(image_object_embedding_flow)
    app.state.live_updater.start()

Starthändelsehanteraren initialiserar applikationen när den startar först.

  1. load_dotenv(): Ladda miljövariabler från en .env-fil, som är användbar för konfiguration som API-nycklar och URL-adresser
  2. cocoindex.init(): Initialiserar CocoIndex-ramverket och ställer in nödvändiga komponenter och konfigurationer
  3. Qdrant Client Setup:
    • Creates a new QdrantClient instance
    • Configures it to use the gRPC URL specified in environment variables
    • Enables gRPC preference for better performance
    • Stores the client in the FastAPI app state for access across requests
  4. Live Updater Setup:
    • Creates a FlowLiveUpdater instance for the image_object_embedding_flow
    • This enables real-time updates to the image search index
    • Starts the live updater to begin monitoring for changes

Denna initialisering säkerställer att alla nödvändiga komponenter är korrekt konfigurerade och körs när programmet startar.

Fronten

Du kan kontrollera frontend-kodenhärVi har avsiktligt hållit det enkelt och minimalistiskt att fokusera på bildsökningsfunktionaliteten.

Dags att ha kul!

  • Create a collection in Qdrant

    curl -X PUT 'http://localhost:6333/collections/image_search' \
    -H 'Content-Type: application/json' \
    -d '{
        "vectors": {
        "embedding": {
            "size": 768,
            "distance": "Cosine"
        }
        }
    }'
    
  • Setup indexing flow

    cocoindex setup main.py
    

    It is setup with a live updater, so you can add new files to the folder and it will be indexed within a minute.

  • Run backend

    uvicorn main:app --reload --host 0.0.0.0 --port 8000
    
  • Run frontend

    cd frontend
    npm install
    npm run dev
    

Gå tillhttp://localhost:5174För att söka.


Example Search


More Example Search


Lägg till en ny bild iimgFolders, till exempel dettaSöt sköldpaddaVänta en minut för att den nya bilden ska bearbetas och indexeras.


Squirrel Search


Om du vill övervaka indexeringsprocessen kan du se den i CocoInsightcocoindex server -ci main.py .


Indexing status


Finally - we are constantly improving, and more features and examples are coming soon. If you love this article, please give us a star ⭐ at GitHub to help us grow. Thanks for reading!

GitHub

Trending Topics

blockchaincryptocurrencyhackernoon-top-storyprogrammingsoftware-developmenttechnologystartuphackernoon-booksBitcoinbooks