Spécification des signatures de modèles

Pour garantir une expérience cohérente quel que soit l’endroit où un modèle est exécuté, le registre de modèles de Snowflake doit connaître le schéma d’entrée et de sortie des méthodes d’inférence du modèle : c’est-à-dire le nom et le type de toutes les colonnes du DataFrame d’entrée ou de sortie. Cela permet de mapper ces colonnes entre les types de données Python et SQL si nécessaire. Ce schéma est appelé signature par analogie avec les arguments d’une fonction et leurs types.

Pour certains cadres ML, le registre des modèles peut déduire ces schémas, soit à partir des structures de données du modèle lui-même, soit à partir d’un échantillon de données d’entrée. Cependant, les modèles acceptent ou renvoient souvent des objets dépourvus de ces informations, tels que les tableaux NumPy. Dans ces cas, Snowpark ML déduit les noms des fonctions d’entrée comme input_feature_1, input_feature_2, et ainsi de suite. De même, les fonctionnalités de sortie sont nommées output_feature_1, output_feature_2, etc.

Pour utiliser des noms plus significatifs dans vos modèles personnalisés, vous pouvez procéder de l’une des manières suivantes :

  • Mettez à jour sample_input_data avec les noms des colonnes, généralement en le convertissant au format pandas ou Snowpark DataFrame.

  • Transmettez explicitement les signatures à log_model. Lorsqu’un modèle ne produit pas de noms dans ses sorties, les signatures explicites peuvent être la seule option.

Déduire une signature

Tout comme le registre des modèles, vous pouvez générer des signatures automatiquement. Utilisez snowflake.ml.model.model_signature.infer_signature pour déduire une signature basée sur les noms d’entrée, de sortie et de colonne de l’échantillon fourni, puis appliquez cette signature aux méthodes appropriées lors de l’enregistrement du modèle, comme dans l’exemple ci-dessous :

import pandas as pd
from sklearn import svm, datasets

from snowflake.ml.model import model_signature

digits = datasets.load_digits()
target_digit = 6

def one_vs_all(dataset, digit):
    return [x == digit for x in dataset]

train_features = digits.data[:10]
train_labels = one_vs_all(digits.target[:10], target_digit)
clf = svm.SVC(gamma=0.001, C=10.0, probability=True)
clf.fit(train_features, train_labels)

sig = model_signature.infer_signature(
    train_features,
    labels_df,
    input_feature_names=['column1', 'column2', ...],
    output_feature_names=['is_target_digit'])

# Supply signature for every functions the model exposes. In this case only `predict`.
mv = reg.log_model(clf, model_name='my_model', version_name='v1', signatures={"predict": sig})
Copy

Cet exemple applique la signature à un seul modèle, mais vous pouvez déduire une signature pour chaque méthode exposée par votre modèle. Vous pouvez utiliser le même objet de signature (sig dans l’exemple) pour toutes les méthodes qui ont la même signature.

Construction d’une signature

Vous pouvez également construire manuellement une signature à l’aide de snowflake.ml.model.model_signature.ModelSignature. Les types scalaires et tensoriels (y compris les tenseurs en escalier) sont pris en charge.

Exemple :

sig = ModelSignature(
    inputs=[
        FeatureSpec(dtype=DataType.DOUBLE, name=f_0),
        FeatureSpec(dtype=DataType.INT64,
                name=sparse_0_fixed_len, shape=(5, 5)),
                FeatureSpec(dtype=DataType.INT64, name=sparse_1_variable_len, shape=(-1,)),
    ],
    outputs=[
        FeatureSpec(dtype=DataType.FLOAT, name=output),
    ]
)
Copy

Transmettez ensuite l’objet de signature, sig, à log_model comme indiqué dans l’exemple pour les méthodes auxquelles il s’applique.

Mappages de types de données

Cette section décrit l’équivalence des types dans le registre de modèles de Snowflake pour les systèmes de types pris en charge.

Types de données de colonnes

Le tableau suivant montre l’équivalence entre le type de signature de modèle (SQL), le type pandas DataFrames (NumPy) et le type Snowpark Python.

Type de signature du modèle (SQL)

Type pandas DataFrame (NumPy)

Type Snowpark Python

INT8

np.int8

ByteType

INT16

np.int16

ShortType

INT32

np.int32

IntegerType

INT64

np.int64

LongType

FLOAT

np.float32

FloatType

DOUBLE

np.float64

DoubleType

UINT8

np.uint8

ByteType

UINT16

np.uint16

ShortType

UINT32

np.uint32

IntegerType

UINT64

np.uint64

LongType

BOOL

np.bool_

BooleanType

STRING

np.str_

StringType

BYTES

np.bytes_

BinaryType

TIMESTAMP_NTZ

np.datetime64

TimestampType

La représentation des fonctions tensorielles dont la forme est spécifiée utilise np.object_.

Valeurs manquantes

Les valeurs NULL ne sont pas autorisées dans les données d’entrée de l’échantillon ou dans les données d’entrée de l’inférence.

Conversion depuis NumPy

Si le type de données NumPy peut être converti en toute sécurité en un type NumPy indiqué dans Types de données de colonnes, il est considéré comme le type de données correspondant.

Conversion depuis PyTorch

Type PyTorch

Type de signature du modèle (SQL)

torch.uint8

UINT8

torch.int8

INT8

torch.int16

INT16

torch.int32

INT32

torch.int64

INT64

torch.float32

FLOAT

torch.float64

DOUBLE

torch.bool

BOOL

Conversion depuis Snowpark

Outre les mappages indiqués dans Types de données de colonnes, les conversions suivantes s’appliquent :

  • DecimalType avec une échelle de 0 correspond à INT64.

  • DecimalType avec une échelle supérieure à 0 correspond à DOUBLE.