De artefatos a modelos no MLflow

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

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

Se você não está familiarizado com MLflow, talvez não conheça a diferença entre registrar artefatos ou arquivos versus registrar modelos de MLflow. Há algumas diferenças fundamentais entre os dois:

Artefato

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

Talvez você já tenha registrado artefatos de registro em log:

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

mlflow.log_artifact(filename)

Modelar

Um modelo no MLflow também é um artefato. No entanto, fazemos suposições mais fortes sobre esse tipo de artefato. Tais suposições proporcionam um contrato claro entre os arquivos salvos e o que eles significam. Ao registrar seus modelos como artefatos (arquivos simples), você precisa saber o que o construtor de modelos desejava 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 log 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 têm um Swagger gerado automaticamente e o recurso Teste 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 os modelos.

Você pode registrar modelos usando o SDK do 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. Esse 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 modelo MLflow de exemplo 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 nomenclatura desta pasta. A pasta contém o arquivo MLmodel, 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 o arquivo MLmodel para um modelo de pesquisa visual computacional treinado com fastai pode ser semelhante a:

MLmodel

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]}
            }]'

Variantes de modelo

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

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

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

Assinatura de modelo

A 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 do modelo no momento da implantação. Se uma assinatura está disponível, o MLflow impõe tipos de entrada quando os dados são enviados ao seu modelo. Para mais informações, confira imposição de assinatura do MLflow.

As assinaturas são indicadas quando os modelos são registrados e elas são persistidas na seção signature do arquivo MLmodel. O recurso de log automático no MLflow infere automaticamente as assinaturas segundo os melhores esforços. 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.

Há dois tipos de assinaturas:

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

O exemplo a seguir corresponde a um modelo de pesquisa visual computacional treinado com fastai. Esse modelo recebe um lote de imagens representadas como tensores com a forma (300, 300, 3) e com sua representação RGB (inteiros sem sinal). Esse modelo gera lotes de previsões (probabilidades) para duas classes.

MLmodel

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

Dica

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

Ambiente de modelo

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

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

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

Observação

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

Embora um ambiente do MLflow opere no nível do modelo, um ambiente do Azure Machine Learning opera no nível do workspace (para ambientes registrados) ou dos trabalhos/implantações (para ambientes anônimos). Quando você implanta modelos de MLflow no Azure Machine Learning, 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 do MLflow usando um ambiente específico do Azure Machine Learning.

Função Predict

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

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

Fluxos de trabalho para carregar modelos de MLflow

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

  • diretamente da execução em que os modelos foram registrados
  • do sistema de arquivos em que os modelos são salvos
  • do registro de modelo em que os modelos são registrados.

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

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

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

  • Recarregar modelo para executar a inferência: é possível carregar modelos usando o SDK do MLflow e obter um wrapper em que o MLflow garante que haverá uma função predict. Não importa o tipo usado, todo modelo do MLflow precisa de uma função predict. Além disso, o MLflow garante que essa função possa ser chamada usando argumentos do tipo pandas.DataFrame, numpy.ndarray ou dict[string, numpyndarray] (dependendo da assinatura do modelo). O MLflow lida com a conversão para o tipo de entrada que o modelo espera. Use mlflow.pyfunc.load_model() para carregar de volta um modelo para executar a inferência.