Corso

Immagina di aver lavorato a un problema di machine learning end-to-end e di essere arrivato alla soluzione ottimale con i migliori modelli. Tuttavia, quando consegni il codice al team di engineering, il codice che funzionava sul tuo computer non sembra funzionare sui loro server, che potrebbero avere un sistema operativo diverso con versioni di librerie differenti.
Nonostante la tua diligenza e il tuo impegno, questa situazione frustrante a volte può capitare. La maggior parte degli sviluppatori la vive almeno una volta. Quindi qual è la soluzione? È qui che entra in gioco Docker. Con Docker puoi definire un ambiente preciso e coerente per il tuo progetto, assicurandoti che il codice giri senza intoppi, indipendentemente dall'ambiente o dalla configurazione sottostante.
Questo tutorial introdurrà Docker e i concetti correlati e ne spiegherà l'importanza per i data scientist. Inoltre, l'articolo ti aiuterà a installare lo strumento e a usarlo nel tuo prossimo progetto con esempi. Infine, imparerai le best practice diffuse nel settore da seguire mentre usi Docker e avrai risposta a tutte le tue domande su Docker.
Che cosa sono Docker, i container e le immagini?
Docker è una piattaforma per creare, eseguire e distribuire applicazioni.
I container sono pacchetti leggeri, autonomi ed eseguibili che contengono tutto il necessario per eseguire un'applicazione, inclusi il codice, un runtime, librerie, variabili d'ambiente e file di configurazione.
Una immagine Docker è un file in sola lettura che contiene tutte le istruzioni necessarie per creare un container. Viene usata per creare e avviare nuovi container in fase di esecuzione.
Docker aiuta gli sviluppatori a impacchettare le applicazioni insieme alle dipendenze in un container, che può poi essere eseguito su qualsiasi macchina su cui sia installato Docker.
In un certo senso, è come se ti fosse stata data una nuova macchina per un nuovo progetto. Installeresti i pacchetti necessari, copieresti i file richiesti sulla macchina ed eseguiresti gli script. Puoi anche spedire questa nuova macchina altrove. È un esempio semplificato, ma rende l'idea.
In cosa i container Docker sono diversi dalle macchine virtuali?
Appena abbiamo definito i container, potresti chiederti in cosa differiscono dalle macchine virtuali, dato che entrambe le tecnologie consentono a più ambienti isolati di girare sulla stessa macchina fisica.
Dai un'occhiata alla differenza architetturale nell'immagine qui sotto e vedi se riesci a coglierla.

Immagine dell'autore
Ogni macchina virtuale è un ambiente isolato che può eseguire sistemi operativi e configurazioni differenti. Significa anche che ogni VM richiede una copia completa del sistema operativo, con un consumo notevole di risorse. Un'applicazione containerizzata, invece, gira in un ambiente isolato senza richiedere una copia completa del sistema operativo, risultando quindi più leggera ed efficiente.
Sebbene le macchine virtuali siano utili, i container sono in genere sufficienti e ideali per distribuire applicazioni.
Perché Docker per i data scientist?
Probabilmente ti stai chiedendo perché dovresti imparare Docker come data scientist. Non ci sono i team DevOps a occuparsi dell'infrastruttura?
Domanda legittima, ma Docker è estremamente importante per i data scientist, anche se c'è un team DevOps. Vediamo perché Docker è così utile.
Integrazione con il team DevOps
Avere un team DevOps non annulla i vantaggi dell'uso di Docker; può anzi aiutare a colmare il divario tra team di sviluppo e di operations. I data scientist possono usare Docker per impacchettare il proprio codice e passararlo al team DevOps per il deployment e lo scaling. È probabile che tu lo viva in un team di data science più strutturato.
Ambiente coerente e riproducibilità
I data scientist lavorano spesso con dipendenze e configurazioni complesse che devono essere impostate e mantenute. L'ambiente deve restare lo stesso per ottenere risultati simili. Docker consente di creare e condividere un ambiente coerente con tutte le dipendenze e configurazioni necessarie preinstallate, che altri possono replicare facilmente.
Portabilità
I container Docker possono girare in qualsiasi ambiente con Docker installato, inclusi laptop, server e piattaforme cloud. Questo rende facile per i data scientist spostare il proprio lavoro tra ambienti diversi.
Isolamento delle risorse
Docker consente di eseguire più container sulla stessa macchina, ciascuno con risorse isolate. Questo può aiutare i data scientist a gestire le risorse in modo più efficiente ed evitare conflitti con altre applicazioni. Quando hai più progetti di ML, questa funzionalità può salvarti la vita.
Abilitare la collaborazione
Docker permette ai data scientist di condividere il proprio lavoro con chiunque, anche team remoti, all'interno di container. La collaborazione è una parte cruciale del lavoro in team per i data scientist e Docker riduce gli attriti nel farlo.
La maggior parte dei data scientist esperti concorderebbe che, grazie a Docker, i data scientist possono concentrarsi sul proprio lavoro senza preoccuparsi dell'infrastruttura sottostante.
Tutorial Docker: usare Docker per il tuo prossimo progetto
Dal momento che abbiamo chiarito la necessità di Docker per un data scientist, non perdiamo tempo e mettiamoci in pari con Docker. Per prima cosa dobbiamo installare Docker sulla nostra macchina e familiarizzare con i comandi comuni.
Installare Docker sulla tua macchina o su un server locale
Docker è disponibile per tutti i principali sistemi operativi, come Linux, Windows e Mac. L'installazione è semplice e spiegata al meglio nella documentazione ufficiale.
- Istruzioni per installare Docker su Linux.
- Istruzioni per installare Docker su Windows.
- Istruzioni per installare Docker su Mac.
Se vuoi creare le tue immagini e pubblicarle su Docker Hub (come mostrato in alcuni dei comandi sotto), devi creare un account su Docker Hub. Pensa a Docker Hub come a un luogo centrale dove gli sviluppatori possono archiviare e condividere le loro immagini Docker.
Familiarizzare con i comandi Docker comuni
Una volta configurato Docker sulla tua macchina (o sul server), il passo successivo è prendere confidenza con alcuni comandi Docker. Ecco l'elenco dei comandi a cui dovresti fare riferimento dalla documentazione ufficiale di Docker.
Per aiutarti a iniziare, abbiamo elencato i dieci comandi Docker più usati che sicuramente incontrerai.
- docker run: questo comando viene usato per eseguire un container a partire da un'immagine. Il flag -p mappa una porta sulla macchina host a una porta del container. Ad esempio, il comando seguente eseguirà un container dall'immagine "nginx" e mapperà la porta 80 della macchina host alla porta 80 del container.
docker run -p 80:80 nginx- docker ps: questo comando viene usato per elencare tutti i container in esecuzione. È utile quando abbiamo diversi container isolati in esecuzione sulla stessa macchina.
docker ps- docker stop: questo comando viene usato per arrestare un container in esecuzione.
docker stop <container_id>- docker rm: questo comando viene usato per rimuovere un container arrestato.
docker rm <container_id>- docker images: questo comando viene usato per elencare tutte le immagini sulla macchina host. È utile per vedere le immagini locali disponibili prima di eseguirle per creare un container.
docker images- docker rmi: questo comando viene usato per rimuovere un'immagine.
docker rmi <image_id>- docker build: questo comando viene usato per creare un'immagine da un Dockerfile. Il flag -t specifica il nome dell'immagine e il . finale specifica il contesto di build, ovvero la directory corrente.
docker build -t my_image .- docker exec: questo comando viene usato per eseguire un comando all'interno di un container in esecuzione.
docker exec -it <container_id> /bin/bash- docker pull: questo comando viene usato per scaricare un'immagine da un registry, come ad esempio Docker Hub.
docker pull <image_name>- docker push: questo comando viene usato per pubblicare un'immagine su un registry.
docker push <image_name>
Ora che abbiamo imparato a configurare Docker e i comandi comuni, il nostro prossimo obiettivo è containerizzare un'applicazione di machine learning.
Vuoi ottenere una certificazione Docker? Dai un'occhiata alla nostra guida per ottenere una certificazione Docker!
Containerizzare una semplice applicazione di machine learning
Containerizzare qualsiasi applicazione di machine learning è più facile di quanto pensi se segui un semplice approccio in tre passaggi.

Immagine dell'autore.
Per semplicità, prendiamo uno script di machine learning per principianti, dato che il nostro obiettivo è mostrare come potresti procedere per containerizzare uno script. L'esempio che vedremo costruisce un semplice modello di regressione logistica sul dataset iris.
# Load the libraries
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
# Load the iris dataset
iris = load_iris()
X = iris.data
y = iris.target
# Split the data
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
# Train a logistic regression model
clf = LogisticRegression()
clf.fit(X_train, y_train)
# Make predictions
y_pred = clf.predict(X_test)
# Print the accuracy of the model
accuracy_score = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy_score}')
1. Definire l'ambiente
Devi conoscere con precisione l'ambiente attuale per poterlo replicare altrove. Il modo più semplice (e più comune) è creare un file requirements.txt che elenchi tutte le librerie utilizzate dal progetto, incluse le versioni.
Ecco come appare il contenuto del file:
scikit-learn==1.2.0
Nota: Un'applicazione di machine learning più complessa utilizzerebbe più librerie come NumPy, pandas, matplotlib e altre. Pertanto creare un file requirements.txt avrebbe più senso invece di installare semplicemente la libreria (ne parleremo meglio nelle best practice del settore più avanti).
2. Scrivere un Dockerfile
Il passo successivo è creare un file chiamato Dockerfile che possa creare l'ambiente ed eseguire la nostra applicazione al suo interno. In termini più semplici, è come il nostro manuale di istruzioni per Docker, in cui si specificano l'ambiente, i contenuti e gli altri passaggi di esecuzione.
FROM python:3.9
WORKDIR /src
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python","iris_classification.py"]
Questo Dockerfile usa l'immagine ufficiale di Python come base, imposta la working directory, copia il file requirements.txt e installa le dipendenze, copia il codice dell'applicazione ed esegue il comando python iris_classification.py per avviare l'applicazione.
3. Creare l'immagine
L'ultimo passaggio per creare un ambiente riproducibile è creare un'immagine (nota anche come template) che può essere eseguita per creare un qualsiasi numero di container con le stesse configurazioni.
Puoi creare l'immagine eseguendo il comando docker build -t <image-name> . nella stessa directory in cui si trova il Dockerfile.
Ora che hai containerizzato la semplice applicazione di machine learning che abbiamo visto, puoi usare il comando docker run, creare container e poi arrestarli secondo necessità. Abbiamo già trattato alcuni comandi comuni in precedenza.
Passiamo ora dalle basi alle aspettative del settore.
Best practice diffuse nel settore per usare Docker
Capire le basi è sufficiente per iniziare, ma man mano che lavori nel settore è fondamentale seguire le best practice.
Mantenere basso il numero di layer
Ogni istruzione nel Dockerfile genera un nuovo layer. Troppi layer possono rendere l'immagine grande e lenta da trasferire.
Dai un'occhiata al seguente esempio di codice:
# Use the official Python image as the build image
FROM python:3.9
# Install the dependencies
RUN pip install pandas
RUN pip install matplotlib
RUN pip install seaborn
# Copy neccesary files
COPY my_script.py .
COPY data/ .
# Run the script
CMD ["python","my_script.py"]
Qual è il problema qui? L'uso di diversi comandi run e copy era superfluo. Ecco come potremmo risolverlo:
# Use the official Python image as the build image
FROM python:3.9
# Install the dependencies using requirements.txt
COPY my_script.py requirements.txt data/ .
RUN pip install --no-cache-dir -r requirements.txt
# Run the script
CMD ["python","my_script.py"]
Anche se è evidente in un file piccolo come questo, ti sorprenderà quanto spesso scriviamo Dockerfile più grandi del necessario. Raggruppare comandi che svolgono funzioni simili o modificano lo stesso file è un modo semplice per ridurre i layer in un Dockerfile.
Usare immagini ufficiali
Le immagini ufficiali sono immagini mantenute e supportate dal publisher dell'immagine. In genere sono considerate più stabili e sicure rispetto ad altre immagini.
A volte, per fare in fretta, usiamo con leggerezza un'immagine non ufficiale. Quando possibile, usa immagini ufficiali come base per le tue immagini.
Build multi-stage per ottimizzare le prestazioni
Una build multi-stage in Docker ti consente di usare più istruzioni FROM in un unico Dockerfile.
Possiamo usare un'immagine più grande come immagine di build per compilare l'applicazione e poi copiare i file necessari in una piccola immagine di runtime. Non includendo file non necessari, riduciamo la dimensione dell'immagine finale, ottimizzando non solo le prestazioni ma rendendo anche l'applicazione più sicura.
Vediamo un esempio per capirlo meglio, dato che viene usato ripetutamente nel settore:
# Use the official Python image as the build image
FROM python:3.9 AS build
# Set the working directory
WORKDIR /app
# Copy the requirements.txt file
COPY requirements.txt ./
# Install the dependencies
RUN pip install --no-cache-dir -r requirements.txt
# Copy the application files
COPY . .
# Train the model
RUN python train.py
# Use the official Alpine Linux image as the runtime image
FROM alpine:3
# Set the working directory
WORKDIR /app
# Copy the model files from the build image
COPY --from=build /app/models /app/models
# Copy the requirements.txt file
COPY --from=build /app/requirements.txt /app
# Install the dependencies
RUN pip install --no-cache-dir -r requirements.txt
# Run the application
CMD ["python","predict.py"]
Analizzando l'esempio, l'immagine ufficiale di Python viene usata inizialmente come immagine di build e si installano tutte le dipendenze in quella fase.
Dopo aver eseguito il file train.py, copiamo i file del modello generati e il file requirements.txt in una piccola immagine Alpine Linux per il runtime, che useremo per eseguire l'applicazione. Utilizzando una build multi-stage e non includendo le dipendenze di build e l'interprete Python nell'immagine finale, abbiamo ridotto in modo significativo la dimensione dell'immagine finale.
Usare volumi per persistere i dati
I dati all'interno di un container non sono disponibili una volta che viene arrestato ed eliminato, ma a volte ti servono i risultati degli esperimenti per riferimento futuro. Potrebbe anche essere che tu voglia condividere dati tra più container.
Usando il comando dei volumi, assicuri che i dati persistano al di fuori del container. Ecco un esempio di come potresti farlo:
# Use the official Python image as the base image
FROM python:3.9
# Set the working directory
WORKDIR /app
# Copy the requirements.txt file
COPY requirements.txt ./
# Install the dependencies
RUN pip install --no-cache-dir -r requirements.txt
# Copy the rest of the application files
COPY . .
# Create a directory for storing data
RUN mkdir /app/data
# Define a volume for the data directory
VOLUME /app/data
# Run the application
CMD ["python","main.py"]
Organizzare e versionare le immagini Docker
Quando inizi a lavorare con più immagini Docker, tutto può diventare confuso e nasce l'esigenza di organizzarle. Sebbene queste pratiche varino da organizzazione a organizzazione, possiamo delineare alcune pratiche comunemente seguite per organizzare le immagini Docker:
- Seguire una convenzione di denominazione coerente per ogni immagine. Ad esempio, usare il formato <registry>/<organization>/<image>:<version>. Questo può aiutare a identificare le immagini e le loro versioni nel registry.
- Seguire pratiche di versionamento delle immagini è essenziale, se necessario, per effettuare il rollback a una versione precedente. Hai visto come la versione entri nella convenzione di denominazione, e la versione può essere articolata come major version>.<minor version>.<patch version>.
- Taggare le immagini con parole significative, come latest, staging, production, può anche aiutare a organizzare e gestire le immagini. Questo ti consente di identificare rapidamente le immagini destinate a diversi ambienti e fasi della pipeline di deployment.
È consigliabile allinearsi con la tua organizzazione; ci si aspetta che l'intero team segua la stessa convenzione.
Conclusione
Questo articolo ha trattato l'importanza, per i data scientist, di creare codice e applicazioni riproducibili usando strumenti come Docker. Siamo partiti dall'importanza di Docker per i data scientist, passando per le istruzioni di installazione e alcuni comandi Docker comunemente usati. In seguito l'articolo ha mostrato come possiamo containerizzare applicazioni di machine learning tramite esempi di codice e le best practice da seguire nell'uso di Docker.
Per approfondire, puoi seguire il nostro corso Introduction to Docker, che copre molti dei fondamenti. Potresti anche pensare di conseguire una certificazione Docker se lavori nel settore.
La maggior parte dei data scientist si concentra su competenze core come statistica, matematica, machine learning, deep learning e coding, ma dimentica di imparare le best practice di ingegneria del software attese nel settore.
Se vuoi consolidare l'apprendimento sui fondamenti della data science, dai un'occhiata al percorso Data Scientist with Python che offre apprendimento guidato con progetti. In alternativa, se hai bisogno di rinfrescare le tue competenze di ingegneria del software, dai un'occhiata al corso software engineering for data scientists with Python, che copre concetti essenziali come modularità, documentazione e test automatizzati.
Docker per Data Scientist: FAQ
I data scientist dovrebbero imparare Docker?
Imparare Docker può essere utile per i data scientist perché consente di gestire facilmente dipendenze e ambienti, garantendo che il codice giri in modo coerente su sistemi diversi. Significa anche non dover fare affidamento esclusivamente sul team DevOps.
Come posso usare Jupyter Notebook in un container Docker?
Per usare Jupyter Notebook in un container Docker, in modo simile al tutorial sopra, puoi creare un nuovo Dockerfile e poi usare il comando RUN per installare Jupyter. Quindi usa il comando CMD per avviare il server di Jupyter Notebook. In alternativa, puoi usare immagini preconfigurate dal Docker Hub con Jupyter installato. Ecco una guida dettagliata all'uso di Jupyter Notebook, anche tramite Docker.
Come posso condividere i miei progetti di data science usando Docker?
Puoi condividere i tuoi progetti di data science usando Docker pubblicando la tua immagine su un registry di container come Docker Hub. Dopodiché, altri possono scaricare l'immagine ed eseguire il progetto nel proprio ambiente.

