General invocation

Updated at:

This topic describes how to use the ML_PREDICT function to call AI models in Flink, covering syntax and parameters, per-call configuration, content type configuration, column-level parameters, and examples for text, image, and multimodal inference.

Quick start

Prerequisites

The following example demonstrates how to use ML_PREDICT to call a Flink built-in model. Go to Data Development > ETL, create a job, paste the code, and click Debug.

CREATE TEMPORARY TABLE text_source (
  user_input STRING
) WITH ('connector' = 'datagen');

CREATE TEMPORARY TABLE result_sink (
  user_input STRING,
  ai_analysis STRING
) WITH ('connector' = 'print');

CREATE TEMPORARY MODEL text_model
INPUT (user_input STRING)
OUTPUT (content STRING)
WITH (
  'provider' = 'openai-compat',
  'model' = 'qwen3.6-flash',
  'task' = 'chat/completions',
  'system-prompt' = 'Rate the gibberish level of the input on a scale of 0 to 100'
);

INSERT INTO result_sink
SELECT user_input, content as ai_analysis FROM
    ML_PREDICT(
        TABLE text_source,
        MODEL text_model,
        DESCRIPTOR(user_input)
);

Limits

  • Realtime Compute engine VVR 11.1 or later is required.

  • Some parameters are only supported when using Flink AI Service (built-in models) and require VVR 11.8.preview.2 or later.

  • The throughput of the ML_PREDICT operator is subject to rate limiting by Model Studio. When the rate limit is reached, backpressure occurs at the ML_PREDICT operator, which may cause timeout errors and job restarts. For more information, see Rate limits on Model Studio.

  • The number of types in content-types and the number of columns in DESCRIPTOR must match the number of INPUT columns defined in CREATE MODEL.

  • Columns of type image_url must be STRING. Columns of type multi_image_urls must be ARRAY<STRING>.

  • base64 images must include the data:image/<format>;base64, prefix. Raw base64 strings and local file paths are not supported.

Syntax

ML_PREDICT(TABLE <table_name>, MODEL <model_name>, DESCRIPTOR(<input_columns>) [, CONFIG => MAP[...]])        

Parameters

Parameter

Data type

Description

TABLE

TABLE

The input data stream for model inference. You can specify a physical table or a view.

MODEL

MODEL

The name of a registered model. For more information, see Model settings.

DESCRIPTOR()

The input columns for model inference.

Note

VVR 11.8.preview.2 and later supports multiple input columns. This is only available when using Flink AI Service (built-in models). The number of DESCRIPTOR columns must match the number of CREATE MODEL INPUT columns.

CONFIG => MAP[...]

MAP

Optional. For more information, see Per-call configuration.

Note

Only supported in VVR 11.8.preview.2 and later with Flink AI Service (built-in models).

Per-call configuration

You can specify per-call configuration when calling ML_PREDICT. If a parameter is already set in CREATE MODEL, the per-call value takes precedence but does not persist to the MODEL definition.

Parameter

Description

Example

user-prompt

Specifies the user prompt. Pass an empty string to bypass the MODEL-level value.

MAP['user-prompt', 'Answer in English']

content-type

Specifies the content type for single-column input.

MAP['content-type', 'text']

content-types

Specifies the content types for multi-column input.
The number of types in content-types must match the number of INPUT columns in CREATE MODEL.

MAP['content-types', 'text;image_url']

{column}.{param}

Specifies column-level parameters.

MAP['image_input.min_pixels', '100']

extra-body

Specifies additional parameters as a JSON string.

MAP['extra-body', '{"enable_search": true}']

bundle-size

The bundle size.

MAP[
  'bundle-size', '10',
  'bundle-allow-latency', '5s'
]

bundle-allow-latency

The allowed bundle latency.

Content type parameters

  • For single-column input, use content-type to specify the content type. Supported values: text, image_url.

  • For multi-column input, use content-types to specify the content type for each column. The supported values and their mapping to Flink SQL column types are listed below:

content-types value

Flink SQL type

Description

text

STRING

image_url

STRING

image_bytes

BYTES

Supported in VVR 11.9.preview.1 and later.

multi_image_bytes

ARRAY<BYTES>

Supported in VVR 11.9.preview.1 and later.

multi_image_urls

ARRAY<STRING>

Supported in VVR 11.8 and later.

video_bytes

BYTES

Supported in VVR 11.9.preview.1 and later.

video_url

STRING

Supported in VVR 11.9.preview.1 and later.

  • We recommend that you specify content-types in the parameters. If you set both content-type and content-types, the framework reports an error. Note: the content-type and content-types settings in model parameters and per-call settings affect each other:

CREATE MODEL setting

Allowed per-call option

Not allowed per-call option

Description

content-type (single column)

content-type

content-types

You can switch between text and image_url

content-types (multiple columns)

content-types

content-type

You can change the type combination, e.g. text;image_url to text;text

Neither content-type nor content-types specified

content-type
content-types

Same as above

Column-level parameters

Parameter

Description

Values

Example

{column}.min_pixels

Sets the minimum pixel threshold for input images or video frames. Images with fewer pixels than min_pixels are upscaled until they exceed the threshold.

Qwen3.7, Qwen3.6, Qwen3.5: default and minimum are both 65536.

MAP['image_input.min_pixels', '100']

{column}.max_pixels

Sets the maximum pixel threshold for input images or video frames. Images within [min_pixels, max_pixels] are processed at their original resolution. Images exceeding max_pixels are downscaled.

Qwen3.7, Qwen3.6, Qwen3.5: default is 2621440, maximum is 16777216.

MAP['image_input.max_pixels', '10000']

{column}.total_pixels

Limits the total pixels across all frames extracted from a video (single frame pixels x total frames). If the video exceeds this limit, frames are scaled down while keeping each frame within [min_pixels, max_pixels].
For long videos with many extracted frames, you can lower this value to reduce token consumption and processing time, but this may cause loss of image detail.

Qwen3.7 series, Qwen3.6 series, Qwen3.5 series: default and maximum are both 819200000. This value corresponds to 800000 image tokens (each 32x32 pixel block equals 1 image token).

MAP['image_input.total_pixels', '1000000']

{column}.cache_control

Enables explicit caching.

{"type": "ephemeral"}

MAP['content.cache_control', '{"type": "ephemeral"}']

{column}.fps

Sets the frame sampling rate for video understanding.

Valid values: [0.1, 10]. Default value: 2.0.

MAP['video_input.fps', '1.0']

Bundle processing

  • Processing: Bundle processing first aggregates multiple input records into a batch and then calls the AI model for the batch. This reduces the number of model calls but increases the model inference time for each request. When records can be effectively aggregated, bundle processing can significantly improve operator throughput.

  • Parameter description: bundle-size specifies the maximum number of records accumulated in a batch. bundle-allow-latency specifies the maximum wait time when a batch has not reached the bundle-size value. Processing starts when either the batch-size or wait-time condition is met.

  • Data type: Only text is supported.

  • Supported functions: ML_PREDICT, text classification (AI_CLASSIFY), sentiment analysis (AI_SENTIMENT), information extraction (AI_EXTRACT), text summarization (AI_SUMMARIZE), text translation (AI_TRANSLATE), data masking (AI_MASK), and text embedding (AI_EMBED).

  • Global configuration: This configuration applies to every ML_PREDICT call and every call to the listed domain-specific AI functions in the job. Use the following global parameters to enable bundle processing:

    SET 'table.exec.ml-predict.bundle-size' = '10';
    SET 'table.exec.ml-predict.bundle-allow-latency' = '5s';
  • Per-call configuration: These parameters apply only to the function call in which they are specified. ML_PREDICT and the listed domain-specific AI functions use the same configuration method. For parameters and examples, see Per-call configuration.

Examples

Text

The following example registers and uses a Flink AI Service built-in model to classify input text by sentiment. Example 1 uses MODEL-level parameters. Example 2 overrides user-prompt at call time.

-- Register a built-in model. When content-type is not specified, it defaults to text
CREATE MODEL sentiment_model
INPUT (prompt STRING)
OUTPUT (response STRING)
WITH (
  'provider' = 'openai-compat',
  'task' = 'chat/completions',
  'model' = 'qwen3.6-flash',
  'system-prompt' = 'You are a sentiment classifier. Output one label: negative, positive, or neutral'
);

-- Create a source table: simulated product review data
CREATE TEMPORARY VIEW input_table(id, content)
AS VALUES
  (1, 'Great quality, soft fabric, fits perfectly'),
  (2, 'Had loose threads on arrival, faded badly after one wash'),
  (3, 'Received the item, looks as pictured'),
  (4, 'Started pilling after two weeks, customer service refused returns'),
  (5, 'Flattering fit, color is even better than the photo, already ordered a third one');

-- Create a result table
CREATE TEMPORARY TABLE output_table (
  id INT,
  content STRING,
  sentiment STRING
) WITH (
  'connector' = 'print'
);

-- Use ML_PREDICT for real-time inference
-- Example 1: Use MODEL-level parameters
INSERT INTO output_table
SELECT
  id,
  content,
  response AS sentiment
FROM ML_PREDICT(
  TABLE input_table,
  MODEL sentiment_model,
  DESCRIPTOR(content));

-- Example 2: Specify per-call parameters
INSERT INTO output_table
SELECT
  id,
  content,
  response AS sentiment
FROM ML_PREDICT(
  TABLE input_table,
  MODEL sentiment_model,
  DESCRIPTOR(content),
  MAP['user-prompt', 'Reply in Chinese']);

Example 1 output:

id

content

sentiment

1

Great quality, soft fabric, fits perfectly

positive

2

Had loose threads on arrival, faded badly after one wash

negative

3

Received the item, looks as pictured

positive

4

Started pilling after two weeks, customer service refused returns

negative

5

Flattering fit, color is even better than the photo, already ordered a third one

positive

Example 2 output:

id

content

sentiment

1

Great quality, soft fabric, fits perfectly

Positive

2

Had loose threads on arrival, faded badly after one wash

Negative

3

Received the item, looks as pictured

Positive

4

Started pilling after two weeks, customer service refused returns

Negative

5

Flattering fit, color is even better than the photo, already ordered a third one

Positive

Image

The following example registers a multimodal model and classifies input images.

-- Register a built-in model with content-type set to image_url
CREATE TEMPORARY MODEL sentiment_model
INPUT (prompt STRING)
OUTPUT (response STRING)
WITH (
  'provider' = 'openai-compat',
  'task' = 'chat/completions',
  'model' = 'qwen3.6-flash',
  'content-type' = 'image_url'
);

-- Use ML_PREDICT for real-time inference
INSERT INTO output_table
SELECT
  id,
  content,
  response AS sentiment
FROM ML_PREDICT(
  TABLE input_table,
  MODEL sentiment_model,
  DESCRIPTOR(content));

Video

The following example registers a multimodal model to understand an input video.

CREATE TEMPORARY MODEL sentiment_model
INPUT (video_url STRING)
OUTPUT (response STRING)
WITH (
  'provider' = 'openai-compat',
  'task' = 'chat/completions',
  'model' = 'qwen3.6-plus',
  'content-types' = 'video_url',
  'system-prompt' = 'Briefly describe the video content'
);

CREATE TEMPORARY VIEW input_table(content)
AS VALUES ('https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20251111/ckgcxt/%E5%8D%95%E4%BA%BA%E8%AF%B4%E8%AF%9D-1.mp4');

SELECT
  content,
  response AS sentiment
FROM ML_PREDICT(
  TABLE input_table,
  MODEL sentiment_model,
  DESCRIPTOR(content));

Text + single image

The following example registers a multimodal model for chat-based inference on text and image inputs.

CREATE MODEL vl_model
INPUT (text_input STRING, image_input STRING)
OUTPUT (content STRING)
WITH (
  'provider' = 'openai-compat',
  'model' = 'qwen3.5-plus',
  'task' = 'chat/completions',
  'content-types' = 'text;image_url'
);

INSERT INTO result_sink
SELECT content FROM TABLE(ML_PREDICT(
  TABLE image_source,
  MODEL vl_model,
  DESCRIPTOR(text_input, image_input)
));         

Text + multiple images (multiple columns)

Pass each image through a separate INPUT column. Specify image_url for each image column in content-types.

CREATE MODEL vl_model_multi
INPUT (prompt STRING, img1 STRING, img2 STRING)
OUTPUT (content STRING)
WITH (
  'provider' = 'openai-compat',
  'model' = 'qwen3.5-plus',
  'task' = 'chat/completions',
  'content-types' = 'text;image_url;image_url'
);

SELECT content FROM TABLE(ML_PREDICT(
  TABLE my_source,
  MODEL vl_model_multi,
  DESCRIPTOR(prompt, img1, img2)
));          

Text + multiple images (array)

Pass multiple images in an ARRAY<STRING> column. Use multi_image_urls in content-types.

CREATE MODEL vl_model_array
INPUT (prompt STRING, images ARRAY<STRING>)
OUTPUT (content STRING)
WITH (
  'provider' = 'openai-compat',
  'model' = 'qwen3.5-plus',
  'task' = 'chat/completions',
  'content-types' = 'text;multi_image_urls'
);

SELECT content FROM TABLE(ML_PREDICT(
  TABLE my_source,
  MODEL vl_model_array,
  DESCRIPTOR(prompt, images)
)); 

Text + video

CREATE TEMPORARY MODEL sentiment_model
INPUT (video_url STRING, question STRING)
OUTPUT (response STRING)
WITH (
  'provider' = 'openai-compat',
  'task' = 'chat/completions',
  'model' = 'qwen3.6-plus',
  'content-types' = 'video_url;text'
);

CREATE TEMPORARY VIEW input_table(content, question)
AS VALUES ('https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20251111/ckgcxt/%E5%8D%95%E4%BA%BA%E8%AF%B4%E8%AF%9D-1.mp4', 'How many people are there?');

SELECT
  content,
  response AS sentiment
FROM ML_PREDICT(
  TABLE input_table,
  MODEL sentiment_model,
  DESCRIPTOR(content, question));

Per-call parameter examples

Example 1: Specify content type parameters

-- When content-type / content-types are not specified in CREATE MODEL, the default is content-type = text
CREATE MODEL model_single
INPUT (input STRING)
OUTPUT (content STRING)
WITH (
  'provider' = 'openai-compat',
  'model' = 'qwen3.5-plus',
  'task' = 'chat/completions'
);

-- Call 1: Use MODEL parameters, content type is text
SELECT content FROM TABLE(ML_PREDICT(
  TABLE source_text,
  MODEL model_single,
  DESCRIPTOR(input)
));

-- Call 2: Override content type to image at call time
SELECT content FROM TABLE(ML_PREDICT(
  TABLE source_img,
  MODEL model_single,
  DESCRIPTOR(input),
  MAP['content-type', 'image_url']
));

Example 2: Specify user-prompt and column-level parameters

-- Set default configuration in CREATE MODEL (multi-column model)
CREATE MODEL vl_model
INPUT (text_input STRING, image_input STRING)
OUTPUT (content STRING)
WITH (
  'provider' = 'openai-compat',
  'model' = 'qwen3.5-plus',
  'task' = 'chat/completions',
  'content-types' = 'text;image_url',
  'user-prompt' = 'Describe the image'
);

-- Call 1: Use default configuration
SELECT content FROM TABLE(ML_PREDICT(
  TABLE source_a, MODEL vl_model, DESCRIPTOR(text_input, image_input)
));

-- Call 2: Override user-prompt and column-level parameters
SELECT content FROM TABLE(ML_PREDICT(
  TABLE source_b, MODEL vl_model, DESCRIPTOR(text_input, image_input),
  MAP[
    'user-prompt', 'Answer in English',
    'image_input.min_pixels', '100',
    'image_input.max_pixels', '5000'
  ]
));

-- Call 3: Override content-types to change the type combination (treat both columns as text)
SELECT content FROM TABLE(ML_PREDICT(
  TABLE source_c, MODEL vl_model, DESCRIPTOR(text_input, image_input),
  MAP['content-types', 'text;text']
));

-- Call 4: Override content-types to change the type combination (reverse order)
SELECT content FROM TABLE(ML_PREDICT(
  TABLE source_c, MODEL vl_model, DESCRIPTOR(text_input, image_input),
  MAP['content-types', 'image_url;text']
));