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:
- Un file
app.pyper definire l'API di serving del modello con vLLM e FastAPI. - Un file
requirements.txtper indicare i pacchetti Python necessari da installare nell'ambiente cloud. - Un file
bentofile.yamlper 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:
- Importare librerie Python come
bentoml,fastapievllm. - Creare un'app FastAPI per esporre endpoint compatibili con OpenAI.
- Definire i parametri del modello, il system prompt e l'ID del modello.
- Specificare le route per chat completions, completions e l'elenco dei modelli.
- Configurare un servizio BentoML con risorse GPU (NVIDIA A100) e montare l'app FastAPI.
- Impostare il motore VLLM e il tokenizer per l'inferenza del modello.
- 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

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.

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!

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.

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":

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:

Dopodiché, scriveremo il prompt e cliccheremo sul pulsante "Submit".
La generazione della risposta è stata rapida e accurata:

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:

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

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.

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

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".

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

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



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