Un’introduzione a BentoML un framework unificato per applicazioni di intelligenza artificiale

BentoML un framework unificato per l'IA

Navigare il percorso dalla creazione di modelli di apprendimento automatico (ML) alla loro distribuzione in produzione può spesso essere una strada accidentata. È un processo essenziale ma complesso in cui i data scientist e gli ingegneri devono colmare la lacuna di conoscenza. I data scientist, abili nella creazione di modelli, potrebbero inciampare quando si tratta di distribuzione in produzione. D’altra parte, gli ingegneri potrebbero avere difficoltà con l’iterazione continua dei modelli di ML, portando a operazioni inefficienti e soggette ad errori.

Considera questo scenario specifico: hai appena creato un modello di ML per la sintesi del testo, che si comporta in modo eccellente nei test. Hai intenzione di condividere questo modello con il tuo team per costruire un’applicazione su di esso. Tuttavia, la distribuzione di questo modello presenta una sfida unica: garantire che il tuo team possa utilizzare il modello senza dover modificare il codice o impostare l’ambiente.

Entra in gioco BentoML.

BentoML è un framework open-source per la distribuzione di modelli di ML progettato per semplificare il processo di distribuzione. Facilitando un passaggio più fluido dalla creazione del modello alla produzione, questo framework end-to-end consente ai data scientist e agli sviluppatori di concentrarsi su ciò che sanno fare meglio, colmando il divario tra questi due ruoli cruciali. Di conseguenza, i modelli possono essere distribuiti in modo rapido e scalabile, garantendo un servizio di produzione più stabile.

Puoi utilizzare il framework BentoML per sviluppare endpoint di servizio di modelli pronti per la produzione. Ecco il modus operandi di BentoML:

  1. Specificare un modello: Prima di utilizzare BentoML, è necessario partire da un modello di ML o un insieme di modelli. Questi modelli possono essere addestrati utilizzando varie librerie come TensorFlow o PyTorch.
  2. Salvare il modello: Dopo aver addestrato il modello, salvare il modello nel BentoML local Model Store. Funge da hub di gestione per tutti i tuoi modelli, fornendo un facile accesso per il servizio e un modo sistematico per tenerli traccia.
  3. Creare un servizio BentoML: Creare un file service.py per incapsulare il modello e definire la logica di servizio. Specifica i Runners (un’astrazione in BentoML per ottimizzare l’inferenza) per eseguire l’inferenza del modello su larga scala e costruire gli endpoint che si desidera esporre esternamente.
  4. Creare un Bento: Questo passaggio consiste nel confezionare il/i modello/i e il servizio BentoML in un Bento tramite un file YAML di configurazione. Un Bento è un artefatto pronto per la distribuzione che raggruppa tutti gli elementi necessari: il codice del tuo modello, le dipendenze e la logica di servizio. Ti fornirò un esempio più concreto in seguito.
  5. Distribuire il Bento: Una volta preparato il Bento, è il momento della distribuzione. Puoi incapsulare il Bento in un’immagine Docker per la distribuzione su Kubernetes. Se preferisci una soluzione tutto-in-uno, puoi distribuire il tuo Bento direttamente su Yatai, una piattaforma open-source nell’ecosistema BentoML che automatizza e gestisce le distribuzioni di apprendimento automatico su Kubernetes. Se desideri un servizio completamente gestito, considera la distribuzione di Bentos tramite BentoCloud, una soluzione serverless per la creazione e il funzionamento di applicazioni AI.

Ora che hai una comprensione di base di BentoML e del suo flusso di lavoro, vediamo un esempio di come BentoML semplifica il servizio e la distribuzione dei modelli.

Preparazione dell’ambiente

Per eseguire questo progetto in locale, assicurati di avere quanto segue:

  • Python 3.8+
  • pip installato.

Dopo di ciò, crea una directory per archiviare tutti i file del progetto, inclusi service.py come indicato in precedenza. Li creerò uno per uno.

mkdir bentoml-demo
cd bentoml-demo

Ti consiglio di utilizzare un Ambiente Virtuale per l’isolamento delle dipendenze.

python -m venv venv
source venv/bin/activate

Crea un file requirements.txt, che contiene tutte le librerie richieste.

bentoml
transformers
torch>=2.0

Installa le dipendenze:

pip install -r requirements.txt

Scaricare i Modelli nel Local Model Store

In questo post del blog, utilizzo un modello di sintesi del testo Transformer (sshleifer/distilbart-cnn-12-6) dall’Hugging Face Model Hub come esempio.

Come ho menzionato in precedenza, è necessario scaricare il modello nel BentoML Model Store. Ciò viene fatto tramite uno script download_model.py, che utilizza la funzione bentoml.transformers.save_model(). Crea un file download_model.py come descritto di seguito.

import transformers
import bentoml

model = "sshleifer/distilbart-cnn-12-6"
task = "summarization"

bentoml.transformers.save_model(
    task,
    transformers.pipeline(task, model=model),
    metadata=dict(model_name=model),
)

Eseguendo questo script, il modello verrà scaricato e salvato localmente.

python3 download_model.py

Se il download è avvenuto con successo, il modello dovrebbe apparire nel Model Store. Potrai recuperare questo modello in seguito per creare un servizio BentoML.

$ bentoml models list

Tag                                    Module                Size       Creation Time       
summarization:5kiyqyq62w6pqnry         bentoml.transformers  1.14 GiB   2023-07-10 11:57:40 

Nota: Tutti i modelli scaricati nel Model Store vengono salvati nella directory /home/user/bentoml/models/.

Creare un servizio BentoML

Con un modello pronto all’uso, puoi creare un servizio BentoML definendo un file service.py come segue. Questo script crea un’istanza summarizer_runner dal modello scaricato in precedenza e lo incapsula all’interno di un bentoml.Service(). La funzione summarize(), decorata con @svc.api(), specifica il punto di accesso API per il servizio e la logica per elaborare gli input e gli output.

import bentoml

summarizer_runner = bentoml.models.get("summarization:latest").to_runner()

svc = bentoml.Service(
    name="summarization", runners=[summarizer_runner]
)

@svc.api(input=bentoml.io.Text(), output=bentoml.io.Text())
async def summarize(text: str) -> str:
    generated = await summarizer_runner.async_run(text, max_length=3000)
    return generated[0]["summary_text"]

Nella directory del progetto, utilizza bentoml serve per avviare il server BentoML in modalità di sviluppo.

$ bentoml serve service:svc --development --reload

2023-07-10T12:13:33+0800 [INFO] [cli] Le metriche di Prometheus per HTTP BentoServer da "service:svc" possono essere consultate all'indirizzo http://localhost:3000/metrics.
2023-07-10T12:13:34+0800 [INFO] [cli] Avvio del server HTTP BentoML di produzione da "service:svc" in ascolto su http://0.0.0.0:3000 (Premere CTRL+C per interrompere)
2023-07-10 12:13:34 circus[5290] [INFO] Caricamento del plugin...
2023-07-10 12:13:34 circus[5290] [INFO] Endpoint: 'tcp://127.0.0.1:61187'
2023-07-10 12:13:34 circus[5290] [INFO] Pub/sub: 'tcp://127.0.0.1:61188'
2023-07-10T12:13:34+0800 [INFO] [observer] Osservazione delle directory: ['/Users/sherlock/Documents/bentoml-demo', '/Users/sherlock/bentoml/models']

Il server è ora attivo all’indirizzo http://0.0.0.0:3000, che fornisce un’interfaccia utente web che puoi utilizzare. Visita il sito web, scorri fino a Service APIs e clicca su Try it out.

Inserisci il tuo testo nella casella Request body e clicca su Execute. Di seguito è riportato un esempio sul concetto di Large Language Models.

Input:

Un large language model (LLM) è un modello di linguaggio computerizzato, incarnato da una rete neurale artificiale che utilizza un'enorme quantità di "parametri" (cioè "neuroni" nei suoi strati con fino a decine di milioni o miliardi di "pesi" tra di essi), che vengono (pre-)allenati su molte GPU in tempi relativamente brevi grazie all'elaborazione parallela massiva di vaste quantità di testi non etichettati contenenti fino a trilioni di token (cioè parti di parole) forniti da corpora come il Corpus di Wikipedia e il Common Crawl, utilizzando l'apprendimento auto-supervisionato o l'apprendimento semi-supervisionato, risultando in un vocabolario tokenizzato con una distribuzione di probabilità. I LLM possono essere aggiornati utilizzando ulteriori GPU per (pre-)allenare il modello con ancora più parametri su quantità ancora più vaste di testi non etichettati.

Output dal modello di sintesi del testo:

Un grande modello di linguaggio (LLM) è un modello di linguaggio computerizzato, incarnato da una rete neurale artificiale che utilizza una quantità enorme di "parametri" nei suoi strati con decine di milioni o miliardi di "pesi" tra di essi. Gli LLM possono essere migliorati utilizzando GPU aggiuntive per addestrare (pre-)il modello con ancora più parametri su quantità ancora più vaste di testi non etichettati.

Costruzione di un Bento

Ora che il modello funziona correttamente, è necessario confezionarlo nel formato di distribuzione standard in BentoML, noto anche come “Bento”. Un Bento contiene tutto il codice sorgente, i file del modello e le dipendenze necessarie per eseguire il Servizio. Per creare un Bento, creare un file bentofile.yaml nella directory del progetto. Questo file definisce le opzioni di compilazione, come le dipendenze, le impostazioni dell’immagine Docker e i modelli. Qui elenco solo le informazioni di base richieste per creare un Bento, come il Servizio, i file Python da includere e le dipendenze. Consultare la documentazione di BentoML per saperne di più.

service: 'service:svc'
include:
  - '*.py'
python:
  requirements_txt: requirements.txt

Eseguire il comando bentoml build nella directory del progetto per creare il Bento. È possibile trovare tutti i Bentos creati in /home/user/bentoml/bentos/.

$ bentoml build

Creazione del servizio BentoML "summarization:ulnyfbq66gagsnry" dal contesto di compilazione "/Users/sherlock/Documents/bentoml-demo".
Impacchettamento del modello "summarization:5kiyqyq62w6pqnry"

██████╗░███████╗███╗░░██╗████████╗░█████╗░███╗░░░███╗██╗░░░░░
██╔══██╗██╔════╝████╗░██║╚══██╔══╝██╔══██╗████╗░████║██║░░░░░
██████╦╝█████╗░░██╔██╗██║░░░██║░░░██║░░██║██╔████╔██║██║░░░░░
██╔══██╗██╔══╝░░██║╚████║░░░██║░░░██║░░██║██║╚██╔╝██║██║░░░░░
██████╦╝███████╗██║░╚███║░░░██║░░░╚█████╔╝██║░╚═╝░██║███████╗
╚═════╝░╚══════╝╚═╝░░╚══╝░░░╚═╝░░░░╚════╝░╚═╝░░░░░╚═╝╚══════╝

Creazione di Bento(tag="summarization:ulnyfbq66gagsnry") completata con successo.

Possibili passaggi successivi:

 * Containerizza il tuo Bento con `bentoml containerize`:
    $ bentoml containerize summarization:ulnyfbq66gagsnry

 * Esegui il push su BentoCloud con `bentoml push`:
    $ bentoml push summarization:ulnyfbq66gagsnry

Per visualizzare tutti i Bentos disponibili, eseguire il seguente comando:

$ bentoml list

Tag                               Dimensioni       Data di creazione
summarization:ulnyfbq66gagsnry    1.25 GiB   2023-07-10 15:28:51

Deploy del Bento

Una volta che il Bento è pronto, è possibile utilizzare bentoml serve per servirlo in produzione. Nota che se si dispone di più versioni dello stesso modello, è possibile modificare il tag latest con la versione corrispondente.

$ bentoml serve summarization:latest

2023-07-10T15:36:58+0800 [INFO] [cli] Ambiente per il worker 0: impostare il conteggio dei thread della CPU su 12
2023-07-10T15:36:58+0800 [INFO] [cli] Le metriche Prometheus per BentoServer HTTP da "summarization:latest" sono accessibili all'indirizzo http://localhost:3000/metrics.
2023-07-10T15:36:59+0800 [INFO] [cli] Avvio di BentoServer HTTP di produzione da "summarization:latest" in ascolto su http://0.0.0.0:3000 (Premere CTRL+C per interrompere)

In alternativa, puoi containerizzare il Bento con Docker. Durante la creazione del Bento, è stato creato automaticamente un Dockerfile in /home/user/bentoml/bentos/summarization/ulnyfbq66gagsnry/env/docker/. Per creare un’immagine Docker, esegui semplicemente il seguente comando:

bentoml containerize summarization:latest

Visualizza l’immagine Docker creata:

$ docker images

REPOSITORY                    TAG                IMAGE ID       CREATED         SIZE
summarization                 ulnyfbq66gagsnry   da287141ef3e   7 secondi fa    2.43GB

Puoi eseguire l’immagine Docker in locale:

docker run -it --rm -p 3000:3000 summarization:ulnyfbq66gagsnry serve

Con l’immagine Docker, puoi eseguire il modello su Kubernetes e creare un servizio Kubernetes per esporlo in modo che gli utenti possano interagire con esso.

Se stai cercando una soluzione end-to-end per il rilascio di modelli, puoi scegliere Yatai per distribuire Bentos e gestire il rilascio su larga scala su Kubernetes. Yatai è un componente importante nell’ecosistema di BentoML e merita un post dedicato per spiegare i dettagli. Se sei interessato, dai un’occhiata al repository GitHub di Yatai.

Conclusioni

Mettere i modelli di machine learning dalla fase di addestramento alla produzione non è una cosa semplice, ed è qui che BentoML brilla davvero. Con BentoML, puoi concentrarti sulla creazione del modello mentre il framework si occupa delle complessità del rilascio.

Man mano che i modelli di ML diventano sempre più integrali alle operazioni aziendali, avere una soluzione di distribuzione e rilascio di modelli ottimizzata come BentoML diventerà indispensabile. Non solo BentoML semplifica il rilascio dei modelli, ma garantisce anche che i modelli vengano gestiti in modo efficiente e possano scalare in base alle tue esigenze. Se sei interessato, inizia oggi stesso con BentoML e scopri quanto sia facile il rilascio dei modelli. Buon coding!