Gestisci un LLM su GPU L4 con Ray


Questa guida mostra come gestire modelli linguistici di grandi dimensioni (LLM) utilizzando Ray e il componente aggiuntivo Ray Operator con Google Kubernetes Engine (GKE).

In questa guida, puoi pubblicare uno qualsiasi dei seguenti modelli:

Questa guida illustra anche le tecniche di distribuzione dei modelli, come il multiplexing del modello e la composizione del modello, supportate Framework Ray Serve.

Contesto

Il framework Ray fornisce una piattaforma end-to-end di AI/ML per l'addestramento, l'addestramento e l'inferenza dei carichi di lavoro di machine learning. Ray Serve è un in Ray che puoi usare per pubblicare modelli LLM popolari di Hugging Face.

Il numero di GPU varia a seconda del formato dei dati del modello. In questo un modello può usare una o due GPU L4.

Questa guida illustra i seguenti passaggi:

  1. Crea un cluster GKE Autopilot o Standard con Componente aggiuntivo Ray Operator in un bucket in cui è abilitato il controllo delle versioni.
  2. Esegui il deployment di una risorsa RayService che scarica e gestisce un modello linguistico di grandi dimensioni (LLM). di Hugging Face.
  3. Esegui il deployment di un'interfaccia di chat e di un dialogo con gli LLM.

Prima di iniziare

Prima di iniziare, assicurati di aver eseguito le seguenti attività:

  • Attiva l'API Google Kubernetes Engine.
  • Abilita l'API Google Kubernetes Engine
  • Se vuoi utilizzare Google Cloud CLI per questa attività, install e poi inizializzare con gcloud CLI. Se hai già installato gcloud CLI, scarica la versione più recente eseguendo gcloud components update.
  • Crea un account Hugging Face, se non l'hai ancora fatto ne hai uno.
  • Assicurati di avere un Token Hugging Face.
  • Assicurati di avere accesso al modello Hugging Face che vuoi utilizzare. In genere questa operazione viene concessa firmando un contratto e richiedendo l'accesso al proprietario del modello nella pagina del modello di Hugging Face.
  • Assicurati di avere una quota GPU nella regione us-central1. Per saperne di più, vedi Quota GPU.

prepara l'ambiente

  1. Nella console Google Cloud, avvia un'istanza di Cloud Shell:
    Apri Cloud Shell

  2. Clona il repository di esempio:

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git
    cd kubernetes-engine-samples/ai-ml/gke-ray/rayserve/llm
    export TUTORIAL_HOME=`pwd`
    
  3. Imposta le variabili di ambiente predefinite:

    gcloud config set project PROJECT_ID
    export PROJECT_ID=$(gcloud config get project)
    export COMPUTE_REGION=us-central1
    export CLUSTER_VERSION=CLUSTER_VERSION
    export HF_TOKEN=HUGGING_FACE_TOKEN
    

    Sostituisci quanto segue:

    • PROJECT_ID: il tuo account Google Cloud ID progetto.
    • CLUSTER_VERSION: la versione GKE da per gli utilizzi odierni. Deve essere 1.30.1 o una versione successiva.
    • HUGGING_FACE_TOKEN: il tuo accesso a Hugging Face di accesso.

Crea un cluster con un pool di nodi GPU

Puoi gestire un LLM su GPU L4 con Ray in un ambiente GKE Cluster Autopilot o Standard con il componente aggiuntivo Ray Operator. In genere consigliamo di usare un cluster Autopilot per una gestione con Kubernetes. Scegli invece un cluster Standard se il tuo caso d'uso richiede scalabilità elevata o se si desidera un maggiore controllo sulla configurazione del cluster. A scegli la modalità operativa GKE più adatta al tuo carichi di lavoro, vedi Scegli una modalità operativa di GKE.

Usa Cloud Shell per creare un cluster Autopilot o Standard:

Autopilot

Crea un cluster Autopilot con il componente aggiuntivo Ray Operator abilitato:

gcloud container clusters create-auto rayserve-cluster \
    --enable-ray-operator \
    --cluster-version=${CLUSTER_VERSION} \
    --location=${COMPUTE_REGION}

Standard

Crea un cluster Standard con il componente aggiuntivo Ray Operator abilitato:

gcloud container clusters create rayserve-cluster \
    --addons=RayOperator \
    --cluster-version=${CLUSTER_VERSION} \
    --machine-type=g2-standard-24 \
    --location=${COMPUTE_ZONE} \
    --num-nodes=2 \
    --accelerator type=nvidia-l4,count=2,gpu-driver-version=latest

Crea un secret Kubernetes per le credenziali di Hugging Face

In Cloud Shell, crea un secret di Kubernetes nel seguente modo:

  1. Configura kubectl per comunicare con il tuo cluster:

    gcloud container clusters get-credentials ${CLUSTER_NAME} --location=${COMPUTE_REGION}
    
  2. Crea un secret Kubernetes che contiene il token Hugging Face:

    kubectl create secret generic hf-secret \
      --from-literal=hf_api_token=${HF_TOKEN} \
      --dry-run=client -o yaml | kubectl apply -f -
    

Esegui il deployment del modello LLM

Il repository GitHub che hai clonato ha una directory per ogni modello include una configurazione RayService. La configurazione di ogni modello include i seguenti componenti:

  • Deployment di Ray Serve: il deployment di Ray Serve, che include risorse configurazione e runtime.
  • Modello: l'ID modello di Hugging Face.
  • Cluster Ray: il cluster Ray sottostante e le risorse necessarie per ogni che include pod head e worker.

Gemma 2B IT

  1. Esegui il deployment del modello:

    kubectl apply -f gemma-2b-it/
    
  2. Attendi che la risorsa RayService sia pronta:

    kubectl get rayservice gemma-2b-it -o yaml
    

    L'output è simile al seguente:

    status:
      activeServiceStatus:
        applicationStatuses:
          llm:
            healthLastUpdateTime: "2024-06-22T02:51:52Z"
            serveDeploymentStatuses:
              VLLMDeployment:
                healthLastUpdateTime: "2024-06-22T02:51:52Z"
                status: HEALTHY
            status: RUNNING
    

    In questo output, status: RUNNING indica la risorsa RayService è pronto.

  3. Conferma che GKE ha creato il servizio per Ray Serve applicazione:

    kubectl get service gemma-2b-it-serve-svc
    

    L'output è simile al seguente:

    NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
    gemma-2b-it-serve-svc   ClusterIP   34.118.226.104   <none>        8000/TCP   45m
    

Gemma 7B

  1. Esegui il deployment del modello:

    kubectl apply -f gemma-7b-it/
    
  2. Attendi che la risorsa RayService sia pronta:

    kubectl get rayservice gemma-7b-it -o yaml
    

    L'output è simile al seguente:

    status:
      activeServiceStatus:
        applicationStatuses:
          llm:
            healthLastUpdateTime: "2024-06-22T02:51:52Z"
            serveDeploymentStatuses:
              VLLMDeployment:
                healthLastUpdateTime: "2024-06-22T02:51:52Z"
                status: HEALTHY
            status: RUNNING
    

    In questo output, status: RUNNING indica che la risorsa RayService è pronto.

  3. Conferma che GKE ha creato il servizio per Ray Serve applicazione:

    kubectl get service gemma-7b-it-serve-svc
    

    L'output è simile al seguente:

    NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
    gemma-7b-it-serve-svc   ClusterIP   34.118.226.104   <none>        8000/TCP   45m
    

Lama 2 7B

  1. Esegui il deployment del modello:

    kubectl apply -f llama-2-7b/
    
  2. Attendi che la risorsa RayService sia pronta:

    kubectl get rayservice llama-2-7b -o yaml
    

    L'output è simile al seguente:

    status:
      activeServiceStatus:
        applicationStatuses:
          llm:
            healthLastUpdateTime: "2024-06-22T02:51:52Z"
            serveDeploymentStatuses:
              VLLMDeployment:
                healthLastUpdateTime: "2024-06-22T02:51:52Z"
                status: HEALTHY
            status: RUNNING
    

    In questo output, status: RUNNING indica la risorsa RayService è pronto.

  3. Conferma che GKE ha creato il servizio per Ray Serve applicazione:

    kubectl get service llama-2-7b-serve-svc
    

    L'output è simile al seguente:

    NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
    llama-2-7b-serve-svc    ClusterIP   34.118.226.104   <none>        8000/TCP   45m
    

Lama 3 8B

  1. Esegui il deployment del modello:

    kubectl apply -f llama-3-8b/
    
  2. Attendi che la risorsa RayService sia pronta:

    kubectl get rayservice llama-3-8b -o yaml
    

    L'output è simile al seguente:

    status:
      activeServiceStatus:
        applicationStatuses:
          llm:
            healthLastUpdateTime: "2024-06-22T02:51:52Z"
            serveDeploymentStatuses:
              VLLMDeployment:
                healthLastUpdateTime: "2024-06-22T02:51:52Z"
                status: HEALTHY
            status: RUNNING
    

    In questo output, status: RUNNING indica la risorsa RayService è pronto.

  3. Conferma che GKE ha creato il servizio per Ray Serve applicazione:

    kubectl get service llama-3-8b-serve-svc
    

    L'output è simile al seguente:

    NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
    llama-3-8b-serve-svc    ClusterIP   34.118.226.104   <none>        8000/TCP   45m
    

Mistral 7B

  1. Esegui il deployment del modello:

    kubectl apply -f mistral-7b/
    
  2. Attendi che la risorsa RayService sia pronta:

    kubectl get rayservice mistral-7b -o yaml
    

    L'output è simile al seguente:

    status:
      activeServiceStatus:
        applicationStatuses:
          llm:
            healthLastUpdateTime: "2024-06-22T02:51:52Z"
            serveDeploymentStatuses:
              VLLMDeployment:
                healthLastUpdateTime: "2024-06-22T02:51:52Z"
                status: HEALTHY
            status: RUNNING
    

    In questo output, status: RUNNING indica la risorsa RayService è pronto.

  3. Conferma che GKE ha creato il servizio per Ray Serve applicazione:

    kubectl get service mistral-7b-serve-svc
    

    L'output è simile al seguente:

    NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
    mistral-7b-serve-svc    ClusterIP   34.118.226.104   <none>        8000/TCP   45m
    

Pubblica il modello

I modelli Llama2 7B e Llama3 8B utilizzano Specifiche della chat dell'API OpenAI. Gli altri modelli supportano solo la generazione di testo, una tecnica che genera testo in base a un prompt.

Configura port forwarding

Imposta il port forwarding al server di inferenza:

Gemma 2B IT

kubectl port-forward svc/gemma-2b-it-serve-svc 8000:8000

Gemma 7B

kubectl port-forward svc/gemma-7b-it-serve-svc 8000:8000

Lama2 7B

kubectl port-forward svc/llama-7b-serve-svc 8000:8000

Lama 3 8B

kubectl port-forward svc/llama-3-8b-serve-svc 8000:8000

Mistral 7B

kubectl port-forward svc/mistral-7b-serve-svc 8000:8000

Interagire con il modello utilizzando curl

Usa curl per chattare con il tuo modello:

Gemma 2B IT

In una nuova sessione del terminale:

curl -X POST http://localhost:8000/ -H "Content-Type: application/json" -d '{"prompt": "What are the top 5 most popular programming languages? Be brief.", "max_tokens": 1024}'

Gemma 7B

In una nuova sessione del terminale:

curl -X POST http://localhost:8000/ -H "Content-Type: application/json" -d '{"prompt": "What are the top 5 most popular programming languages? Be brief.", "max_tokens": 1024}'

Lama2 7B

In una nuova sessione del terminale:

curl http://localhost:8000/v1/chat/completions     -H "Content-Type: application/json"     -d '{
      "model": "meta-llama/Llama-2-7b-chat-hf",
      "messages": [
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "What are the top 5 most popular programming languages? Please be brief."}
      ],
      "temperature": 0.7
    }'

Lama 3 8B

In una nuova sessione del terminale:

curl http://localhost:8000/v1/chat/completions     -H "Content-Type: application/json"     -d '{
      "model": "meta-llama/Llama-3-8b-chat-hf",
      "messages": [
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "What are the top 5 most popular programming languages? Please be brief."}
      ],
      "temperature": 0.7
    }'

Mistral 7B

In una nuova sessione del terminale:

curl -X POST http://localhost:8000/ -H "Content-Type: application/json" -d '{"prompt": "What are the top 5 most popular programming languages? Be brief.", "max_tokens": 1024}'

Poiché i modelli forniti non conservano la cronologia, ogni messaggio e la risposta deve essere inviata al modello per creare un dialogo interattivo un'esperienza senza intervento manuale. L'esempio seguente mostra come creare un dialogo interattivo utilizzando il modello Llama 3 8B:

Crea una finestra di dialogo con il modello utilizzando curl:

curl http://localhost:8000/v1/chat/completions \
    -H "Content-Type: application/json" \
    -d '{
      "model": "meta-llama/Meta-Llama-3-8B-Instruct",
      "messages": [
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "What are the top 5 most popular programming languages? Please be brief."},
        {"role": "assistant", "content": " \n1. Java\n2. Python\n3. C++\n4. C#\n5. JavaScript"},
        {"role": "user", "content": "Can you give me a brief description?"}
      ],
      "temperature": 0.7
}'

L'output è simile al seguente:

{
  "id": "cmpl-3cb18c16406644d291e93fff65d16e41",
  "object": "chat.completion",
  "created": 1719035491,
  "model": "meta-llama/Meta-Llama-3-8B-Instruct",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Here's a brief description of each:\n\n1. **Java**: A versatile language for building enterprise-level applications, Android apps, and web applications.\n2. **Python**: A popular language for data science, machine learning, web development, and scripting, known for its simplicity and ease of use.\n3. **C++**: A high-performance language for building operating systems, games, and other high-performance applications, with a focus on efficiency and control.\n4. **C#**: A modern, object-oriented language for building Windows desktop and mobile applications, as well as web applications using .NET.\n5. **JavaScript**: A versatile language for client-side scripting on the web, commonly used for creating interactive web pages, web applications, and mobile apps.\n\nNote: These descriptions are brief and don't do justice to the full capabilities and uses of each language."
      },
      "logprobs": null,
      "finish_reason": "stop",
      "stop_reason": null
    }
  ],
  "usage": {
    "prompt_tokens": 73,
    "total_tokens": 245,
    "completion_tokens": 172
  }
}

(Facoltativo) Connettersi all'interfaccia di chat

Puoi usare Gradio per creare applicazioni web che ti consentano di interagire con un modello di machine learning. Gradio è una libreria Python con un wrapper ChatInterface che crea interfacce utente per i chatbot. Per Llama 2 7B e Llama 3 7B, installato Gradio quando hai eseguito il deployment del modello LLM.

  1. Configura il port forwarding al servizio gradio:

    kubectl port-forward service/gradio 8080:8080 &
    
  2. Apri http://localhost:8080 nel browser per chattare con il modello.

Gestisci più modelli con il multiplexing dei modelli

Multitasking del modello è una tecnica utilizzata per offrire modelli multipli all'interno dello stesso cluster Ray. Puoi instradare il traffico a modelli specifici utilizzando le intestazioni delle richieste o per carico e del bilanciamento del carico.

In questo esempio, viene creata un'applicazione Ray Serving multiplex composta da due modelli: Gemma 7B IT e Llama 3 8B.

  1. Esegui il deployment della risorsa RayService:

    kubectl apply -f model-multiplexing/
    
  2. Attendi che la risorsa RayService sia pronta:

    kubectl get rayservice model-multiplexing -o yaml
    

    L'output è simile al seguente:

    status:
      activeServiceStatus:
        applicationStatuses:
          llm:
            healthLastUpdateTime: "2024-06-22T14:00:41Z"
            serveDeploymentStatuses:
              MutliModelDeployment:
                healthLastUpdateTime: "2024-06-22T14:00:41Z"
                status: HEALTHY
              VLLMDeployment:
                healthLastUpdateTime: "2024-06-22T14:00:41Z"
                status: HEALTHY
              VLLMDeployment_1:
                healthLastUpdateTime: "2024-06-22T14:00:41Z"
                status: HEALTHY
            status: RUNNING
    

    In questo output, status: RUNNING indica la risorsa RayService è pronto.

  3. Verifica che GKE abbia creato il servizio Kubernetes per Ray Gestisci applicazione:

    kubectl get service model-multiplexing-serve-svc
    

    L'output è simile al seguente:

    NAME                           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
    model-multiplexing-serve-svc   ClusterIP   34.118.226.104   <none>        8000/TCP   45m
    
  4. Configura il port forwarding per l'applicazione Ray Serve:

    kubectl port-forward svc/model-multiplexing-serve-svc 8000:8000
    
  5. Invia una richiesta al modello IT di Gemma 7B:

    curl -X POST http://localhost:8000/ -H "Content-Type: application/json" --header "serve_multiplexed_model_id: google/gemma-7b-it" -d '{"prompt": "What are the top 5 most popular programming languages? Please be brief.", "max_tokens": 200}'
    

    L'output è simile al seguente:

    {"text": ["What are the top 5 most popular programming languages? Please be brief.\n\n1. JavaScript\n2. Java\n3. C++\n4. Python\n5. C#"]}
    
  6. Invia una richiesta al modello Llama 3 8B:

    curl -X POST http://localhost:8000/ -H "Content-Type: application/json" --header "serve_multiplexed_model_id: meta-llama/Meta-Llama-3-8B-Instruct" -d '{"prompt": "What are the top 5 most popular programming languages? Please be brief.", "max_tokens": 200}'
    

    L'output è simile al seguente:

    {"text": ["What are the top 5 most popular programming languages? Please be brief. Here are your top 5 most popular programming languages, based on the TIOBE Index, a widely used measure of the popularity of programming languages.\r\n\r\n1. **Java**: Used in Android app development, web development, and enterprise software development.\r\n2. **Python**: A versatile language used in data science, machine learning, web development, and automation.\r\n3. **C++**: A high-performance language used in game development, system programming, and high-performance computing.\r\n4. **C#**: Used in Windows and web application development, game development, and enterprise software development.\r\n5. **JavaScript**: Used in web development, mobile app development, and server-side programming with technologies like Node.js.\r\n\r\nSource: TIOBE Index (2022).\r\n\r\nThese rankings can vary depending on the source and methodology used, but this gives you a general idea of the most popular programming languages."]}
    
  7. Invia una richiesta a un modello casuale escludendo l'intestazione serve_multiplexed_model_id:

    curl -X POST http://localhost:8000/ -H "Content-Type: application/json" -d '{"prompt": "What are the top 5 most popular programming languages? Please be brief.", "max_tokens": 200}'
    

    L'output è uno degli output dei passaggi precedenti.

Componi più modelli con composizione dei modelli

Composizione del modello è una tecnica utilizzata per comporre più modelli in un'unica applicazione. Modello composizione consente di concatenare input e output su più LLM e scalare i modelli come una singola applicazione.

In questo esempio, vengono composti due modelli, Gemma 7B IT e Llama 3 in un'unica applicazione. Il primo è il modello di assistente risponde alle domande fornite nel prompt. Il secondo modello è il generatore di riassunti un modello di machine learning. L'output del modello dell'assistente è concatenato all'input del del generatore di riassunti. Il risultato finale è una versione riepilogativa della risposta dal modello dell'assistente.

  1. Esegui il deployment della risorsa RayService:

    kubectl apply -f model-composition/
    
  2. Attendi che la risorsa RayService sia pronta:

    kubectl get rayservice model-composition -o yaml
    

    L'output è simile al seguente:

    status:
      activeServiceStatus:
        applicationStatuses:
          llm:
            healthLastUpdateTime: "2024-06-22T14:00:41Z"
            serveDeploymentStatuses:
              MutliModelDeployment:
                healthLastUpdateTime: "2024-06-22T14:00:41Z"
                status: HEALTHY
              VLLMDeployment:
                healthLastUpdateTime: "2024-06-22T14:00:41Z"
                status: HEALTHY
              VLLMDeployment_1:
                healthLastUpdateTime: "2024-06-22T14:00:41Z"
                status: HEALTHY
            status: RUNNING
    

    In questo output, status: RUNNING indica la risorsa RayService è pronto.

  3. Verifica che GKE abbia creato il servizio per Ray Serve applicazione:

    kubectl get service model-composition-serve-svc
    

    L'output è simile al seguente:

    NAME                           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
    model-composition-serve-svc    ClusterIP   34.118.226.104   <none>        8000/TCP   45m
    
  4. Invia una richiesta al modello:

    curl -X POST http://localhost:8000/ -H "Content-Type: application/json" -d '{"prompt": "What is the most popular programming language for machine learning and why?", "max_tokens": 1000}'
    
  5. L'output è simile al seguente:

    {"text": ["\n\n**Sure, here is a summary in a single sentence:**\n\nThe most popular programming language for machine learning is Python due to its ease of use, extensive libraries, and growing community."]}
    

Elimina il progetto

  1. Nella console Google Cloud, vai alla pagina Gestisci risorse.

    Vai a Gestisci risorse

  2. Nell'elenco dei progetti, seleziona il progetto che vuoi eliminare, quindi fai clic su Elimina.
  3. Nella finestra di dialogo, digita l'ID del progetto e fai clic su Chiudi per eliminare il progetto.

Elimina le singole risorse

Se hai utilizzato un progetto esistente e non vuoi eliminarlo, puoi eliminare il alle singole risorse.

  1. Elimina il cluster:

    gcloud container clusters delete rayserve-cluster
    

Passaggi successivi