For AI agents: the complete documentation index is available at https://docs.ovhcloud.com/fr/llms.txt, the full documentation bundle is available at https://docs.ovhcloud.com/fr/llms-full.txt, and this page is available as Markdown at https://docs.ovhcloud.com/fr/guides/public-cloud/ai-machine-learning/ai-deploy-streamlit-eda-iris.md.

AI Deploy - Tutoriel - Déployer une app interactive pour l'EDA et la prédiction en utilisant Streamlit

Voir en Markdown

Comment déployer une app Streamlit pour de la prédiction et visualisation interactive de données

Info

AI Deploy est couvert par les Conditions particulières OVHcloud Public Cloud.

Objectif

L'objectif de ce tutoriel est de déployer une application d'Exploratory Data Analysis (EDA) et de prédiction interactive.

Le cas d'usage est le jeu de données IRIS. Il s'agit d'une collection de données contenant des informations sur 50 observations de quatre variables différentes : petal length, petal width, sepal length et sepal width.

Aperçu

Le premier objectif est d'effectuer une exploration des données source du jeu de données Iris.

Ensuite, l'objectif est de réaliser des prédictions à l'aide d'un modèle entraîné. Nous allons donc utiliser un réseau de neurones et les poids issus de ce notebook pour classifier les fleurs d'iris entre différentes espèces (Setosa, Versicolor et Virginica). Les quatre caractéristiques sont envoyées en entrée du réseau de neurones.

Le modèle PyTorch sera chargé et exécuté, et les probabilités de prédiction pour chaque classe seront extraites. Selon les données d'entrée, il sera possible de visualiser l'iris correspondant sur un graphique PCA afin de comparer l'entrée aux autres points de données de notre jeu de données Iris.

Pour cela, vous allez utiliser Streamlit, un framework Python qui transforme des scripts en application web partageable. Vous apprendrez également à construire et à utiliser une image Docker personnalisée pour une application Streamlit.

Prérequis

  • Un projet AI Deploy créé au sein d'un projet Public Cloud dans votre compte OVHcloud ;
  • Un utilisateur pour AI Deploy ;
  • Docker installé sur votre ordinateur local ;
  • Quelques connaissances sur la construction d'images et les Dockerfile ;
  • Vous devez également avoir suivi l'étape 6 du notebook Classification of iris varieties within the same species du dépôt GitHub. Vous pourrez ainsi sauvegarder votre modèle PyTorch model_iris_classification.pth.

En pratique

Vous allez suivre différentes étapes pour construire votre application Streamlit.

  • Plus d'informations sur les capacités de Streamlit sont disponibles ici.
  • Le lien direct vers le fichier Python complet est disponible ici.

Nous allons ici principalement voir comment écrire les codes utils.py et app.py, le fichier requirements.txt et le Dockerfile. Si vous souhaitez voir le code complet, reportez-vous au dépôt GitHub.

Créer l'application Streamlit

Deux fichiers Python sont créés dans le but de charger le modèle PyTorch et de construire l'app Streamlit.

Définir le fichier utils.py

Ce fichier Python est dédié au chargement du modèle PyTorch. Vous pouvez trouver le code complet ici.

Tout d'abord, nous devons définir la classe Model avec l'architecture du réseau de neurones.

class Model(nn.Module):
    def __init__(self):
        super().__init__()
        # fully connected layer : 4 input features for 4 parameters in X
        self.layer1 = nn.Linear(in_features=4, out_features=16)
        # fully connected layer
        self.layer2 = nn.Linear(in_features=16, out_features=12)
        # output layer : 3 output features for 3 species
        self.output = nn.Linear(in_features=12, out_features=3)

    def forward(self, x):
        # activation fonction : reLU
        x = F.relu(self.layer1(x))
        x = F.relu(self.layer2(x))
        x = self.output(x)
        return x

Ensuite, nous créons la fonction permettant de charger le checkpoint du modèle.

def load_checkpoint(path):

    model = Model()
    print("Model display: ", model)
    model.load_state_dict(torch.load(path))
    model.eval()

    return model

La dernière fonction nous permet de charger le modèle et d'obtenir des prédictions.

Info

Pour en savoir plus sur la façon de sauvegarder un modèle avec PyTorch, reportez-vous à la dernière étape "Save the model for future inference" du notebook.

Info

Vous pouvez trouver le modèle PyTorch model_iris_classification.pth sur le dépôt GitHub.

def load_model(X_tensor):
    model = load_checkpoint(path)
    predict_out = model(X_tensor)
    _, predict_y = torch.max(predict_out, 1)
    return predict_out.squeeze().detach().numpy(), predict_y.item()

# pytorch model
path = "model_iris_classification.pth"

Écrire le fichier app.py

Chargez le jeu de données IRIS pour l'EDA.

@st.cache
def load_data():
    # load the iris dataset with sklearn
    dataset_iris = load_iris()
    # define inputs and output
    df_inputs = pd.DataFrame(dataset_iris.data, columns=dataset_iris.feature_names)
    df_output = pd.DataFrame(dataset_iris.target, columns=['variety'])
    return df_inputs, df_output

Affichez la figure d'EDA basée sur le jeu de données source.

@st.cache(allow_output_mutation=True)
def data_visualization(df_inputs, df_output):
    df = pd.concat([df_inputs, df_output['variety']], axis=1)
    eda = sns.pairplot(data=df, hue="variety", palette=['#0D0888', '#CB4779', '#F0F922'])
    return eda

Créez une barre latérale avec des curseurs.

def create_slider(df_inputs):
    # slidebars with min, max and mean (by default) values
    sepal_length = st.sidebar.slider(
        label='Sepal Length',
        min_value=float(df_inputs['sepal length (cm)'].min()),
        max_value=float(df_inputs['sepal length (cm)'].max()),
        value=float(round(df_inputs['sepal length (cm)'].mean(), 1)),
        step=0.1)
    sepal_width = st.sidebar.slider(
        label='Sepal Width',
        min_value=float(df_inputs['sepal width (cm)'].min()),
        max_value=float(df_inputs['sepal width (cm)'].max()),
        value=float(round(df_inputs['sepal width (cm)'].mean(), 1)),
        step=0.1)
    petal_length = st.sidebar.slider(
        label='Petal Length',
        min_value=float(df_inputs['petal length (cm)'].min()),
        max_value=float(df_inputs['petal length (cm)'].max()),
        value=float(round(df_inputs['petal length (cm)'].mean(), 1)),
        step=0.1)
    petal_width = st.sidebar.slider(
        label='Petal Width',
        min_value=float(df_inputs['petal width (cm)'].min()),
        max_value=float(df_inputs['petal width (cm)'].max()),
        value=float(round(df_inputs['petal width (cm)'].mean(), 1)),
        step=0.1)
    return sepal_length, sepal_width, petal_length, petal_width

Exécutez une PCA.

@st.cache
def run_pca():
    pca = PCA(2)
    X = df_inputs.iloc[:, :4]
    X_pca = pca.fit_transform(X)
    df_pca = pd.DataFrame(pca.transform(X))
    df_pca.columns = ['PC1', 'PC2']
    df_pca = pd.concat([df_pca, df_output['variety']], axis=1)
    return pca, df_pca

Créez une fonction qui filtre les valeurs négatives du dataframe. Seules les valeurs positives du dataframe sont conservées. Si une valeur est négative, elle est fixée à zéro.

def extract_positive_value(prediction):
    # f(prediction) = max(0, prediction)
    prediction_positive = []
    for p in prediction:
        if p < 0:
            p = 0
        prediction_positive.append(p)
    return pd.DataFrame({'Species': ['Setosa', 'Versicolor', 'Virginica'], 'Confidence': prediction_positive})

Définissez une fonction Python pour afficher une image selon l'espèce d'Iris.

def display_img(species):
    # define the list of images
    list_img = ['setosa.png', 'versicolor.png', 'virginica.png']
    return Image.open(list_img[species])
Info

Toutes les fonctions définies ci-dessus sont appelées dans le fichier Python main app.py pour construire l'app Streamlit. Vous pouvez trouver cette partie du code ainsi que les différentes fonctions définies précédemment sur le dépôt GitHub.

Écrire le fichier requirements.txt de l'application

Le fichier requirements.txt nous permettra d'indiquer tous les modules nécessaires au fonctionnement de notre application. Ce fichier sera utile lors de l'écriture du Dockerfile.

pandas==1.4.4
numpy==1.23.2
torch==1.12.1
streamlit==1.12.2
scikit-learn==1.1.2
plotly==5.10.0
Pillow==9.2.0
seaborn==0.12.0

Écrire le Dockerfile de l'application

Votre Dockerfile doit commencer par l'instruction FROM indiquant l'image parente à utiliser. Dans notre cas, nous choisissons de partir de l'image OVHcloud python:3.8 :

python:3.8

Créez le répertoire personnel et ajoutez-y vos fichiers :

WORKDIR /workspace
ADD . /workspace

Installez le fichier requirements.txt qui contient les modules Python nécessaires à l'aide d'une commande pip install ... :

RUN pip install -r requirements.txt

Définissez votre commande de lancement par défaut pour démarrer l'application :

CMD [ "streamlit", "run", "/workspace/app.py", "--server.address=0.0.0.0" ]

Attribuez les droits d'accès corrects à l'utilisateur ovhcloud (42420:42420) :

RUN chown -R 42420:42420 /workspace
ENV HOME=/workspace

Construire l'image Docker depuis le Dockerfile

Depuis le répertoire contenant votre Dockerfile, exécutez l'une des commandes suivantes pour construire l'image de votre application :

# Build the image using your machine's default architecture
docker build . -t streamlit-eda-iris:latest

# Build image targeting the linux/amd64 architecture
docker buildx build --platform linux/amd64 -t streamlit-eda-iris:latest .
  • La première commande construit l'image en utilisant l'architecture par défaut de votre système. Cela peut fonctionner si votre machine utilise déjà l'architecture linux/amd64, qui est requise pour exécuter des containers avec nos produits AI. Cependant, sur des systèmes avec une architecture différente (par exemple ARM64 sur Apple Silicon), l'image résultante ne sera pas compatible et ne pourra pas être déployée.

  • La seconde commande cible explicitement l'architecture linux/amd64 afin de garantir la compatibilité avec nos services AI. Elle nécessite buildx, qui n'est pas installé par défaut. Si vous n'avez jamais utilisé buildx auparavant, vous pouvez l'installer en exécutant : docker buildx install

Info

L'argument point . indique que votre contexte de build (emplacement du Dockerfile et des autres fichiers nécessaires) est le répertoire courant.

L'argument -t vous permet de choisir l'identifiant à donner à votre image. Les identifiants d'image sont généralement composés d'un nom et d'un tag de version <name>:<version>. Pour cet exemple, nous avons choisi streamlit-eda-iris:latest.

Tester en local (optionnel)

Lancez la commande Docker suivante pour lancer votre application localement sur votre ordinateur :

docker run --rm -it -p 8501:8501 --user=42420:42420 streamlit-eda-iris:latest
Info

L'argument -p 8501:8501 indique que vous souhaitez exécuter une redirection de port depuis le port 8501 de votre machine locale vers le port 8501 du container Docker. Le port 8501 est le port par défaut utilisé par les applications Streamlit.

Warning

N'oubliez pas l'argument --user=42420:42420 si vous souhaitez simuler exactement le même comportement que celui qui se produira sur les apps AI Deploy. Il exécute le container Docker en tant qu'utilisateur OVHcloud spécifique (utilisateur 42420:42420).

Une fois démarrée, votre application devrait être disponible sur http://localhost:8501.

Envoyer l'image vers le registre partagé

Warning

Le registre partagé ne doit être utilisé qu'à des fins de test. Pensez à créer et à rattacher votre propre registre. Plus d'informations à ce sujet sont disponibles ici. Les images envoyées vers ce registre sont réservées aux workloads AI Tools et ne seront pas accessibles pour des usages externes.

Trouvez l'adresse de votre registre partagé en lançant cette commande :

ovhai registry list

Connectez-vous au registre partagé avec vos identifiants habituels d'utilisateur AI Platform :

docker login -u `<user>` -p <password> `<shared-registry-address>`

Envoyez l'image compilée vers le registre partagé :

docker tag streamlit-eda-iris:latest `<shared-registry-address>`/streamlit-eda-iris:latest
docker push `<shared-registry-address>`/streamlit-eda-iris:latest

Lancer l'app AI Deploy

La commande suivante démarre une nouvelle app exécutant votre application Streamlit :

ovhai app run \
      --default-http-port 8501 \
      --cpu 12 \
      `<shared-registry-address>`/streamlit-eda-iris:latest
Info

--default-http-port 8501 indique que le port à atteindre sur l'URL de l'app est le 8501.

--cpu 12 indique que nous demandons 12 CPU pour cette app.

Info

Pensez à ajouter l'attribut --unsecure-http si vous souhaitez que votre application soit accessible sans authentification.

Aller plus loin

  • Vous pouvez imaginer déployer un modèle d'IA avec un autre outil : Gradio. Reportez-vous à ce tutoriel.
  • Une autre façon de créer une app AI Deploy est d'utiliser Flask ! C'est par ici.

Pour une formation ou une assistance technique sur la mise en œuvre de nos solutions, contactez votre commercial ou consultez la page Professional Services pour obtenir un devis et faire analyser votre projet par nos experts.

Votre avis nous intéresse !

N'hésitez pas à nous faire part de vos questions, retours et suggestions pour améliorer le service :

Cette page vous a-t-elle aidé ?