De artefatos a modelos no MLflow

O artigo a seguir explica as diferenças entre um artefato MLflow e um modelo MLflow e como fazer a transição de um para o outro. Ele também explica como o Aprendizado de Máquina do Azure usa o conceito de um modelo MLflow para habilitar fluxos de trabalho de implantação simplificados.

Qual é a diferença entre um artefato e um modelo?

Se você não estiver familiarizado com o MLflow, talvez não esteja ciente da diferença entre registrar artefatos ou arquivos versus registrar modelos MLflow. Existem algumas diferenças fundamentais entre os dois:

Artefacto

Um artefato é qualquer arquivo gerado (e capturado) a partir da execução ou trabalho de um experimento. Um artefato pode representar um modelo serializado como um arquivo pickle, os pesos de um modelo PyTorch ou TensorFlow, ou até mesmo um arquivo de texto contendo os coeficientes de uma regressão linear. Alguns artefatos também não podem ter nada a ver com o modelo em si; em vez disso, eles podem conter configurações para executar o modelo, ou informações de pré-processamento, ou dados de exemplo, e assim por diante. Os artefatos podem vir em vários formatos.

Você já pode estar registrando artefatos:

filename = 'model.pkl'
with open(filename, 'wb') as f:
  pickle.dump(model, f)

mlflow.log_artifact(filename)

Modelo

Um modelo no MLflow também é um artefato. No entanto, fazemos suposições mais fortes sobre esse tipo de artefato. Tais suposições fornecem um contrato claro entre os arquivos salvos e o que eles significam. Quando você registra seus modelos como artefatos (arquivos simples), você precisa saber o que o construtor de modelos significou para cada um desses arquivos para saber como carregar o modelo para inferência. Pelo contrário, os modelos MLflow podem ser carregados usando o contrato especificado no formato MLmodel.

No Azure Machine Learning, os modelos de registo têm as seguintes vantagens:

  • Você pode implantá-los em pontos de extremidade em tempo real ou em lote sem fornecer um script de pontuação ou um ambiente.
  • Quando você implanta modelos, as implantações automaticamente têm um swagger gerado e o recurso Test pode ser usado no estúdio do Azure Machine Learning.
  • Você pode usar os modelos diretamente como entradas de pipeline.
  • Você pode usar o painel de IA responsável com seus modelos.

Você pode registrar modelos usando o SDK MLflow:

import mlflow
mlflow.sklearn.log_model(sklearn_estimator, "classifier")

O formato MLmodel

O MLflow adota o formato MLmodel como uma forma de criar um contrato entre os artefatos e o que eles representam. O formato MLmodel armazena ativos em uma pasta. Entre esses ativos, há um arquivo chamado MLmodel. Este arquivo é a única fonte de verdade sobre como um modelo pode ser carregado e usado.

A captura de tela a seguir mostra uma pasta de exemplo do modelo MLflow no estúdio do Azure Machine Learning. O modelo é colocado em uma pasta chamada credit_defaults_model. Não há nenhum requisito específico sobre a nomeação desta pasta. A pasta contém o MLmodel arquivo entre outros artefatos de modelo.

A screenshot showing assets of a sample MLflow model, including the MLmodel file.

O código a seguir é um exemplo de como MLmodel o arquivo para um modelo de visão computacional treinado com fastai pode parecer:

Modelo de ML

artifact_path: classifier
flavors:
  fastai:
    data: model.fastai
    fastai_version: 2.4.1
  python_function:
    data: model.fastai
    env: conda.yaml
    loader_module: mlflow.fastai
    python_version: 3.8.12
model_uuid: e694c68eba484299976b06ab9058f636
run_id: e13da8ac-b1e6-45d4-a9b2-6a0a5cfac537
signature:
  inputs: '[{"type": "tensor",
             "tensor-spec": 
                 {"dtype": "uint8", "shape": [-1, 300, 300, 3]}
           }]'
  outputs: '[{"type": "tensor", 
              "tensor-spec": 
                 {"dtype": "float32", "shape": [-1,2]}
            }]'

Sabores do modelo

Considerando o grande número de estruturas de aprendizado de máquina disponíveis para uso, o MLflow introduziu o conceito de sabor como uma maneira de fornecer um contrato exclusivo para trabalhar em todas as estruturas de aprendizado de máquina. Um sabor indica o que esperar de um determinado modelo criado com uma estrutura específica. Por exemplo, o TensorFlow tem seu próprio sabor, que especifica como um modelo do TensorFlow deve ser persistido e carregado. Como cada sabor de modelo indica como persistir e carregar o modelo para uma determinada estrutura, o formato MLmodel não impõe um único mecanismo de serialização que todos os modelos devem suportar. Essa decisão permite que cada sabor use os métodos que fornecem o melhor desempenho ou o melhor suporte de acordo com suas melhores práticas, sem comprometer a compatibilidade com o padrão MLmodel.

O código a seguir é um exemplo da flavors seção para um fastai modelo.

flavors:
  fastai:
    data: model.fastai
    fastai_version: 2.4.1
  python_function:
    data: model.fastai
    env: conda.yaml
    loader_module: mlflow.fastai
    python_version: 3.8.12

Modelo de assinatura

Uma assinatura de modelo no MLflow é uma parte importante da especificação do modelo, pois serve como um contrato de dados entre o modelo e o servidor que executa o modelo. Uma assinatura de modelo também é importante para analisar e impor os tipos de entrada de um modelo no momento da implantação. Se uma assinatura estiver disponível, o MLflow impõe tipos de entrada quando os dados são enviados para o seu modelo. Para obter mais informações, consulte Imposição de assinatura MLflow.

As assinaturas são indicadas quando os modelos são registrados e persistem na signature seção do MLmodel arquivo. O recurso Autolog no MLflow infere automaticamente as assinaturas da melhor maneira possível. No entanto, talvez seja necessário registrar os modelos manualmente se as assinaturas inferidas não forem as necessárias. Para obter mais informações, consulte Como registrar modelos com assinaturas.

Existem dois tipos de assinaturas:

  • Assinatura baseada em colunas: esta assinatura opera em dados tabulares. Para modelos com esse tipo de assinatura, o MLflow fornece pandas.DataFrame objetos como entradas.
  • Assinatura baseada em tensor: esta assinatura opera com matrizes ou tensores n-dimensionais. Para modelos com essa assinatura, o MLflow fornece numpy.ndarray como entradas (ou um dicionário de, no caso de numpy.ndarray tensores nomeados).

O exemplo a seguir corresponde a um modelo de visão computacional treinado com fastai. Este modelo recebe um lote de imagens representadas como tensores de forma (300, 300, 3) com a representação RGB delas (inteiros não assinados). O modelo produz lotes de previsões (probabilidades) para duas classes.

Modelo de ML

signature:
  inputs: '[{"type": "tensor",
             "tensor-spec": 
                 {"dtype": "uint8", "shape": [-1, 300, 300, 3]}
           }]'
  outputs: '[{"type": "tensor", 
              "tensor-spec": 
                 {"dtype": "float32", "shape": [-1,2]}
            }]'

Gorjeta

O Azure Machine Learning gera um arquivo swagger para uma implantação de um modelo MLflow com uma assinatura disponível. Isso facilita o teste de implantações usando o estúdio do Azure Machine Learning.

Ambiente do modelo

Os requisitos para que o modelo seja executado são especificados no conda.yaml arquivo. MLflow pode detetar automaticamente dependências ou você pode indicá-las manualmente chamando o mlflow.<flavor>.log_model() método. Este último pode ser útil se as bibliotecas incluídas no seu ambiente não forem as que você pretendia usar.

O código a seguir é um exemplo de um ambiente usado para um modelo criado com a fastai estrutura:

conda.yaml

channels:
- conda-forge
dependencies:
- python=3.8.5
- pip
- pip:
  - mlflow
  - astunparse==1.6.3
  - cffi==1.15.0
  - configparser==3.7.4
  - defusedxml==0.7.1
  - fastai==2.4.1
  - google-api-core==2.7.1
  - ipython==8.2.0
  - psutil==5.9.0
name: mlflow-env

Nota

Qual é a diferença entre um ambiente MLflow e um ambiente do Azure Machine Learning?

Enquanto um ambiente MLflow opera no nível do modelo, um ambiente do Azure Machine Learning opera no nível do espaço de trabalho (para ambientes registrados) ou trabalhos/implantações (para ambientes anônimos). Quando você implanta modelos MLflow no Aprendizado de Máquina do Azure, o ambiente do modelo é criado e usado para implantação. Como alternativa, você pode substituir esse comportamento com a CLI v2 do Azure Machine Learning e implantar modelos MLflow usando um ambiente específico do Azure Machine Learning.

Função de previsão

Todos os modelos MLflow contêm uma predict função. Essa função é chamada quando um modelo é implantado usando uma experiência de implantação sem código. O que a predict função retorna (por exemplo, classes, probabilidades ou uma previsão) depende da estrutura (ou seja, o sabor) usada para treinamento. Leia a documentação de cada sabor para saber o que eles retornam.

Nos mesmos casos, talvez seja necessário personalizar essa predict função para alterar a maneira como a inferência é executada. Nesses casos, você precisa registrar modelos com um comportamento diferente no método predict ou registrar o sabor de um modelo personalizado.

Fluxos de trabalho para carregar modelos MLflow

Você pode carregar modelos que foram criados como modelos MLflow de vários locais, incluindo:

  • diretamente da corrida onde os modelos foram registrados
  • do sistema de arquivos onde os modelos são salvos
  • do registo modelo onde os modelos estão registados.

O MLflow fornece uma maneira consistente de carregar esses modelos, independentemente do local.

Há dois fluxos de trabalho disponíveis para carregar modelos:

  • Carregue de volta o mesmo objeto e os mesmos tipos que foram registrados: você pode carregar modelos usando o SDK MLflow e obter uma instância do modelo com tipos pertencentes à biblioteca de treinamento. Por exemplo, um modelo ONNX retorna enquanto ModelProto um modelo de árvore de decisão treinado com scikit-learn retorna um DecisionTreeClassifier objeto. Use mlflow.<flavor>.load_model() para carregar de volta o mesmo objeto de modelo e os tipos que foram registrados.

  • Carregar de volta um modelo para executar inferência: Você pode carregar modelos usando o SDK MLflow e obter um wrapper onde MLflow garante que haverá uma predict função. Não importa qual sabor você está usando, cada modelo MLflow tem uma predict função. Além disso, MLflow garante que esta função pode ser chamada usando argumentos do tipo pandas.DataFrame, numpy.ndarrayou dict[string, numpyndarray] (dependendo da assinatura do modelo). MLflow manipula a conversão de tipo para o tipo de entrada que o modelo espera. Use mlflow.pyfunc.load_model() para carregar de volta um modelo para executar inferência.