Amazon SageMaker con Microsoft CNTK/Keras

January, 2018


I marchi sono di proprietà dei legittimi proprietari.
SageMaker è l’ambiente di Amazon che facilita la costruzione e distribuzione di modelli Machine/Deep Learning. Sostanzialmente è un servizio gestito della piattaforma AWS che agevola l’adozione di un paradigma di design & deploy basato su containerizzazione Docker, packaging di web service su lightweight serving stack come Nginx + Gunicorn + Flask e diverse altre amenità.


Serving stack utilizzato in SageMaker. Nginx è il server HTTP e reverse proxy, open source e ad alte prestazioni, noto per le sue elevate prestazioni, stabilità, ricco set di funzioni, semplicità di configurazione e basso consumo di risorse. Nginx assolve il ruolo di server di buffering di interfaccia. Green Unicorn (gunicorn) è un server HTTP/WSGI (porting del progetto Ruby Unicorn) con bilanciamento del carico tramite pre-fork e socket condivisi. Flask è un framework scritto in Python, basato su librerie altamente performanti per la gestione del protocollo WSGI e il templating.
In questo articolo propongo un approccio per il deployment di un modello custom ML/DL basato sulla libreria Microsoft CNTK, sfruttando le funzionalità di SageMaker. Assumo che il lettore abbia già una conoscenza operativa di Docker.

Il modello di distribuzione di SageMaker prevede l’incapsulamento dei modelli ML/DL in immagini Docker. Semplificando, da un’immagine, è dinamicamente generato un container che è eseguito automaticamente su un’istanza EC2Amazon Elastic Computer Cloud dedicata e ottimizzata per l’impiego MLAmazon SageMaker ML Instance Types . Il modello è pacchettizzato in modo da essere accessibile attraverso una RESTful API che è automaticamente collegata ad un endpoint HTTPS in grado di offrire un punto di contatto robusto e scalabile verso il modo esterno. Questo tipo di approccio ben si coniuga con uno stile architetturale a microservizi.

Lo stile architetturale a microservizi è un approccio allo sviluppo di una singola applicazione come insieme di piccoli servizi, ciascuno dei quali viene eseguito da un proprio processo e comunica con un meccanismo snello, spesso una HTTP API. Martin Fowler

SageMaker offre anche un insieme di immagini Docker preconfigurate in cui sono incapsulati framework ML/DL e implementazioni di algoritmi base. Utilizzando queste immagini è possibile costruire rapidamente semplici modelli facilmente distribuibili.

Creazione di una notebook instance su SageMaker

Il primo passo consiste nell’accedere alla console di SageMaker e da questa attivare (o creare) una notebook instance. A seguire, facendo click su Open, accediamo all’istanza Jupyter. Dalla finestra di Jupyter, facciamo click su New e apriamo una finestra Terminal nel browser, ossia una shell sulla nostra istanza EC2. Siamo loggati come utenti ec2-user.

Dalla linea di comando digitiamo cd SageMaker, quindi cloniamo (git clone) il package git CNTK_KERAS_SAGEMAKER che ho appositamente predisposto per agevolare le prossime operazioni.

Digitiamo cd CNTK_KERAS_SAGEMAKER/container per spostarci all’interno del package appena clonato. Per semplicità, chiamiamo questo punto di accesso cartella base.

La cartella base è così organizzata:

build_and_push_to_ecr.sh: lo script file per la generazione dell’immagine e il pushing sul registro Docker ECRAmazon Elastic Container Registry ;

Dockefile: il file di testo contenente le istruzioni necessarie per creare una nuova immagine basata su Microsoft CNTK (versione 2.3 con supporto per Py27 e CPUIl file può essere facilmente modificato per selezionare una versione più recente di CNTK sia con supporto GPU sia Py2 o Py3. Per ulteriori informazioni consultare la pagina CNTK Docker Containers. );

keras.json: il file di testo contente le impostazioni per il framework Keras (versione 2.0.6 o superiore) incluso nell’immagine. Queste impostazioni consentono l’integrazione di Keras con la libreria CNTK. Il file è automaticamente caricato all’interno dell’immagine durante la fase di building;

context: la cartella che contiene i file dati e di configurazione per la creazione del modello;

setup: la cartella che contiene i file script che permettono a SageMaker di istanziare un container e attivare un modello richiamando le funzioni di addestramento e predizione;

evaluation: la cartella con file dati esemplificativi e i notebook jupyter che illustrano come utilizzare il modello basato su CNTK da un notebook in SageMaker.

Test in locale

Partiamo con l’esame della cartella context. La cartella è utilizzata esclusivamente per finalità di test in locale (ossia prima di operare su ECR e con SageMaker) e replica al suo interno una gerarchia che riflette esattamente il funzionamento a regime di SageMaker. In input, carichiamo il file json hyperparameters.json che contiene i parametri di configurazione del nostro modello (imposteremo parametri simili anche attraverso SageMaker). Sempre in input, in apposita sottocartella, carichiamo i file CSV trainset.csv e testset.csv contenenti rispettivamente training e testing set, per l’addestramento del modello. Infine, le sottocartelle model e output sono utilizzate per il salvataggio del modello addestrato (pesi e architettura) e per logging. A differenza della cartella di configurazione, il popolamento delle cartelle model e output è automatico, a valle della fase di addestramento del modello.

Per testare in modalità locale il funzionamento del container e del modello in esso incapsulato, è necessario spostarsi nella cartella base e creare un’immagine Docker locale usando il comando:

  docker build -t cntkdemo .

Dopo la creazione dell’immagine cntkdemo è possibile spostarsi nella cartella evaluation e digitare uno dei seguenti comandi:

./run_local.sh train: per istanziare il modello ed eseguire il training;

./run_local.sh serve: per attivare il modello in modalità serving (in attesa di richieste);

./predict.py eval_data.csv: per richiedere una predizione (p.e. usando un file di dati di validazione). Questo script richiede che un’istanza del modello sia funzionante in modalità serving (vedi punto precedente) in una finestra Terminal dedicata. Nella cartella evaluation sono anche memorizzati i file eval_data.csv ed eval_pred.csv contententi dati di validazione del modello.

Programmazione del modello

La programmazione del modello è confinata entro specifici file memorizzati all’interno della cartella setup. In particolare, gli unici due punti dove inseriamo i nostri sviluppi custom sono:

train: in questo file, all’interno della funzione omonima train() è confinato il codice per: la lettura dei file di training e testing; la lettura dei parametri di configurazione; la costruzione del modello; l’addestramento e la serializzazione delle impostazioni (pesi e architettura). Nell’esempio fornito, si utilizza Keras per interfacciarsi a CNTK e creare una semplice rete neurale. Ovviamente, è possibile utilizzare qualsiasi libreria Python, istanziare più algoritmi ML/DL, etc.., per la creazione di modelli di qualsivoglia complessità;

predictor.py: in questo file, all’interno della funzione get_model() è confinato il codice per l’istanziazione del modello (a partire dai file dei pesi e dell’architettura creati con l’esecuzione di train) e l’implementazione della funzione di predizione. Null’altro è richiesto.

Generazione dell’immagine e caricamento su ECR

Dopo aver verificato, in locale, il corretto funzionamento del container e del modello in esso incapsulato, possiamo generare (build) una nuova immagine e spedirla (push) al registro Docker ECR. Per questa operazione dobbiamo spostarci nella cartella base ed eseguire l’istruzione:

  ./build_and_push_to_ecr.sh cntkdemo-ecr-4

dove cntkdemo-ecr-4 è un nome che ho arbitrariamente assegnato all’immagine.

Possiamo visualizzare l’elenco delle immagini (sia in locale sia su ECR) digitando l’istruzione:

  docker images

Configurazione di un modello e creazione dell’artifact

Abbandondiamo la finestra del Terminal e accediamo al Jupyter su SageMaker. Quindi, spostiamoci nella cartella CNTK_KERAS_SAGEMAKER/container/evaluation. In questa cartella sono precaricati tre notebook.

Selezioniamo il notebook HowToPrepareModel. Il notebook contiene le istruzioni per:

il caricamento dei dataset di training e testing dalla cartella locale context ad una cartella remota sullo storage S3Amazon Simple Storage associato all’utenza che abbiamo usato per accedere a SageMaker;

la predisposizione del container, attraverso l’impiego dell’interfaccia sage.estimator.EstimatorConsultare Amazon SageMaker Python SDK per ulteriori dettagli sull’SDK Python per SageMaker. e avendo cura di specificare: il riferimento all’immagine precedentemente caricata su ECR; il tipo di istanza EC2 da attivare; il puntamento alla cartella su S3 creata e popolata al passo precedente;

la configurazione dei parametriI parametri sono esattamente gli stessi che in locale abbiamo specificato all’interno del file hyperparameters.json. SageMaker provvede automaticamente alla creazione di un file json analogo a quello che abbiamo usato per i nostri test in locale. del modello attraverso il metodo set_hyperparameters dell’Estimator;

l’addestramento del modello attraverso l’invocazione del metodo fit dell’Estimator.

Al termine dell’addestramento, i file dei pesi e dell’architettura saranno automaticamente compressi nell’archivio model.tar.gz che è salvato su S3. L’insieme dei file contenenti pesi e architettura è chiamato model artifact. Possiamo ottenere l’indirizzo esteso del model artifact memorizzato su S3 eseguendo l’istruzione:

  estimator.model_data

Incapsulare il modello in container e associare un endpoint

Selezioniamo il notebook HowToDeployModel. Il notebook contiene le istruzioni per:

istanziare il modello partendo dal model artifact generato nella sezione precedente;

assegnare il container ad un endpoint HTTPS;

attivare l’endpoint (l’attivazione può richiedere qualche minuto).

Accedere all’endpoint

Selezioniamo il notebook HowToInvokeModel. Il notebook contiene le istruzioni per:

caricare i dati di validazione dal file locale eval_data.csv;

accedere all’endpoint HTTPS per invocare la funzione di predizione. L’accesso all’endpoint avviene attraverso il metodo invoke_endpoint comodamente richiamabile attraverso il modulo boto3boto3 è l’SDK Python per l’accesso ai servizi AWS. . Il payload dell’invocazione è composto dai dati di validazione che abbiamo opportunamente letto e pre-trattato per l’invio (vedi passo precedente).

Il notebook include istruzioni esemplificative per l’estrazione dei risultati dalla response e la valutazione dell’accuratezza usando i dati ground truth memorizzati in eval_pred.csv, ma questi sono passaggi semplici.

Buon divertimento con il vostro nuovo modello custom!

Amazon SageMaker con Microsoft CNTK/Keras - January 21, 2018 - lorenzo toscano
To Top