Disponibilização de modelos MLflow antiga no Azure Databricks

Importante

Esta funcionalidade está em Pré-visualização Pública.

Importante

  • Esta documentação foi desativada e pode não ser atualizada. Os produtos, serviços ou tecnologias mencionados neste conteúdo não são mais suportados.
  • A orientação neste artigo é para o Legacy MLflow Model Serving. A Databricks recomenda que migre os seus fluxos de trabalho de disponibilização de modelos para o Model Serving, para beneficiar de uma implementação de endpoints de modelo melhorada e de maior escalabilidade. Para mais informações, consulte Implementar modelos usando Model Serving.

O Legacy MLflow Model Serving permite hospedar modelos de aprendizado de máquina do Model Registry como pontos de extremidade REST que são atualizados automaticamente com base na disponibilidade de versões de modelo e seus estágios. Utiliza um cluster de nó único que é executado na sua própria conta dentro do que é agora chamado de plano clássico de computação. Este plano de computação inclui a rede virtual e os respetivos recursos de computação associados, como clusters para notebooks e tarefas, armazéns de dados SQL Pro e clássicos, e pontos finais de serviço de modelos legados.

Quando você habilita o serviço de modelo para um determinado modelo registrado, o Azure Databricks cria automaticamente um cluster exclusivo para o modelo e implanta todas as versões não arquivadas do modelo nesse cluster. O Azure Databricks reinicia o cluster se ocorrer um erro e encerra o cluster quando você desabilita o serviço de modelo para o modelo. O serviço de modelo sincroniza automaticamente com o Registro de modelo e implanta todas as novas versões de modelo registrado. As versões de modelo implantadas podem ser consultadas com uma solicitação de API REST padrão. O Azure Databricks autentica solicitações para o modelo usando sua autenticação padrão.

Enquanto esse serviço está em visualização, o Databricks recomenda seu uso para aplicativos de baixa taxa de transferência e não críticos. A taxa de transferência alvo é de 200 qps e a disponibilidade alvo é de 99,5%, embora nenhuma garantia seja feita quanto a isso. Além disso, há um limite de tamanho de carga útil de 16 MB por solicitação.

Cada versão do modelo é implementada utilizando a funcionalidade de implementação de modelos do MLflow e é executada num ambiente Conda especificado pelas suas dependências.

Nota

  • O cluster é mantido enquanto o serviço estiver habilitado, mesmo que não exista uma versão ativa do modelo. Para encerrar o cluster de disponibilização, desative a disponibilização do modelo do modelo registado.
  • O cluster é considerado um cluster de uso geral, sujeito aos preços aplicáveis a cargas de trabalho de uso geral.
  • Os scripts de inicialização global não são executados em clusters de serviço de modelo.

Importante

Anaconda Inc. atualizou os seus termos de serviço para os canais do anaconda.org. Com base nos novos termos de serviço, você pode precisar de uma licença comercial se depender da embalagem e distribuição da Anaconda. Consulte Anaconda Commercial Edition FAQ para obter mais informações. Seu uso de qualquer canal Anaconda é regido por seus termos de serviço.

Os modelos MLflow registados antes da v1.18 (Databricks Runtime 8.3 ML ou versões anteriores) eram, por predefinição, registados com o canal conda defaults (https://repo.anaconda.com/pkgs/) como dependência. Devido a esta alteração de licença, a Databricks deixou de utilizar o canal defaults para modelos registados com o MLflow v1.18 e posteriores. O canal predefinido agora registado é conda-forge, apontando para o https://conda-forge.org/ gerido pela comunidade.

Se você registrou um modelo antes do MLflow v1.18 sem excluir o defaults canal do ambiente conda para o modelo, esse modelo pode ter uma dependência do defaults canal que você pode não ter pretendido. Para confirmar manualmente se um modelo tem esta dependência, pode examinar o valor channel no ficheiro conda.yaml incluído com o modelo registado. Por exemplo, um modelo com uma dependência de canal conda.yaml pode ter esta aparência: defaults

channels:
- defaults
dependencies:
- python=3.8.8
- pip
- pip:
    - mlflow
    - scikit-learn==0.23.2
    - cloudpickle==1.6.0
      name: mlflow-env

Como a Databricks não pode determinar se seu uso do repositório Anaconda para interagir com seus modelos é permitido sob seu relacionamento com a Anaconda, a Databricks não está forçando seus clientes a fazer alterações. Se o seu uso do repositório de Anaconda.com através do uso do Databricks for permitido sob os termos da Anaconda, você não precisará tomar nenhuma ação.

Se desejar alterar o canal usado no ambiente de um modelo, pode reinscrever o modelo no registo do modelo com um novo conda.yaml. Você pode fazer isso especificando o conda_env canal no parâmetro de log_model().

Para obter mais informações sobre a log_model() API, consulte a documentação do MLflow para o modelo com o qual você está trabalhando, por exemplo, log_model para scikit-learn.

Para obter mais informações sobre conda.yaml arquivos, consulte a documentação do MLflow.

Requisitos

  • O Legacy MLflow Model Serving está disponível para modelos Python MLflow. Você deve declarar todas as dependências do modelo no ambiente conda. Consulte Dependências do modelo de log.
  • Para habilitar o Serviço de Modelo, você deve ter permissão de criação de cluster.

Disponibilização de modelos a partir do Registo de Modelos

O serviço de modelo está disponível no Azure Databricks a partir do Registo de Modelo.

Ativar e desativar o serviço de modelo

Pode ativar um modelo para disponibilização na sua página do modelo registado.

  1. Clique no separador Disponibilização. Se o modelo ainda não estiver ativado para disponibilização, aparece o botão Ativar disponibilização.

    Ativar botão de disponibilização

  2. Clique em Ativar Serviço. O separador Serviço aparece com Status indicado como Pendente. Após alguns minutos, o Status muda para Pronto.

Para desativar um modelo de serviço, clique em Parar.

Validar modelo de serviço

Na guia Servir, você pode enviar uma solicitação para o modelo atendido e visualizar a resposta.

Ativar a veiculação

URIs da versão do modelo

A cada versão do modelo implantado é atribuído um ou vários URIs exclusivos. No mínimo, a cada versão do modelo é atribuído um URI construído da seguinte forma:

<databricks-instance>/model/<registered-model-name>/<model-version>/invocations

Por exemplo, para chamar a versão 1 de um modelo registrado como iris-classifier, use este URI:

https://<databricks-instance>/model/iris-classifier/1/invocations

Também pode invocar uma versão do modelo pelo respetivo estágio. Por exemplo, se a versão 1 estiver na fase Production, também pode ser classificada utilizando este URI:

https://<databricks-instance>/model/iris-classifier/Production/invocations

A lista de URIs de modelos disponíveis aparece na parte superior do separador Versões do modelo na página de disponibilização.

Gerenciar versões servidas

Todas as versões de modelo ativas (não arquivadas) são implantadas e você pode consultá-las usando os URIs. O Azure Databricks implanta automaticamente novas versões de modelo quando elas são registradas e remove automaticamente as versões antigas quando elas são arquivadas.

Nota

Todas as versões implantadas de um modelo registrado compartilham o mesmo cluster.

Gerenciar direitos de acesso ao modelo

Os direitos de acesso ao modelo são herdados do Registro do modelo. Ativar ou desativar o recurso de serviço requer a permissão 'gerir' no modelo registrado. Qualquer pessoa com permissões de leitura pode atribuir uma pontuação a qualquer uma das versões implementadas.

Avaliar versões de modelos implementados

Para pontuar um modelo implantado, você pode usar a interface do usuário ou enviar uma solicitação de API REST para o URI do modelo.

Pontuação via UI

Esta é a maneira mais fácil e rápida de testar o modelo. Você pode inserir os dados de entrada do modelo no formato JSON e clicar em Enviar solicitação. Se o modelo tiver sido registrado com um exemplo de entrada (como mostrado no gráfico acima), clique em Carregar exemplo para carregar o exemplo de entrada.

Pontuação via solicitação de API REST

Você pode enviar uma solicitação de pontuação por meio da API REST usando a autenticação padrão do Databricks. Os exemplos abaixo demonstram a autenticação usando um token de acesso pessoal com MLflow 1.x.

Nota

Como prática recomendada de segurança, quando você se autentica com ferramentas, sistemas, scripts e aplicativos automatizados, o Databricks recomenda que você use tokens de acesso pessoal pertencentes a entidades de serviço em vez de usuários do espaço de trabalho. Para criar tokens para entidades de serviço, consulte Gerenciar tokens para uma entidade de serviço.

Tendo um MODEL_VERSION_URI como https://<databricks-instance>/model/iris-classifier/Production/invocations (em que <databricks-instance> é o nome da sua instância do Databricks) e um token da API REST do Databricks com o nome DATABRICKS_API_TOKEN, os exemplos seguintes mostram como consultar um modelo disponibilizado:

Os exemplos a seguir refletem o formato de pontuação para modelos criados com MLflow 1.x. Se preferir usar o MLflow 2.0, será necessário atualizar o formato de carga útil da solicitação.

Bash

Trecho para consultar um modelo que aceita entradas de dataframe.

curl -X POST -u token:$DATABRICKS_API_TOKEN $MODEL_VERSION_URI \
  -H 'Content-Type: application/json' \
  -d '[
    {
      "sepal_length": 5.1,
      "sepal_width": 3.5,
      "petal_length": 1.4,
      "petal_width": 0.2
    }
  ]'

Trecho para consultar um modelo que aceita entradas tensoras. As entradas do tensor devem ser formatadas conforme descrito nos documentos da API do TensorFlow Serving.

curl -X POST -u token:$DATABRICKS_API_TOKEN $MODEL_VERSION_URI \
   -H 'Content-Type: application/json' \
   -d '{"inputs": [[5.1, 3.5, 1.4, 0.2]]}'

Python

import numpy as np
import pandas as pd
import requests

def create_tf_serving_json(data):
  return {'inputs': {name: data[name].tolist() for name in data.keys()} if isinstance(data, dict) else data.tolist()}

def score_model(model_uri, databricks_token, data):
  headers = {
    "Authorization": f"Bearer {databricks_token}",
    "Content-Type": "application/json",
  }
  data_json = data.to_dict(orient='records') if isinstance(data, pd.DataFrame) else create_tf_serving_json(data)
  response = requests.request(method='POST', headers=headers, url=model_uri, json=data_json)
  if response.status_code != 200:
      raise Exception(f"Request failed with status {response.status_code}, {response.text}")
  return response.json()

# Scoring a model that accepts pandas DataFrames
data =  pd.DataFrame([{
  "sepal_length": 5.1,
  "sepal_width": 3.5,
  "petal_length": 1.4,
  "petal_width": 0.2
}])
score_model(MODEL_VERSION_URI, DATABRICKS_API_TOKEN, data)

# Scoring a model that accepts tensors
data = np.asarray([[5.1, 3.5, 1.4, 0.2]])
score_model(MODEL_VERSION_URI, DATABRICKS_API_TOKEN, data)

PowerBI

Você pode pontuar um conjunto de dados no Power BI Desktop usando as seguintes etapas:

  1. Abra o conjunto de dados que você deseja pontuar.

  2. Aceda a Transformar dados.

  3. Clique com o botão direito do mouse no painel esquerdo e selecione Criar nova consulta.

  4. Vá para Ver > Editor Avançado.

  5. Substitua o corpo da consulta pelo trecho de código abaixo, após preencher adequadamente DATABRICKS_API_TOKEN e MODEL_VERSION_URI.

    (dataset as table ) as table =>
    let
      call_predict = (dataset as table ) as list =>
      let
        apiToken = DATABRICKS_API_TOKEN,
        modelUri = MODEL_VERSION_URI,
        responseList = Json.Document(Web.Contents(modelUri,
          [
            Headers = [
              #"Content-Type" = "application/json",
              #"Authorization" = Text.Format("Bearer #{0}", {apiToken})
            ],
            Content = Json.FromValue(dataset)
          ]
        ))
      in
        responseList,
      predictionList = List.Combine(List.Transform(Table.Split(dataset, 256), (x) => call_predict(x))),
      predictionsTable = Table.FromList(predictionList, (x) => {x}, {"Prediction"}),
      datasetWithPrediction = Table.Join(
        Table.AddIndexColumn(predictionsTable, "index"), "index",
        Table.AddIndexColumn(dataset, "index"), "index")
    in
      datasetWithPrediction
    
  6. Nomeie a consulta com o nome do modelo desejado.

  7. Abra o editor de consultas avançado para seu conjunto de dados e aplique a função de modelo.

Monitorizar modelos em produção

A página de disponibilização apresenta indicadores de estado para o cluster de disponibilização, bem como para versões individuais do modelo.

  • Para inspecionar o estado do cluster de disponibilização, utilize o separador Eventos do modelo, que apresenta uma lista de todos os eventos de disponibilização deste modelo.
  • Para inspecionar o estado de uma única versão do modelo, clique no separador Model Versions e desloque-se para ver os separadores Logs ou Version Events.

Separador de serviço

Personalize o cluster de disponibilização

Para personalizar o cluster de serviço, use o separador Configurações do Cluster no separador Serviço.

Configurações de cluster

  • Para modificar o tamanho da memória e o número de núcleos de um cluster de processamento, utilize o menu suspenso Tipo de instância para selecionar a configuração do cluster pretendida. Quando você clica em Salvar, o cluster existente é encerrado e um novo cluster é criado com as configurações especificadas.
  • Para adicionar uma etiqueta, escreva o nome e o valor nos campos Adicionar Etiqueta e clique em Adicionar.
  • Para editar ou eliminar uma etiqueta existente, clique num dos ícones na coluna Ações da tabela Etiquetas .

Integração com a loja de recursos

O serviço de modelos legados pode procurar automaticamente valores de atributos em lojas online publicadas.

O Databricks Legacy MLflow Model Serving suporta a pesquisa automática de funcionalidades das lojas online:

  • Azure Cosmos DB (v0.5.0 e superior)
  • Base de Dados do Azure para MySQL

Erros conhecidos

ResolvePackageNotFound: pyspark=3.1.0

Este erro pode ocorrer se um modelo depende de pyspark e é registado com o Databricks Runtime 8.x. Se você vir esse erro, especifique a pyspark versão explicitamente ao registrar o modelo, usando o conda_env parâmetro.

Unrecognized content type parameters: format

Este erro pode ocorrer como resultado do novo formato de protocolo de pontuação MLflow 2.0. Se você estiver vendo esse erro, provavelmente está usando um formato de solicitação de pontuação desatualizado. Para resolver o erro, você pode:

  • Atualize o formato do seu pedido de pontuação para o protocolo mais recente.

    Nota

    Os exemplos a seguir refletem o formato de pontuação introduzido no MLflow 2.0. Se preferir usar o MLflow 1.x, você pode modificar suas log_model() chamadas de API para incluir a dependência de versão do MLflow desejada no extra_pip_requirements parâmetro. Isso garante que o formato de pontuação apropriado seja usado.

        mlflow.<flavor>.log_model(..., extra_pip_requirements=["mlflow==1.*"])
    

    Bash

    Consulte um modelo que aceite entradas em DataFrames do pandas.

    curl -X POST -u token:$DATABRICKS_API_TOKEN $MODEL_VERSION_URI \
      -H 'Content-Type: application/json' \
      -d '{
          "dataframe_records": [{"sepal_length (cm)": 5.1, "sepal_width (cm)": 3.5, "petal_length (cm)": 1.4, "petal_width": 0.2},
                                {"sepal_length (cm)": 4.2, "sepal_width (cm)": 5.0, "petal_length (cm)": 0.8, "petal_width": 0.5}]
          }'
    

    Consultar um modelo aceitando entradas tensoras. As entradas do tensor devem ser formatadas conforme descrito nos documentos da API do TensorFlow Serving.

    curl -X POST -u token:$DATABRICKS_API_TOKEN $MODEL_VERSION_URI \
      -H 'Content-Type: application/json' \
      -d '{"inputs": [[5.1, 3.5, 1.4, 0.2]]}'
    

    Python

    import numpy as np
    import pandas as pd
    import requests
    
    def create_tf_serving_json(data):
      return {'inputs': {name: data[name].tolist() for name in data.keys()} if isinstance(data, dict) else data.tolist()}
    
    def score_model(model_uri, databricks_token, data):
      headers = {
        "Authorization": f"Bearer {databricks_token}",
        "Content-Type": "application/json",
      }
      data_dict = {'dataframe_split': data.to_dict(orient='split')} if isinstance(data, pd.DataFrame) else create_tf_serving_json(data)
      data_json = json.dumps(data_dict)
      response = requests.request(method='POST', headers=headers, url=model_uri, json=data_json)
      if response.status_code != 200:
          raise Exception(f"Request failed with status {response.status_code}, {response.text}")
      return response.json()
    
    # Scoring a model that accepts pandas DataFrames
    data =  pd.DataFrame([{
      "sepal_length": 5.1,
      "sepal_width": 3.5,
      "petal_length": 1.4,
      "petal_width": 0.2
    }])
    score_model(MODEL_VERSION_URI, DATABRICKS_API_TOKEN, data)
    
    # Scoring a model that accepts tensors
    data = np.asarray([[5.1, 3.5, 1.4, 0.2]])
    score_model(MODEL_VERSION_URI, DATABRICKS_API_TOKEN, data)
    

    PowerBI

    Você pode pontuar um conjunto de dados no Power BI Desktop usando as seguintes etapas:

    1. Abra o conjunto de dados que você deseja pontuar.

    2. Aceda a Transformar dados.

    3. Clique com o botão direito do mouse no painel esquerdo e selecione Criar nova consulta.

    4. Vá para Ver > Editor Avançado.

    5. Substitua o corpo da consulta pelo trecho de código abaixo, após preencher adequadamente DATABRICKS_API_TOKEN e MODEL_VERSION_URI.

      (dataset as table ) as table =>
      let
        call_predict = (dataset as table ) as list =>
        let
          apiToken = DATABRICKS_API_TOKEN,
          modelUri = MODEL_VERSION_URI,
          responseList = Json.Document(Web.Contents(modelUri,
            [
              Headers = [
                #"Content-Type" = "application/json",
                #"Authorization" = Text.Format("Bearer #{0}", {apiToken})
              ],
              Content = Json.FromValue(dataset)
            ]
          ))
        in
          responseList,
        predictionList = List.Combine(List.Transform(Table.Split(dataset, 256), (x) => call_predict(x))),
        predictionsTable = Table.FromList(predictionList, (x) => {x}, {"Prediction"}),
        datasetWithPrediction = Table.Join(
          Table.AddIndexColumn(predictionsTable, "index"), "index",
          Table.AddIndexColumn(dataset, "index"), "index")
      in
        datasetWithPrediction
      
    6. Nomeie a consulta com o nome do modelo desejado.

    7. Abra o editor de consultas avançado para seu conjunto de dados e aplique a função de modelo.

  • Se sua solicitação de pontuação usa o cliente MLflow, como mlflow.pyfunc.spark_udf(), atualize seu cliente MLflow para a versão 2.0 ou superior para usar o formato mais recente. Saiba mais sobre o protocolo de pontuação do Modelo MLflow atualizado no MLflow 2.0.

Para obter mais informações sobre os formatos de dados de entrada aceites pelo servidor (por exemplo, o formato split-oriented do pandas), consulte a documentação do MLflow.