Slide 1

Slide 1 text

PHP カンファレンス 2026 PHP アプリケーションに 類似画像検索を後付けする @ msng

Slide 2

Slide 2 text

サンプルコード https: github.com/msng/phpcon2026 / / @ msng

Slide 3

Slide 3 text

用語の定義 • 【類似画像検索】画像で画像を探すこと。キーワードで画像を探す「画像検索」とは別物 • 【AI】人間の知覚・認識をコンピュータで模倣するもの全般。本トークに生成 AI や LLM の話は登場しない。 • 【モデル】学習済みのニューラルネットワーク。本トークでは「画像を入れると数字の列が出てくる箱」。 • 【embedding / 特徴量 / ベクトル】画像の特徴を表す数字の列。本トークではほぼ同義に使う。 • 【次元】その数字の個数のこと。空間や異世界のことではない。クールなガンマンでもない。 • 【距離 / 類似度】「似ている」を数値で言えるようにしたもの。 • 【コサイン距離】ベクトルの向きの違いを測るものさし。同じ向きで 0、正反対で 2。 本トークで「距離」と言ったらこれを指す。厳密には「距離」ではないと思うけど、なんかこう呼ばれる。 • 【推論】学習済みモデルにデータを入れて結果を得ること。 • 【ベクトル検索】距離が近いベクトルを探すこと。 • 【インデックス】検索を速くするためのデータ構造。 • 【GPU】高いよね。 @ msng

Slide 4

Slide 4 text

お話の流れ • • • • • • 状況設定 実演 全体構成 Embedding ベクトル検索 まとめ @ msng

Slide 5

Slide 5 text

状況設定 • 「これに似たやつ」を探したい • 固定費は増やしたくない • 多数の商品を扱う現場 @ msng

Slide 6

Slide 6 text

状況設定 現状のインフラ構成 • VPS 1台(メモリ 4GB) 以上 @ msng

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

サンプルデータ Amazon Berkeley Objects (ABO) Dataset https: amazon-berkeley-objects.s3.amazonaws.com/index.h l m t / / @ msng

Slide 9

Slide 9 text

サーバーのありさま • • • • メモリ: 2GB (4GB) GPU: なし 外部 API: なし メイン DB: MySQL @ msng

Slide 10

Slide 10 text

全体構成 embedding サーバー FastAPI + DINOv2 アプリケーション PHP ベクトルデータベース pgvector @ msng

Slide 11

Slide 11 text

全体構成 画像 embedding サーバー FastAPI + DINOv2 アプリケーション PHP ベクトル ベクトルデータベース pgvector @ msng

Slide 12

Slide 12 text

全体構成 ベクトル embedding サーバー FastAPI + DINOv2 アプリケーション PHP ベクトルデータベース pgvector 結果 / 画像の情報 @ msng

Slide 13

Slide 13 text

全体構成 embedding サーバー FastAPI + DINOv2 アプリケーション PHP 無 ベクトルデータベース pgvector @ msng

Slide 14

Slide 14 text

全体構成 embedding サーバー FastAPI + DINOv2 アプリケーション PHP 疎 ベクトルデータベース pgvector @ msng

Slide 15

Slide 15 text

Embedding @ msng

Slide 16

Slide 16 text

Embedding 採用モデル: DINOv2 @ msng

Slide 17

Slide 17 text

DINOv2 選定理由 ありとあらゆるモデルを比較検討 してません @ msng

Slide 18

Slide 18 text

DINOv2 選定理由 条件に合うのがこれだった。 使ってみたらわりといけた。 @ msng

Slide 19

Slide 19 text

DINOv2 選定理由 それで済むように作ってある (後述) @ msng

Slide 20

Slide 20 text

Embedding 初期データ取り込み @ msng

Slide 21

Slide 21 text

Embedding 1秒かかる @ msng

Slide 22

Slide 22 text

Embedding サンプル画像数: 398,212枚 @ msng

Slide 23

Slide 23 text

Embedding 398,212 3600 110 (時間) 4日と14時間かかる @ msng

Slide 24

Slide 24 text

Embedding 最初だけ Mac でやろう @ msng

Slide 25

Slide 25 text

Embedding % php artisan embeddings:generate -v 生成 id: 565 (7e/7e35cd84.jpg)(565件目、24.1件/秒、残り4:35:13) 生成 id: 566 (c6/c66b2e14.jpg)(566件目、24.1件/秒、残り4:35:14) 生成 id: 567 (1c/1cab1979.jpg)(567件目、24.1件/秒、残り4:35:12) 生成 id: 568 (d0/d09b9080.jpg)(568件目、24.1件/秒、残り4:35:13) 生成 id: 569 (82/82487ca4.jpg)(569件目、24.1件/秒、残り4:35:15) 生成 id: 570 (6a/6ae2fea4.jpg)(570件目、24.1件/秒、残り4:35:15) @ msng

Slide 26

Slide 26 text

Embedding 速い環境で用意して 本番に突っ込む @ msng

Slide 27

Slide 27 text

Embedding 画像 HTTP embedding サーバー FastAPI + DINOv2 アプリケーション PHP など HTTP ベクトル @ msng

Slide 28

Slide 28 text

Embedding どれでも同じ形 • • • • 省メモリマシンにぜんぶ同居(現状) 専用ハイスペックマシンに引っ越し Cloud Run with GPU Embedding SaaS @ msng

Slide 29

Slide 29 text

Embedding PHP(コアアプリケーション)を主軸に embedding モデルは道具として いつでも取り替え可能 @ msng

Slide 30

Slide 30 text

ベクトル検索 @ msng

Slide 31

Slide 31 text

ベクトル検索 pgvector 一択 @ msng

Slide 32

Slide 32 text

ベクトル検索 インデックスをはる @ msng

Slide 33

Slide 33 text

インデックス候補 • IVFFlat • HNSW @ msng

Slide 34

Slide 34 text

HNSW • 検索速度: 高 • メモリ使用量: 多 • 検索精度: 高 @ msng

Slide 35

Slide 35 text

IVFFlat • 検索速度: 高め • メモリ使用量: 少 • 検索精度: 高め @ msng

Slide 36

Slide 36 text

IVFFlat • 近いベクトルが同じクラスタに入りやすい • 検索時はまず各クラスタの重心とだけ比べる • 対象のベクトルと重心が近いクラスタを開いて検査 • 開くクラスタ数 (probes) を増やせば • 全レコードをクラスタに分ける 精度が上がり速度が下がる @ msng

Slide 37

Slide 37 text

IVFFlat 倉庫に例えると 「これに似たやつ、どこにありますか?」 「だいたいあのへんの箱に入ってるんじゃないかな。 知らんけど。」 「じゃああのへんのを3箱ほど開けて探してみます。」 @ msng

Slide 38

Slide 38 text

IVFFlat 倉庫に例えると 箱をたくさん開けると 時間はかかるが、より正確になる @ msng

Slide 39

Slide 39 text

お金をかければ解決する @ msng

Slide 40

Slide 40 text

お金をかけずにできる工夫も まだまだたくさんありそう @ msng