You need to enable JavaScript to run this app.
Lake AI Service

Lake AI Service

Copy page
Download PDF
Hands-on practice
Hands-on practice: Image data ingestion and processing
Copy page
Download PDF
Hands-on practice: Image data ingestion and processing

Practice objectives

By following the steps described in this document, you can experience the complete end-to-end process from ingesting image data into the lake, processing image datasets, to text-based image search and image-based image search. Through this process, you will acquire the following skills:

  • You will gain a clearer understanding of the core logic of image processing scenarios based on LAS, master the technical implementation details and operational steps, and further enhance your ability to break down requirements and design solutions for real-world business scenarios.
  • You will learn about the data processing operators of LAS (Lakehouse Analytics Service)—the invocation process for online and offline operators.
  • You will learn the basic workflow for using LAS key features, including: datasets (creating datasets, reading and writing data), queue resources, and development machines.

  • Image retrieval system: Suitable for building large-scale image retrieval (image-to-image search) systems. Image vectorization enables fast and accurate similar image search and product recommendation.
  • Cross-modal retrieval: Suitable for cross-modal retrieval applications such as image-text matching, image-to-text search, and text-to-image search. The generated image vectors can be compared with text vectors in the same semantic space for similarity calculation.
  • Content review and clustering: Suitable for scenarios such as image deduplication, similar content clustering, and copyright image recognition. Vector similarity enables efficient analysis of massive image datasets.

Preparations

Prepare experimental data

This practice uses the following 1,000 animal images to test the full process of image data ingestion, processing, and value-added processing. You can click to download this sample data or prepare your own test images.

pic_search_1000_images(1).zip
Unknown size

warning

  • The sample data above is drawn from the Animal Image Dataset published by Sourav Banerjee on Kaggle. For more details, visit: Kaggle data source.
  • When using your own image dataset, pay attention to the format and size details of the images, and adjust the image data parameters as needed during subsequent experiments.

TOS

You need to enable Volcano Engine Object Storage TOS and create a TOS bucket to store the test image data during this experiment.

Preparations

Key points

Reference documentation

Configuration example

Create Bucket

  • All operations in this practice use resources in the North China 2 (Beijing) region. Therefore, when creating a Bucket:
    • You need to create a Bucket in the Beijing region.
    • Other parameters can remain at their default settings.

Create a bucket

Bucket name: las-doctest
Image

Access control (IAM)

You need to log in to the Access Control (IAM) console and prepare an AK and SK for subsequent API access to TOS and LAS.

Preparation

Key points

Reference documentation

Configuration example

Obtain AK and SK

To ensure the security of access to TOS/LAS services, you must provide valid access keys (AK/SK) for subsequent authentication.

  • The access key of the primary account has extensive permissions. You can create a sub-account with TOS and LAS operation permissions on the Identity and Access Management (IAM) page, enable access keys for the sub-account, and then use the sub-account's access keys.
  • Access key information is sensitive, and leakage may lead to data insecurity. Therefore, it is recommended to configure the AK and SK information as environment variables in subsequent development environments.

View AKSK information

Image

LAS

You need to enable the LAS service and create the queue resources and development machine environment required for this experiment.

Preparation

Key points

Reference documentation

Configuration example

Queue resources

  • If you have already created LAS queue resources, you can use the existing queue resources.
  • If you have not previously created queue resources, you need to create a queue resource. When creating queue resources for practice:
    • It is recommended to use resources in the North China 2 (Beijing) region.
    • For experimental practice, you can select resources with the minimum CPU specification. There is no need to enable GPU resources.
    • Other parameters can remain at their default settings.

Queue management

See key points

LAS API Key

Before calling LAS online operators, you need to generate an API Key for authentication when invoking operators.

  • If you already have a LAS API Key, you can use the existing LAS API Key. Otherwise, you need to create a LAS API Key.
  • Because API Key information is sensitive, leaking the API Key may result in your model usage being consumed by others, causing certain losses. Therefore, after obtaining the API Key, it is recommended to configure the API Key as an environment variable in subsequent development environments to facilitate safe and proper use of the API Key.

warning

LAS provides you with two types of data processing operators: offline and online. Only online operators require authentication using the LAS API Key.

  • Online operators are invoked directly by calling the operator API.
  • Offline operators use the Daft engine for operator invocation. LAS provides the VeDaft engine, which integrates the SDK for offline operator invocation and enables more efficient scheduling and execution of batch data processing tasks.

Obtain and configure the API Key

See key points

Development machine

Before calling LAS offline operators, you need to prepare the development environment for invoking offline operators.

  • LAS provides development machines with pre-installed development environment images, such as the veDaft engine. You can directly create an LAS development machine, and after creation, remotely log in to the development machine to develop and debug offline operator data processing tasks. When creating a development machine:
    • Queue: Select the prepared queue resource mentioned above.
    • Image: It is recommended to select the latest version of the built-in ve-daft image. The version used in this example is: 0.7.2.post4-py3.11-ubuntu24.04.
    • When creating the development machine, it is recommended to configure the above TOS AK/SK, Endpoint, Region, and LAS API Key as environment variables. If you did not configure them when creating the development machine, you can also configure them after logging in to the development machine.
    • The SSH public key can be generated locally using the ssh-keygen -t rsa command. After configuring it on the development machine, you can directly obtain the remote login command from the development machine page.
    • Keep the other parameters at their default values.
  • To develop and debug offline operators in your own environment, you need to deploy the Daft engine in your environment first. For details, see: Quick start.

Image

Practice steps

Step 1: Create an image dataset

warning

The main purpose of this step is to upload images to a TOS Bucket and create an image dataset in LAS. Afterwards, you can directly preview and process images in the LAS image dataset.

Upload images to TOS bucket

After logging in to the TOS product console, upload the images to be processed to the TOS bucket.

Procedure

Key points

Reference documentation

Configuration example

Upload images

Upload the images to be processed to the prepared TOS Bucket. You can create folders as needed and upload images to the folders.
Image
After the upload is complete, you can click "Copy Path" to record the TOS path where the current image data is located.

上传文件

The TOS path is: tos://las-doctest/images/animals/pic_search_1000_images/

Create an image dataset

Log in to the LAS console, click Datasets > Common dataset in the left navigation bar, then click "Create dataset" on the dataset page. Refer to the following configuration points to set the dataset parameters. After completing the configuration, click "Create" to finish creating the image dataset.

Procedure

Key points

Reference documentation

Configuration example

Create an image dataset

Image

  • New dataset name: Customize the dataset name.
  • Data source: Select TOS and set the TOS path to the path where the images to be processed were uploaded in the previous step.
  • Dataset formats: Select "image".

Create a dataset

  • Dataset name: las_dataset_image.
  • Data source TOS path: tos://las-doctest/images/animals/pic_search_1000_images/

Preview image data

After the dataset is created, you can view the basic information of the dataset on the dataset details page. For image datasets, previewing the first ten images is supported.
Image

Step summary/Additional knowledge

  • Common dataset operations:
    • After the LAS dataset is created, you can manage permissions for the dataset and authorize it for use by other sub-users under the same primary account.
    • You can also share the dataset across primary accounts. After sharing, the corresponding primary or sub-account will have the permissions granted for dataset operations. For details, see Dataset sharing.
  • At this point, although we have an image dataset, it is not much different from simply storing images in TOS. Demonstrating the advantages of datasets—enabling better, faster, and more intelligent consumption of image data—is our goal. You can continue to refer to the following content for operations such as ingesting image data into the lake and data processing.

Step 2: Ingest image data into the lake

warning

The main purpose of this practice step is to convert the image dataset into a Lance dataset, enabling image data ingestion into the data lake, which facilitates subsequent operations such as image content understanding, vectorization, and other data processing tasks.

Create the TOS path for the Lance dataset

You need to log in to the TOS console and prepare a TOS path for storing the converted Lance dataset data. The TOS path for the Lance dataset in this example is: tos://las-doctest/image2lance/.

Configure environment variables

This step is mainly performed on the development machine using VeDaft to call the SDK for operations such as reading and writing the dataset. Since accessing the TOS Bucket is involved, it is recommended to configure some authentication parameters and fixed path parameters as environment variables in the development environment, making it easier to reference them in subsequent code execution.

  1. You can refer to the following content to prepare the environment variable configuration.

    # Region settings, in this example, the North China 2 - Beijing region is used.
    export REGION="cn-beijing"
    
    # Environment variables related to AK authentication
    # Authentication sk and ak for accessing TOS and LAS
    export LAS_TOS_SECRET_KEY="<your_sk>"
    export LAS_TOS_ACCESS_KEY="<your_ak>"
    
    # Environment variables related to TOS access
    # TOS access endpoint
    export LAS_TOS_ENDPOINT="https://tos-cn-beijing.ivolces.com"
    # TOS endpoint (for TOSConfig)
    export TOS_ENDPOINT="https://tos-cn-beijing.ivolces.com"
    
  2. On the development machine, run the source env.sh command to activate the environment variables.

Convert the image dataset to a Lance dataset

  1. Run the following Python script on the development machine to create a new Lance dataset and convert the image data into the Lance format of the Lance dataset, writing it into the new Lance dataset. The core sample code is as follows.
    # Please run the following code on the LAS development machine
    import os
    
    """
    Convert to Lance Dataset
    """
    import daft
    from daft.io import CreateLasDatasetOptions, IOConfig, LanceWriteOptions
    from daft.las.io import TOSConfig
    
    # You need to set the image dataset name and configure the TOS path for the new Lance dataset
    dataset_name = "las_dataset_image"
    lance_tos_dir = f"tos://las-doctest/image2lance/las_dataset_image_lance.lance"
    LANCE_DATASET_FORMAT = "lance"
    
    # Create the relevant configuration
    io_config = IOConfig(s3=TOSConfig.from_env().to_s3_config())
    write_options = LanceWriteOptions(io_config=io_config, uri=lance_tos_dir)
    create_ds_options = CreateLasDatasetOptions(
        nick_name="daft_test_lance_write",
        privacy="public",
        description="This is my dataset",
    )
    
    # Read the original data
    df = daft.read_las_dataset(name=dataset_name)
    
    Create here: The naming rule for the new Lance dataset is to use the image dataset name with the _lance suffix appended
    new_dataset_name = dataset_name + "_lance"
    df.write_las_dataset(
        name=new_dataset_name,
        format=LANCE_DATASET_FORMAT,
        write_options=write_options,
        create_ds_options=create_ds_options,
    )
    
    # Read the converted new dataset
    df = daft.read_las_dataset(name=new_dataset_name)
    print("\n\nnew dataset:")
    df.show()
    

You need to modify the following parameters.

  • dataset_name: Set as the name of the image dataset. In this example, it is las_dataset_image
  • lance_tos_dir: Set to the TOS path of the newly converted Lance dataset prepared in the previous steps.

Other parameters can remain as the sample values.

  1. After the script is executed, the page will display the details of the newly converted Lance dataset by reading them back. An example output is shown below.
new dataset:
ERROR:daft_local_execution.runtime_stats:RuntimeStatsManager finished with active nodes {0}
╭────────────────────────────────┬────────┬──────────╮
│ image                          ┆ size   ┆ num_rows │
│ ---                            ┆ ---    ┆ ---      │
│ String                         ┆ Int64  ┆ Int64    │
╞════════════════════════════════╪════════╪══════════╡
│ s3://las-doctest/images/anima… ┆ 15390  ┆ None     │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
│ s3://las-doctest/images/anima… ┆ 240478 ┆ None     │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
│ s3://las-doctest/images/anima… ┆ 15008  ┆ None     │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
│ s3://las-doctest/images/anima… ┆ 11645  ┆ None     │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
│ s3://las-doctest/images/anima… ┆ 9909   ┆ None     │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
│ s3://las-doctest/images/anima… ┆ 14252  ┆ None     │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
│ s3://las-doctest/images/anima… ┆ 3226   ┆ None     │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
│ s3://las-doctest/images/anima… ┆ 878304 ┆ None     │
╰────────────────────────────────┴────────┴──────────╯

(Showing first 8 rows)

The converted Lance dataset contains the fields "image", "size", and "num_rows". Specifically:

  • image field: The TOS path (in s3 format) of each image data in the current Lance dataset.
  • size field: The size of each image.

If an ERROR prompt appears in the output but the dataset data is returned normally, the ERROR prompt can be ignored.

View the Lance dataset

After completing the conversion to a Lance dataset, you can log in to the LAS console and view the newly created Lance dataset on the dataset list page.
Image

Step summary/Additional knowledge

  • Register metadata: Similar to the steps above, after converting to a Lance dataset, you can manage permissions for the dataset. In addition, you can register this dataset in the metadata (Catalog) of LAS. Afterwards, you can view the metadata details of the dataset in the LAS Catalog. When there are changes to the dataset fields, the dataset metadata in the Catalog will also be automatically refreshed in real time.

Step 3: Initial processing of image data

warning

The main purpose of this practice step is to perform simple processing on the images, writing the binary data of the images into the Lance dataset after ingestion, so that the image content can be previewed directly in the Lance dataset and to prepare for subsequent operations such as image content understanding and vectorization.

Configure environment variables

  1. You can refer to the following to prepare the environment variable configuration.
Region settings
This example uses the North China 2 (Beijing) region.
export REGION="cn-beijing"

# Authentication AK environment variables
Access authentication keys (SK and AK) for TOS and LAS
export LAS_TOS_SECRET_KEY="<your_sk>"
export LAS_TOS_ACCESS_KEY="<your_ak>"

# TOS access-related environment variables
# Access endpoints of TOS
export LAS_TOS_ENDPOINT="https://tos-cn-beijing.ivolces.com"
# TOS endpoints (for TOSConfig)
export TOS_ENDPOINT="https://tos-cn-beijing.ivolces.com"

# Fixed parameters of the dataset can also be set as environment variables
export DATASET_NAME="las_dataset_image_lance"

This step adds:

  • DATASET_NAME: Set as the name of the newly converted Lance dataset from the previous step for easy reference in subsequent task code.
  1. In the development machine environment, run the source env.sh command to activate the environment variables.

Insert image data

Run the following script on the development machine to convert the images to binary format and write them into the Lance dataset.

import os
# Import the values of the following parameters from environment variables
LAS_TOS_ACCESS_KEY = os.environ["LAS_TOS_ACCESS_KEY"] 
LAS_TOS_SECRET_KEY = os.environ["LAS_TOS_SECRET_KEY"] 
TOS_ENDPOINT = os.environ["TOS_ENDPOINT"] 
REGION = os.environ["REGION"]
dataset_name = os.environ["DATASET_NAME"]

import pyarrow as pa
import tos
from daft.io.lance import merge_columns
from daft.io import IOConfig
from daft.las.io import TOSConfig

# Read image data from tos path
def read_tos_path(path: str, tos_client: tos.TosClientV2):
    if (not path) or path.strip() == "":
        return None

    if path.startswith("tos://"):
        path = path[len("tos://") :]

    if path.startswith("s3://"):
        path = path[len("s3://") :]

    bucket, path = path.split("/", 1)
    obj = tos_client.get_object(bucket=bucket, key=path)
    return obj.read()

def get_create_assign_raw_image_func(input_col: str, output_col: str):
    def create_assign_raw_image(batch: pa.RecordBatch) -> pa.RecordBatch:
        paths = batch.column(input_col).to_pylist()
        tos_client = tos.TosClientV2(LAS_TOS_ACCESS_KEY, LAS_TOS_SECRET_KEY, TOS_ENDPOINT, REGION)

        image_data_list = []
        for path in paths:
            data = read_tos_path(path, tos_client)
            image_data_list.append(data)

        image_data_array = pa.array(image_data_list, type=pa.binary())
        new_batch = pa.RecordBatch.from_arrays([image_data_array], names=[output_col])

        Only return new columns
        return new_batch

    return create_assign_raw_image

print("正在将图片原始数据存入 lance 数据集中 ...")

Modify lance_tos_dir and the transform parameter in merge_columns in the following code
io_config = IOConfig(s3=TOSConfig.from_env().to_s3_config())
lance_tos_dir = f"tos://las-doctest/image2lance/{dataset_name}.lance"
merge_columns(
    uri=lance_tos_dir.replace("tos://", "s3://"),
    io_config=io_config,
    transform=get_create_assign_raw_image_func("image", "raw_image"),
)

print("图片原始数据已存入 lance 数据集")

You need to modify the following parameters in the sample code according to your actual situation:

  • lance_tos_dir: Modify the TOS path of the Lance dataset to your actual path.
  • transform in merge_columns: A function is called, and the input parameters "image" and "raw_image" can be modified as needed:
    • image: The TOS path field in the Lance dataset
    • raw_image: A custom new field name. After the image is processed into binary data, it will be written into this field.

To delete unnecessary fields or data from a dataset caused by accidental operations, refer to the following content: Reference: Common dataset operation examples.

View processing results

Read the dataset:

"""
read data
"""
import os
import daft
dataset_name = os.environ["DATASET_NAME"]
df = daft.read_las_dataset(name=dataset_name)
df.show()

Code output:

ERROR:daft_local_execution.runtime_stats:RuntimeStatsManager finished with active nodes {0}
╭────────────────────────────────┬────────┬──────────┬────────────────────────────────╮
│ image                          ┆ size   ┆ num_rows ┆ raw_image                      │
│ ---                            ┆ ---    ┆ ---      ┆ ---                            │
│ String                         ┆ Int64  ┆ Int64    ┆ Binary                         │
╞════════════════════════════════╪════════╪══════════╪════════════════════════════════╡
│ s3://las-doctest/images/anima… ┆ 15390  ┆ None     ┆ b"ÿØÿà�JFI… │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ s3://las-doctest/images/anima… ┆ 240478 ┆ None     ┆ b"ÿØÿà�JFI… │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ s3://las-doctest/images/anima… ┆ 15008  ┆ None     ┆ b"ÿØÿà�JFI… │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ s3://las-doctest/images/anima… ┆ 11645  ┆ None     ┆ b"ÿØÿà�JFI… │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ s3://las-doctest/images/anima… ┆ 9909   ┆ None     ┆ b"ÿØÿà�JFI… │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ s3://las-doctest/images/anima… ┆ 14252  ┆ None     ┆ b"ÿØÿà�JFI… │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ s3://las-doctest/images/anima… ┆ 3226   ┆ None     ┆ b"ÿØÿà�JFI… │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ s3://las-doctest/images/anima… ┆ 878304 ┆ None     ┆ b"ÿØÿà�JFI… │
╰────────────────────────────────┴────────┴──────────┴────────────────────────────────╯

(Showing first 8 rows)

Step summary / Expanded knowledge

  • For more common dataset operations, see Reference: Common dataset operation examples, for example, if unnecessary fields or data appear in the dataset due to mistaken operations, you can refer to this content for deletion.
  • Through the above steps, the creation of the image Lance dataset is complete, and the images in binary format have been inserted into the dataset. Currently, the dataset simply stores images. To better align with business scenarios and increase its value, consider adding more information. We will add more information to the dataset in the future.

Step 4: Value-added processing for the dataset

warning

The main purpose of this practice step is to invoke LAS data processing operators to enhance image data:

  • Invoke the image understanding operator: Use a large model to understand the content of the image, write the understood content into the Lance dataset, and facilitate subsequent application scenarios that consume image data, such as text-to-image search.
  • Invoke the multimodal vectorization operator: Use a large model to vectorize the image, write the vectorized result into the Lance dataset, and facilitate subsequent application scenarios that consume image data, such as image-to-image search.

Configure environment variables

  1. You can refer to the following to prepare the environment variable configuration.
# Region settings
This example uses the North China 2 (Beijing) region.
export REGION="cn-beijing"

# AK authentication-related environment variables
# Access the authentication SK and AK of TOS and LAS
export LAS_TOS_SECRET_KEY="<your_sk>"
export LAS_TOS_ACCESS_KEY="<your_ak>"
# LAS API Key required for invoking LAS operators using the online method (API)
export LAS_API_KEY="464812df-2dfb-41f6-********"

# TOS access-related environment variables
TOS's access endpoints
export LAS_TOS_ENDPOINT="https://tos-cn-beijing.ivolces.com"
TOS endpoint (for TOSConfig)
export TOS_ENDPOINT="https://tos-cn-beijing.ivolces.com"

# Fixed parameters of the dataset can also be set as environment variables
export DATASET_NAME="las_dataset_image_lance"
export TOS_LANCE_DIR="tos://las-doctest/image2lance/las_dataset_image_lance.lance"

Test configuration
# Sample image URL for testing
export TEST_IMAGE_URL="https://ark-project.tos-cn-beijing.volces.com/images/view.jpeg"

This step adds:

  • LAS_API_KEY: When invoking LAS operators online, LAS_API_KEY is required for authentication. You can set it to the actual value obtained in the above "Preparation" node.
  • TOS_LANCE_DIR: Set the fixed value of the TOS path for the Lance dataset as an environment variable to facilitate referencing in task code.
  • TEST_IMAGE_URL: A test image for subsequent operator capability testing. You can use the URL in the example directly or modify it to another test image URL.
  1. In the development machine environment, run the source env.sh command to activate the environment variables.

Image content understanding: multimodal deep thinking operator

You can use a test image URL to quickly experience the result of LAS's multimodal deep thinking operator for image content understanding. The following demonstrates invoking the 多模态深度思考(Doubao-seed-1.8) operator for a quick experience. Execute the following curl command on the development machine to quickly view an example result of LAS operator's image understanding processing.

curl --location "https://operator.las.cn-beijing.volces.com/api/v1/chat/completions" --header "Content-Type: application/json" --header "Authorization: Bearer $LAS_API_KEY" --data '{
    "messages": [
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {
                        "url": "https://ark-project.tos-cn-beijing.volces.com/images/view.jpeg"
                    }
                },
                {
                    "type": "text",
                    "text": "图片里面有什么"
                }
            ]
        }
    ],
    "model": "doubao-seed-1-8-251228"
}'

Return example:

{"model":"doubao-seed-1-8-251228","usage":{"prompt_tokens":270,"completion_tokens":521,"total_tokens":791,"prompt_tokens_details":{"cached_tokens":0,"provisioned_tokens":null},"completion_tokens_details":{"reasoning_tokens":354,"provisioned_tokens":null}},"created":1773200390,"id":"0217732003734693dfd182f******","choices":[{"finish_reason":"stop","index":0,"logprobs":null,"message":{"content":"这是一幅充满自然静谧感的户外场景:
- **前景**:开阔的深蓝色湖面水波轻漾,一艘亮橙色的单人皮划艇浮在水面,艇上坐着一人,正抬起黑色船桨,似乎正在划行,水面清晰倒映出皮划艇与人的身影。
- **中景**:湖对岸是一片茂密的深绿色针叶林,林间萦绕着淡淡的薄雾,给树林添了几分朦胧感。
- **背景**:树林后方是连绵巍峨的雪山,山体被冰雪覆盖,山峦硬朗的轮廓在光影下清晰可见,尽显雄伟壮阔。
- **天空**:上方是澄澈的淡蓝色天空,点缀着几缕轻薄的云丝,整体氛围开阔宁静,传递出户外自然的闲适与苍茫感。","reasoning_content":"用户现在需要描述这张图片里的内容,首先看整体:首先是前景,一片平静的深蓝色湖泊,水面上有一个橙色的皮划艇,艇上有一个人,正举着黑色的船桨,似乎在划行,水面有他和皮划艇的倒影。然后中间部分,湖泊对岸是茂密的深绿色针叶林,树林上方有淡淡的雾气,显得很静谧。背景是巍峨的雪山,山体覆盖着积雪,轮廓硬朗,在蓝天之下显得很壮阔。天空是浅蓝色,飘着几缕轻薄的白云,整体氛围宁静又开阔,有种户外自然的闲适感。现在把这些元素整理清楚,分层次描述。

首先看主体:
1. 水面与皮划艇:前景是开阔平静的深蓝色湖面,水面有轻微波纹,一艘亮橙色的单人皮划艇在湖面,艇上坐着一个人,正抬起黑色船桨,似乎在进行划行动作,水面倒映出皮划艇和人的身影。
2. 中景:湖的对岸是一片茂密的深色针叶林(看起来像冷杉、松树这类),林间有淡淡的薄雾,给树林蒙上了一层朦胧感。
3. 背景:树林后方是连绵巍峨的雪山,山体被冰雪覆盖,山峦的轮廓清晰,在光影下显现出岩石与积雪的质感,显得很雄伟。
4. 天空:上方是澄澈的淡蓝色天空,点缀着几缕轻薄的白色云丝,整体天气晴朗,让整个画面的氛围宁静又开阔,充满自然的静谧与壮阔感。

现在把这些组织成通顺的描述,让内容清晰有条理。","role":"assistant"}}],"object":"chat.completion"}

Image vectorization: multimodal vectorization operator

The following uses Image-text embedding (Doubao series models) as an example to demonstrate how to vectorize image and text content in batches. During processing, a new column will be added to the Lance dataset: image_embedding, which is used to store the vectorization results. After image vectorization, subsequent image search scenarios are supported.

Run the following script on the development machine.

#This code segment requires you to execute "source env.sh" first. The env.sh file is located in the "Configure environment variables" section.
# Import necessary libraries
import os

import daft
import lance
import pandas as pd
import pyarrow as pa
from daft import col
from daft.io import IOConfig
from daft.io.object_store_options import io_config_to_storage_options

from daft.las.functions.ark_llm.doubao_embedding_vision import DoubaoEmbeddingVision
from daft.las.functions.udf import las_udf
from daft.las.io import TOSConfig
from daft.las.infra.las_dataset import LasDatasetClient, LasDatasetConfig

# Get configuration from environment variables
TOS_LANCE_DIR = os.getenv("TOS_LANCE_DIR")  # Lance dataset path
DATASET_NAME = os.getenv("DATASET_NAME")    # Dataset namename

# Batch processing parameters
BATCH_SIZE  = int(os.getenv("BATCH_SIZE",  "10"))  # Maximum number of rows per operation
MAX_CYCLES  = int(os.getenv("MAX_CYCLES",  "5"))   # Maximum batch count

# Column name configuration
IMAGE_EMBEDDING_NEW_COLUMN = "image_embedding"    # New embedding column name
DOUBAO_LLM_COLUMN          = "doubao_llm_result"  # Doubao LLM result column name


# Set environment variables related to TOS object storage
os.environ["LAS_TOS_ACCESS_KEY"] = os.getenv("LAS_TOS_ACCESS_KEY")
os.environ["LAS_TOS_SECRET_KEY"] = os.getenv("LAS_TOS_SECRET_KEY")
os.environ["TOS_ENDPOINT"]       = os.getenv("LAS_TOS_ENDPOINT")

Configure IO settings for accessing TOS object storage
io_config = IOConfig(s3=TOSConfig.from_env().to_s3_config())

def update_image_embedding():
    # Convert TOS path to S3-compatible path
    lance_path = TOS_LANCE_DIR.replace("tos://", "s3://")

    Check whether the embedding column exists; if not, create it
    storage_options = io_config_to_storage_options(io_config, lance_path)
    lance_ds = lance.dataset(uri=lance_path, storage_options=storage_options)
    existing_columns = [field.name for field in lance_ds.schema]

    column_exists = IMAGE_EMBEDDING_NEW_COLUMN in existing_columns
    print(f"{IMAGE_EMBEDDING_NEW_COLUMN} 列存在: {column_exists}")

    if not column_exists:
        print(f"创建 {IMAGE_EMBEDDING_NEW_COLUMN} 列...")
        vec_type = pa.list_(pa.float64())

        @lance.batch_udf()
        def add_empty_column(batch):
            null_array = pa.array([None] * batch.num_rows, type=vec_type)
            return pa.RecordBatch.from_arrays([null_array], names=[IMAGE_EMBEDDING_NEW_COLUMN])

        lance_ds.add_columns(add_empty_column)
        print(f"成功创建 {IMAGE_EMBEDDING_NEW_COLUMN} 列")

    # Read the complete dataset and filter for rows to be processed
    df = daft.read_lance(lance_path, io_config=io_config)
    all_data = df.collect().to_pandas()

    if IMAGE_EMBEDDING_NEW_COLUMN in all_data.columns:
        pending_data = all_data[all_data[IMAGE_EMBEDDING_NEW_COLUMN].isna()].copy()
        pending_data = pending_data.reset_index(drop=True)
        print(f"跳过已有 embedding 的 {len(all_data) - len(pending_data)} 行")
    else:
        pending_data = all_data.copy()

    print(f"待处理图片总数: {len(pending_data)}")

    process_limit = MAX_CYCLES * BATCH_SIZE
    pending_data = pending_data.iloc[:process_limit].copy()
    print(f"本次实际处理: {len(pending_data)} 张图片")

    if pending_data.empty:
        print("所有图片已处理完成,无需继续")
        return

    pending_data[DOUBAO_LLM_COLUMN] = (
        pending_data[DOUBAO_LLM_COLUMN]
        .fillna("图片内容")
        .replace("", "图片内容")
    )

    # 2. Build Daft DataFrame and invoke operators to batch compute embedding
    pending_daft_df = daft.from_pandas(pending_data)

    pending_daft_df = pending_daft_df.with_column(
        IMAGE_EMBEDDING_NEW_COLUMN,
        las_udf(
            DoubaoEmbeddingVision,
            construct_args={
                "image_format": "jpeg",   # Adjust image format as needed
                "source_type":  "url",    The # image column stores URL
            },
        )(col("image"), col(DOUBAO_LLM_COLUMN)),  # image column + text column → multimodal joint vector
    )

    result_df = pending_daft_df.collect().to_pandas()
    # ------------------------------------------------------------------

    # Filter out rows where the operator call failed (returned None)
    valid_mask = result_df[IMAGE_EMBEDDING_NEW_COLUMN].notna()
    valid_df   = result_df[valid_mask].copy()
    print(f"成功生成 embedding: {len(valid_df)} 行,失败: {(~valid_mask).sum()} 行")

    if valid_df.empty:
        print("没有成功生成的 embedding,跳过更新")
        return

    # Update the Lance dataset (consistent with the original logic)
    try:
        lance_ds = lance.dataset(uri=lance_path, storage_options=storage_options)

        update_table = pa.Table.from_pandas(valid_df, preserve_index=False)
        update_table = update_table.cast(lance_ds.schema)

        lance_ds.merge_insert("image").when_matched_update_all().execute(update_table)
        print("数据集更新成功")

    except Exception as e:
        print(f"更新数据集失败: {e}")
        print("尝试备用方案(内存更新,不写回)...")
        try:
            current_df = daft.read_lance(lance_path, io_config=io_config).collect().to_pandas()
            for _, row in valid_df.iterrows():
                mask = current_df["image"] == row["image"]
                idx  = current_df[mask].index
                if len(idx) > 0:
                    current_df.at[idx[0], IMAGE_EMBEDDING_NEW_COLUMN] = row[IMAGE_EMBEDDING_NEW_COLUMN]
            print("备用方案:内存已更新,但未写回数据集")
        except Exception as e2:
            print(f"备用方案也失败: {e2}")

    print(f"\n处理完成!共处理了 {len(valid_df)} 张图片")

# Program entry point
if __name__ == "__main__":
    update_image_embedding()

You need to modify the following parameters in the sample code as needed:

  • BATCH_SIZE & MAX_CYCLES: Set the number of rows and batches of images processed each time the script is executed.
  • IMAGE_EMBEDDING_NEW_COLUMN: Customize a column name; the vectorization results will be written to this column later.
  • DOUBAO_LLM_COLUMN: Configure this as the Lance dataset column where the above image content understanding results are written.
  • If you are using your own test image set, you need to modify the values of las_udf when performing image-text vectorization according to your actual situation, including image_format (image format) and source_type (type of image source).

View Lance dataset

After processing the images, you can view the Lance dataset to check the processing results.

Read the dataset:

"""
读取数据
"""
import os
import daft
dataset_name = os.environ["DATASET_NAME"]
df = daft.read_las_dataset(name=dataset_name)
df.show()

Return example:

ERROR:daft_local_execution.runtime_stats:RuntimeStatsManager finished with active nodes {0}
╭────────────────────┬────────┬────────────┬───────────────────┬───────────────────╮
│ image              ┆ size   ┆      …     ┆ llm_result03      ┆ image_embedding   │
│ ---                ┆ ---    ┆            ┆ ---               ┆ ---               │
│ String             ┆ Int64  ┆ (3 hidden) ┆ String            ┆ List[Float64]     │
╞════════════════════╪════════╪════════════╪═══════════════════╪═══════════════════╡
│ s3://las-doctest/i ┆ 15390  ┆ …          ┆ {"description":   ┆ [0.06982421875,   │
│ mages/anima…       ┆        ┆            ┆ "一群袋鼠站在绿色 ┆ 0.00019168853…    │
│                    ┆        ┆            ┆ 的草地上…         ┆                   │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ s3://las-doctest/i ┆ 240478 ┆ …          ┆ {"description":"  ┆ [0.02880859375,   │
│ mages/anima…       ┆        ┆            ┆ 一只棕黄色带斑纹  ┆ -0.0268554687…    │
│                    ┆        ┆            ┆ 的蜥蜴,尾…       ┆                   │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ s3://las-doctest/i ┆ 15008  ┆ …          ┆ {"content": "一只 ┆ [0.040771484375,  │
│ mages/anima…       ┆        ┆            ┆ 黑色羽毛、颈部有  ┆ -0.040039062…     │
│                    ┆        ┆            ┆ 橙红色裸露皮…     ┆                   │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ s3://las-doctest/i ┆ 11645  ┆ …          ┆ {"description":   ┆ [-0.0003032684326 │
│ mages/anima…       ┆        ┆            ┆ "一只蝙蝠展开翅膀 ┆ 171875, -0.0…     │
│                    ┆        ┆            ┆ 停在红苹…         ┆                   │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ s3://las-doctest/i ┆ 9909   ┆ …          ┆ {"description":   ┆ [0.00689697265625 │
│ mages/anima…       ┆        ┆            ┆ "一只小考拉被灰色 ┆ , -0.0222167…     │
│                    ┆        ┆            ┆ 布料包裹…         ┆                   │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ s3://las-doctest/i ┆ 14252  ┆ …          ┆ {"description":   ┆ [-0.015380859375, │
│ mages/anima…       ┆        ┆            ┆ "一个穿粉色上衣的 ┆ -0.02966308…      │
│                    ┆        ┆            ┆ 小女孩,…         ┆                   │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ s3://las-doctest/i ┆ 3226   ┆ …          ┆ {"content": "一只 ┆ [0.0279541015625, │
│ mages/anima…       ┆        ┆            ┆ 白色的鹅,喙和脚  ┆ -0.03710937…      │
│                    ┆        ┆            ┆ 呈橙色,站立…     ┆                   │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ s3://las-doctest/i ┆ 878304 ┆ …          ┆ {"description":   ┆ [0.036865234375,  │
│ mages/anima…       ┆        ┆            ┆ "图片展示了一只毛 ┆ 0.0063171386…     │
│                    ┆        ┆            ┆ 发乌黑的…         ┆                   │
╰────────────────────┴────────┴────────────┴───────────────────┴───────────────────╯

(Showing first 8 rows)

Step summary / Expanded knowledge

At this point, we have completed the creation of the Lance-format image dataset, image labeling, image vectorization, and other related operations. Based on this information, it is possible to implement text-to-image search, image-to-image search, model training, and more.
To meet additional business requirements or to include more image label data, refer to the previous steps to add more information, such as image recognition information columns from GPT, Claude, and so on.

Step 5: Dataset application examples

Tool preparation

The following examples demonstrate image data consumption via text-to-image and image-to-image search. Since there is a need to display image search results, Jupyter notebook is used to run the sample code. You must install Jupyter notebook in advance.

  1. Run the following sample code to search for images in the dataset using natural language.
import daft
import os
from PIL import Image
import io
import matplotlib.pyplot as plt

# ✅ Use UDF to implement string containment check
@daft.udf(return_dtype=daft.DataType.bool())
def contains_keyword(col, keyword):
    return [keyword in (s or "") for s in col.to_pylist()]

def query_pic_with_word(dataset_name, query_word):
    df = daft.read_las_dataset(name=dataset_name)

    keyword = "袋鼠"
    # ✅ Filter using UDF
    result = df.where(contains_keyword(df["doubao_llm_result"], keyword))

    result_data = result.collect()

    for i, row in enumerate(result_data.to_pylist()):
        print(f"URL: {row['image']}")

        if 'raw_image' in row and row['raw_image'] is not None:
            image_data = row['raw_image']
            raw_image = Image.open(io.BytesIO(image_data))
            plt.figure(figsize=(8, 6))
            plt.imshow(raw_image)
            plt.axis('off')
            plt.show()

        if 'doubao_llm_result' in row and row['doubao_llm_result']:
            print(f"描述: {row['doubao_llm_result']}")

        print("-" * 50)

def main():
    dataset_name = "las_dataset_image_lance"
    query_word = "帮我查询袋鼠图片"
    query_pic_with_word(dataset_name, query_word)

if __name__ == "__main__":
    main()

The sample code for image search in this document is used to search for images related to "kangaroo" in the Lance dataset.
In the main function:

  • dataset_name: The name of the Lance dataset to be queried.
  • query_word: The natural language description to search for.
  1. Sample output. The returned results include the relevant image URLs, images, and image descriptions.
    Image

  1. Run the following sample code to search for images in the dataset using an image.
import numpy as np
from daft.las.functions.ark_llm.doubao_embedding_vision import DoubaoEmbeddingVision
from daft.las.functions.udf import las_udf
from daft import col
import daft
import os
from PIL import Image
import io
import matplotlib.pyplot as plt


# ✅ Use UDF to implement string containment check
@daft.udf(return_dtype=daft.DataType.bool())
def contains_keyword(col, keyword):
    return [keyword in (s or "") for s in col.to_pylist()]


def query_pic_with_word(dataset_name, query_word):
    df = daft.read_las_dataset(name=dataset_name)


    keyword = "袋鼠"
    # ✅ Filter using UDF
    result = df.where(contains_keyword(df["llm_result03"], keyword))


    result_data = result.collect()


    for i, row in enumerate(result_data.to_pylist()):
        print(f"URL: {row['image']}")


        if 'raw_image' in row and row['raw_image'] is not None:
            image_data = row['raw_image']
            raw_image = Image.open(io.BytesIO(image_data))
            plt.figure(figsize=(8, 6))
            plt.imshow(raw_image)
            plt.axis('off')
            plt.show()


        if 'llm_result03' in row and row['llm_result03']:
            print(f"描述: {row['llm_result03']}")


        print("-" * 50)


def main():
    dataset_name = "las_dataset_image_lance"
    query_word = "帮我查询袋鼠图片"
    query_pic_with_word(dataset_name, query_word)


def cosine_similarity(a, b):
    """计算余弦相似度"""
    return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))


def generate_image_embedding(image_url):
    """使用算子生成图片embedding(直接传URL,无需下载转base64)"""
    df = daft.from_pydict({"image_path": [image_url]})
    df = df.with_column(
        "embedding",
        las_udf(
            DoubaoEmbeddingVision,
            construct_args={
                "image_format": "jpeg",
                "source_type": "url",
            },
        )(col("image_path")),
    )
    result = df.collect().to_pydict()
    return result["embedding"][0]


def query_pic_with_pic(dataset_name, query_pic_url):
    """
    以图片向量的方式查询相似图片并显示


    参数:
        dataset_name: LAS数据集名称
        query_pic_url: 查询的图片URL
    """
    # Download the query image (for display only)
    from urllib.parse import urlparse
    import tos


    parsed = urlparse(query_pic_url)
    bucket = parsed.netloc
    key = parsed.path.lstrip('/')
    client = tos.TosClientV2(os.environ["LAS_TOS_ACCESS_KEY"], os.environ["LAS_TOS_SECRET_KEY"], "tos-cn-beijing.volces.com", "cn-beijing")
    resp = client.get_object(bucket=bucket, key=key)
    query_image_data = resp.read()
    query_image = Image.open(io.BytesIO(query_image_data))


    print("正在生成查询图片的embedding...")
    query_embedding = generate_image_embedding(query_pic_url)


    if query_embedding is None:
        print("无法生成查询图片的embedding")
        return


    print(f"成功生成embedding,维度: {len(query_embedding)}")


    # Read the LAS dataset
    df = daft.read_las_dataset(name=dataset_name)


    # Retrieve all data
    all_data = df.collect()
    all_rows = all_data.to_pylist()


    # Display the query image
    print("查询图片:")
    plt.figure(figsize=(8, 6))
    plt.imshow(query_image)
    plt.title("查询图片")
    plt.axis('off')
    plt.show()
    print("-" * 50)


    # Calculate the similarity between all images and the query image
    similarities = []
    for i, row in enumerate(all_rows):
        if row['image_embedding'] is not None:
            similarity = cosine_similarity(query_embedding, row['image_embedding'])
            similarities.append((similarity, i, row))


    # Sort by similarity, select the top 3 with similarity greater than 40%
    similarities.sort(key=lambda x: x[0], reverse=True)
    top_3 = [s for s in similarities[:3] if s[0] > 0.40]


    if not top_3:
        print("未找到相似度大于40%的图片")
        return


    # Display the results
    for similarity, idx, row in top_3:
        print(f"URL: {row['image']}")
        print(f"相似度: {similarity:.4f}")


        if 'raw_image' in row and row['raw_image'] is not None:
            image_data = row['raw_image']
            raw_image = Image.open(io.BytesIO(image_data))
            plt.figure(figsize=(8, 6))
            plt.imshow(raw_image)
            plt.axis('off')
            plt.show()


        if 'llm_result03' in row and row['llm_result03']:
            print(f"描述: {row['llm_result03']}")


        print("-" * 50)


if __name__ == "__main__":
    dataset_name = "las_dataset_image_lance"
    query_pic_url = "tos://las-doctest/images/animals/pic_search_1000_images/0009fc27d9.jpg"


    query_pic_with_pic(dataset_name, query_pic_url)

The sample code for image search in this document is used to search for images in the Lance dataset based on a given input image, calculate the cosine similarity, and return the top 3 images with the highest similarity.
In the main function:

  • dataset_name: The name of the Lance dataset to be queried.
  • query_pic_url: The URL of the image to search for. In this example, an image from TOS is used as input, configured as the URL in the TOS path format for the corresponding image.
  1. Sample output. The returned results include the original search image, as well as the URLs, similarity scores, images, and descriptions of the top 3 most similar images.
    Image
Last updated: 2026.05.22 13:51:37