Traga seus próprios tipos de modelos por meio de arquivos serializados

O registro de modelos oferece suporte ao registro em log de tipos de modelos incorporados diretamente no registro. Também fornecemos um método de registro em log de outros tipos de modelos com snowflake.ml.model.custom_model.CustomModel. Modelos serializáveis treinados usando ferramentas externas ou obtidos de repositórios de código aberto podem ser usados com CustomModel.

Este guia explica como:

  • Criar um modelo personalizado.

  • Criar contexto de modelo com arquivos e objetos de modelo.

  • Incluir um código adicional em seu modelo usando code_paths.

  • Registrar em log o modelo personalizado no Snowflake Model Registry.

  • Implementar o modelo para inferência.

Nota

Este guia de início rápido fornece um exemplo de registro de um modelo PyCaret personalizado.

Definição do contexto do modelo por argumentos de palavras-chave

O snowflake.ml.model.custom_model.ModelContext pode ser instanciado com argumentos de palavra-chave definidos pelo usuário. Os valores podem ser caminhos de arquivos de cadeia de caracteres ou instâncias de tipos de modelos suportados. Os arquivos e modelos serializados serão empacotados com o modelo para uso na lógica de inferência de modelos.

Usando objetos de modelo na memória

Ao trabalhar com tipos de modelos integrados, a abordagem recomendada é passar os objetos de modelo na memória diretamente para ModelContext. Isso permite que o Snowflake ML processe a serialização automaticamente.

import pandas as pd
from snowflake.ml.model import custom_model

# Initialize ModelContext with an in-memory model object
# my_model can be any supported model type (e.g., sklearn, xgboost, lightgbm, and others)
model_context = custom_model.ModelContext(
    my_model=my_model,
)

# Define a custom model class that utilizes the context
class ExampleBringYourOwnModel(custom_model.CustomModel):
    def __init__(self, context: custom_model.ModelContext) -> None:
        super().__init__(context)

    @custom_model.inference_api
    def predict(self, input: pd.DataFrame) -> pd.DataFrame:
        # Use the model with key 'my_model' from the context to make predictions
        model_output = self.context['my_model'].predict(input)
        return pd.DataFrame({'output': model_output})

# Instantiate the custom model with the model context. This instance can be logged in the model registry.
my_model = ExampleBringYourOwnModel(model_context)
Copy

Nota

Em sua classe de modelos personalizada, sempre acesse os objetos do modelo pelo contexto. Por exemplo, use self.model = self.context['my_model'] em vez de atribuir diretamente self.model = model (em que model é um objeto de modelo na memória). O acesso ao modelo captura diretamente uma segunda cópia do modelo em um fechamento, o que resulta em arquivos significativamente maiores durante a serialização.

Usando arquivos serializados

Para modelos ou dados armazenados em arquivos serializados, como pickles Python ou JSON, você pode fornecer caminhos de arquivo para ModelContext. Os arquivos podem ser modelos serializados, arquivos de configuração ou arquivos com parâmetros. Isso é útil para trabalhar com modelos pré-treinados salvos em disco ou dados de configuração.

import pickle
import pandas as pd
from snowflake.ml.model import custom_model

# Initialize ModelContext with a file path
# my_file_path is a local pickle file path
model_context = custom_model.ModelContext(
    my_file_path='/path/to/file.pkl',
)

# Define a custom model class that loads the pickled object
class ExampleBringYourOwnModel(custom_model.CustomModel):
    def __init__(self, context: custom_model.ModelContext) -> None:
        super().__init__(context)

        # Use 'my_file_path' key from the context to load the pickled object
        with open(self.context['my_file_path'], 'rb') as f:
            self.obj = pickle.load(f)

    @custom_model.inference_api
    def predict(self, input: pd.DataFrame) -> pd.DataFrame:
        # Use the loaded object to make predictions
        model_output = self.obj.predict(input)
        return pd.DataFrame({'output': model_output})

# Instantiate the custom model with the model context. This instance can be logged in the model registry.
my_model = ExampleBringYourOwnModel(model_context)
Copy

Importante

When you combine a supported model type (such as XGBoost) with unsupported models or data, you don’t need to serialize the supported model yourself. Set the supported model object directly in the context (e.g., base_model = my_xgb_model) and it is serialized automatically.

Teste e registro de um modelo personalizado

Você pode testar um modelo personalizado executando-o localmente.

my_model = ExampleBringYourOwnModel(model_context)
output_df = my_model.predict(input_df)
Copy

Quando o modelo funcionar como pretendido, registre-o no Snowflake Model Registry. Conforme mostrado no próximo exemplo de código, forneça conda_dependencies (ou pip_requirements) para especificar as bibliotecas que a classe de modelo precisa. Forneça sample_input_data (um pandas ou Snowpark DataFrame) para inferir a assinatura de entrada do modelo. Como alternativa, forneça uma assinatura do modelo.

reg = Registry(session=sp_session, database_name="ML", schema_name="REGISTRY")
mv = reg.log_model(my_model,
            model_name="my_custom_model",
            version_name="v1",
            conda_dependencies=["scikit-learn"],
            comment="My Custom ML Model",
            sample_input_data=train_features)
output_df = mv.run(input_df)
Copy

Incluindo código adicional com code_paths

Use o parâmetro code_paths em Registry.log_model para empacotar o código Python, como módulos auxiliares, utilitários e arquivos de configuração, com seu modelo. Você pode importar esse código da mesma forma que faz localmente.

Você pode fornecer caminhos de cadeia de caracteres para copiar arquivos ou diretórios, ou objetos CodePath. Os objetos oferecem mais controle sobre quais subdiretórios ou arquivos são incluídos e os caminhos de importação que serão usados pelo modelo.

Usando caminhos de cadeia de caracteres

Passe uma lista de caminhos de cadeia de caracteres para incluir arquivos ou diretórios. O último componente de cada caminho se torna o nome do módulo importável.

mv = reg.log_model(
    my_model,
    model_name="my_model",
    version_name="v1",
    code_paths=["src/mymodule"],  # import with: import mymodule
)
Copy

Usando CodePath com filtro

Use a classe CodePath quando você deseja empacotar apenas parte de uma árvore de diretórios ou controlar os caminhos de importação usados pelo seu modelo.

from snowflake.ml.model import CodePath
Copy

Um CodePath tem dois parâmetros:

  • root: um caminho de diretório ou arquivo.

  • filter (opcional): um caminho relativo em root que seleciona um subdiretório ou arquivo.

Quando filter é fornecido, a fonte é root/filter, e o valor filter determina o caminho de importação. Por exemplo, filter="utils" permite import utils, e filter="pkg/subpkg" permite import pkg.subpkg.

Exemplo: considerando esta estrutura de projeto:

my_project/src/
├── utils/
│   └── preprocessing.py
├── models/
│   └── classifier.py
└── tests/          # Not needed for inference
Copy

Para empacotar apenas utils/ e models/, excluindo tests/:

mv = reg.log_model(
    my_model,
    model_name="my_model",
    version_name="v1",
    code_paths=[
        CodePath("my_project/src/", filter="utils/"),
        CodePath("my_project/src/", filter="models/"),
    ],
)
Copy

Você também pode filtrar um único arquivo:

code_paths=[
    CodePath("my_project/src/", filter="utils/preprocessing.py"),
]
# Import with: import utils.preprocessing
Copy

Exemplo: Registro de um modelo PyCaret

The following example uses PyCaret to log a custom model type. PyCaret is a low-code, high-efficiency third-party package that Snowflake doesn’t support natively. You can bring your own model types using similar methods.

Etapa 1: Definir o contexto do modelo

Before you log your model, define the model context. The model context refers to your own custom model type. The following example specifies the path to the serialized (pickled) model using the context’s model_file attribute. You can choose any name for the attribute as long as the name is not used for anything else.

pycaret_model_context = custom_model.ModelContext(
  model_file = 'pycaret_best_model.pkl',
)
Copy

Etapa 2: Criar uma classe de modelo personalizada

Defina uma classe de modelo personalizada para registrar um tipo de modelo sem suporte nativo. Neste exemplo, uma classe PyCaretModel, derivada de CustomModel, é definida para que o modelo possa ser registrado no registro.

from pycaret.classification import load_model, predict_model

class PyCaretModel(custom_model.CustomModel):
    def __init__(self, context: custom_model.ModelContext) -> None:
        super().__init__(context)
        model_dir = self.context["model_file"][:-4]  # Remove '.pkl' suffix
        self.model = load_model(model_dir, verbose=False)
        self.model.memory = '/tmp/'  # Update memory directory

    @custom_model.inference_api
    def predict(self, X: pd.DataFrame) -> pd.DataFrame:
        model_output = predict_model(self.model, data=X)
        return pd.DataFrame({
            "prediction_label": model_output['prediction_label'],
            "prediction_score": model_output['prediction_score']
        })
Copy

Nota

Conforme mostrado, defina o diretório de memória do modelo como /tmp/. Os nós de warehouse do Snowflake têm acesso restrito ao diretório. /tmp é sempre gravável e é uma escolha segura quando o modelo precisa de um local para gravar arquivos. Isso pode não ser necessário para outros tipos de modelos.

Etapa 3: Testar o modelo personalizado

Teste o modelo PyCaret localmente usando um código como o seguinte.

test_data = [
    [1, 237, 1, 1.75, 1.99, 0.00, 0.00, 0, 0, 0.5, 1.99, 1.75, 0.24, 'No', 0.0, 0.0, 0.24, 1],
    # Additional test rows...
]
col_names = ['Id', 'WeekofPurchase', 'StoreID', 'PriceCH', 'PriceMM', 'DiscCH', 'DiscMM',
            'SpecialCH', 'SpecialMM', 'LoyalCH', 'SalePriceMM', 'SalePriceCH',
            'PriceDiff', 'Store7', 'PctDiscMM', 'PctDiscCH', 'ListPriceDiff', 'STORE']

test_df = pd.DataFrame(test_data, columns=col_names)

my_pycaret_model = PyCaretModel(pycaret_model_context)
output_df = my_pycaret_model.predict(test_df)
Copy

Etapa 4: Definir uma assinatura de modelo

Neste exemplo, use os dados de amostra para inferir uma assinatura do modelo para validação de entrada:

predict_signature = model_signature.infer_signature(input_data=test_df, output_data=output_df)
Copy

Etapa 5: Registrar o modelo

O código a seguir faz o log (registra) do modelo no Snowflake Model Registry.

snowml_registry = Registry(session)

custom_mv = snowml_registry.log_model(
    my_pycaret_model,
    model_name="my_pycaret_best_model",
    version_name="version_1",
    conda_dependencies=["pycaret==3.0.2", "scipy==1.11.4", "joblib==1.2.0"],
    options={"relax_version": False},
    signatures={"predict": predict_signature},
    comment = 'My PyCaret classification experiment using the CustomModel API'
)
Copy

Etapa 6: Verificar o modelo no registro

Para verificar se o modelo está disponível no Model Registry, use a função show_models.

snowml_registry.show_models()
Copy

Etapa 7: Fazer previsões com o modelo registrado

Use a função run para chamar o modelo para previsão.

snowpark_df = session.create_dataframe(test_data, schema=col_nms)

custom_mv.run(snowpark_df).show()
Copy

Próximos passos

Depois de implantar um modelo PyCaret por meio do Snowflake Model Registry, você pode visualizar o modelo no Snowsight. No menu de navegação, selecione AI & ML » Models. Se não o vir, verifique se está usando a função ACCOUNTADMIN ou a função que usou para registrar o modelo.

Para usar o modelo de SQL, use SQL da seguinte forma:

SELECT
    my_pycaret_model!predict(*) AS predict_dict,
    predict_dict['prediction_label']::text AS prediction_label,
    predict_dict['prediction_score']::double AS prediction_score
from pycaret_input_data;
Copy