すべてのプロダクト
Search
ドキュメントセンター

Hologres:自動運転のための視覚データ分析システムの構築

最終更新日:Oct 14, 2025

自動運転 (AD) システムにおいて、車両画像分析は環境認識モジュールの中核コンポーネントです。車両カメラからの視覚情報をリアルタイムで解析し、システムが周囲の状況を正確に理解して意思決定できるようにします。このトピックでは、BDD 自動運転データセットを使用して AD シナリオを実証します。このデータセットには、さまざまな運転エリア、地理、環境、気象条件など、多様なシナリオをカバーする 100,000 枚の画像が含まれています。これらの画像を分析・検索することで、このトピックではフルスタックの技術ソリューションを実証します。このソリューションには、運転軌跡分析、環境認識の最適化、歩行者および車両検出精度の向上が含まれます。その目的は、複雑な交通シナリオにおけるシステムの適応性、安全性、ユーザーエクスペリエンスを向上させることです。

コア機能

このトピックでは、画像処理とマルチモーダル検索分析に焦点を当てており、これには以下の Hologres のコア機能が含まれます。

  • オブジェクトテーブル: PDF、画像、PPT ファイルなどの非構造化データを、Object Storage Service (OSS) から直接、表形式で読み取ります。

  • AI 関数: Hologres で標準 SQL を使用して、AI サービスのために組み込みの LLM を自動的に呼び出す関数を呼び出します。

    • データ変換: Embed および Chunk オペレーターを提供します。非構造化データを構造化データに変換して保存し、外部アルゴリズムなしで自動データ埋め込みを可能にします。

    • データ取得と分析: ai_genai_summarize などのオペレーターを提供します。標準 SQL を使用して LLM の推論、要約、翻訳を行います。

  • 動的テーブル: 増分更新モードをサポートし、非構造化データを自動的に処理します。このモードでは増分データのみを処理するため、冗長な計算とリソース消費が削減されます。

  • ベクトル検索: 標準 SQL を使用したベクトル検索をサポートし、非構造化データに対する類似検索やシーン認識を行います。同じクエリ内でベクトル検索とスカラー検索を自由に組み合わせることができます。

  • 全文検索: 転置インデックスとトークン化を使用して、非構造化データを効率的に検索します。キーワード一致やフレーズ検索などの柔軟な検索方法をサポートし、多目的なデータ取得を実現します。

メリット

Hologres で画像検索にこれらの機能を使用する主な利点は次のとおりです。

  • AI データ処理のライフサイクル全体をカバー: データ埋め込み、チャンキング、増分処理、取得、分析。標準的なビッグデータシステムと同じくらい簡単に AI アプリケーションを構築できます。

  • 標準 SQL で画像データを処理: 特別なプログラミング言語は不要です。SQL のみを使用して画像データを抽出し、変換します。

  • マルチモーダル検索のためのワンプラットフォーム: テキストから画像への検索と画像から画像への検索をサポートします。セマンティック理解は単純なキーワード一致を超えています。Hologres で直接マルチモーダル検索を実行できます。

  • より正確で、柔軟で、インテリジェントな検索: キーワード検索、セマンティック検索、マルチモーダル検索を組み合わせたハイブリッド検索パイプラインを簡単に構築でき、完全一致検索から複雑な意図認識まですべてのシナリオをカバーします。AI 関数を使用して、ユーザーの意図、セマンティックな関連付け、コンテキスト推論をより深く理解できます。

  • 安全なインプレース分析: データはデータベース内に留まるため、外部システムにエクスポートする必要がありません。これにより、さまざまな Hologres のセキュリティ機能とシームレスに統合され、データを効率的に保護します。

ワークフロー

このソリューションのワークフローは次のとおりです。

  1. データセットを準備します。

    画像データを OSS にアップロードします。

  2. 画像を処理します。

    オブジェクトテーブルを使用して画像メタデータを読み取ります。次に、増分更新を行う動的テーブルを作成してデータを埋め込みます。最後に、動的テーブルにベクトルインデックスを作成して、後続の検索パフォーマンスを最適化します。

  3. ai_embed オペレーターを使用して自然言語の質問を埋め込みます。次に、ベクトル検索を実行して上位 N 件の結果を取得します。

準備

  • データ準備

    このソリューションでは、ModelScope で公開されている BDD100K 自動運転画像データセットval.zip ファイルを使用します。このデータセットは、複数の車両からの実際の運転データをシミュレートします。

  • 環境準備

    1. V4.0 以降の Hologres インスタンスを購入し、データベースを作成します。

    2. AI リソースを購入します。

      この例では、1 ノードの large-96core-512GB-384GB インスタンスを例として使用します。

    3. モデルをデプロイします。このソリューションのモデルと割り当てられたリソースは次のとおりです。

      カテゴリ

      値の例

      モデル名

      image_embed

      モデルカテゴリ

      clip-ViT-B-32

      モデルの説明

      画像埋め込み

      レプリカあたりの vCPU

      7

      レプリカあたりのメモリ

      30 GB

      レプリカあたりの GPU

      1 カード (96 GB)

      レプリカ数

      1

      説明

      モデルリソースはデフォルトの割り当てを使用します。

手順

  1. 画像データをダウンロードして OSS にインポートします。

    1. BDD100K 自動運転画像データセット から val.zip ファイルをダウンロードします。

    2. OSS コンソールにログインします。バケットを作成し、ダウンロードした val.zip ファイルをバケットにアップロードします。ファイルのアップロードの詳細については、「単純なアップロード」をご参照ください。

      説明

      フォルダ名には小文字を使用してください。

  2. 権限を付与します。

    1. RAM コンソールにログインし、RAM ロールを作成して、必要な OSS 権限を付与します。

      AliyunOSSReadOnlyAccess 権限を付与することをお勧めします。

    2. RAM ロールにログイン権限と Hologres アクセス権限を追加します。

      • Alibaba Cloud アカウント

        RAM ロールの信頼ポリシーを変更します。次の主要なパラメーターを更新します。

        • Action: sts:AssumeRole に更新します。

        • Service: hologres.aliyuncs.com に更新します。

        {
          "Statement": [
            {
              "Action": "sts:AssumeRole",
              "Effect": "Allow",
              "Principal": {
                "RAM": [
                  "acs:ram::1866xxxx:root"
                ],
                "Service": [
                  "hologres.aliyuncs.com"
                ]
              }
            }
          ],
          "Version": "1"
        }
      • RAM ユーザー

        1. RAM ユーザーに権限を付与します。

          1. [権限管理] > [ポリシー] ページで、[ポリシーの作成] をクリックし、[スクリプトエディター] モードを選択してポリシーを作成します。詳細については、「カスタムポリシーの作成」をご参照ください。

            Hologres はこのポリシーを使用して、現在の RAM ユーザーが指定された RAM ロールを偽装する権限を持っているかどうかを判断します。ポリシードキュメントは次のとおりです。

            {
              "Version": "1",
              "Statement": [
                {
                  "Effect": "Allow",
                  "Action": "hologram:GrantAssumeRole",
                  "Resource": "<arn_account>"
                }
              ]
            }
          2. [ID 管理] > [ユーザー] ページで、対象の RAM ユーザーの [操作] 列にある [権限の追加] をクリックして、作成した権限ポリシーを付与します。詳細については、「RAM ユーザーへの権限付与」をご参照ください。

        2. 作成した RAM ロールに権限を付与します。

          RAM ロールの信頼ポリシーを変更します。更新する主要なパラメーターは次のとおりです。

          • Action: sts:AssumeRole に更新します。

          • Service: hologres.aliyuncs.com に更新します。

          {
            "Statement": [
              {
                "Action": "sts:AssumeRole",
                "Effect": "Allow",
                "Principal": {
                  "RAM": [
                    "acs:ram::1866xxxx:root"
                  ],
                  "Service": [
                    "hologres.aliyuncs.com"
                  ]
                }
              }
            ],
            "Version": "1"
          }
  3. 画像を埋め込みます。

    オブジェクトテーブルと動的テーブルを作成して、画像メタデータを読み取り、画像を埋め込みます。これを効率化するために、Hologres はロジックをストアドプロシージャにカプセル化します。詳細については、「付録: ストアドプロシージャの定義」をご参照ください。このストアドプロシージャは、次の機能を提供します。

    • 画像メタデータを読み取るためのオブジェクトテーブルを作成します。

    • 処理されたデータを保存するために、増分更新を行う動的テーブルである結果テーブルを作成します。ベクトルインデックスも作成されます。動的テーブルは手動で更新する必要があります。

    • 動的テーブルの更新中に、ai_embed オペレーターを使用して画像を埋め込みます。

    ストアドプロシージャは次のように使用されます。

    -- オブジェクトテーブルと動的テーブルを作成し、動的テーブルを使用して画像を埋め込むストアドプロシージャ
    CALL create_image_table_from_oss(
        oss_path => 'oss://xxxx/bdd100k/val/images',
        oss_endpoint => 'oss-ap-southeast-1-internal.aliyuncs.com',
        oss_role_arn => 'acs:ram::1xxxx:role/xxxx',
        image_table => 'public.dt_image_bdd100k',
        embedding_model =>'image_embed'
    );
  4. 結果テーブルを更新します。

    前のステップで作成したオブジェクトテーブルと動的テーブルは、データ変換を完了するために手動で更新する必要があります。このステップはストアドプロシージャにカプセル化されています。詳細については、「付録: ストアドプロシージャの定義」をご参照ください。このストアドプロシージャは、次の機能を提供します。

    • オブジェクトテーブルを一度更新して、画像メタデータを取得します。

    • 動的テーブルを一度更新して、画像を埋め込みます。

    ストアドプロシージャは次のように使用されます。

    -- 動的テーブルを更新して画像を埋め込む
    CALL refresh_image_table(
        image_table => 'public.dt_image_bdd100k'
    );
    
  5. 画像を検索します。

    画像データが処理された後、ベクトル検索と AI 関数を使用して画像を検索できます。

    テキストから画像への検索

    clip-ViT-B-32 モデルをテキストから画像への検索に使用する場合、クエリには英語を使用してください。クエリが中国語の場合は、LLM に切り替える必要があります。次の SQL 文は、テキストから画像への検索の例です。

    -- テキストから画像への検索
    SELECT
        object_uri,
        approx_cosine_distance (embedding_vector, ai_embed ('image_embed', 'a red car in the rain')) AS score
    FROM
        public.dt_image_bdd100k
    ORDER BY
        score DESC
    LIMIT 1;
    
                                object_uri                         |  score   
    ---------------------------------------------------------------+-------
     oss://****/bd****k/val/images/b836b14a-fb13****.jpg| 0.322337151
    (5 rows)

    OSS で見つかった上位の結果は次のとおりです。

    image

    画像から画像への検索

    次の SQL 文は、画像による検索の例です。

    -- 画像で検索
    SELECT
        object_uri,
        approx_cosine_distance (embedding_vector, ai_embed ('image_embed', to_file ('oss://xxxx/val/images/b9b53753-91a5d5f8.jpg', 'oss-cn-hangzhou-internal.aliyuncs.com', 'acs:ram::18xxx:role/xxx'))) AS score
    FROM
        public.dt_image_bdd100k
    WHERE
        object_uri <> 'oss://hm-**-hangzhou/bd****k/val/images/b9b53753-91a5****.jpg' -- 画像自体を除外
    ORDER BY
        score DESC
    LIMIT 1;
    
                              object_uri                           |  score   
    ---------------------------------------------------------------+------
     oss://****/bd****k/val/images/c0e9b7c4-cd8b****.jpg | 0.918008327
    

    取得された画像は OSS で見つかります。クエリ画像と上位の結果を以下に示します。

    image

付録: ストアドプロシージャの定義

  • オブジェクトテーブルと動的テーブルの作成

    -- デフォルトでは、クエリは最大 200 行を返します。より多くのデータを返すには、LIMIT 句を変更します。最大 10,000 行または 20 MB のデータを表示できます。
    CREATE OR REPLACE PROCEDURE create_image_table_from_oss(
        oss_path TEXT,
        oss_endpoint TEXT,
        oss_role_arn TEXT,
        image_table TEXT,
        embedding_model TEXT DEFAULT NULL,
        overwrite BOOLEAN DEFAULT FALSE
    )
    AS $$
    DECLARE
        image_schema_name TEXT;
        image_table_name TEXT;
        obj_table_name TEXT;
        full_image_table_ident TEXT;
        full_obj_ident TEXT;
        embed_expr TEXT;
        create_sql TEXT;
        embedding_dims INT;
    BEGIN
        -- 1. スキーマ名とテーブル名を分割します。
        IF position('.' in image_table) > 0 THEN
            image_schema_name := split_part(image_table, '.', 1);
            image_table_name  := split_part(image_table, '.', 2);
        ELSE
            image_schema_name := 'public';
            image_table_name  := image_table;
        END IF;
    
        obj_table_name := image_table_name || '_obj_table';
    
        full_image_table_ident := format('%I.%I', image_schema_name, image_table_name);
        full_obj_ident    := format('%I.%I', image_schema_name, obj_table_name);
        
        -- 2. 上書きするには、まずテーブルとインデックスを削除します。
        IF overwrite THEN
            DECLARE
                dyn_table_exists BOOLEAN;
                rec RECORD;
            BEGIN
                -- 動的テーブルが存在するかどうかを確認します。
                SELECT EXISTS (
                    SELECT 1
                    FROM pg_class c
                    JOIN pg_namespace n ON n.oid = c.relnamespace
                    WHERE c.relname = image_table_name
                    AND n.nspname = image_schema_name
                )
                INTO dyn_table_exists;
    
                IF dyn_table_exists THEN
                    -- 2.1 動的テーブルの自動更新を無効にします。
                    -- RAISE NOTICE 'Disabling auto refresh for %', full_image_table_ident;
                    -- EXECUTE format('ALTER TABLE IF EXISTS %s SET (auto_refresh_enable=false)', full_image_table_ident);
    
                    -- 2.2 実行中の更新タスクを見つけてキャンセルします。
                    FOR rec IN
                        EXECUTE format(
                            $f$
                            SELECT query_job_id
                                FROM hologres.hg_dynamic_table_refresh_log(%L)
                                WHERE status = 'RUNNING';
                            $f$,
                            image_table
                        )
                    LOOP
                        RAISE NOTICE 'Found running refresh job: %', rec.query_job_id;
                        IF hologres.hg_internal_cancel_query_job(rec.query_job_id::bigint) THEN
                            RAISE NOTICE 'Cancel job % succeeded.', rec.query_job_id;
                        ELSE
                            RAISE WARNING 'Cancel job % failed.', rec.query_job_id;
                        END IF;
                    END LOOP;
    
                    -- 2.3 動的テーブルを削除します。
                    EXECUTE format('DROP TABLE IF EXISTS %s;', full_image_table_ident);
                ELSE
                    RAISE NOTICE 'Dynamic table % does not exist, skip cancel job and drop.', full_image_table_ident;
                END IF;
    
                -- 2.4 いずれの場合も、オブジェクトテーブルを削除する必要があります。
                EXECUTE format('DROP OBJECT TABLE IF EXISTS %s;', full_obj_ident);
            END;
        END IF;
    
        -- 3. オブジェクトテーブルを作成します。
        RAISE NOTICE 'Create object table: %', obj_table_name;
        EXECUTE format(
            $f$
            CREATE OBJECT TABLE %s
            WITH (
                path = %L,
                oss_endpoint = %L,
                role_arn = %L
            );
            $f$,
            full_obj_ident,
            oss_path,
            oss_endpoint,
            oss_role_arn
        );
    
        COMMIT;
    
        -- 4. オブジェクトテーブルを更新します。
        RAISE NOTICE 'Refresh object table: %', obj_table_name;
        EXECUTE format('REFRESH OBJECT TABLE %s;', full_obj_ident);
    
        COMMIT;
    
        -- 5. 埋め込みモデルを選択します。
        IF embedding_model IS NULL OR length(trim(embedding_model)) = 0 THEN
            embed_expr := 'ai_embed(file)';
    
            EXECUTE 'SELECT array_length(ai_embed(''dummy''), 1)'
            INTO embedding_dims;
        ELSE
            embed_expr := format('ai_embed(%L, file)', embedding_model);
    
            EXECUTE format(
                'SELECT array_length(ai_embed(%L, ''dummy''), 1)',
                embedding_model
            )
            INTO embedding_dims;
        END IF;
    
        RAISE NOTICE 'embedding dimension is: %', embedding_dims;
    
        -- 6. RAG 出力用の動的テーブルを作成します。
        RAISE NOTICE 'create dynamic table: %', image_table_name;
        EXECUTE format(
            $f$
            CREATE DYNAMIC TABLE %s(
                CHECK(array_ndims(embedding_vector) = 1 AND array_length(embedding_vector, 1) = %s)
            )
            WITH (
                vectors = '{
                    "embedding_vector": {
                        "algorithm": "HGraph",
                        "distance_method": "Cosine",
                        "builder_params": {
                        "base_quantization_type": "sq8_uniform",
                        "max_degree": 64,
                        "ef_construction": 400,
                        "precise_quantization_type": "fp32",
                        "use_reorder": true
                        }
                    }
                }',
                auto_refresh_mode = 'incremental',
                freshness = '5 minutes',
                auto_refresh_enable = 'false'
            ) AS
            SELECT
                object_uri,
                etag,
                %s AS embedding_vector
            FROM %s;
            $f$,
            full_image_table_ident,
            embedding_dims,
            embed_expr,
            obj_table_name
        );
    
        COMMIT;
    
        RAISE NOTICE '';
        RAISE NOTICE 'Create image table success: %', image_table;
        RAISE NOTICE '    Vector index is: %.embedding_vector', image_table;
    END;
    $$ LANGUAGE plpgsql;
    
    
    
    
  • オブジェクトテーブルと動的テーブル

    -- 動的テーブルを更新して画像を埋め込みます
    CREATE OR REPLACE PROCEDURE refresh_image_table(
        image_table TEXT
    )
    AS $$
    DECLARE
        image_schema_name TEXT;
        image_table_name   TEXT;
        obj_table_name TEXT;
        full_image_table_ident TEXT;
        full_obj_ident    TEXT;
    BEGIN
        -- 1. スキーマとテーブル名を解析します。
        IF position('.' in image_table) > 0 THEN
            image_schema_name := split_part(image_table, '.', 1);
            image_table_name  := split_part(image_table, '.', 2);
        ELSE
            image_schema_name := 'public';
            image_table_name  := image_table;
        END IF;
    
        obj_table_name := image_table_name || '_obj_table';
    
        full_image_table_ident := format('%I.%I', image_schema_name, image_table_name);
        full_obj_ident    := format('%I.%I', image_schema_name, obj_table_name);
    
        -- 2. オブジェクトテーブルを更新します。
        RAISE NOTICE 'Refreshing Object Table: %', obj_table_name;
        EXECUTE format('REFRESH OBJECT TABLE %s;', full_obj_ident);
    
        -- 3. 動的テーブルを更新します。
        RAISE NOTICE 'Refreshing Dynamic Table: %', image_table_name;
        EXECUTE format('REFRESH TABLE %s;', full_image_table_ident);
    
        RAISE NOTICE 'Refresh image table complete: %', image_table;
    END;
    $$ LANGUAGE plpgsql;
  • オブジェクトテーブルと動的テーブルの削除

    CREATE OR REPLACE PROCEDURE drop_image_table(
        image_table TEXT
    )
    AS $$
    DECLARE
        image_schema_name TEXT;
        image_table_name   TEXT;
        obj_table_name TEXT;
        full_image_table_ident TEXT;
        full_obj_ident    TEXT;
        rec RECORD;
    BEGIN
        -- 1. スキーマとテーブル名を解析します。
        IF position('.' in image_table) > 0 THEN
            image_schema_name := split_part(image_table, '.', 1);
            image_table_name   := split_part(image_table, '.', 2);
        ELSE
            image_schema_name := 'public';
            image_table_name   := image_table;
        END IF;
    
        obj_table_name := image_table_name || '_obj_table';
    
        full_image_table_ident := format('%I.%I', image_schema_name, image_table_name);
        full_obj_ident    := format('%I.%I', image_schema_name, obj_table_name);
    
        -- 2. テーブルを削除します。
        -- 2.1 動的テーブルの自動更新を無効にします。
        -- RAISE NOTICE 'Disabling auto refresh for %', full_image_table_ident;
        -- EXECUTE format('ALTER TABLE IF EXISTS %s SET (auto_refresh_enable=false)', full_image_table_ident);
    
        -- 2.2 実行中の更新タスクを見つけてキャンセルします。
        FOR rec IN
            EXECUTE format(
                $f$
                SELECT query_job_id
                    FROM hologres.hg_dynamic_table_refresh_log(%L)
                    WHERE status = 'RUNNING';
                $f$,
                image_table
            )
        LOOP
            RAISE NOTICE 'Found running refresh job: %', rec.query_job_id;
            IF hologres.hg_internal_cancel_query_job(rec.query_job_id::bigint) THEN
                RAISE NOTICE 'Cancel job % succeeded.', rec.query_job_id;
            ELSE
                RAISE WARNING 'Cancel job % failed.', rec.query_job_id;
            END IF;
        END LOOP;
    
        -- 2.3 動的テーブルを削除します。
        RAISE NOTICE 'Dropping Dynamic Table: %', image_table_name;
        EXECUTE format('DROP TABLE IF EXISTS %s;', full_image_table_ident);
    
        -- 2.4 オブジェクトテーブルを削除します。
        RAISE NOTICE 'Dropping Object Table: %', obj_table_name;
        EXECUTE format('DROP OBJECT TABLE IF EXISTS %s;', full_obj_ident);
    
        RAISE NOTICE 'Drop image table complete: %', image_table;
    END;
    $$ LANGUAGE plpgsql;