DUICUO

ChatGPTをビデオドメイン用のSQL風トランスレータに変換する - オープンソースアプリケーションVoxelGPTを例に

翻訳者|朱賢宗

校正者 | Chonglou

VoxelGPT は自然言語クエリを使用して画像データセット (著者が提供する画像) を照会します。

導入

表形式のデータとは異なり、コンピュータービジョンタスクのデータセットは非構造化データです。ピクセルパッチ、ラベルスタック、ラベルバッグといったデータで、構造化されたメタデータが含まれている場合もあります。それでもなお、コンピュータービジョンに携わる私たちは、データセットを理解し、トレーニングセットとテストセットを準備し、パターンを見つけ、エッジケースを特定し、モデルのパフォーマンスを評価するなど、これらのデータを効果的に精査する能力を必要としています。

視覚データを理解する必要がある場合(基本的にいつもそうですが)、オープンソースライブラリFiftyOneを使用します。これは、コンピュータービジョンデータのクエリに使用できる強力なPython構文を定義しています。これは、コンピュータービジョンデータの非構造化世界におけるSQLのようなもので、画像、動画、さらには3Dポイントクラウドで構成されるデータセットをプログラムでフィルタリング、並べ替え、セマンティックにスライスすることができます。

数か月前、 ChatGPTブームが最高潮に達した頃、 OpenAIのウェブサイトで自然言語入力をSQLクエリに変換するサンプルアプリケーションを見ました。このアプリケーションは非常に基本的なもので、コンピュータービジョンのデータははるかに複雑でしたが、私はある疑問を抱きました。画像や動画のデータセットでも同様のことができるのだろうか? 言い換えれば、

大規模言語モデル (LLM) の汎用性を活用して、自然言語クエリを非構造化コンピューター ビジョン データセットのフィルター処理されたビューに変換できるでしょうか?

答えは、「はい、できます!」です。

最近、私たちのVoxel51 チームは、LLM の一般的な言語と推論機能を FiftyOne のクエリ言語と組み合わせて、コードを 1 行も書かずにコンピューター ビジョン データセットを完全にクエリできるオープンソースの AI アシスタントであるVoxelGPT を構築しました

このツールは、 LangChain TikTok、Fiftyoneを活用して開発されました。https ://gpt.fiftyone.ai/無料でお試しいただけます

この記事では、ヒント エンジニアリング、ソフトウェア エンジニアリング広範な試行錯誤によるデバッグの全プロセスを網羅し、ドメイン固有のLLM アプリケーションの構築方法を説明します

実際、私たちはプロセス全体を通して何度も挫折し、タスクが実現不可能なのではないかと懸念していました。LLMを活用したアプリケーションの構築に苦労されている方にとって、この記事がご自身が設定した障壁乗り越えるきっかけになれば幸いです

この記事の目次は次のとおりです。

  • SQLに似た画像と動画のクエリ
  • 全体的なタスクを定義する
  • モデルコンテキストを提供する
  • 生成と利用の例
  • 分解問題
  • 実用化

クエリ言語

VoxelGPT は自然言語クエリを使用して画像データセット (著者が提供する画像) を照会します。

LLMを用いたクエリ生成方法を詳しく説明する前に、モデル変換タスクで使用するクエリ言語について少し説明する必要があります。以下は、必要な基本情報です。より包括的な概要については、 FiftyOneユーザーガイドご覧ください既にクエリ言語に精通している場合は、次のセクションに進んでください。

  • データセットとは、SQLのテーブルまたはPandasのDataFrameをコンピュータービジョンでシミュレーションしたものです。メディアファイルのコレクションに関連するすべての情報が含まれています。
  • サンプル: データテーブルの行と同様に、サンプルはデータセットの原子要素です。各サンプルにはメディアファイルを指すファイルパスがあり、そのデータセグメントに関連するその他のすべての情報が保存されます
  • フィールドフィールドは、サンプルの属性(画像の幅、高さ、ファイルパスなど)を定義するため、データテーブルの列に似ています。ただし、フィールドは他のフィールドを含めることができるため、柔軟性があります(以下のラベルを参照)。
  • ラベル:ラベルは、意味的な根拠となる真実情報や予測情報を格納するフィールドです。例えば、物体検出は検出ラベルフィールドに格納され、分類は分類ラベルフィールドに格納されます。

SQL やPanasと同様に、クエリ操作を使用してデータをフィルタリングできます。例えば、データテーブルで次のようなクエリを実行したいとします。

エントリの値が 0.5 より大きい列「 A 」のすべての行

ただし、データ テーブルは数値スライスやフィルタリングに適していますが、非構造化コンピューター ビジョン データは本質的にセマンティック スライスに適しています。次に例を示します。

少なくとも3 つの「犬」以外のグラウンド トゥルース検出を含む画像から、大きな境界ボックスを使用して信頼性の高い「犬」の予測を取得します

つまり、非構造化データのセマンティック スライスには、より高い柔軟性が求められます。

このレベルの柔軟性を実現するために、 FiftyOneは、フィルタリング、マッチング、選択、並べ替え、除外といった許可されたクエリ操作をカプセル化するViewStageメソッドのセットを定義しています。これらのメソッドは、SQLのSELECT、WHERE、ORDER BYとほぼ同様ですが、クエリ空間がはるかに広いため、メソッドの数もはるかに多く、それぞれのメソッドには多様なユースケースがあります。興味のある方は、包括的な解説については、こちらのビューチートシートをご覧ください。

複数の ViewStage 操作を順番に組み合わせることで、データセットの任意のサブセット (DatasetView と呼ばれる) を取得できます。

クエリ言語の動作は次のようになります。my_datasetという名前のデータセットがあり、「cat」を含むランダムな画像 10 枚の「predictions」ラベル フィールド (およびその「ground_truth」ラベル フィールド) 内のすべての「 dog 検出を取得する場合は次のクエリを使用できます。

 view = my_dataset.match( F("ground_truth.detections.label").contains(["cat"]) ).filter_labels( "predictions", F("label") == "dog" ).take(10)

`match()`関数は、「ground_truth」検出フィールドに「cat」が含まれる画像のみを対象とします。次に、`filter_labels()`関数は「predictions」フィールドをフィルタリングし、「dog」検出のみを取得します。最後に、`take()`関数はデータセットのサブセットをランダムに選択します。

タスクを定義する

この旅に乗り出した当初、 LLMが一体何なのか全く分かっていませんでした。2022年12月、私はChatGPTをいじっていて、 「コンピュータビジョンにおけるトンネルビジョン:ChatGPTはそれを理解できるか? という記事を書きチャットボットがコンピュータビジョンの概念をどのように理解できるかを探りました。当時、汎用言語モデルが基本的な画像処理タスクに対してかなり正しいPythonコードを書けるというのは印象的でしたが、GPTによって生成されたコードを(人間による検証なしで)コンピュータビジョンアプリケーションで使用するという考えは、やや非現実的に思えました。

テキストからSQLへの変換例や、GPT-4がBAR(およびその他の試験)で優れたスコアを達成したという報告を読んだ、GPT for CVをもう一度試してみることにしました。GPT-4にいくつかの簡単なクエリのPythonコードを生成させてみたところその応答に驚くほど満足しました。FiftyOneライブラリに関する情報を入力しなかったため GPT-4のそのままの結果の精度はまだ完璧とは言えませんが、このような結果理解できます。それでも、この研究の将来性は非常に有望です。

一貫性が必要

プロンプティング手法 (後述) を組み込む場合、それをより大きなエンジニアリング パイプラインに統合するには、まずタスクを明確に定義する必要があります。

問題のシナリオは複雑なため、 GPT モデルの応答はプロンプトの形式によって大きく異なります。

ここに 2 つの簡単な例を示します。これらをすぐに分析します。

ヒント1:

英語のヒント:入力された自然言語クエリをPythonコードに変換し、コンピュータービジョンライブラリFiftyOneのViewStagesを生成することが課題です。最初の自然言語クエリは「犬だけを含む画像」です。FiftyOneのコードをください。

意味:入力された自然言語クエリをPythonコードに変換し、コンピュータビジョンライブラリFiftyOne用のViewStagesを生成することが課題です。これはあなたの最初の自然言語クエリです:「犬だけを含む画像」。FiftyOneライブラリを使用した適切なプログラミングコードをご提供ください

返信1:

英語の返信:はい、犬だけを含む画像の ViewStage を生成する FiftyOne のコードは次のとおりです。

中国語での意味: もちろん、以下は犬だけを含む画像の ViewStage を生成する FiftyOne コードです。

 import fiftyone as fo import fiftyone.zoo as foz # Load the dataset dataset = foz.load_zoo_dataset( "open-images-v6", split="validation", label_types=["detections"], classes=["Dog"], ) # Create a view stage that filters out images without any dog detections view_stage = fo.ViewStage("detections", fo.FilterField("detections", "label", "Dog")) # Apply the view stage to the dataset dataset = dataset.add_stage(view_stage) # View the dataset session = fo.launch_app(dataset)

このコードは、犬の「検出」ラベルタイプのみを含むOpen Images v6検証データセットを読み込み、犬が検出されない画像を除外するビューを作成します。最後に、このビューをデータセットに適用し、FiftyOneアプリで起動します。

ヒント2:

英語のプロンプトは次のとおりです。

あなたの課題は、入力された自然言語クエリをPythonコードに変換し、機械学習ライブラリFiftyOne用のViewStagesを生成することです。最初の自然言語クエリは「誤検知された最もユニークな画像」です。FiftyOneのコードを教えてください。

意味:入力された自然言語クエリをPythonコードに変換し、FiftyOne機械学習ライブラリ用のViewStagesを生成することが課題です。これはあなたの最初の自然言語クエリです:「誤検知された最もユニークな画像」。FiftyOneライブラリを使用した関連するプログラミングコードをご提供ください

返信2:

英語の返信:はい、Python の FiftyOne ライブラリを使用して、「誤検出が最も多いユニークな画像」という自然言語クエリの ViewStages を生成する FiftyOne コードは次のとおりです。

中国語での意味: もちろん、以下は、 FiftyOne ライブラリを使用して「誤検出が最も多いユニークな画像」という自然言語クエリの ViewStages を生成する Python の FiftyOne コードです。

 import fiftyone as fo import fiftyone.zoo as foz # Load your dataset dataset = fo.load_dataset("your_dataset_name") # Define your false positive detection model model = foz.load_zoo_model("your_model_name") # Define your pipeline pipeline = [ {"$set": {"predictions": {"$predict": model}}}, {"$match": {"predictions.mistakes.false_positive": True}}, {"$group": {"_id": "$filepath"}}, {"$count": "num_images"}, {"$sort": {"num_images": -1}}, ] # Run your pipeline and display the results in a view stage view = dataset.aggregate(pipeline).limit(10).display()

このコードでは、まずFiftyOneライブラリと必要な依存関係をロードします。次に、fo.load_dataset()を使用してデータセットをロードします。

次に、 `foz.load_zoo_mode()` を使用して誤検知モデルを定義します。この関数は、最先端のコンピュータービジョンモデルスイートを含む FiftyOne Zoo モデルから事前学習済みのモデルを読み込みます

次に、 $set、$match、$group、$count、$sortなどの集計コマンドを使用してパイプラインを定義します。パイプラインはまず$setを使用して、データセット内のモデルの予測値を含む各サンプルにフィールドを追加します。次に、$matchを使用してサンプルをフィルタリングし誤検知として検出されたものだけを含めます。

次に、`$group` を使ってサンプルをファイルパスに基づいてグループ化し、`$count` を使って各グループに含まれる画像の数をカウントします。最後に、`$sort` を使ってグループを画像数の降順で並べ替えます。

最後に、データセットに対してパイプラインを実行し、 limit() を使って結果を誤検知数が最も多い上位10枚の画像に絞り込みます。次に、display() を使って結果をビューに表示します

どちらの例もプロンプトの構造は同じですが、レスポンスはいくつかの重要な点で異なります。例えば、レスポンス1はデータセットにViewStageを追加してDatasetViewを作成しようとします。レスポンス2はMongoDB集計パイプラインを定義・適用し、その後にlimit()メソッド(limitステップを適用)でビューを10サンプルに制限し、display()メソッドは存在しません。さらに、レスポンス2はレスポンス1を実際のデータセット(Open Images V6)にロードする際のテンプレートコードであり、「your_dataset_name」と「your_model_name」の入力を求めます。

要約すると、これらの例では次の問題も浮き彫りになっています。

  1. モジュール コード: 一部の応答には、モジュールをインポートし、データセット (およびモデル) をインスタンス化し、視覚化を作成するためのコードが含まれています (sessinotallow=fo.lonch_app(dataset))。
  2. 説明テキスト:教育分野を含む多くの場合、モデルが「推論」の根拠を説明することは有益です。しかし、ユーザーに代わってクエリを実行する場合、この説明テキストは障害となります。クエリによっては、複数のテキストベースのコードブロックが生成されることもあります。

私たちが本当に求めているのは、 LLMがPythonプロセスにコピー&ペーストできるコードを返すことです。余分なオーバーヘッドは一切ありません。プロンプトモデルの最初の試みとして、翻訳したい自然言語クエリの前に、次のテキストを付けることにしました。

あなたのタスクは、入力された自然言語クエリを Python コードに変換して、コンピューター ビジョン ライブラリ FiftyOne の ViewStages を生成することです。

ここにいくつかのルールがあります:

- パッケージのインポートなどのすべてのヘッダー コード、およびデータセットの保存や FiftyOne アプリの起動などのすべてのフッター コードを避けます。

- 中間コードスニペットや説明は不要で、最終的な Python コードだけを提供してください。

- データセットは常にPython変数`dataset`に格納されていると想定します

- 次の ViewStages を任意の組み合わせで使用してレスポンスを生成できます: exclude、exclude_by、exclude_fields、exclude_frames、…

重要なのは、タスクを定義し、モデルが実行できることと実行できないことを指示するルールを確立したことです。

注: より標準化された形式の返信では、 ChatGPT チャット インターフェースから OpenAI API を介して GPT-4 を使用しています。

制限事項

私たちのチームは、少なくとも当初は、 LLMに実行させるタスクの範囲を限定することに決めました。FiftyOneクエリ言語自体は豊富な機能を備えていますが、事前学習済みのモデルに微調整なしに任意の複雑なタスクを実行させるのは期待外れです。そこで、まずは単純なタスクから始め、徐々に複雑なタスクを増やしていきました。

この実験では、次の制約を課しました。

  • 画像とビデオのみ: LLM クエリで 3D ポイント クラウドまたはグループ化されたデータセットが取得されることは想定されません。
  • 予測不可能なViewStagesを無視:ほとんどのViewStagesは同じ基本ルールに従いますが、いくつか例外があります。Concatは2つ目のDatasetViewを受け入れる唯一のViewStageです。MongoはMongoDBの集計構文を使用します。GeoNearにはfiftyne.utils.geojson.geo_within()オブジェクトを受け入れるクエリパラメータがあります。GeoWithinは「inner」が適用される領域を定義する2次元配列を必要とします。そこで、Concat、Mongo、GeoWithinを無視し、クエリパラメータを除くすべてのGeoNearの用途をサポートすることにしました。
  • 2フェーズに絞る:モデルは任意の数のフェーズで構成できますが、私が目にしたほとんどのワークフローでは、必要なDatasetViewを作成するには1つか2つのViewStageで十分です。この記事のプロジェクトの目的は読者を困らせることではなく、コンピュータービジョンの実践者にとって役立つものを作成することです

文脈を提供する

VoxelGPT は自然言語クエリを使用して画像データセット (著者が提供する画像) を照会します。

モデルに明確な「タスク」を与え、明示的な指示を与えることに加え、 FiftyOneのクエリ言語の動作に関する詳細な情報をモデルに提供することで、パフォーマンスを向上できることが分かりました。この情報がなければ、LLMは単に盲目的に動作し、ビッグデータの暗黒世界から無計画にデータを取得することになります

例えば、プロンプト2で誤検知予測を要求したところ、レスポンスは`predictions.mistakes.false_ppositive`を使用してこれらの誤検知を参照しようとしました。これは、ChatGPTのコンテキストにおいて誤検知情報を保存およびアクセスするための合理的な方法のように思えます。

このモデルは、FiftyOneでは検出予測の真正性/偽陽性率が`dataset.evalate_detections()`を用いて評価されることを認識していません。この評価を実行した後、`eval_fp > 0`を満たすことで、偽陽性の画像をすべて取得できます。ここで、

 images_with_fp = dataset.match(F("eval_fp")>0)

私は、次のような他のルールを提供することで、このタスクを明確にしようとしています。

- ユーザーが最も「ユニークな」画像を求める場合、サンプルに保存されている「ユニークさ」フィールドを参照しています。

- ユーザーが最も「間違った」または「誤った」画像を求める場合、サンプルに保存されている「誤り度」フィールドを参照しています。

- ユーザーが特定の操作を適用するラベル フィールド (「predictions」や「ground_truth」など) を指定しない場合、データに ground_truth フィールドが存在する場合は「ground_truth」を意味するものと想定します。

タグの種類に関する情報も提供しました。

- オブジェクト検出の境界ボックスは[左上x座標、左上y座標、幅、高さ]の形式で、すべて画像の幅と高さを基準とし、[0, 1]の範囲で表されます。

- ラベルの種類には、分類、分類、検出、検出、セグメンテーション、キーポイント、回帰、ポリラインなどがあります。

さらに、許可されたビュー ステージのリストを提供することで、モデルに許可されたビュー ステージを使用するように指示することはできましたが、次のことはわかりませんでした。

  • 特定の段階が関連する場合、または
  • 正しい構文でステージを使用する方法

このギャップを埋めるために、 LLMに各ビューステージに関する情報を提供したいと考えました。そのために、ビューステージ(fiftyone.list_view_stages() でリストできます)をループ処理し、ドキュメントストリングを保存し、ドキュメントストリングのテキストを説明と入力/パラメータに分割するコードを作成しました。

しかし、すぐにコンテキストの長さという問題に遭遇しました。

OpenAI API経由で基本的なGPT-4モデルを使用した際に、トークンコンテキスト長が8192である問題が発生しました。これは、データセット自体に関する例や情報を追加する前の状況です。

OpenAIは32,768トークンコンテキストのGPT-4モデルを提供しており、理論的には使用できますが、大まかな計算では非常に高価になる可能性があります。32,000トークンコンテキストすべてを埋めようとすると、OpenAIの価格設定を考慮すると、クエリごとに約2ドルのコストがかかります。

代わりに、私たちのチームは使用していた方法論を再検討し、次の手順を実行しました。

  • GPT-3.5に切り替える
  • トークン数を最小限に抑える
  • 入力情報のより選択的な

GPT-3.5に切り替える

タダ飯なんてありません。少なくとも当初は、パフォーマンスがわずかに低下しました。しかし、プロジェクト全体を通して、タイムリーなエンジニアリングによって回復し、それをはるかに上回ることができました。私たちの場合、その努力はコスト削減に見合うものでした。しかし、他のケースではそうではないかもしれません。

トークン数を最小限に抑える

コンテキストの長さが制限要因になったため、 ChatGPT を使用して提案を最適化するという簡単な手法を採用しました。

ViewStageを1つずつ実行し、元の説明と入力リストを取得し、この情報をChatGPTに入力して、LLMにテキストのトークン数を最小化するよう指示します。ただし、すべての意味情報は保持されます。tiktokenを使用して元のバージョンと圧縮バージョンのトークンを計算することで、トークン数を約30%削減できました。

より選択的

モデルにコンテキストを提供することは有益ですが、タスクによっては、ある情報が他の情報よりも役立つ場合があります。モデルが2つのViewStageを含む単一のPythonクエリを生成するだけでよい場合、もう一方のViewStageが受け取る入力情報はあまり役に立たない可能性があります。

入力された自然言語クエリに基づいて関連情報を選択する方法が必要であることはわかっています。しかし、これは説明と入力パラメータの類似性検索を実行するほど単純ではありません。前者の言語は後者の言語と大きく異なることが多いためです。入力と情報の選択を結び付ける方法が必要です。

この接続は例であることが証明されました。

例を生成する

ChatGPT や他の LLMを使用したことがある方は、モデルに関連する例を提供するだけでもパフォーマンスが大幅に向上することをすでに直接体験したことがあるかもしれません。

まず、完全に合成された 10 個の例を提供し、これらの例をタスク ルールと入力候補の ViewStage の説明の下に追加し、最後にこれらの例を GPT-3.5 に渡します。

以下は、 A と B の形式の入力/出力ペアの例です。

A) 「ファイルパスは '/Users' で始まります」

B) `dataset.match(F("filepath").starts_with("/Users"))`


A) 「信頼度が0.95を超える予測」

B) `dataset.filter_labels("予測", F("信頼度") > 0.95)`

…………

わずか10 例でモデルの応答品質が大幅に向上したため、私たちのチームはこのプロセスを体系化することにしました。

  1. まず、ドキュメントを確認し、 ViewStagesコンポジションを通じて作成されたビューの例をすべて見つけました
  2. 次に、ViewStagesリストを見直し、使用構文を可能な限り網羅的に網羅するために例を追加しました。そのために、各パラメータまたはキーワードに少なくとも1つの例を追加し、モデルが従うべきパターンを提供しました。
  3. 使用構文を導入した後、例のフィールドとクラスの名前を変更しました。これにより、モデルがステージに関連する名前について誤った推測をすることがなくなります。例えば、 `match_labels()` のすべての例にたまたま `person` クラスが含まれているという理由だけで、モデルが `person` クラスと `match_labels()` メソッドを強く関連付けてしまうような事態は避けたいと考えています。

同様の例を選択してください

この例生成プロセスが終わる頃には、コンテキストの長さをはるかに超える数百の例が生成されていました。幸いなことに、これらの例には自然言語クエリ(入力として)が含まれていたため、ユーザーが入力した自然言語クエリと直接比較することができました。

比較のために、OpenAIのtext-embedding-ada–002モデルを用いて、これらのサンプルクエリの埋め込みを事前に計算しました。実行時には、同じモデルを用いてユーザーのクエリ埋め込みがモデル化され、自然言語クエリと最も類似した例(コサイン距離)が選択されました。当初はChromaDBを用いてインメモリベクターデータベースを構築していましたが、数十万や数百万ではなく、数百や数千のベクトルを扱うことを考えると、実際には完全ベクトル検索(および限定的な依存関係)に切り替える方が理にかなっていると判断しました。

これらの例と提案に関連するコンポーネントの管理がますます困難になったため、この時点でLangChainの提案モジュールの使用を開始しました。当初は類似性に基づくExampleSelectorを使用して最も関連性の高い例を選択できましたが、最終的には事前フィルタリングをより適切に制御できるように、カスタムExampleSelectorを作成する必要がありました。

適切な例をフィルタリングする

コンピュータービジョンのクエリ言語では、データセット内のサンプルのメディアタイプに応じて適切なクエリ構文が異なる場合があります。例えば、動画と画像を異なる方法で扱う必要がある場合があります。私たちは、一見矛盾する例を提供することでモデルを混乱させたり、メディアタイプに基づいて推論を強制することでタスクを複雑化させたりするのではなく、与えられたデータセットに対して文法的に正しい例のみを提供することにしました。ベクトル検索の文脈では、これはプレフィルタリングと呼ばれます

このアイデアは非常にうまく機能したため、最終的にデータセットの他の特徴にも同様の考慮を適用しました。場合によっては、違いは単に構文上のものです。例えば、タグをクエリする際の検出ラベルへのアクセス構文は、分類ラベルへのアクセス構文と異なります。また、より戦略的なフィルターもあります。モデルにクエリ言語の特定の特徴を知らせたくない場合もあります。

例えば、アクセスできない計算を使用するLLMの例を提供するつもりはありません。特定のデータセットに対してテキスト類似性インデックスが構築されていない場合、自然言語クエリに視覚的に最適な一致を検索するモデ​​ルの例を提供しても意味がありません。同様に、データセットに評価実行がない場合、クエリの真陽性と偽陽性によって、不正確な結果や無効な結果が生成されます。

完全な事前フィルタリング パイプラインの例は、GitHub リポジトリの view_stage_example_selector.py ファイルで確認できます。

例に基づいてコンテキスト情報を選択します。

特定の自然言語クエリに対して、 ExampleSelector を使用して例を選択し、コンテキストで提供する追加情報を決定します。

特に、これらの選択された例における各ViewStageの出現回数をカウントし、最も頻繁に出現する5つのViewStageを特定し、これらのViewStageの入力パラメータに関する説明と情報をプロンプトのコンテキストとして追加しました。これを行う理由は、あるステージが類似のクエリに頻繁に出現する場合、そのステージは(必ずしもそうとは限りませんが)そのクエリと関連している可能性が高いためです。

関連性がない場合、説明はモデルが関連性がないと判断するのに役立ちます。関連性がある場合、入力パラメータに関する情報はモデルが構文的に正しいViewStage操作を生成するのに役立ちます。

分割して征服する

VoxelGPT は自然言語クエリを使用して画像データセット (著者が提供する画像) を照会します。

これまで私たちは、できるだけ多くの関連情報を、そして関連情報だけを1つのプロンプトに圧縮することに重点を置いてきました。しかし、このアプローチは限界に達しました。

各データセットに独自のフィールドとクラス名があるという事実を考慮に入れなくても、潜在的なPython クエリ空間は大きすぎます。

前進するためには、問題をより小さな部分に分割する必要があります。思考連鎖ヒントや選択推論ヒントといった最近開発された手法に着想を得て、データセットビュー生成の問題を4つの異なる選択サブ問題に分割します。

  1. アルゴリズム
  2. アルゴリズムの実行
  3. 関連分野
  4. 関連クラス名

次に、これらの選択をリンクし、その出力を DatasetView 推論の最後のヒントでモデルに渡します。

これらのサブタスクのそれぞれにおいて、一貫性と簡潔さという同じ原則が適用されます。既存の例から自然言語クエリを可能な限り再利用するよう努めますが、選択された各タスクのすべての入力と出力のフォーマットを簡素化することに重点を置いています。あるリンクにとって最もシンプルな表現が、別のリンクにとって最もシンプルであるとは限りません。

アルゴリズム

FiftyOneでは、データセットの計算によって生成された情報は「runs」として保存されますこれには、データセット内の他の画像と比較した各画像のユニークさを測定する「uniqueness モデルがそのサンプルから学習する際に経験する難易度を定量化する「hardness などの計算が含まれます。また、各サンプルに関連付けられた埋め込みのベクトルインデックスの生成を含む「similarity」計算前述の評価計算も含まれます。

各計算は異なる種類の結果オブジェクトを生成し、それぞれに独自のAPIを持ちます。さらに、ViewStageとこれらの計算の間には1対1の対応関係はありません。

簡単な説明として、ユニークネスを例に挙げてみましょうユニークネスの計算結果は、各画像の浮動小数点値フィールド(デフォルトは「ユニークネス」)に保存されます。つまり状況によっては、ユニークネスで並べ替える必要がある場合があります。

 view = dataset.sort_by("uniqueness")

一意性が特定のしきい値を超えるサンプルを取得します。

 from fiftyone import ViewField as F view = dataset.match(F("uniqueness") > 0.8)

一意性フィールドを表示するだけでも次のようになります。

 view = dataset.select_fields("uniqueness")

この選択ステップでは、 LLMに、ユーザーの自然言語クエリに関連する可能性のある計算を予測するよう依頼します。このタスクの例を以下に示します。

 Query: "most unique images with a false positive" Algorithms used: ["uniqueness", "evaluation"]

アルゴリズムの実行

関連する可能性のある計算アルゴリズムが特定されたら、 LLM に各計算に最適な実行を選択させる必要があります。これは非常に重要です。なぜなら、一部の計算は同一のデータセットに対して異なる設定で複数回実行される可能性があり、ViewStage は適切な「実行」の下でのみ意味を成す可能性があるからです。

類似度計算が良い例です。2つのモデル(InceptionV3とCLIP)をデータに対してテストし、データセット上で各モデルのベクトル類似度インデックスを生成するとします。SortBySimilarityビューステージを使用する場合、どの画像がどの画像に最も類似しているかは埋め込みモデルに大きく依存するため、次の2つのクエリは異なる結果を生成します。

 ## query A: "show me the 10 most similar images to image 1 with CLIP" ## query B: "show me the 10 most similar images to image 1 with InceptionV3"

各計算には変更されたタスク ルールと例のセットが必要であるため、この実行選択プロセスは計算の種類ごとに個別に処理されます。

関連分野

この連鎖のリンクには、自然言語クエリには関連しているものの、計算実行には関連しないすべてのフィールド名を特定することが含まれます。例えば、予測を含むすべてのデータセットが、これらのラベルを「予測」という名前で保存しているわけではありません。個々のデータセット、アプリケーションによっては、予測は「pred」、「resnet」、「fine-tuned」、「predictions_05_16_2023」といった名前のフィールドに保存される場合もあれば、全く異なる名前のフィールドに保存される場合もあります。

このタスクには、クエリの例、データセット内のすべてのフィールドの名前とタイプ、および関連フィールドの名前が含まれています。

 Query: "Exclude model2 predictions from all samples" Available fields: "[id: string, filepath: string, tags: list, ground_truth: Detections, model1_predictions: Detections, model2_predictions: Detections, model3_predictions: Detections]" Required fields: "[model2_predictions]"

関連クラス名

分類や検出などのラベル分野では、自然言語クエリをPythonコードに変換するには、データセット内の実際のクラス名を使用する必要があります。これを実現するために、GPT-3.5に入力クエリ内のラベルクラスに対して固有表現抽出を実行させました

クエリ「少なくとも1つの牛の予測があり、馬は含まれていないサンプル」において、モデルの役割は「馬」と「牛」を識別することです。識別されたこれらの名前は、前のステップで選択したラベルフィールドのクラス名と比較されます。比較では、まず大文字と小文字を区別し、次に大文字と小文字を区別しないという処理が行われます。

データセット内の名前付きエンティティとクラス名の間に一致が見つからない場合は、セマンティックマッチングに戻ります: 「 people」→「person」、「table」→「dining table」、および「animal」→[「cat」、「dog」、「horse」、…]。

一致するものが見つからない場合は、一致クラスの名前を使用して、最終推論ステップに渡されるクエリを更新します。

 query: "20 random images with a table" ## becomes: query: "20 random images with a dining table"

ViewStage推論

これらすべての選択が行われると、類似の例、関連する説明、および関連するデータセット情報 (選択されたアルゴリズムの実行、フィールド、クラス) が、(変更された可能性のある) クエリとともにモデルに渡されます。

当初提案されていたように、 dataset.view1().view2()...viewn()という形式でコードを返すようモデルに指示する代わりに、データセット部分の検索を停止し、ViewStages をリストとして返すようにモデルに指示しました。当時、このアプローチが実際にパフォーマンスを向上させたことに驚きました今にして思えば、この配置はタスクを細分化すればするほど LLM のパフォーマンスが向上するという考えと一致しています。

実用的な応用

LLM技術ベースにしたプログラムを作るのはクールですが、同じカーネルをLLM対応アプリケーションに変えるのはさらにクールです。このアプリケーションの開発方法の概要を以下に示します

ユニットテスト

当我们将其从原理验证转变为稳健的工程系统时,我们使用单元测试来对管道进行压力测试并确定薄弱环节。链中链接的模块化特征意味着,每个步骤都可以单独进行单元测试、验证和迭代,而无需运行整个链。

这样的技术会导致更快的改进,因为一个提示工程团队中的不同个人或团队可以并行处理链中的不同环节。此外,它还降低了成本,因为理论上,您只需要运行LLM推理的单个步骤即可优化链中的单个环节。

评估LLM生成的代码

我们使用Python的eval()函数将GPT-3.5的响应转换为DatasetView。然后,我们设置FiftyOne应用程序会话的状态以显示视图。

输入验证

垃圾输入→垃圾输出。为了避免这种情况,我们运行验证以确保用户的自然语言查询是合理的。

首先,我们使用OpenAI的审核端点。然后,我们将任何提示分类为以下四种情况之一:

1 .明智而完整:提示可以合理地翻译成用于查询数据集的Python代码。

All images with dog detections (检测到狗的所有图像)。

2 .明智不完整:提示是合理的,但如果没有其他信息,就无法转换为DatasetView。例如,如果我们有两个模型对我们的数据进行了预测,那么以下仅引用“my model 我的模型 ”的提示是不够的:

Retrieve my model's incorrect predictions (检索我的模型中的错误预测)。

3 .超出范围:我们正在构建一个应用程序,将查询的视图生成为计算机视觉数据集。虽然底层GPT-3.5模型是通用LLM,但我们的应用程序不应变成一个数据集附近断开连接的ChatGPT会话。以下提示应该被取消:

Explain quantum computing like I'm five (像我是五岁孩子一样解释量子计算)。

4 .不明智:给定一个随机字符串,尝试生成数据集的视图是没有意义的——从哪里开始?!

Azlsakjdbiayervbg

在尝试将用户的输入查询转换为一系列视图阶段之前,我们将输入与验证说明和示例一起传递到模型中。根据响应,我们要么提示用户提供更多信息或更合理的查询,要么继续数据集视图生成管道。

要約

VoxelGPT正在运行(视频由作者提供)

一个简单的想法导致产生了一个疯狂的想法,而这段旅程将这个疯狂的想法带到了生活中。凭借提示工程、一些真正的软件工程技术和一系列的技术黑魔法,我们的小团队创建了一个LLM驱动的应用程序,将自然语言查询转换为计算机视觉数据集的过滤视图。

要点很简单:定义任务,用规则指导,限制范围,简化,选择统一性,分解问题,并保持相关性。

当我们把所有的部分放在一起时,它看起来是这样的:

  1. 验证查询
  2. 查找类似的示例
  3. 检索相关文档
  4. 识别潜在的算法/计算
  5. 选择最有可能运行的算法
  6. 确定在查询中访问/使用哪些字段(属性)
  7. 推断每个标签字段的类名
  8. 生成用于查询的视图阶段列表
  9. 组合视图阶段并将筛选后的视图返回到数据集中
  10. 成功

需要说明的是, VoxelGPT远非一款完美的应用程序,但这从来都不是目标。每一步都有改进的空间,更不用说更多的例子了!还可以将此作为构建计算机视觉任务的AutoGPT风格委托器的基础来使用。

最后,欢迎对VoxelGPT提供您的任何贡献。它是免费和开源的!

翻訳者紹介

Zhu Xianzong 氏は、51CTO コミュニティ エディター、51CTO 専門ブロガー兼講師、維坊の大学のコンピューター教師、そしてフリー プログラミング コミュニティのベテランです。

原文标题: How I Turned ChatGPT into an SQL-Like Translator for Image and Video Datasets ,作者:Jacob Marks