Share via


Serviço de Modelo do MLflow Herdado no Azure Databricks

Importante

Esse recurso está em uma versão prévia.

Importante

  • Esta documentação foi desativada e pode não estar atualizada. Não há mais suporte para os produtos, serviços ou tecnologias mencionados neste conteúdo.
  • As diretrizes neste artigo é para o Serviço de Modelo MLflow Herdado. O Databricks recomenda migrar seus fluxos de trabalho de serviço de modelo para o Serviço de Modelo para a implantação e escalabilidade do ponto de extremidade do modelo aprimorado. Para obter mais informações, consulte Serviço de Modelo do Azure Databricks.

O Serviço de Modelo do MLflow Herdado permite a hospedagem de modelos de machine learning por meio do Registro de Modelo como pontos de extremidade REST que são atualizados automaticamente com base na disponibilidade e nas fases de versões de modelo. Ele usa um cluster de nó único que é executado em sua própria conta dentro do que agora é chamado de plano de computação clássico. Esse plano de computação inclui a rede virtual e seus recursos de computação associados, como clusters para notebooks e trabalhos, warehouses de SQL clássicos e pro, além do modelo herdado servindo pontos de extremidade.

Quando você habilita o serviço de modelo para 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 reiniciará o cluster se ocorrer um erro e encerrará o cluster quando você desabilitar o serviço de modelo para o modelo. O serviço de modelo é sincronizado automaticamente com o Registro de Modelo e implanta todas as novas versões de modelo registradas. As versões de modelo implantadas podem ser consultadas com uma solicitação padrão da API REST. O Azure Databricks autentica as solicitações no modelo usando a autenticação padrão.

Enquanto esse serviço está em versão prévia, o Databricks recomenda o uso dele para aplicativos de baixa taxa de transferência e não críticos. A taxa de transferência de destino é de 200 qps e a disponibilidade de destino é de 99,5%, embora nenhuma garantia seja feita quanto às duas. Além disso, há um limite de tamanho de conteúdo de 16 MB por solicitação.

Cada versão do modelo é implantada por meio da implantação de modelo do MLflow e é executada em um ambiente do Conda especificado pelas respectivas dependências.

Observação

  • O cluster é mantido desde que o serviço esteja habilitado, mesmo que não exista nenhuma versão de modelo ativa. Para encerrar o cluster de serviço, desabilite o serviço de modelo para o modelo registrado.
  • O cluster é considerado um cluster para todas as finalidades, sujeito aos preços das cargas de trabalho para todas as finalidades.
  • Os scripts de inicialização global não são executados em clusters do serviço de modelo.

Importante

O Anaconda Inc. atualizou os termos de serviço dos canais de anaconda.org. Com base nos novos termos de serviço, você poderá precisar de uma licença comercial se depender do empacotamento e da distribuição do Anaconda. Confira Perguntas frequentes sobre a Edição Comercial do Anaconda para obter mais informações. O uso de qualquer canal do Anaconda é regido pelos termos de serviço.

Os modelos de MLflow registrados antes da v1.18 (Databricks Runtime 8.3 ML ou anterior) eram registrados por padrão com o canal conda defaults (https://repo.anaconda.com/pkgs/) como uma dependência. Devido a essa alteração de licença, o Databricks interrompeu o uso do canal defaults para modelos registrados usando o MLflow v1.18 e superior. O canal padrão registrado agora é conda-forge, o que aponta para a comunidade gerenciada https://conda-forge.org/.

Se você registrou um modelo antes do MLflow v1.18 sem excluir o canal defaults do ambiente conda para o modelo, esse modelo poderá ter uma dependência no canal defaults que talvez você não tenha pretendido. Para confirmar manualmente se um modelo tem essa dependência, você pode examinar o valor channel no arquivo conda.yaml que está empacotado com o modelo registrado. Por exemplo, um conda.yaml de modelo com uma dependência de canal defaults pode ser assim:

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

Como o Databricks não pode determinar se o uso do repositório do Anaconda para interagir com seus modelos é permitido em seu relacionamento com o Anaconda, o Databricks não está forçando seus clientes a fazer alterações. Se o uso do repositório do Anaconda.com por meio do Databricks for permitido nos termos do Anaconda, você não precisará tomar nenhuma medida.

Caso você queira alterar o canal usado no ambiente de um modelo, é possível registrar novamente o modelo no registro de modelo com um novo conda.yaml. Você pode fazer isso especificando o canal no parâmetro conda_env de log_model().

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

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

Requisitos

Serviço de modelo do Registro de Modelo

O serviço de modelo está disponível no Azure Databricks por meio do Registro de Modelo.

Habilitar e desabilitar o serviço de modelo

Habilite um modelo para serviço na página do modelo registrado.

  1. Clique na guia Serviço. Se o modelo ainda não estiver habilitado para serviço, o botão Habilitar Serviço será exibido.

    Botão Habilitar serviço

  2. Clique em Habilitar Serviço. A guia Serviço é exibida com o Status mostrado como Pendente. Após alguns minutos, o Status muda para Pronto.

Para desabilitar um modelo para serviço, clique em Parar.

Validar o serviço de modelo

Na guia Serviço, você pode enviar uma solicitação ao modelo fornecido e ver a resposta.

Habilitar serviço

URIs de versão do modelo

Cada versão de modelo implantado recebe um ou vários URIs exclusivos. No mínimo, cada versão de modelo recebe 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

Você também pode chamar uma versão de modelo pela fase. Por exemplo, se a versão 1 estiver na fase Produção, ela também poderá ser pontuada por meio deste URI:

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

A lista de URIs de modelo disponíveis é exibida na parte superior da guia Versões do Modelo na página de serviço.

Gerenciar as versões fornecidas

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.

Observação

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

Gerenciar direitos de acesso ao modelo

Os direitos de acesso ao modelo são herdados do Registro de Modelo. A habilitação ou a desabilitação do recurso de serviço exige a permissão ‘gerenciar’ no modelo registrado. Qualquer pessoa com direitos de leitura pode pontuar uma das versões implantadas.

Pontuar as versões de modelo implantadas

Para pontuar um modelo implantado, use a interface do usuário ou envie uma solicitação de API REST para o URI do modelo.

Pontuação por meio da interface do usuário

Essa é 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 (conforme mostrado no gráfico acima), clique em Carregar Exemplo para carregar o exemplo de entrada.

Pontuação por meio da solicitação da 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.

Observação

Como melhor prática de segurança, ao autenticar com ferramentas, sistemas, scripts e aplicativos automatizados, o Databricks recomenda que você use tokens de acesso pertencentes às entidades de serviço e não aos usuários do workspace. Para criar tokens para entidades de serviço, consulte Gerenciar tokens para uma entidade de serviço.

Considerando um MODEL_VERSION_URI como https://<databricks-instance>/model/iris-classifier/Production/invocations (em que <databricks-instance> é o nome da instância do Databricks) e um token da API REST do Databricks chamado DATABRICKS_API_TOKEN, os exemplos a seguir mostram como consultar um modelo de serviço:

Os exemplos a seguir refletem o formato de pontuação para modelos criados com o MLflow 1.x. Se preferir usar o MLflow 2.0, você precisará atualizar o formato de conteúdo da solicitação.

Bash

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

Snippet para consultar um modelo que aceita entradas de tensor. As entradas de tensor devem ser formatadas conforme descrito nos documentos da API do Serviço do TensorFlow.

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)

Power BI

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

  1. Abra o conjunto de dados que deseja pontuar.

  2. Acesse Transformar Dados.

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

  4. Acesse Exibir > Editor Avançado.

  5. Substitua o corpo da consulta pelo snippet de código abaixo, depois de preencher um DATABRICKS_API_TOKEN e um MODEL_VERSION_URI apropriados.

    (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. Dê à consulta o nome do modelo desejado.

  7. Abra o editor de consultas avançadas do conjunto de dados e aplique a função de modelo.

Monitorar os modelos fornecidos

A página de serviço exibe indicadores de status para o cluster de serviço, bem como versões de modelo individuais.

  • Para inspecionar o estado do cluster de serviço, use a guia Eventos de Modelo, que exibe uma lista de todos os eventos de serviço para esse modelo.
  • Para inspecionar o estado de uma só versão de modelo, clique na guia Versões do Modelo e role a página para ver as guias Logs ou Eventos de Versão.

Guia de serviço

Personalizar o cluster de serviço

Para personalizar o cluster de serviço, use a guia Configurações do Cluster na guia Serviço.

Configurações do cluster

  • Para modificar o tamanho da memória e o número de núcleos de um cluster de serviço, use o menu suspenso Tipo de Instância para selecionar a configuração de cluster desejada. Quando você clica em Salvar, o cluster existente é encerrado e outro cluster é criado com as configurações especificadas.
  • Para adicionar uma marca, digite o nome e o valor nos campos Adicionar Marca e clique em Adicionar.
  • Para editar ou excluir uma marca existente, clique em um dos ícones na coluna Ações da tabela Marcas.

Integração do repositório de recursos

O serviço de modelo pode pesquisar automaticamente os valores dos recursos de armazenamentos online publicados.

.. aws:

Databricks Legacy MLflow Model Serving supports automatic feature lookup from these online stores:

- Amazon DynamoDB (v0.3.8 and above)
- Amazon Aurora (MySQL-compatible)
- Amazon RDS MySQL

.. azure::

Databricks Legacy MLflow Model Serving supports automatic feature lookup from these online stores:

- Azure Cosmos DB (v0.5.0 and above)
- Azure Database for MySQL

Erros conhecidos

ResolvePackageNotFound: pyspark=3.1.0

Esse erro poderá ocorrer se um modelo depender de pyspark e for registrado em log por meio do Databricks Runtime 8.x. Se você receber esse erro, especifique a versão pyspark explicitamente ao registrar o modelo em log usando o parâmetro conda_env.

Unrecognized content type parameters: format

Esse erro pode ocorrer como resultado do novo formato de protocolo de pontuação do MLflow 2.0. Se você receber esse erro, provavelmente está usando um formato de solicitação de pontuação desatualizado. Para resolver o erro, é possível:

  • Atualizar o formato de solicitação de pontuação para o protocolo mais recente.

    Observação

    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 à API para incluir a dependência de versão do MLflow desejada no parâmetro extra_pip_requirements. Fazer isso garante o uso do formato de pontuação apropriado.

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

    Bash

    Consultar um modelo que aceita entradas de dataframe 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 que aceita entradas de tensor. As entradas de tensor devem ser formatadas conforme descrito nos documentos da API do Serviço do TensorFlow.

    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)
    

    Power BI

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

    1. Abra o conjunto de dados que deseja pontuar.

    2. Acesse Transformar Dados.

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

    4. Acesse Exibir > Editor Avançado.

    5. Substitua o corpo da consulta pelo snippet de código abaixo, depois de preencher um DATABRICKS_API_TOKEN e um MODEL_VERSION_URI apropriados.

      (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. Dê à consulta o nome do modelo desejado.

    7. Abra o editor de consultas avançadas do conjunto de dados e aplique a função de modelo.

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

Para obter mais informações sobre os formatos de dados de entrada aceitos pelo servidor (por exemplo, formato orientado a divisão do Pandas), confira a documentação do MLflow.