En este blog, construiremos la búsqueda de imágenes en vivo y la interrogaremos con el lenguaje natural. Por ejemplo, puede buscar "un elefante", o un "animal bonito" con una lista de imágenes como entrada. Vamos a usar el modelo de incorporación multimodal para comprender y incorporar la imagen, y construir un índice vectorial para una recuperación eficiente. Vamos a usar CocoIndex para construir el flujo de indexación, es un marco de transformación de datos en tiempo real de alto rendimiento. Durante la ejecución, puede agregar nuevos archivos a la carpeta y sólo procesará archivos cambiados y se indexarán en un minuto. significaría mucho para nosotros si pudieras lanzar una estrella en Si este tutorial es útil. CocoIndex en GitHub Tecnologías CocoIndex Es un marco de transformación de datos en tiempo real para la IA. CocoIndex Clásico ViT-L/14 Es un poderoso modelo de lenguaje de visión que puede entender tanto imágenes como textos. Se ha entrenado para alinear las representaciones visuales y textuales en un espacio de embalaje compartido, lo que lo hace perfecto para nuestro caso de uso de búsqueda de imagen. Clásico ViT-L/14 En nuestro proyecto, utilizamos CLIP para: Generar incorporaciones de las imágenes directamente Convertir las consultas de búsqueda de lengua natural en el mismo espacio de embalaje Permite la búsqueda semántica comparando las incorporaciones de consultas con las incorporaciones de subtítulos Quirón es una base de datos vectorial de alto rendimiento. la usamos para almacenar y consultar las incorporaciones. Quirón Rápido es un moderno, rápido (de alto rendimiento), marco web para la construcción de APIs con Python 3.7+ basado en las pistas de tipo estándar de Python. Rápido Precondiciones Instalar Postgres. CocoIndex utiliza Postgres para mantener el seguimiento de la línea de datos para el procesamiento incremental. Instalación de Qdrant. Definición del flujo de indexación Diseño de flujo El diagrama de flujo ilustra cómo procesaremos nuestra base de código: Leer archivos de imagen del sistema de archivos local Utilice CLIP para comprender y incorporar la imagen Almacenar las incorporaciones en una base de datos vectorial para la recuperación 1 Incorporar las imágenes. @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() se creará una tabla con subcampos ( , de ), podemos referirnos a la Para más detalles. flow_builder.add_source filename content Documentación Procesar cada imagen y recopilar la información. 2.1 Incorporar la imagen con 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 El En este caso, garantiza que solo cargamos el modelo CLIP y el procesador una vez. @functools.cache @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() Es una función personalizada que utiliza el modelo CLIP para convertir una imagen en una incorporación vectorial.Acepta datos de imagen en formato de bytes y devuelve una lista de números de puntos flotantes que representan la incorporación de la imagen. embed_image La función soporta el cache a través de la Parámetro. Cuando está habilitado, el ejecutor almacenará los resultados de la función para su reutilización durante el procesamiento, lo que es particularmente útil para operaciones computacionalmente intensivas. Para obtener más información sobre los parámetros de la función personalizada, consulte . cache Documentación Luego vamos a procesar cada imagen y recoger la información. 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 Colectar los engranajes Exportar las incorporaciones a una mesa en 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, ) Quiero el índice Incorporar la consulta con CLIP, que mapea tanto el texto como las imágenes en el mismo espacio de incorporación, permitiendo la búsqueda de similitud entre modos. 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() Definición de un punto final Realizar una búsqueda semántica de imagen. /search @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 ) Esto busca la base de datos de vectores de Qdrant para inserciones similares. Devuelve la parte superior Resultados limit # Format results out = [] for result in search_results: out.append({ "filename": result.payload["filename"], "score": result.score }) return {"results": out} Este punto final permite la búsqueda de imágenes semánticas donde los usuarios pueden encontrar imágenes describiéndolas en lenguaje natural, en lugar de usar coincidencias exactas de palabras clave. Aplicación Fuego rápido 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") Instalación de aplicaciones FastAPI con middleware CORS y archivos estáticos que sirven La aplicación está configurada para: Permitir solicitudes cruzadas de cualquier origen Servir archivos de imagen estáticos desde el directorio 'img' Gestionar los endpoints de API para la funcionalidad de búsqueda de imagen @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() El gestor de eventos de inicio inicia la aplicación cuando se inicia por primera vez.Aquí está lo que hace cada parte: load_dotenv(): Carga variables de entorno de un archivo .env, que es útil para la configuración como claves de API y URL cocoindex.init(): Inicializa el marco de CocoIndex, configurando los componentes y configuraciones necesarios Qdrant Client Setup: Creates a new instance QdrantClient 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 Live Updater Setup: Creates a instance for the FlowLiveUpdater image_object_embedding_flow This enables real-time updates to the image search index Starts the live updater to begin monitoring for changes Esta inicialización asegura que todos los componentes necesarios se configuran correctamente y se ejecuten cuando se inicia la aplicación. Frente Puedes comprobar el código frontal Intentamos mantenerlo simple y minimalista para centrarnos en la funcionalidad de búsqueda de imágenes. Aquí ¡Hora de divertirse! 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 Vaya a de la búsqueda. http://localhost:5174 Añade otra imagen en el Por ejemplo, en el folio, este Esperar un minuto para que la nueva imagen sea procesada e indexada. img dulce escarabajo Si desea monitorear el progreso de la indexación, puede verlo en CocoInsight . cocoindex 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 to help us grow. Thanks for reading! GitHub GitHub