Vai al contenuto principale

Come distribuire Llama 3.3 70B sul cloud: guida pratica

Distribuisci la versione AWQ di Llama 3.3 70B usando vLLM, BentoML e BentoCloud per creare un sistema altamente efficiente, a bassa latenza e con throughput eccezionale.
· 8 min leggi

Scopri con l'IA

Il deployment dei large language models (LLM) sta diventando sempre più impegnativo, perché richiede macchine con GPU di fascia alta e molta VRAM. Inoltre, gli ingegneri devono padroneggiare gli strumenti MLOps per gestire attività come serving, deployment, test e monitoraggio dei modelli. Oltre a questo, devono implementare controlli di accesso e mantenere la sicurezza per proteggersi da minacce informatiche e attacchi di prompt injection. La vita di un ingegnere LLMOps può essere dura, ma tranquillo: ti copriamo le spalle!

In questo tutorial esploreremo una soluzione più semplice ed efficiente per distribuire LLM, come Llama 3.3 70B, sul cloud. Con poche righe di codice Python e qualche comando da terminale, il tuo modello sarà operativo. BentoCloud semplifica e gestisce tutto, rendendo il processo di deployment lineare e sicuro.

Guida semplice per distribuire Llama 3.3 70B sul cloud, immagine di copertina.

Se sei alle prime armi, ti consiglio di seguire il corso Introduction to LLMs in Python per capire le basi dei large language models.

Introduzione a Llama 3.3

Il nuovo Meta Llama 3.3 è un large language model (LLM) multilingue, solo testo (70B), ottimizzato con istruzioni, che offre prestazioni migliori rispetto a Llama 3.1 (70B) e Llama 3.2 (90B). In alcuni casi ha persino superato il più grande Llama 3.1 (405B). Questo modello è solo testo ed è ottimizzato per casi d'uso di dialogo multilingue.

Llama 3.3 è un modello linguistico autoregressivo basato su un'architettura transformer ottimizzata. È stato perfezionato tramite supervised fine-tuning (SFT) e reinforcement learning con feedback umano (RLHF) per allinearsi meglio alle preferenze umane in termini di utilità e sicurezza.

Scopri di più su Llama 3.3 leggendo l'articolo What Is Meta's Llama 3.3 70B? How It Works, Use Cases & More.

Capire gli strumenti e i servizi chiave per il progetto

In questo progetto useremo BentoML per creare il servizio AI, vLLM per il serving del modello ad alto throughput e BentoCloud per un'infrastruttura e un deployment robusti. Inoltre, distribuiremo la versione AWQ del modello per ottimizzare le prestazioni. 

In breve, vLLM combinato con AWQ è un'accoppiata micidiale per costruire applicazioni LLM super veloci e in grado di gestire più richieste in parallelo.

AWQ

AWQ (Activation-aware Weight Quantization) è una tecnica di quantizzazione innovativa pensata per migliorare il deployment dei large language models. Ci riesce riducendo in modo significativo l'uso di memoria e aumentando la velocità di inferenza, mantenendo al contempo un'elevata accuratezza.

Leggi l'articolo di ricerca per conoscere la tecnologia AWQ e come ottimizza l'inferenza del modello mantenendo l'accuratezza.

vLLM

vLLM (Virtual Large Language Model) è una libreria open source progettata specificamente per ottimizzare l'inferenza e il serving dei large language models. Affronta sfide cruciali come throughput ed efficienza della memoria introducendo tecniche avanzate come PagedAttention, che garantisce una gestione efficiente della memoria delle chiavi-valori dell'attenzione. 

Per saperne di più sul pacchetto Python vLLM, segui il tutorial vLLM: configurare vLLM in locale e su Google Cloud per CPU.

BentoML

BentoML è un framework open source per il serving di modelli di machine learning che funge da spina dorsale della pipeline di deployment degli LLM. Semplifica il processo di packaging, deployment e gestione dei modelli di machine learning, inclusi gli LLM, in produzione.

Segui il tutorial How to Deploy LLMs with BentoML per conoscere l'ecosistema BentoML e come distribuire modelli LLM più piccoli.

BentoCloud

BentoCloud è una piattaforma serverless costruita sopra BentoML, progettata per semplificare il deployment e la gestione dei modelli di machine learning. Offre un'infrastruttura robusta ottimizzata per l'inferenza AI, rendendola particolarmente adatta al serving di LLM. 

Con BentoCloud, puoi distribuire soluzioni AI scalabili ed efficienti negli ambienti cloud senza preoccuparti della gestione dell'infrastruttura.

Sviluppare l'applicazione Llama 3.3 70B

Passiamo ora al progetto. Creeremo i seguenti componenti:

  1. Un file app.py per definire l'API di serving del modello con vLLM e FastAPI.
  2. Un file requirements.txt per indicare i pacchetti Python necessari da installare nell'ambiente cloud.
  3. Un file bentofile.yaml per configurare l'infrastruttura, costruire le immagini Docker e impostare l'ambiente di deployment.

Inizieremo installando il pacchetto Python BentoML con il comando pip:

pip install bentoml

Nel file dell'applicazione Python, imposteremo l'endpoint del modello facendo quanto segue:

  1. Importare librerie Python come bentoml, fastapi e vllm.
  2. Creare un'app FastAPI per esporre endpoint compatibili con OpenAI.
  3. Definire i parametri del modello, il system prompt e l'ID del modello.
  4. Specificare le route per chat completions, completions e l'elenco dei modelli.
  5. Configurare un servizio BentoML con risorse GPU (NVIDIA A100) e montare l'app FastAPI.
  6. Impostare il motore VLLM e il tokenizer per l'inferenza del modello.
  7. Implementare un metodo asincrono e in streaming per le risposte in streaming.

Aggiungi il codice qui sotto al tuo app.py:

# Standard library imports
import uuid
from argparse import Namespace
from typing import AsyncGenerator, Optional

# Third-party imports
import bentoml
import fastapi
from annotated_types import Ge, Le
from typing_extensions import Annotated

# Initialize FastAPI application
openai_api_app = fastapi.FastAPI()

# Constants
MAX_MODEL_LEN = 8192
MAX_TOKENS = 1024

SYSTEM_PROMPT = """You are a helpful and respectful assistant. Provide safe, unbiased, and accurate answers.
                If a question is unclear or you don't know the answer, explain why instead of guessing."""

MODEL_ID = "casperhansen/llama-3.3-70b-instruct-awq"

# Define OpenAI-compatible API endpoints
OPENAI_ENDPOINTS = [
    ["/chat/completions", "create_chat_completion", ["POST"]],
    ["/completions", "create_completion", ["POST"]],
    ["/models", "show_available_models", ["GET"]],
]


@bentoml.mount_asgi_app(openai_api_app, path="/v1")
@bentoml.service(
    name="llama3.3-70b-instruct-awq",
    traffic={
        "timeout": 1200,
        "concurrency": 256,
    },
    resources={
        "gpu": 1,
        "gpu_type": "nvidia-a100-80gb",
    },
)


class BentoVLLM:
    def __init__(self) -> None:
        """Initialize the BentoVLLM service with VLLM engine and tokenizer."""
        import vllm.entrypoints.openai.api_server as vllm_api_server
        from transformers import AutoTokenizer
        from vllm import AsyncEngineArgs, AsyncLLMEngine

        # Configure VLLM engine arguments
        ENGINE_ARGS = AsyncEngineArgs(
            model=MODEL_ID,
            max_model_len=MAX_MODEL_LEN,
            enable_prefix_caching=True,
        )

        # Initialize engine and tokenizer
        self.engine = AsyncLLMEngine.from_engine_args(ENGINE_ARGS)
        self.tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)

        # Register API endpoints
        for route, endpoint_name, methods in OPENAI_ENDPOINTS:
            endpoint_func = getattr(vllm_api_server, endpoint_name)
            openai_api_app.add_api_route(
                path=route,
                endpoint=endpoint_func,
                methods=methods,
            )

        # Configure model arguments
        model_config = self.engine.engine.get_model_config()
        args = Namespace(
            model=MODEL_ID,
            disable_log_requests=True,
            max_log_len=1000,
            response_role="assistant",
            served_model_name=None,
            chat_template=None,
            lora_modules=None,
            prompt_adapters=None,
            request_logger=None,
            disable_log_stats=True,
            return_tokens_as_token_ids=False,
            enable_tool_call_parser=True,
            enable_auto_tool_choice=True,
            tool_call_parser="llama3_json",
            enable_prompt_tokens_details=False,
        )

        # Initialize application state
        vllm_api_server.init_app_state(
            self.engine, model_config, openai_api_app.state, args
        )

    @bentoml.api
    async def generate(
        self,
        prompt: str = "Describe the process of photosynthesis in simple terms",
        system_prompt: Optional[str] = SYSTEM_PROMPT,
        max_tokens: Annotated[int, Ge(128), Le(MAX_TOKENS)] = MAX_TOKENS,
    ) -> AsyncGenerator[str, None]:
        """
        Generate text based on the input prompt using the VLLM engine.

        Args:
            prompt: The user's input prompt
            system_prompt: Optional system prompt to guide the model's behavior
            max_tokens: Maximum number of tokens to generate

        Returns:
            AsyncGenerator yielding generated text chunks
        """
        from vllm import SamplingParams

        # Configure sampling parameters
        SAMPLING_PARAM = SamplingParams(
            max_tokens=max_tokens,
            skip_special_tokens=True,
        )

        # Use default system prompt if none provided
        if system_prompt is None:
            system_prompt = SYSTEM_PROMPT

        # Prepare messages for chat
        messages = [
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": prompt},
        ]

        # Apply chat template
        prompt = self.tokenizer.apply_chat_template(
            messages,
            tokenize=False,
            add_generation_prompt=True,
        )

        # Generate response stream
        stream = await self.engine.add_request(uuid.uuid4().hex, prompt, SAMPLING_PARAM)

        # Stream the generated text
        cursor = 0
        async for request_output in stream:
            text = request_output.outputs[0].text
            yield text[cursor:]
            cursor = len(text)

Crea un file requirements.txt e includi tutti i pacchetti Python necessari per costruire l'applicazione AI. Specifica le versioni esatte di ciascun pacchetto per mantenere stabilità e riproducibilità del progetto.

Ecco come dovrebbe apparire il requirements.txt:

accelerate==1.2.0
autoawq==0.2.7.post3
bentoml>=1.3.15
fastapi==0.115.6
openai==1.57.0
vllm==0.6.4.post1; sys_platform == "linux"

Il file bentofile.yaml è il file di configurazione usato per definire e costruire il servizio BentoML. Include i seguenti componenti:

  • Definizione del servizio: specifica il nome del servizio, collegando il file dell'applicazione Python (app.py) e il nome della classe del servizio (BentoVLLM).
  • Etichette: aggiunge metadati come owner, team e stage per aiutare a organizzare e gestire il servizio.
  • File: garantisce che i file Python necessari siano inclusi nel processo di build.
  • Dipendenze: installa i pacchetti Python richiesti usando il file requirements.txt.
  • Versione di Python: configura il container Docker per usare Python 3.11 per compatibilità e stabilità.

Aggiungi i seguenti contenuti al tuo file bentofile.yaml:

service: 'app:BentoVLLM'
labels:
  owner: Abid
  team: DataCamp
  stage: dev
include:
  - '*.py'
python:
  requirements_txt: './requirements.txt'
  lock_packages: false
docker:
  python_version: "3.11"

Distribuire l'applicazione Llama 3.3 70B

Ora arriva la parte magica: BentoCloud farà tutto per noi e ci basterà digitare un solo comando. Prima, però, dobbiamo accedere a BentoCloud digitando il seguente comando nel terminale.

bentoml cloud login

CLI di BentoML per l'accesso al cloud.

Lo strumento CLI ti farà alcune domande e poi ti reindirizzerà al sito di BentoCloud per creare un account e generare la chiave API. 

Una volta fatto, applicherà automaticamente la chiave API ai tuoi strumenti CLI.

Creazione del token della chiave API.

Nota: distribuire la versione completa del modello 70B richiede 80 GB di memoria GPU. Anche se BentoCloud offre 10 USD di crediti gratuiti, dovrai abbonarti al piano pro per accedere alle GPU A100 con 80 GB di VRAM.

Per abbonarti, vai alla scheda "Billing" cliccando sulla tua immagine profilo in alto a destra e aggiungi i dati della tua carta di credito.

Niente panico: se fai attenzione ai deployment, non spenderai più di 6 USD. Ma assicurati di terminare il deployment quando hai finito gli esperimenti!

Ciclo di fatturazione corrente su BentoCloud

Ora viene il bello: distribuiremo l'applicazione BentoML sul cloud usando il seguente comando e abiliteremo l'autorizzazione all'accesso. Significa che solo gli utenti con la chiave API di BentoML possono accedere a questo server API.

bentoml deploy . --access-authorization true

Ci vorranno pochi secondi per inviare tutti i file, le configurazioni e gli altri componenti necessari, dopodiché BentoCloud gestirà il resto.

Deployment di un LLM su BentoCloud tramite CLI.

Per vedere i deployment in esecuzione, vai alla dashboard di BentoCloud e clicca sulla scheda "Deployments". Ad esempio, l'immagine sotto mostra l'applicazione nella fase di "Image Building":

Dashboard di BentoCloud, scheda "Deployments"

Accedere al modello distribuito

Dopo qualche altro minuto per costruire l'immagine, configurare l'infrastruttura e distribuire il modello, la nostra applicazione è pronta all'uso!

1. Playground

BentoCloud fornisce una UI di Playground per testare il tuo modello dalla dashboard, simile alla piattaforma OpenAI. Dato che il nostro servizio è ristretto, dovremo fornire una chiave API per accedere al modello nel Playground, come mostrato sotto:

Dashboard di BentoCloud, "Deployments" > "Playground" impostazione della chiave API.

Dopodiché, scriveremo il prompt e cliccheremo sul pulsante "Submit". 

La generazione della risposta è stata rapida e accurata:

Dashboard di BentoCloud, "Deployments" > "Playground" test del servizio LLM.

2. Comando CURL

Useremo un comando CURL nel terminale per accedere localmente al servizio LLM. Prima, però, dobbiamo generare una nuova chiave API per usare questo servizio su qualsiasi sistema:

Dashboard di BentoCloud, generazione della chiave API.

Inoltre, ci servirà l'URL dell'endpoint che possiamo copiare dalla scheda "Deployments":

Dashboard di BentoCloud, "Deployments" per copiare l'URL dell'endpoint.

Una volta che hai la chiave API e l'URL dell'endpoint, puoi generare una risposta usando il seguente comando CURL. 

Il comando include l'URL dell'endpoint, la chiave API, l'argomento max_tokens e il prompt:

curl -s -X POST \
    'https://llama-3-3-70-b-instruct-awq-zkd2-39800880.mt-guc1.bentoml.ai/generate' \
    -H "Authorization: Bearer $(echo $BENTO_CLOUD_API_KEY)" \
    -H 'Content-Type: application/json' \
    -d '{
        "max_tokens": 1024,
        "prompt": "Describe the process of photosynthesis in simple terms"
    }'

La risposta è accurata e ci sono voluti un paio di invii per generarla. 

Inferenza del modello usando il comando CURL.

3. Client Python di OpenAI 

L'endpoint di BentoML è compatibile con il client Python di OpenAI. Non devi modificare molto il tuo codice per integrare questo modello open source nella tua applicazione. 

Ti basta cambiare la base URL, fornire la chiave API e specificare il nome del modello:

import os

from openai import OpenAI

BENTOML_API_KEY = os.getenv("BENTO_CLOUD_API_KEY")  #
if BENTOML_API_KEY is None:
    raise ValueError("BENTOML_API_KEY environment variable is not set.")


client = OpenAI(
    base_url="https://llama-3-3-70-b-instruct-awq-zkd2-39800880.mt-guc1.bentoml.ai/v1",
    api_key=BENTOML_API_KEY,
)

chat_completion = client.chat.completions.create(
    model="casperhansen/llama-3.3-70b-instruct-awq",
    messages=[
        {"role": "user", "content": "What is a black hole and how does it work?"}
    ],
    stream=True,
    stop=["<|eot_id|>", "<|end_of_text|>"],
)
for chunk in chat_completion:
    print(chunk.choices[0].delta.content or "", end="")

Inferenza del modello usando il client Python di OpenAI.

Dai un'occhiata al repository GitHub kingabzpro/Deploying-Llama-3.3-70B, che contiene il file dell'applicazione, le configurazioni e i codici di inferenza.

Monitorare il servizio Llama 3.3

Su BentCloud puoi monitorare prestazioni del modello, latenza, uso dell'hardware, throughput del modello e altre metriche critiche senza configurare strumenti di logging o monitoring.

Vai ai tuoi deployment e clicca sulla scheda "Monitoring".

Monitoraggio del modello su BentoCloud.

Scorri in basso per vedere metriche relative a servizio, risorse e LLM in grafici intuitivi e chiari.

Monitoraggio del modello su BentoCloud.

Conclusione

Creare e distribuire un endpoint LLM è diventato estremamente semplice con l'ecosistema BentoML. 

Scrivendo poche righe di codice per creare la tua API, impostando un "bentofile" e distribuendo il modello, puoi avere tutto operativo in pochi minuti. Una volta distribuito, l'endpoint è accessibile tramite comandi CURL, la libreria Python requests, il client BentoML o il client OpenAI.

Il risultato è un sistema altamente efficiente, a bassa latenza e con elevato throughput, capace di gestire più richieste contemporaneamente. BentoCloud offre anche auto-scaling in base alla tua configurazione, assicurando che il sistema possa gestire volumi di traffico elevati scalando verso l'alto o verso il basso quando necessario.

Per una guida più approfondita sul deployment di LLM con BentoML, ti consiglio di seguire How to Deploy LLMs with BentoML: A Step-by-Step Guide.

Abid Ali Awan

Autore

Abid Ali Awan

In quanto data scientist certificato, sono appassionato di sfruttare tecnologie all’avanguardia per creare applicazioni di machine learning innovative. Con una solida esperienza in riconoscimento vocale, analisi e reportistica dei dati, MLOps, AI conversazionale e NLP, ho affinato le mie competenze nello sviluppo di sistemi intelligenti in grado di avere un impatto concreto. Oltre alla mia expertise tecnica, sono anche un comunicatore efficace, con il talento di rendere chiari e sintetici concetti complessi. Di conseguenza, sono diventato un blogger molto seguito in ambito data science, condividendo idee ed esperienze con una community in crescita di professionisti dei dati. Attualmente mi concentro sulla creazione e sull’editing di contenuti, lavorando con large language model per sviluppare contenuti potenti e coinvolgenti che possano aiutare aziende e singoli a valorizzare al meglio i propri dati.

Argomenti

Correlato