Condividi tramite


Servizio LLM (Optimized Large Language Model)

Importante

Questa funzionalità è disponibile in anteprima pubblica.

Importante

Gli esempi di codice in questa guida usano API deprecate. Databricks consiglia di usare l'esperienza di produttività con provisioning per l'inferenza ottimizzata degli LLM. Vedere Eseguire la migrazione di endpoint di servizio LLM ottimizzati per la produttività con provisioning.

Questo articolo illustra come abilitare le ottimizzazioni per modelli di linguaggio di grandi dimensioni (LLM) in Mosaic AI Model Serving.

Il servizio LLM ottimizzato offre miglioramenti della produttività e della latenza nell'intervallo di 3-5 volte migliore rispetto agli approcci di servizio tradizionali. La tabella seguente riepiloga le famiglie LLM supportate e le relative varianti.

Databricks consiglia di installare modelli di base usando Databricks Marketplace. È possibile cercare una famiglia di modelli e nella pagina del modello selezionare Ottenere l'accesso e specificare le credenziali di accesso per installare il modello in Unity Catalog.

Famiglia del modello Installare da Marketplace
Llama 2 Modelli Llama 2
MPT
Mistral Modelli Mistral

Requisiti

  • Il servizio LLM ottimizzato è supportato come parte dell'anteprima pubblica delle distribuzioni GPU.

  • Il modello deve essere registrato usando MLflow 2.4 e versioni successive o Databricks Runtime 13.2 ML e versioni successive.

  • Quando si distribuiscono modelli, è essenziale associare le dimensioni dei parametri del modello alle dimensioni di calcolo appropriate. Per i modelli con 50 miliardi o più parametri, contattare il team dell'account Azure Databricks per accedere alle GPU necessarie.

    Dimensioni dei parametri del modello Dimensioni di calcolo consigliate Tipo di carico di lavoro
    7 miliardi 1xA100 GPU_LARGE
    13 miliardi 1xA100 GPU_LARGE
    30-34 miliardi 1xA100 GPU_LARGE
    70 miliardi 2xA100 GPU_LARGE_2

Registrare il modello linguistico di grandi dimensioni

Prima di tutto, registrare il modello con la versione MLflow transformers e specificare il campo attività nei metadati MLflow con metadata = {"task": "llm/v1/completions"}. Specifica la firma API usata per l'endpoint di servizio del modello.

Il servizio LLM ottimizzato è compatibile con i tipi di route supportati dal gateway di IA di Azure Databricks; attualmente, llm/v1/completions. Se è presente una famiglia di modelli o un tipo di attività che si vuole servire non è supportato, contattare il team dell'account di Azure Databricks.

model = AutoModelForCausalLM.from_pretrained("mosaicml/mpt-7b-instruct",torch_dtype=torch.bfloat16, trust_remote_code=True)
tokenizer = AutoTokenizer.from_pretrained("mosaicml/mpt-7b-instruct")
with mlflow.start_run():
    components = {
        "model": model,
        "tokenizer": tokenizer,
    }
    mlflow.transformers.log_model(
        artifact_path="model",
        transformers_model=components,
        input_example=["Below is an instruction that describes a task. Write a response that appropriately completes the request.\n\n### Instruction:\nWhat is Apache Spark?\n\n### Response:\n"],
        metadata={"task": "llm/v1/completions"},
        registered_model_name='mpt'
    )

Dopo che il modello è stato registrato, è possibile registrare i modelli in Unity Catalog utilizzando il seguente comando, sostituendo CATALOG.SCHEMA.MODEL_NAME con il nome a tre livelli del modello.


mlflow.set_registry_uri("databricks-uc")

registered_model_name=CATALOG.SCHEMA.MODEL_NAME

Creare l'endpoint di servizio del modello

Creare quindi l'endpoint di servizio del modello. Se il modello è supportato dal servizio LLM ottimizzato, Azure Databricks crea automaticamente un endpoint ottimizzato per il servizio del modello quando si tenta di usarlo.

import requests
import json

# Set the name of the MLflow endpoint
endpoint_name = "llama2-3b-chat"

# Name of the registered MLflow model
model_name = "ml.llm-catalog.llama-13b"

# Get the latest version of the MLflow model
model_version = 3

# Specify the type of compute (CPU, GPU_SMALL, GPU_LARGE, etc.)
workload_type = "GPU_LARGE"

# Specify the scale-out size of compute (Small, Medium, Large, etc.)
workload_size = "Small"

# Specify Scale to Zero (only supported for CPU endpoints)
scale_to_zero = False

# Get the API endpoint and token for the current notebook context
API_ROOT = dbutils.notebook.entry_point.getDbutils().notebook().getContext().apiUrl().get()
API_TOKEN = dbutils.notebook.entry_point.getDbutils().notebook().getContext().apiToken().get()

# send the POST request to create the serving endpoint

data = {
    "name": endpoint_name,
    "config": {
        "served_models": [
            {
                "model_name": model_name,
                "model_version": model_version,
                "workload_size": workload_size,
                "scale_to_zero_enabled": scale_to_zero,
                "workload_type": workload_type,
            }
        ]
    },
}

headers = {"Context-Type": "text/json", "Authorization": f"Bearer {API_TOKEN}"}

response = requests.post(
    url=f"{API_ROOT}/api/2.0/serving-endpoints", json=data, headers=headers
)

print(json.dumps(response.json(), indent=4))

Formato dello schema di input e output

Un endpoint di servizio LLM ottimizzato ha schemi di input e output che Azure Databricks controlla. Sono supportati quattro formati diversi.

  • dataframe_split è un Dataframe di Pandas serializzato in JSON nell’orientamento split.

    
    {
      "dataframe_split":{
        "columns":["prompt"],
        "index":[0],
        "data":[["Below is an instruction that describes a task. Write a response that appropriately completes the request.\n\n### Instructions:\nWhat is Apache Spark?\n\n### Response:\n"]]
      },
      "params": {
        "temperature": 0.5,
        "max_tokens": 100,
        "stop": ["word1","word2"],
        "candidate_count": 1
      }
    }
    
  • dataframe_records è un Dataframe di Pandas serializzato in JSON nell’orientamento records.

    {
      "dataframe_records": [{"prompt": "Below is an instruction that describes a task. Write a response that appropriately completes the request.\n\n### Instructions:\nWhat is Apache Spark?\n\n### Response:\n"}],
      "params": {
        "temperature": 0.5,
        "max_tokens": 100,
        "stop": ["word1","word2"],
        "candidate_count": 1
      }
    }
    
  • instances

    {
      "instances": [
       {
         "prompt": "Below is an instruction that describes a task. Write a response that appropriately completes the request.\n\n### Instructions:\nWhat is Apache Spark?\n\n### Response:\n"
       }
      ],
      "params": {
      "temperature": 0.5,
      "max_tokens": 100,
      "stop": ["word1","word2"],
      "candidate_count": 1
      }
    }
    
  • input

    
    {
      "inputs": {
        "prompt": "Below is an instruction that describes a task. Write a response that appropriately completes the request.\n\n### Instructions:\nWhat is Apache Spark?\n\n### Response:\n"
      },
      "params": {
        "temperature": 0.5,
        "max_tokens": 100,
        "stop": ["word1","word2"],
        "candidate_count": 1
      }
    }
    

Eseguire la query dell’endpoint

Una volta pronto l'endpoint, è possibile eseguirne una query eseguendo una richiesta API. A seconda delle dimensioni e della complessità del modello, possono essere necessari 30 minuti o più per preparare l'endpoint.


data = {
    "inputs": {
        "prompt": [
            "Hello, I'm a language model,"
        ]
    },
    "params": {
        "max_tokens": 100,
        "temperature": 0.0
    }
}

headers = {"Context-Type": "text/json", "Authorization": f"Bearer {API_TOKEN}"}

response = requests.post(
    url=f"{API_ROOT}/serving-endpoints/{endpoint_name}/invocations", json=data, headers=headers
)

print(json.dumps(response.json()))

Limiti

  • Data l'aumento dei requisiti di installazione per i modelli serviti in GPU, la creazione di immagini del contenitore per il servizio della GPU richiede più tempo rispetto alla creazione di immagini per il servizio della CPU.
    • Le dimensioni del modello influisce anche sulla creazione di immagini. Ad esempio, i modelli con 30 miliardi di parametri o più possono richiedere almeno un'ora per la compilazione.
    • Databricks riutilizza lo stesso contenitore alla successiva distribuzione della stessa versione del modello, quindi le distribuzioni successive richiederanno meno tempo.
  • La scalabilità automatica per la gestione della GPU richiede più tempo rispetto alla gestione della CPU, a causa di un aumento del tempo di configurazione per i modelli serviti nel calcolo GPU. Databricks consiglia il provisioning eccessivo per evitare timeout delle richieste.