Comment accélérer l'inférence des modèles NLP basés sur les Transformers

Les modèles de deep learning avancés pour le NLP basés sur les Transformers donnent des résultats impressionnants. Mais obtenir de bonne performances est un défi. Dans cet article nous résumons les meilleures options à votre disposition afin de réduire la latence de vos prédictions en production.

Utilisez un meilleur CPU ou un GPU

Quand on souhaite augmenter la vitesse des modèles NLP basés sur les Transformers, l'approche "naïve" est d'utiliser un hardware plus avancé.

La plupart du temps il s'agit d'une solution inévitable car les solutions basées uniquement sur de l'optimisation logicielle ont toutes une limite. Imaginons que vous soyez en train d'effectuer votre inférence sur un CPU. Vous aurez beau passer des semaines à travailler sur de l'optimisation bas niveau pour votre modèle Transformers favori, il est fort probable que vous obteniez de meilleures performances simplement en faisant tourner votre modèle sur un GPU NVIDIA A100.

Actuellement, les GPUs les plus utilisés en production pour l'inférence sont les NVIDIA Tesla T4 et V100.

NVIDIA Tesla GPU

Mais, et si vous aviez déjà upgradé votre hardware ? Ou encore, et si votre budget est limité et que vous ne pouvez pas vous permettre d'utiliser le tout dernier GPU à la pointe ? Lisez ce qui suit !

Inférence par batch

L'inférence par batch consiste à envoyer plusieurs requêtes en même temps à votre modèle, de façon à ce qu'il les traite toutes d'un coup.

L'inférence par batch est très puissante car votre modèle va prendre à peu près le même temps pour traiter plusieurs requêtes à la fois, et n'en traiter qu'une seule. Sous le capot la plupart des opérations sont en réalité factorisées de façon à ce que le modèle n'ait pas à répéter plusieurs fois la même opération.

Techniquement parlant, cela ne diminue pas la latence de vos requêtes, car vos requêtes ne seront pas traitées plus rapidement, mais cela améliorera le débit de votre application de manière spectaculaire (votre application pourra gérer plus de requêtes tout en utilisant le même hardware).

En revanche l'inférence par batch a aussi des inconvénients :

Premièrement elle n'est pas toujours adaptée à l'inférence online (c'est à dire pour des applications utilisées par des clients en live), parce qu'afin de construire vos batchs vous aurez besoin de mettre en tampon certaines requêtes utilisateurs. Donc certains utilisateurs devront patienter un peu plus que d'habitude.

2nd challenge : l'inférence par batch fonctionne mieux avec des requêtes similaires. Par exemple si vous déployez un modèle NLP de génération de texte, le batching sera plus efficace si toute vos requêtes ont à peu près la même longueur.

Enfin, l'inférence par batch n'est pas réalisée par le modèle de deep learning lui-même mais mais par une surcouche dédiée, comme une serveur d'inférence. Il n'est pas toujours simple de mettre en place une telle surcouche. Par exemple, Triton Inference Server de NVIDIA (cf. ci-dessous) est excellent lorsqu'il s'agit d'effectuer de l'inférence par batch. Mais pour cela vous devez au préalable trouver une façon de rendre votre modèle compatible avec Triton.

une fois que vous avez réussi à exporter votre modèle vers Triton, l'inférence par batch est simple comme bonjour. Voici par exemple comment créer des batchs composés de 128 requêtes maximum, tout en attendant maximum 5 secondes avant de lancer le batch (mettez cela dans votre fichier "config.pbtxt").

max_batch_size: 128
dynamic_batching {
    max_queue_delay_microseconds: 5000000
}

Tirez parti d'implémentations custom

e nombreuses personnes et entreprises travaillent dur sur des optimisations bas niveau pour les modèles NLP basés sur les Transformers. Cela peut être intéressant pour vous de tirer parti d'une de ces implémentations pour votre modèle.

La plupart du temps, ces implémentations custom sont faciles à utiliser et ne requièrent presqu'aucun travail de votre part. Laissez-moi en mentionner quelques unes ici :

Voici un exemple sur la façon d'utiliser DeepSpeed pour de l'inférence avec le modèle GPT-Neo 2.7B. Plutôt facile n'est-ce pas ?

# Filename: gpt-neo-2.7b-generation.py
import os
import deepspeed
import torch
from transformers import pipeline

local_rank = int(os.getenv('LOCAL_RANK', '0'))
world_size = int(os.getenv('WORLD_SIZE', '1'))
generator = pipeline('text-generation', model='EleutherAI/gpt-neo-2.7B',
                        device=local_rank)



generator.model = deepspeed.init_inference(generator.model,
                                            mp_size=world_size,
                                            dtype=torch.float,
                                            replace_method='auto')

string = generator("DeepSpeed is", do_sample=True, min_length=50)
if not torch.distributed.is_initialized() or torch.distributed.get_rank() == 0:
    print(string)         
            

lorsque vous utilisez une de ces implémentations custom, n'oubliez pas de rigoureusement tester la qualité de votre nouveau modèle, car vous n'êtes jamais certain qu'il n'y a aucun bug dans ces nouvelles implémentations.

Utilisez un moteur d'inférence dédié

Microsoft et NVIDIA ont tous deux travaillé sur des moteurs d'inférence avancés afin d'améliorer les performances de l'inférence.

ONNX Runtime (aussi connu sous le nom d'"ORT"), de Microsoft, est un accélérateur d'inférence et d'entrainement pour le deep learning. TensorRT ("TRT"), de NVIDIA, est un SDK pour une inférence de haute performance pour le deep learning. Cela inclut un optimiseur d'inférence et un moteur afin d'améliorer la vitesse et le débit des applications de deep learning.

De plus, Triton Inference Server de NVIDIA est un logiciel qui facilite l'inférence en permettant de déployer des modèles d'IA issus de divers frameworks. Grâce à Triton, il est par exemple possible de réaliser de l'inférence par batch, de faire tourner plusieurs modèles de façon concurrente sur le même GPU, our encore de faire tourner un modèle sur plusieurs GPUs, et plus encore.

ONNX Runtime
TensorRT
Triton Inference Server

Ce qui précède est attrayant, mais ce n'est bien entendu pas si simple... Afin que votre modèle puisse tirer parti de ces moteurs d'inférence, vous devez commencer par convertir votre modèle au bon format.

Plusieurs choix s'offrent à vous :

Quand vous jouez avec les techniques ci-dessus, vous devez être très prudents quant à la qualité des modèles exportés. Vous pourriez penser que votre modèle a été exporté avec succès, mais il est possible que vous ayez perdu de la précision dans la bataille, soyez donc rigoureux lorsque vous testez votre nouveau modèle.

Conclusion

Les modèles NLP modernes basés sur les Transformers donnent des résultats impressionnants, si bien que de plus en plus d'entreprises les utilisent en production. Mais il apparait souvent que bien souvent les performances sont décevantes...

Travailler sur l'accélération de vos prédictions est crucial mais, comme vous avez pu le voir ci-dessus, il n'y a pas de solution toute faite à cette question.

Si vous avez des questions à propos de comment accélérer voter inférence, n'hésitez pas à nous contacter !

Julien Salinas
CTO chez NLP Cloud