Udostępnij za pośrednictwem


Zoptymalizowany model języka (LLM) obsługujący

Ważne

Ta funkcja jest dostępna w publicznej wersji zapoznawczej.

Ważne

Przykłady kodu w tym przewodniku używają przestarzałych interfejsów API. Usługa Databricks zaleca używanie aprowizowanego środowiska przepływności w celu zoptymalizowanego wnioskowania maszyn LLM. Zobacz Migrowanie zoptymalizowanych punktów końcowych usługi LLM do aprowizowanej przepływności.

W tym artykule pokazano, jak włączyć optymalizacje dla dużych modeli językowych (LLMs) w usłudze Mozaika AI Model Serving.

Zoptymalizowana obsługa LLM zapewnia ulepszenia przepływności i opóźnień w zakresie od 3 do 5 razy lepsze w porównaniu z tradycyjnymi podejściami obsługującymi. Poniższa tabela zawiera podsumowanie obsługiwanych rodzin LLM i ich wariantów.

Usługa Databricks zaleca instalowanie modeli podstawowych przy użyciu witryny Databricks Marketplace. Możesz wyszukać rodzinę modeli i na stronie modelu wybrać pozycję Uzyskaj dostęp i podać poświadczenia logowania, aby zainstalować model do katalogu Unity.

Rodzina modeli Instalowanie z witryny Marketplace
Llama 2 Modele Llama 2
MPT
Mistral Modele mistralne

Wymagania

  • Zoptymalizowana obsługa usługi LLM jest obsługiwana w ramach publicznej wersji zapoznawczej wdrożeń procesora GPU.

  • Model musi być rejestrowany przy użyciu platformy MLflow 2.4 lub nowszej lub środowiska Databricks Runtime 13.2 ML lub nowszego.

  • Podczas wdrażania modeli istotne jest dopasowanie rozmiaru parametru modelu do odpowiedniego rozmiaru obliczeniowego. W przypadku modeli z co najmniej 50 miliardami parametrów skontaktuj się z zespołem konta usługi Azure Databricks, aby uzyskać dostęp do niezbędnych procesorów GPU.

    Rozmiar parametru modelu Zalecany rozmiar obliczeniowy Typ obciążenia
    7 miliardów 1xA100 GPU_LARGE
    13 miliardów 1xA100 GPU_LARGE
    30–34 miliardy 1xA100 GPU_LARGE
    70 miliardów 2xA100 GPU_LARGE_2

Rejestrowanie dużego modelu językowego

Najpierw zarejestruj model przy użyciu odmiany MLflow i określ pole zadania w metadanych MLflow transformers za pomocą polecenia metadata = {"task": "llm/v1/completions"}. Określa sygnaturę interfejsu API używaną dla punktu końcowego obsługującego model.

Zoptymalizowana obsługa usługi LLM jest zgodna z typami tras obsługiwanymi przez usługę Azure Databricks AI Gateway; obecnie , llm/v1/completions. Jeśli istnieje rodzina modeli lub typ zadania, który nie jest obsługiwany, skontaktuj się z zespołem konta usługi 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'
    )

Po zapisaniu modelu możesz zarejestrować swoje modele w Unity Catalog, wykonując następujące czynności, w których zastąpisz CATALOG.SCHEMA.MODEL_NAME trzypoziomowym imieniem modelu.


mlflow.set_registry_uri("databricks-uc")

registered_model_name=CATALOG.SCHEMA.MODEL_NAME

Tworzenie punktu końcowego obsługującego model

Następnie utwórz punkt końcowy obsługujący model. Jeśli model jest obsługiwany przez zoptymalizowaną obsługę llm, usługa Azure Databricks automatycznie tworzy zoptymalizowany punkt końcowy obsługujący model podczas próby jego obsługi.

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))

Format schematu wejściowego i wyjściowego

Zoptymalizowany punkt końcowy obsługujący usługę LLM ma schematy wejściowe i wyjściowe, które kontroluje usługa Azure Databricks. Obsługiwane są cztery różne formaty.

  • dataframe_split to serializowana ramka danych Biblioteki Pandas w formacie JSON w orientacji 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 to serializowana ramka danych Biblioteki Pandas w formacie JSON w orientacji 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
      }
    }
    
  • wystąpienia

    {
      "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
      }
    }
    
  • Wejścia

    
    {
      "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
      }
    }
    

Wykonywanie zapytań względem punktu końcowego

Gdy punkt końcowy będzie gotowy, możesz wykonać zapytanie, wysyłając żądanie interfejsu API. W zależności od rozmiaru i złożoności modelu przygotowanie punktu końcowego może potrwać 30 minut lub więcej.


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()))

Ograniczenia

  • Biorąc pod uwagę zwiększone wymagania dotyczące instalacji modeli obsługiwanych na procesorze GPU, tworzenie obrazu kontenera na potrzeby obsługi procesora GPU trwa dłużej niż tworzenie obrazu na potrzeby obsługi procesora CPU.
    • Rozmiar modelu ma również wpływ na tworzenie obrazu. Na przykład modele, które mają 30 miliardów parametrów lub więcej, mogą zająć co najmniej godzinę na zbudowanie.
    • Usługa Databricks ponownie używa tego samego kontenera przy następnym wdrożeniu tej samej wersji modelu, więc kolejne wdrożenia potrwają mniej czasu.
  • Skalowanie automatyczne dla obsługi procesora GPU trwa dłużej niż w przypadku obsługi procesora CPU ze względu na zwiększony czas konfigurowania modeli obsługiwanych w obliczeniach procesora GPU. Usługa Databricks zaleca nadmierną aprowizację, aby uniknąć przekroczenia limitu czasu żądań.