Inférence de GPU

Découvrez comment utiliser des déploiements de modèle pour effectuer des inférences sur des instances GPU. Le GPU offre de meilleures performances avec des modèles exigeants en calcul par rapport au CPU.

Les GPU sont parfaits pour certains cas d'utilisation d'inférence d'apprentissage automatique, principalement des modèles d'apprentissage profond tels que les grands modèles de langage, la parole et la reconnaissance d'images. Les GPU utilisent des capacités de traitement parallèles et une bande passante de mémoire élevée, ce qui leur permet de gérer de grandes quantités de données et des calculs complexes beaucoup plus rapidement que les CPU traditionnelles. Les résultats sont des temps d'inférence considérablement réduits et des performances améliorées.

Le déploiement de modèle Data Science prend en charge le déploiement de modèles sur des formes GPU à l'aide de plusieurs méthodes :

Entièrement géré

Le service utilise le serveur d'inférence par défaut pour déployer le modèle sur la forme GPU sélectionnée. Vous avez le contrôle de l'utilisation du GPU à l'aide du fichier score.py.

Basé sur un conteneur

Utilisez votre propre conteneur personnalisé pour le serveur d'inférence. Utilisez le GPU à partir du conteneur et du fichier score.py.

Serveur d'inférence NVIDIA Triton

Le serveur d'inférence Triton fournit une excellente utilisation de GPU et est conçu avec facilité d'utilisation de GPU à partir de zéro. Vous pouvez utiliser un conteneur Triton lors de la création d'un déploiement de modèle.

Préparation de l'artefact de modèle

Le déploiement de modèle requiert un artefact de modèle stocké dans le catalogue de modèles et un modèle à l'état Actif. Le fichier score.py de l'artefact de modèle doit afficher une variable de périphérique GPU. La fonction load_model doit déplacer le modèle vers le périphérique GPU sélectionné. Ensuite, la fonction predict doit déplacer les tenseurs d'entrée vers le périphérique GPU. Après le calcul de l'inférence sur le périphérique GPU, il doit déplacer le tenseur de sortie vers la CPU avant de revenir de la fonction.

Conseil

Envisagez d'utiliser le kit SDK ADS pour générer automatiquement un artefact de modèle.

Le kit SDK ADS offre la génération automatique du fichier score.py pris en charge par le GPU pour les structures PyTorch et TensorFlow.

L'exemple score.py suivant utilise un périphérique GPU disponible pour effectuer l'inférence sur un modèle Resnet152 PyTorch :

import numpy as np
import os
import torch
from torch import nn
import io
from PIL import Image
import base64
from random import randint
  
  
Image.MAX_IMAGE_PIXELS = None
  
model_name = 'PyTorch_ResNet152.pth'
  
# get an available GPU device 
def get_torch_device():
    num_devices = torch.cuda.device_count()
    if num_devices == 0:
        return "cpu"
    if num_devices == 1:
        return "cuda:0"
    else:
        return f"cuda:{randint(0, num_devices-1)}"
  
print("Device selected for inference", get_torch_device())
device = torch.device(get_torch_device())
 
def load_model(model_file_name=model_name):
    """
    Loads model from the serialized format
  
    Returns
    -------
    model:  Pytorch model instance
    """
    print(f"Devcie {device}")
    model_dir = os.path.dirname(os.path.realpath(__file__))
    contents = os.listdir(model_dir)
    if model_file_name in contents:
        model.load_state_dict(torch.load(os.path.abspath(model_file_name)))    
        model = model.to(device)
        print(f"model saved to {model.get_device()}")
        return model
    else:
        raise FileNotFoundError(f'{model_file_name} is not found in model directory {model_dir}.')
 
def predict(data, model=load_model()):
    """
    Returns prediction given the model and data to predict
  
    Parameters
    ----------
    model: Model instance returned by load_model API
    data: Data format in json
  
    Returns
    -------
    predictions: Output from scoring server
        Format: {'prediction':output from model.predict method}
  
    """
  
    img_bytes = io.BytesIO(base64.b64decode(data.encode('utf-8')))
    image = Image.open(img_bytes).resize((224, 224))
    arr = np.array(image)
    X = torch.FloatTensor(np.transpose(arr, axes=(2, 0, 1))).unsqueeze(0)
    X = X.to(device)
    with torch.no_grad():
        Y = model(X).to("cpu")
        pred = torch.nn.functional.softmax(Y[0], dim=0).argmax().item()
    return {'prediction': pred}

Environnement conda avec les dépendances d'exécution de modèle

Le fichier runtime.yaml de l'artefact de modèle doit inclure un environnement conda qui inclut les dépendances GPU.

Dans l'exemple suivant, le fichier runtime.yaml indique au déploiement de modèle d'extraire un environnement conda publié à partir du chemin Object Storage défini par la variable d'environnement INFERENCE_ENV_PATH :

MODEL_ARTIFACT_VERSION: '3.0'
MODEL_DEPLOYMENT:
  INFERENCE_CONDA_ENV:
    INFERENCE_ENV_PATH: oci://service-conda-packs@id19sfcrra6z/service_pack/gpu/PyTorch_1.10_for_GPU_on_Python_3.8/1.0/pytorch110_p38_gpu_v1
    INFERENCE_ENV_SLUG: pytorch_pack_v1
    INFERENCE_ENV_TYPE: data_science
    INFERENCE_PYTHON_VERSION: 3.8

Répliques de modèle

Lorsque vous utilisez un serveur d'inférence géré par service, les déploiements de modèle chargent plusieurs répliques de modèle sur des cartes GPU disponibles pour obtenir un meilleur débit. Le nombre de répliques de modèle est calculé en fonction de

  • Taille du modèle.

  • Mémoire disponible sur la carte GPU.

  • Nombre de cartes GPU.

  • Coeurs de processeur logiques disponibles sur la forme Compute.

Par exemple, le modèle prend 2 Go de mémoire et la forme VM.GPU2.1 est sélectionnée avec 1 carte GPU avec 16 Go de mémoire GPU. Le déploiement de modèle alloue un pourcentage (environ 70 %) de mémoire GPU pour charger les modèles et la mémoire restante est enregistrée pour le calcul d'exécution lors de l'inférence. Le déploiement du modèle charge cinq répliques sur une carte GPU (taille 16*(0.7) / 2 Go du modèle en mémoire). Si 2 cartes sont disponibles, un total de 10 répliques de modèles sont chargées avec 5 modèles dans chaque carte.

Avec les fichiers score.py générés automatiquement, la distribution des répliques de modèle aux cartes GPU est basée sur un algorithme aléatoire, qui place statistiquement un nombre presque égal de répliques sur chaque carte. Toutefois, vous pouvez modifier le nombre de répliques à l'aide de la variable d'environnement d'application WEB_CONCURRENCY.

Utilisation de Triton pour l'inférence de GPU

NVIDIA Triton Inference Server rationalise et standardise l'inférence de l'IA en permettant aux équipes de déployer, d'exécuter et de faire évoluer des modèles d'IA entraînés à partir de n'importe quelle structure sur n'importe quelle infrastructure GPU ou CPU.

Configuration d'un serveur d'inférence NVIDIA Triton à utiliser avec les déploiements de modèle.

Pour activer l'inférence de GPU, config.pbtxt doit contenir KIND_GPU dans le groupe d'instances. La configuration du groupe d'instances peut également être modifiée pour indiquer le nombre de répliques d'un modèle chargées sur le périphérique GPU