Tous les produits
Search
Centre de documentation

Realtime Compute for Apache Flink:Appel général

Dernière mise à jour :Sep 21, 2026

Cette rubrique explique comment utiliser la fonction ML_PREDICT pour appeler des modèles d'IA dans Flink. Elle couvre la syntaxe et les paramètres, la configuration par appel, la configuration du type de contenu, les paramètres au niveau des colonnes, ainsi que des exemples pour l'inférence textuelle, visuelle et multimodale.

Démarrage rapide

Prérequis

L'exemple suivant illustre l'utilisation de ML_PREDICT pour appeler un modèle intégré à Flink. Accédez à Data Development > ETL, créez une tâche, collez le code, puis cliquez sur 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)
);

Limites

  • Le moteur Realtime Compute VVR 11.1 ou une version ultérieure est requis.

  • Certains paramètres sont pris en charge uniquement avec Flink AI Service (modèles intégrés) et nécessitent une version VVR 11.8 ou ultérieure.

  • Le débit de l'opérateur ML_PREDICT est soumis aux limites de débit imposées par Model Studio. Lorsque la limite est atteinte, une contre-pression se produit au niveau de l'opérateur ML_PREDICT, ce qui peut entraîner des erreurs de délai d'attente et des redémarrages de tâches. Pour plus d'informations, consultez la section Limites de débit sur Model Studio.

  • Le nombre de types définis dans content-types et le nombre de colonnes dans DESCRIPTOR doivent correspondre au nombre de colonnes INPUT définies dans CREATE MODEL.

  • Les colonnes de type image_url doivent être de type STRING. Les colonnes de type multi_image_urls doivent être de type ARRAY<STRING>.

  • Les images encodées en base64 doivent inclure le préfixe data:image/<format>;base64,. Les chaînes base64 brutes et les chemins de fichiers locaux ne sont pas pris en charge.

Syntaxe

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

Paramètres

Paramètre

Type de données

Description

TABLE

TABLE

Flux de données d'entrée pour l'inférence du modèle. Vous pouvez spécifier une table physique ou une vue.

MODEL

MODEL

Nom d'un modèle enregistré. Pour plus d'informations, consultez la page Paramètres du modèle.

DESCRIPTOR()

—

Colonnes d'entrée pour l'inférence du modèle.

Remarque

À partir de la version VVR 11.8, plusieurs colonnes d'entrée sont prises en charge. Cette fonctionnalité est disponible uniquement avec Flink AI Service (modèles intégrés). Le nombre de colonnes DESCRIPTOR doit correspondre au nombre de colonnes INPUT de CREATE MODEL.

CONFIG => MAP[...]

MAP

Facultatif. Pour plus d'informations, consultez la section Configuration par appel.

Remarque

Prise en charge uniquement à partir de la version VVR 11.8 avec Flink AI Service (modèles intégrés).

Configuration par appel

Vous pouvez spécifier une configuration par appel lors de l'appel à ML_PREDICT. Si un paramètre est déjà défini dans CREATE MODEL, la valeur spécifiée lors de l'appel est prioritaire, mais elle n'est pas persistée dans la définition du MODEL.

Paramètre

Description

Exemple

user-prompt

Spécifie l'invite utilisateur. Transmettez une chaîne vide pour ignorer la valeur définie au niveau du MODEL.

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

content-type

Spécifie le type de contenu pour une entrée sur une seule colonne.

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

content-types

Spécifie les types de contenu pour une entrée multicolumnes.
Le nombre de types dans content-types doit correspondre au nombre de colonnes INPUT dans CREATE MODEL.

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

{column}.{param}

Spécifie les paramètres au niveau de la colonne.

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

extra-body

Spécifie des paramètres supplémentaires sous forme de chaîne JSON.

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

bundle-size

Taille du lot (bundle).

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

Le traitement par lots (bundle processing) est pris en charge uniquement à partir de la version VVR 11.9.

bundle-allow-latency

Latence maximale autorisée pour le lot.

Paramètres de type de contenu

  • Pour une entrée sur une seule colonne, utilisez content-type afin de spécifier le type de contenu. Valeurs prises en charge : text, image_url.

  • Pour une entrée multicolumnes, utilisez content-types afin de spécifier le type de contenu pour chaque colonne. Les valeurs prises en charge et leur correspondance avec les types de colonnes Flink SQL sont listées ci-dessous :

Valeur de content-types

Type Flink SQL

Description

text

STRING

-

image_url

STRING

-

image_bytes

BYTES

Pris en charge à partir de la version VVR 11.9.

multi_image_bytes

ARRAY<BYTES>

Pris en charge à partir de la version VVR 11.9.

multi_image_urls

ARRAY<STRING>

Pris en charge à partir de la version VVR 11.8.

video_bytes

BYTES

Pris en charge à partir de la version VVR 11.9.

video_url

STRING

Pris en charge à partir de la version VVR 11.9.

  • Il est recommandé de spécifier content-types dans les paramètres. Si vous définissez à la fois content-type et content-types, le framework renvoie une erreur. Remarque : les paramètres content-type et content-types définis dans les paramètres du modèle et dans la configuration par appel s'influencent mutuellement :

Paramètre CREATE MODEL

Option par appel autorisée

Option par appel non autorisée

Description

content-type (colonne unique)

content-type

content-types

Vous pouvez basculer entre text et image_url

content-types (plusieurs colonnes)

content-types

content-type

Vous pouvez modifier la combinaison de types, par exemple passer de text;image_url à text;text

Ni content-type ni content-types spécifiés

content-typecontent-types

—

Identique à ci-dessus

Paramètres au niveau des colonnes

Paramètre

Description

Valeurs

Exemple

{column}.min_pixels

Définit le seuil minimal de pixels pour les images ou les frames vidéo d'entrée. Les images contenant moins de pixels que min_pixels sont agrandies jusqu'à dépasser ce seuil.

Qwen3.7, Qwen3.6, Qwen3.5 : les valeurs par défaut et minimales sont toutes deux de 65536.

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

{column}.max_pixels

Définit le seuil maximal de pixels pour les images ou les frames vidéo d'entrée. Les images dont la taille se situe dans la plage [min_pixels, max_pixels] sont traitées à leur résolution d'origine. Les images dépassant max_pixels sont réduites.

Qwen3.7, Qwen3.6, Qwen3.5 : la valeur par défaut est de 2621440 et la valeur maximale est de 16777216.

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

{column}.total_pixels

Limite le nombre total de pixels sur l'ensemble des frames extraites d'une vidéo (pixels par frame × nombre total de frames). Si la vidéo dépasse cette limite, les frames sont redimensionnées tout en restant dans la plage [min_pixels, max_pixels]. Pour les vidéos longues comportant de nombreuses frames extraites, vous pouvez réduire cette valeur afin de diminuer la consommation de jetons et le temps de traitement, au risque toutefois de perdre certains détails de l'image.

Série Qwen3.7, Série Qwen3.6, Série Qwen3.5 : les valeurs par défaut et maximales sont toutes deux de 819200000. Cette valeur correspond à 800000 jetons d'image (chaque bloc de 32×32 pixels équivaut à 1 jeton d'image).

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

{column}.cache_control

Active la mise en cache explicite.

{"type": "ephemeral"}

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

{column}.fps

Définit la fréquence d'échantillonnage des frames pour la compréhension vidéo.

Valeurs valides : [0,1 ; 10]. Valeur par défaut : 2,0.

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

Traitement par lots (Bundle processing)

  • Traitement : Le traitement par lots agrège d'abord plusieurs enregistrements d'entrée en un lot, puis appelle le modèle d'IA pour ce lot. Cela réduit le nombre d'appels au modèle, mais augmente le temps d'inférence pour chaque requête. Lorsque les enregistrements peuvent être efficacement agrégés, le traitement par lots améliore considérablement le débit de l'opérateur.

  • Description des paramètres : bundle-size spécifie le nombre maximal d'enregistrements accumulés dans un lot. bundle-allow-latency spécifie le temps d'attente maximal lorsqu'un lot n'a pas atteint la valeur bundle-size. Le traitement démarre dès que l'une des conditions (taille du lot ou temps d'attente) est remplie.

  • Exigences : Le traitement par lots prend effet en fonction du schéma d'entrée et de sortie du modèle.

    • Génération de texte : Pour les modèles dont la task est chat/completions, l'entrée contient exactement une colonne de texte de type STRING et la sortie contient exactement une colonne de type STRING ou VARIANT. Les entrées multicolumnes et les entrées multimodales telles que les images, les vidéos et l'audio ne sont pas prises en charge.

    • Embedding de texte : Pour les modèles dont la task est embeddings, l'entrée contient exactement une colonne de type STRING et la sortie contient exactement une colonne de type ARRAY<FLOAT>.

  • Fonctions prises en charge : ML_PREDICT, classification de texte (AI_CLASSIFY), analyse des sentiments (AI_SENTIMENT), extraction d'informations (AI_EXTRACT), résumé de texte (AI_SUMMARIZE), traduction de texte (AI_TRANSLATE), masquage des données (AI_MASK), et embedding de texte (AI_EMBED). Parmi celles-ci, ML_PREDICT prend en charge le traitement par lots uniquement si le modèle enregistré répond aux exigences précédentes.

  • Configuration globale : Cette configuration s'applique aux appels ML_PREDICT et aux appels aux fonctions d'IA spécifiques répertoriées dans la tâche qui satisfont aux exigences précédentes. Utilisez les paramètres globaux suivants pour activer le traitement par lots :

    -- Bundle processing is supported only in VVR 11.9 and later.
    SET 'table.exec.ml-predict.bundle-size' = '10';
    SET 'table.exec.ml-predict.bundle-allow-latency' = '5s';
  • Configuration par appel : Ces paramètres s'appliquent uniquement à l'appel de fonction dans lequel ils sont spécifiés. ML_PREDICT et les fonctions d'IA spécifiques répertoriées utilisent la même méthode de configuration. Pour les paramètres et les exemples, consultez la section Configuration par appel.

Gestion des erreurs

Limites

  • Pris en charge uniquement à partir de la version VVR 11.9.

  • Vous ne pouvez pas activer la gestion des erreurs lorsque les appels de modèle s'exécutent en mode synchrone.

  • La gestion des erreurs ne peut pas être utilisée conjointement avec le Cache de résultats de vectorisation (CACHE_TABLE) pour le moment.

Activer la gestion des erreurs

Ajoutez le paramètre FAIL_ON_ERROR => FALSE lors de l'appel à une fonction d'IA.

Prérequis : Conservez les paramètres de nouvelle tentative par défaut du modèle : error-handling-strategy='retry' et retry-fallback-strategy='failover'. Pour plus d'informations sur les paramètres du modèle, consultez la page Paramètres du modèle.

Paramètre

Description

Obligatoire

Valeur par défaut

FAIL_ON_ERROR

Indique si la tâche échoue lorsqu'un appel échoue définitivement. Si vous définissez ce paramètre sur FALSE, les enregistrements ayant échoué sont générés sous forme de lignes d'erreur et la tâche continue de s'exécuter.

Non

TRUE

Remarque

FAIL_ON_ERROR est défini par défaut sur TRUE ; dans ce cas, la tâche échoue après épuisement de toutes les nouvelles tentatives. La définition de ce paramètre sur FALSE modifie uniquement la manière dont les enregistrements ayant échoué sont gérés, sans affecter le comportement des nouvelles tentatives.

Modifications de la sortie

Après avoir activé la gestion des erreurs, le système ajoute une colonne d'erreur err_msg de type VARIANT nullable à la fin des champs de sortie d'origine. Cette colonne est générée par le système. Vous n'avez pas besoin de la déclarer dans la table d'entrée ni dans la clause OUTPUT de CREATE MODEL.

  • Si l'appel réussit : err_msg est NULL.

  • Si l'appel échoue définitivement : tous les champs de résultat du modèle sont NULL et err_msg contient les informations d'erreur.

Si vous utilisez SELECT *, le résultat inclut la nouvelle colonne d'erreur. Si vous sélectionnez explicitement des champs, vous devez spécifier la colonne manuellement. Le nom de colonne par défaut est err_msg. En cas de conflit de nom avec une colonne de sortie existante, le système ajoute un suffixe numérique, par exemple err_msg0. Utilisez le nom de colonne réel pour faire référence à la colonne.

Important

Utilisez la colonne d'erreur pour déterminer si un appel a échoué : une valeur différente de NULL indique un échec. Des champs de résultat de modèle NULL n'indiquent pas nécessairement un appel ayant échoué.

Champ dans l'objet

Contenu

Modèle de lecture SQL

message

La cause de l'erreur. Vérifiez ce champ en premier lieu lors du dépannage.

CAST(err_msg['message'] AS STRING)

stack_trace

Informations de diagnostic plus détaillées. Consultez ce champ lorsque vous devez identifier la cause racine.

CAST(err_msg['stack_trace'] AS STRING)

details (champ facultatif)

Présent uniquement si l'erreur sous-jacente contient des informations supplémentaires.

err_msg['details'] renvoie NULL si le champ n'existe pas, ou une valeur VARIANT si le champ existe.

Exemples

AI_SENTIMENT conserve les enregistrements ayant échoué

Préparez un modèle d'analyse des sentiments nommé ai_sentiment_model, qui est enregistré et prend en charge les appels asynchrones.

CREATE TEMPORARY VIEW input_data AS
SELECT *
FROM (VALUES
  (1, CAST('xxxx (a description of violent conflict that violates humanity)' AS STRING), 'negative'),
  (2, CAST('The customer service of this store has always been among the best' AS STRING), 'positive')
) AS t(id, input_text, expected_label);

CREATE TEMPORARY VIEW ai_results AS
SELECT i.id, i.input_text, i.expected_label,
       r.score, r.label, r.confidence, r.err_msg
FROM input_data AS i,
LATERAL TABLE(AI_SENTIMENT(
  MODEL => MODEL ai_sentiment_model,
  INPUT => i.input_text,
  FAIL_ON_ERROR => FALSE,
  CONFIG => MAP['async', 'true']
)) AS r(score, label, confidence, err_msg);

SELECT * FROM ai_results;

La requête renvoie les colonnes suivantes dans l'ordre.

Colonne de sortie

Type de données

Source et description

id

INT

L'ID de l'enregistrement d'entrée.

input_text

STRING

Le texte original à traiter.

score / label / confidence

STRING

Renvoyé par AI_SENTIMENT. NULL si l'appel échoue.

err_msg

VARIANT, peut être NULL

Ajouté après l'activation de la gestion des erreurs. NULL pour un appel réussi, ou un objet VARIANT d'erreur pour un appel ayant définitivement échoué.

La requête renvoie le résultat suivant. Les résumés et les messages d'erreur sont donnés à titre d'exemple. Les résultats réels peuvent varier.

id

input_text

score / label / confidence

err_msg

1

xxxx (a description of violent conflict that violates humanity)

NULL

{"message":"com.openai.errors.BadRequestException: 400: <400> InternalError.Algo.DataInspectionFailed: Input text data may contain inappropriate content..... "stack_trace":"org.apache.flink.table.api.TableException: Failed to execute asynchronously prediction with input row xxx}

2

The customer service of this store has always been among the best

1,0 / positive / 0,99

NULL

Autres exemples d'erreurs

L'exemple suivant montre une erreur de délai d'attente lors d'un appel général.

message: 
java.util.concurrent.TimeoutException: AsyncPredictFunction did not complete within the configured timeout. Increase the ML_PREDICT timeout or check external service connectivity.

stack_trace:
java.util.concurrent.TimeoutException: AsyncPredictFunction did not complete within the configured timeout. Increase the ML_PREDICT timeout or check external service connectivity.
at org.apache.flink.table.runtime.operators.predict.AsyncMLPredictRunner.timeout(AsyncMLPredictRunner.java:153)
at org.apache.flink.table.runtime.operators.predict.AsyncMLPredictRunner.timeout(AsyncMLPredictRunner.java:51)
at org.apache.flink.table.runtime.operators.TableKeyedAsyncWaitOperator$KeyedResultHandler.timerTriggered(TableKeyedAsyncWaitOperator.java:462)
at org.apache.flink.table.runtime.operators.TableKeyedAsyncWaitOperator$KeyedResultHandler.lambda$registerTimeout$1(TableKeyedAsyncWaitOperator.java:457)
at org.apache.flink.table.runtime.operators.TableKeyedAsyncWaitOperator.lambda$registerTimer$4(TableKeyedAsyncWaitOperator.java:486)
at org.apache.flink.streaming.runtime.tasks.StreamTask.invokeProcessingTimeCallback(StreamTask.java:2285)
at org.apache.flink.streaming.runtime.tasks.StreamTask.lambda$deferCallbackToMailbox$28(StreamTask.java:2276)
at org.apache.flink.streaming.runtime.tasks.StreamTaskActionExecutor$1.runThrowing(StreamTaskActionExecutor.java:50)
at org.apache.flink.streaming.runtime.tasks.mailbox.Mail.run(Mail.java:115)
at org.apache.flink.streaming.runtime.tasks.mailbox.MailboxProcessor.runMail(MailboxProcessor.java:415)
at org.apache.flink.streaming.runtime.tasks.mailbox.MailboxProcessor.processMailsWhenDefaultActionUnavailable(MailboxProcessor.java:384)
at org.apache.flink.streaming.runtime.tasks.mailbox.MailboxProcessor.processMail(MailboxProcessor.java:369)
at org.apache.flink.streaming.runtime.tasks.mailbox.MailboxProcessor.runMailboxLoop(MailboxProcessor.java:229)
at org.apache.flink.streaming.runtime.tasks.StreamTask.runMailboxLoop(StreamTask.java:1273)
at org.apache.flink.streaming.runtime.tasks.StreamTask.invoke(StreamTask.java:1217)
at org.apache.flink.runtime.taskmanager.Task.runWithSystemExitMonitoring(Task.java:1133)
at org.apache.flink.runtime.taskmanager.Task.restoreAndInvoke(Task.java:1110)
at org.apache.flink.runtime.taskmanager.Task.doRun(Task.java:914)
at org.apache.flink.runtime.taskmanager.Task.run(Task.java:716)
at java.base/java.lang.Thread.run(Thread.java:991)

Gestion de chaque type d'erreur

Le comportement suivant s'applique lorsque la gestion des erreurs est activée et que les paramètres de nouvelle tentative par défaut sont conservés. Une ligne d'erreur est une ligne qui conserve l'entrée, renvoie des résultats de modèle vides et enregistre la raison de l'échec dans err_msg.

Type ou cause d'erreur

Comportement du système

Sortie finale

Échecs de connexion réseau, limitation de débit ou erreurs de service transitoires (429, 500, 502, 503)

Attend la période configurée, puis effectue une nouvelle tentative.

Sortie normale si la nouvelle tentative réussit. Ligne d'erreur si l'appel échoue définitivement.

Paramètres invalides, entrée trop longue, clé invalide, accès refusé ou modèle introuvable (400, 401, 403, 404, 422)

Renvoie généralement un échec directement sans nouvelles tentatives.

Une ligne d'erreur qui enregistre la raison renvoyée par le service.

Rejet par la modération de contenu, ou solde ou quota insuffisant

Décide s'il faut effectuer une nouvelle tentative en fonction de l'erreur renvoyée par le service.

Sortie normale si l'erreur est résolue. Ligne d'erreur si l'appel échoue définitivement.

Un résultat JSON est requis, mais la réponse du modèle ne peut pas être analysée

Renvoie la requête.

Sortie normale si la requête réussit. Ligne d'erreur si l'appel échoue définitivement.

La période d'attente configurée est dépassée

Met fin à l'attente en cours.

Une ligne d'erreur indiquant un délai d'attente.

Un appel échoue définitivement ou expire pendant le traitement par lots

Enregistre l'échec pour chaque entrée du lot.

Une ligne d'erreur par entrée, chacune enregistrant la même raison d'échec.

Exemples

Texte

L'exemple suivant enregistre et utilise un modèle intégré à Flink AI Service pour classer le texte d'entrée selon les sentiments. L'exemple 1 utilise les paramètres au niveau du MODEL. L'exemple 2 remplace user-prompt au moment de l'appel.

-- 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']);

Résultat de l'exemple 1 :

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

Résultat de l'exemple 2 :

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

L'exemple suivant enregistre un modèle multimodal et classe les images d'entrée.

La colonne d'entrée d'image (lorsque content-type est image_url) est de type STRING et prend en charge les formats suivants :

Format d'entrée

Utilisation

Limites

URL publique

Transmettez une chaîne d'URL HTTP ou HTTPS accessible par le service de modèle via Internet. Le service de modèle récupère l'image.

L'URL doit être accessible via Internet depuis l'environnement d'exécution du service de modèle. Si l'URL est limitée dans le temps, sa période de validité doit couvrir la durée de l'appel au modèle. Les formats et tailles d'image sont limités par le service de modèle.

URL de données Base64

Transmettez une chaîne préfixée par data:image/<format>;base64,. Les chaînes Base64 brutes et les chemins de fichiers locaux ne sont pas pris en charge.

Les octets de l'image sont transmis par la tâche Flink, ce qui augmente la charge réseau de la tâche. L'encodage Base64 augmente également la taille des données. Le volume de données est limité par les limites d'entrée du service de modèle.

Si les images sont stockées dans des colonnes Blob d'un catalogue Paimon, vous pouvez utiliser la fonctionnalité d'URL signée temporaire (presigned URL) de Paimon Blob pour générer une URL publique en tant qu'entrée. Pour plus d'informations, consultez la page Apache Paimon.

-- 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));

Vidéo

L'exemple suivant enregistre un modèle multimodal pour comprendre une vidéo d'entrée.

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));

Texte + image unique

L'exemple suivant enregistre un modèle multimodal pour une inférence basée sur le chat avec des entrées textuelles et visuelles.

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)
));         

Texte + plusieurs images (plusieurs colonnes)

Transmettez chaque image via une colonne INPUT distincte. Spécifiez image_url pour chaque colonne d'image dans 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)
));          

Texte + plusieurs images (tableau)

Transmettez plusieurs images dans une colonne ARRAY<STRING>. Utilisez multi_image_urls dans 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)
)); 

Texte + vidéo

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));

Exemples de paramètres par appel

Exemple 1 : Spécifier les paramètres de type de contenu

-- 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']
));

Exemple 2 : Spécifier user-prompt et les paramètres au niveau des colonnes

-- 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']
));