Multimodal function best practices

更新时间:
复制 MD 格式

The ai_query and ai_embedding_multimodal functions in EMR Serverless Spark provide multimodal capabilities for image understanding and embedding vector generation.

Supported versions

These functions are supported only in Spark 3.5.2. You must use EMR Serverless Spark esr-4.7.0 or a later version.

Note

ai_embedding_multimodal and its related model services are available only in specific regions. See the notes in ai_embedding_multimodal for details.

Function signatures

ai_query

The ai_query function calls a large language model for inference and supports image data as multimodal input. The function signature:

ai_query(prompt [, service_name] [, options][, data][, data_type])

The following table describes the parameters.

Parameter

Required

Description

prompt

Yes

The full prompt sent to the model. It should include context, instructions, and input data. We recommend explicitly specifying the output format to improve stability.

service_name

No

Specifies the model service to call. If omitted, the default model qwen3.6-plus is used. You can also specify a model service registered through the model service registration and invocation feature.

options

No

A JSON string containing additional parameters to control the generation behavior. For more information about the supported parameters, see the documentation for the options parameter.

data

No

The column containing the image data to process. This parameter is required only when processing image data. The value to pass depends on the data_type setting:

  • If data_type is binary (default): Pass the image's binary data (from a BINARY type column) or a publicly accessible http(s) URL. For example, you can use the content column from the read_files function or a direct URL to the image.

  • If data_type is uri: Pass the file path as a STRING. Supported formats include OSS paths (for example, oss://bucket/path/to/image.jpg) or local file paths (for example, file:///mnt/data/path/to/image.jpg, which requires the Spark managed mount feature).

data_type

No

Specifies how the image data is passed. The following values are supported:

  • binary (default): The data parameter receives the image's binary data (BINARY type) or an http(s) URL.

  • uri: The data parameter receives a file path (STRING type), and the function reads the file content internally.

Named parameter example:

ai_query(
  'your prompt',
  service_name => 'your_model_service_name',
  options => '{"temperature":0.1}',
  data => image_col,
  data_type => 'binary'
)

Supported named parameters: service_name, options, data, and data_type.

ai_embedding_multimodal

Note

This AI Function is only available in the following regions: China (Beijing), China (Shanghai), China (Hangzhou), China (Shenzhen), China (Ulanqab), China (Chengdu), and China (Zhangjiakou).

The ai_embedding_multimodal function generates an embedding vector from an image for similarity calculations, retrieval, and other tasks. The function signature:

ai_embedding_multimodal(data [, service_name] [, options] [, data_type])

The following table describes the parameters.

Parameter

Required

Description

data

Yes

The column containing the image data from which to generate an embedding vector. The value to pass depends on the data_type setting:

  • If data_type is binary (default): Pass the image's binary data (from a BINARY type column) or a publicly accessible http(s) URL. For example, you can use the content column from the read_files function or a direct URL to the image.

  • If data_type is uri: Pass the file path as a STRING. Supported formats include OSS paths (for example, oss://bucket/path/to/image.jpg) or local file paths (for example, file:///mnt/data/path/to/image.jpg, which requires the Spark managed mount feature).

service_name

No

Specifies the embedding model service to call. If omitted, the default model tongyi-embedding-vision-plus is used, which produces 1152-dimensional vectors. You can also specify a model service registered through the model service registration and invocation feature.

options

No

A JSON string containing additional parameters to control the generation behavior. The supported parameters depend on the target embedding service.

data_type

No

Specifies how the image data is passed. The following values are supported:

  • binary (default): The data parameter receives the image's binary data (BINARY type) or an http(s) URL.

  • uri: The data parameter receives a file path (STRING type), and the function reads the file content internally.

Named parameter example:

ai_embedding_multimodal(
  image_col,
  service_name => 'tongyi-embedding-vision-plus',
  data_type => 'binary'
)

Supported named parameters: service_name, options, and data_type.

Notes

The ai_query function is a chat-type request and has the following default behavior:

  • If you do not pass enable_thinking in the options parameter, the system automatically adds {"enable_thinking": false}.

  • If you explicitly pass enable_thinking, your specified setting is used.

For example, the following two queries are equivalent and both disable thinking:

-- Method 1: Omit options. Thinking is disabled by default.
SELECT ai_query('Describe the image content', data => content) FROM image_table;

-- Method 2: Explicitly disable thinking.
SELECT ai_query(
  'Describe the image content',
  data => content,
  options => '{"enable_thinking": false}'
) FROM image_table;

To enable thinking, you must explicitly pass the parameter:

SELECT ai_query(
  'Describe the image content',
  data => content,
  options => '{"enable_thinking": true}'
) FROM image_table;
Note

The ai_embedding_multimodal function is not a chat-type request. Support for a specific options field depends on the target embedding service.

Use cases

Use case 1: Process data by image path

If your table contains only image paths pointing to OSS, HDFS, or another Hadoop-compatible file system, use the uri mode to have the function read file content internally.

Example: Identify license plate numbers from images based on their file paths.

SELECT
  path,
  ai_query(
    'Return the license plate number in the image. IMPORTANT: Reply with only the plate number; if the image is too blurry to recognize, reply ''Unable to recognize''.',
    service_name => 'qwen3.5-plus',
    data => path,
    data_type => 'uri'
  ) AS plate_number
FROM (
  SELECT /*+ REPARTITION(10) */ path
  FROM ccpd_1m_1000
) t;
Note
  • data => path specifies the path column, and data_type => 'uri' indicates that the function reads files by path.

  • It is recommended to control the number of partitions by using the REPARTITION hint in an inner subquery, instead of specifying it directly on the outer projection that contains an AI function.

  • If you do not specify options.enable_thinking, it defaults to false.

To explicitly control the thinking configuration, use the options parameter:

SELECT
  path,
  ai_query(
    'Return the license plate number in the image. IMPORTANT: Reply with only the plate number; if the image is too blurry to recognize, reply ''Unable to recognize''.',
    service_name => 'qwen3.5-plus',
    data => path,
    data_type => 'uri',
    options => '{"enable_thinking": false}'
  ) AS plate_number
FROM (
  SELECT /*+ REPARTITION(10) */ path
  FROM ccpd_1m_1000
) t;

Use case 2: Process data with binary content

Use the read_files function to read images in bulk from a directory, then pass the returned content column (BINARY type) as multimodal input.

Example: Read images in bulk from an OSS directory and identify license plate numbers.

SELECT
  path,
  ai_query(
    'Return the license plate number in the image. IMPORTANT: Reply with only the plate number.',
    service_name => 'qwen3.5-plus',
    data => content
  ) AS plate_number
FROM read_files(
  'oss://bucket/path/to/images/',
  suffix => 'jpg,jpeg,png'
);
Note
  • The read_files function returns four columns: path, content, modificationTime, and length. The content column is of the BINARY type and can be passed directly to the data parameter.

  • This scenario uses the default data_type => 'binary', which does not need to be explicitly specified.

  • suffix specifies a comma-separated list of case-insensitive suffixes. For example, both jpg and .jpg are valid.

  • By default, read_files does not recursively read subdirectories. To read them recursively, pass recursive => true.

  • The read_files operation generally does not require an additional manual REPARTITION. You can control the scan partition granularity by using the spark.sql.files.maxPartitionBytes parameter.

Use case 3: Generate image embedding vectors

Use the ai_embedding_multimodal function to convert images into embedding vectors for tasks such as similarity search and cluster analysis. Both uri mode and binary mode are supported.

Method 1: Generate an embedding vector from an image path (uri mode).

SELECT
  path,
  ai_embedding_multimodal(
    path,
    service_name => 'tongyi-embedding-vision-plus',
    data_type => 'uri'
  ) AS embedding
FROM image_paths_table;

Method 2: Generate an embedding vector from image binary content (binary mode).

SELECT
  path,
  ai_embedding_multimodal(
    content,
    service_name => 'tongyi-embedding-vision-plus'
  ) AS embedding
FROM read_files(
  'oss://bucket/path/to/images/',
  suffix => 'jpg,png'
);

read_files function

The read_files function reads file content in bulk from a file system and is commonly used with multimodal functions. The function signature:

read_files(path [, suffix] [, recursive])

The following table describes the parameters.

Parameter

Required

Description

path

Yes

The path to a directory or a single file.

suffix

No

A comma-separated list of file suffixes, such as 'jpg,png' or '.jpg,.png'. The list is case-insensitive.

recursive

No

BOOLEAN. Specifies whether to recursively read subdirectories. The default value is false.

Returned columns

Column Name

Type

Description

path

STRING

The full path of the file.

content

BINARY

The binary content of the file.

modificationTime

TIMESTAMP

The time the file was last modified.

length

BIGINT

The size of the file in bytes.

Examples:

-- Read all files in a directory
SELECT * FROM read_files('oss://bucket/images/');

-- Filter files by suffix
SELECT path, content, length
FROM read_files('oss://bucket/images/', suffix => 'jpg,jpeg,png');

-- Recursively read subdirectories
SELECT path, content
FROM read_files(
  'oss://bucket/images/',
  suffix => 'jpg,png',
  recursive => true
);
Note
  • read_files supports only the named parameters suffix and recursive.

  • The suffix filter is pushed down to the file scanning stage to avoid reading other large files in the directory.

  • read_files currently does not support the formatHint parameter.

Usage example

The following example creates a temporary view to control partitioning before calling a multimodal function:

CREATE OR REPLACE TEMPORARY VIEW car_images AS
SELECT /*+ REPARTITION(8) */ path
FROM ccpd_1m_1000;

SELECT
  path,
  ai_query(
    'Return the license plate number in the image. IMPORTANT: Reply with only the plate number; if the image is too blurry to recognize, reply ''Unable to recognize''.',
    service_name => 'qwen3.5-plus',
    data => path,
    data_type => 'uri'
  ) AS plate_number
FROM car_images
LIMIT 20;

Common errors

Error Message

Cause

Solution

Unsupported image format

The image format is not supported.

Use common formats such as JPEG, PNG, or WebP. Confirm that the target model service supports the corresponding MIME type.

Binary data is too short

The file content is incomplete or not a valid image.

Check whether the source file is corrupted. Confirm that the content column contains the image's binary data.

no model service found

The service_name parameter is not configured or is configured incorrectly.

Check whether the model service name exists or confirm that the default model service is configured correctly.

data parameter with data_type='binary' must be a BINARY column or an image URL

data_type='binary' was used, but a regular string column was passed.

For path columns, change the parameter to data_type => 'uri'. Use data_type => 'binary' (the default) only for columns containing binary data.

Performance optimization

Control partitions for path-based tables

Place the REPARTITION hint in an inner subquery and run the AI function in the outer query. You can also use a CTE or CREATE TEMPORARY VIEW:

-- Method 1: Subquery
SELECT
  path,
  ai_query('Describe the image content', service_name => 'qwen3.5-plus', data => path, data_type => 'uri') AS result
FROM (
  SELECT /*+ REPARTITION(32) */ path FROM large_image_dataset
) t;

-- Method 2: CTE
WITH car_images AS (
  SELECT /*+ REPARTITION(32) */ path FROM ccpd_1m_1000
)
SELECT
  path,
  ai_query('Describe the image content', service_name => 'qwen3.5-plus', data => path, data_type => 'uri') AS result
FROM car_images;

-- Method 3: Temporary view
CREATE OR REPLACE TEMPORARY VIEW car_images AS
SELECT /*+ REPARTITION(32) */ path FROM ccpd_1m_1000;

SELECT
  path,
  ai_query('Describe the image content', service_name => 'qwen3.5-plus', data => path, data_type => 'uri') AS result
FROM car_images;

Control parallelism for read_files

When read_files scans a directory directly, manual REPARTITION is usually unnecessary. To increase parallelism or reduce partition size, adjust spark.sql.files.maxPartitionBytes instead.

SET spark.sql.files.maxPartitionBytes = 134217728;

Filter by suffix during file reading

Filter file types with the suffix parameter to reduce unnecessary file scans and downstream AI requests. To recursively read subdirectories, add recursive => true:

SELECT path, content
FROM read_files('oss://bucket/images/', suffix => 'jpg,jpeg,png');

Supported image formats

Format

MIME type

Magic number detection

JPEG

image/jpeg

FF D8 FF

PNG

image/png

89 50 4E 47

GIF

image/gif

47 49 46 38

WebP

image/webp

RIFF....WEBP

BMP

image/bmp

42 4D

TIFF

image/tiff

49 49 2A 00 / 4D 4D 00 2A

ICO

image/x-icon

00 00 01 00

AVIF

image/avif

....ftypavif

HEIF

image/heif

....ftypheic