このブログでは、ライブイメージ検索を構築し、自然言語で検索します. たとえば、入力として画像のリストを持つ「象」や「かわいい動物」を検索できます。
私たちは、画像を理解し、埋め込むために多様な埋め込みモデルを使用し、効率的な検索のためのベクトルインデックスを構築します。我々は、CocoIndexを使用してインデックスフローを構築するつもりです、これは非常にパフォーマンスのリアルタイムデータ変換フレームワークです。実行中に、あなたはフォルダに新しいファイルを追加することができ、それは変更されたファイルのみを処理し、1分以内にインデックスされます。
It would mean a lot for us if you could drop a star atCocoIndex on GitHubこのチュートリアルが役に立つなら
技術
ココインデックス
ココインデックスAIのための超強力なリアルタイムデータ変換フレームワークです。
クライプ・ビット-L/14
クライプ・ビット-L/14これは、画像とテキストの両方を理解できる強力なビジョン言語モデルで、共有された埋め込みスペースで視覚的およびテキスト的表現を調節するために訓練されており、画像検索の使用ケースに最適です。
私たちのプロジェクトでは、Clip を使用して:
- 画像の組み込みを直接生成する
- 自然言語の検索クエリを同じ埋め込みスペースに変換する
- Semantic search を有効にする: query embeddings with caption embeddings
クイズ
クイズハイパフォーマンスベクターデータベースです. We use it to store and query the embeddings.
スピード
スピードis a modern, fast (high-performance), web framework for building APIs with Python 3.7+ based on standard Python type hints. We use it to build the web API for the image search. Python は、標準的な Python タイプヒントに基づいて、Python 3.7+ を使用して API を構築するためのモダンで高速(高性能)な Web フレームワークです。
前提条件
- CocoIndex は Postgres を使用して、増加処理のためのデータラインナップを追跡します。
- Qdrant をインストールする
インデックスフローの定義
FLOW DESIGN
フロー・ダイアグラムは、コードベースをどのように処理するかを示しています。
- ローカルファイルシステムから画像ファイルを読み取る
- CLIP を使用して画像を理解して埋め込む
- Embeddings in a vector database for retrieval
1.画像を挿入する
@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
サブフィールドを含むテーブルを作成します(filename
で、content
), we can refer to the文書化もっと詳細へ
2.各画像を処理し、情報を収集する。
2.1 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
THE@functools.cache
デコレータは機能呼び出しの結果をキャッシュします. In this case, it ensures that we only load the CLIP model and processor once.
@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
is a custom function that uses the CLIP model to convert an image into a vector embedding. It accepts image data in bytes format and returns a list of floating-point numbers representing the image's embedding. 画像データをバイト形式で受け入れ、画像の埋め込みを表す浮動点番号のリストを返します。
この機能は、Caching through thecache
パラメータ を有効にすると、実行器は、再処理中に機能の結果を再利用するために保存し、これは特にコンピュータ強度の高い操作に有用です。文書化.
その後、各画像を処理し、情報を収集します。
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 収集物の収集
埋め込みを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,
)
3.Indexを求める
CLIP を使用してクエリを埋め込み、テキストと画像を同じ埋め込みスペースにマッピングし、クロスモダル類似性の検索を可能にします。
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()
FastAPI Endpointの定義/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
)
これにより、Qdrant ベクターデータベースに類似の埋め込みを検索します。limit
結果
# Format results
out = []
for result in search_results:
out.append({
"filename": result.payload["filename"],
"score": result.score
})
return {"results": out}
このエンドポイントは、ユーザーが正確なキーワードマッチを使用するのではなく、自然言語で画像を説明して画像を見つけることができるセマンティックな画像検索を可能にします。
アプリケーション
速火
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 アプリケーションのセットアップと CORS ミドルウェアと静的ファイルのサービス アプリケーションは以下に構成されています:
- すべての起源からのクロス・オリジンの要求を許可する
- 「img」ディレクトリから静的画像ファイルをサービスする
- 画像検索機能のためのAPIエンドポイントの処理
@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()
起動イベント マネージャーは、最初に起動したときにアプリケーションを初期化します. Here is what each part does:
- load_dotenv(): .env ファイルから環境変数をロードし、API キーや URL などの構成に役立つ
- cocoindex.init():CocoIndexフレームワークを初期化し、必要なコンポーネントと構成を設定する
- 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
この初期化は、すべての必要なコンポーネントが適切に構成され、アプリケーションの起動時に実行されることを保証します。
前線
フロントエンドコードをチェックできます。ここ私たちは意図的に、画像検索機能に焦点を当てることがシンプルでミニマリズム的でした。
楽しむ時間です!
-
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
行こうhttp://localhost:51742 検索
で、もう一枚の画像を追加して、img
たとえば、このフォルダーは、かわいいスカート, または好きな画像. 新しい画像が処理され、インデックスされるまで、しばらくお待ちください。
インデックスの進捗状況を監視したい場合は、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 GitHub to help us grow. Thanks for reading!
GitHub