I denne blog vil vi opbygge live billedsøgning og forespørge det med naturligt sprog. For eksempel kan du søge efter "en elefant", eller et "sød dyr" med en liste over billeder som input.
Vi vil bruge multimodal indlejringsmodel til at forstå og indlejre billedet og opbygge et vektorindeks til effektiv indsamling. Vi vil bruge CocoIndex til at opbygge indekseringsstrømmen, det er en ultra-præstationær realtidsdatatransformationsramme. Under kørslen kan du tilføje nye filer til mappen, og det behandler kun ændrede filer og vil blive indekseret inden for et minut.
Det ville betyde meget for os, hvis du kunne droppe en stjerne påCocoIndex på GitHubHvis denne tutorial er nyttig.
teknologier
af CocoIndex
af CocoIndexer en ultra-yppig real-time data transformation ramme for AI.
Klip ViT-L/14
Klip ViT-L/14er en kraftfuld vision-sprogmodel, der kan forstå både billeder og tekster. Det er uddannet til at justere visuelle og tekstmæssige repræsentationer i et delt indlejringsrum, hvilket gør det perfekt til vores billedsøgning brugssituation.
I vores projekt bruger vi CLIP til:
- Generer indlejringer af billederne direkte
- Konvertering af natursprogssøgningsforespørgsler til samme indlejringsplads
- Aktiver semantisk søgning ved at sammenligne indlejringer af forespørgsler med indlejringer af overskrifter
Køge
Køgeer en vektordatabase med høj ydeevne. Vi bruger den til at gemme og forespørge indlejringerne.
Hurtigt
Hurtigter en moderne, hurtig (høj ydeevne) webramme til opbygning af API'er med Python 3.7+ baseret på standard Python-type tips.
Forudsætninger
- Installer Postgres. CocoIndex bruger Postgres til at holde styr på data linje for incremental behandling.
- Installation af Qdrant.
Indeksering af flow
Flow design
Flow diagrammet illustrerer, hvordan vi vil behandle vores codebase:
- Læs billedfiler fra det lokale filsystem
- Brug CLIP til at forstå og indlejre billedet
- Gem indlejringerne i en vektordatabase til hentning
1 Indsæt billederne.
@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_source
vil oprette en tabel med underfelter (filename
, dercontent
Vi kan henvise til denDokumentation afFor flere detaljer.
Behandle hvert billede og indsamle oplysningerne.
2.1 Indsæt billedet 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.cache
I dette tilfælde sikrer det, at vi kun indlæser CLIP-modellen og processoren én gang.
@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
er en brugerdefineret funktion, der bruger CLIP-modellen til at konvertere et billede til en vektorindlejring. Den accepterer billeddata i byteformat og returnerer en liste over flydende punktnumre, der repræsenterer billedets indlejring.
Funktionen understøtter caching gennemcache
parameter. Når den er aktiveret, gemmer udføreren funktionens resultater til genbrug under genbehandling, hvilket er særligt nyttigt for beregningsintensive operationer.Dokumentation af.
Derefter vil vi behandle hvert billede og indsamle oplysningerne.
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 Indsamle indbyggerne
Eksporter indlejringerne til et 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,
)
Vælg indekset
Indlejr forespørgslen med CLIP, som kortlægger både tekst og billeder i samme indlejringsplads, hvilket giver mulighed for tværmodal lighedssøgning.
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()
Definer et FastAPI endpoint/search
Der er tale om semantisk billedsøgning.
@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
)
Dette søger i Qdrant-vektordatabasen efter lignende indlejringer.limit
Resultaterne
# Format results
out = []
for result in search_results:
out.append({
"filename": result.payload["filename"],
"score": result.score
})
return {"results": out}
Dette endpoint muliggør semantisk billedsøgning, hvor brugerne kan finde billeder ved at beskrive dem i naturligt sprog, i stedet for at bruge nøjagtige søgeord matches.
Ansøgning
Hurtig ild
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 applikationsoprettelse med CORS middleware og statisk fil, der serverer appen er konfigureret til:
- Tillad krydsoprindelsesforespørgsler fra enhver oprindelse
- Server statiske billedfiler fra 'img' -kataloget
- Håndtering af API-endpoints til billedsøgningsfunktionalitet
@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()
Startbegivenhedshåndtering initialiserer applikationen, når den først starter op. Her er, hvad hver del gør:
- load_dotenv(): Indlæser miljøvariabler fra en .env-fil, som er nyttig til konfiguration som API-nøgler og URL'er
- cocoindex.init(): Initialiserer CocoIndex-rammen og opretter de nødvendige komponenter og konfigurationer
- 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
- Creates a new
- Live Updater Setup:
- Creates a
FlowLiveUpdater
instance for theimage_object_embedding_flow
- This enables real-time updates to the image search index
- Starts the live updater to begin monitoring for changes
- Creates a
Denne initialisering sikrer, at alle nødvendige komponenter er korrekt konfigureret og kører, når applikationen starter.
Fronten
Du kan tjekke frontend-kodenHer erVi har bevidst holdt det simpelt og minimalistisk at fokusere på billedsøgningsfunktionaliteten.
Tid til at have det sjovt!
-
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å tilhttp://localhost:5174til at søge.
Tilføj et andet billede iimg
Forkortet, for eksempel denneSøde skildpadder, eller et hvilket som helst billede, du kan lide. Vent et øjeblik, før det nye billede behandles og indekseres.
Hvis du vil overvåge indekseringsprocessen, kan du se den i CocoInsightcocoindex server -ci main.py
.
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!
af Github