Présentation de TensorRT

 

Qu'est-ce que TensorRT

TensorRT est une bibliothèque d'inférence de réseau de neurones hautes performances développée par le langage C++ de Nvidia. Il s'agit d'un optimiseur et d'un moteur d'exécution pour le déploiement en production . Sa puissance de calcul performante s'appuie sur l'unité de traitement graphique de Nvidia. Il se concentre sur les tâches d'inférence et complète les cadres d'apprentissage de réseaux neuronaux couramment utilisés, notamment TensorFlow, Caffe, PyTorch, MXNet, etc. Vous pouvez charger directement les fichiers de modèle entraînés de ces frameworks et également fournir des interfaces API pour créer des modèles par vous-même via la programmation.

 

 

TensorRT s'appuie sur l'environnement matériel d'apprentissage en profondeur de Nvidia, qui peut être GPU ou DLA, et ne peut pas être utilisé sans lui.

TensorRT prend en charge la plupart des définitions de couche de réseau de neurones actuelles et fournit des API permettant aux développeurs d'implémenter eux-mêmes des opérations de couche spéciales. La fonction associée est INetworkDefinition::addPluginV2().

 

type d'interface clé

Dans la bibliothèque principale de TensorRT, les types d'interface les plus critiques sont :

  • Contexte d'exécution du moteur d'inférence IExecutionContext
  • Moteur d'inférence ICudaEngine
  • Désérialisation IRuntime CudaEngine
  • Définition de réseau INetWorkDefinition
  • Analyse du modèle de réseau IParser
  • Configuration de l'optimisation IOptimizationProfile
  • Paramètres de construction de IBuilderConfig CudaEngine
  • Constructeur IBuilder, principalement utilisé pour construire CudaEngine
  • Interface de journal ILogger, qui doit être implémentée par les développeurs

IExecutionContext

Le contexte d'exécution du moteur d'inférence (Context), qui utilise CudaEngine pour effectuer des opérations d'inférence, est l'interface d'exécution finale pour les opérations d'inférence.

Un CudaEngine est autorisé à avoir plusieurs contextes en cours d'exécution, et chaque contexte peut utiliser une taille de lot différente. Si la taille d'entrée du modèle de réseau prend en charge l'ajustement dynamique, chaque contexte peut également utiliser sa propre entrée de taille différente.

La fonction principale est d'effectuer des opérations d'inférence, la fonction spécifique IExecutionContext::executeV2(bindings)

Créé par CudaEngine, ICudaEngine ::createExecutionContext()

 

Moteur ICuda

Il peut être appelé un moteur d'inférence, qui permet aux applications d'appeler cette interface pour effectuer l'inférence, prend en charge l'exécution synchrone et l'exécution asynchrone, et implémente l'asynchronisme via Stream et Event dans Cuda. Un moteur d'inférence peut avoir plusieurs contextes d'exécution et prend en charge l'exécution d'entrées par lots.

La fonction principale de CudaEngine est d'effectuer des tâches d'inférence en créant un contexte. La façon de créer un contexte est ICudaEngine::createExecutionContext().

CudaEngine peut être sérialisé en mémoire puis mis en cache sur le disque. La prochaine fois que vous l'utiliserez, vous pourrez le charger directement du fichier disque dans la mémoire, puis le sérialiser dans CudaEngine, ce qui vous fera gagner beaucoup de temps et de configuration des paramètres.

La méthode de création de CudaEngine dépend de INetworkDefinition (interface de définition de réseau). NetWorkDefinition est généralement obtenu en analysant les fichiers de modèle ONNX ou les fichiers de modèle formés par TensorFlow. L'analyse des fichiers de modèle ONNX nécessite l'interface nvonnxparser::IParser.

Remarque : La génération de CudaEngine à partir de NeworkDefinition prend du temps. Le CudaEngine généré peut être mis en cache dans un fichier disque et peut être chargé directement pour une utilisation ultérieure.

De plus , CudaEngine n'est pas multiplateforme, et le CudaEngine généré par différents modèles de GPU et différentes versions de TensorRT peut être incompatible. Lorsque vous utilisez des fichiers CudaEngine mis en cache, veillez à les distinguer. Ces facteurs d'influence peuvent être utilisés dans le cadre du nom de fichier Différenciez, par exemple, les noms de fichiers tels que Win64_RTX2080TI_70011.engine.

Interfaces associées :

  • IExecutionContext, génère le contexte et infère à travers le contexte, fonctions associées : ICudaEngine::createExecutionContext()
  • IRuntime, désérialiser les fichiers de cache, obtenir CudaEngine, fonctions associées : IRuntime :: deserializeCudaEngine()
  • IBuilder, construit CudaEngine selon NetworkDefinision et BuilderConfig, fonctions associées : IBuilder::buildEngineWithConfig(INetworkDefinision,IBuilderConfig)

 

Iruntime

Le nom de cette interface est facile à mal comprendre. Le nom semble être une interface de très bas niveau, mais sa fonction réelle est principalement une seule, qui est de désérialiser le fichier de cache sérialisé de CudaEngine et de récupérer l'objet CudaEngine.

Comment l'obtenir : nvinfer1::createInferRuntime(void)

Interfaces associées :

  • ICudaEngine, construit CudaEngine selon NetworkDefinision et BuilderConfig, fonctions associées : IBuilder::buildEngineWithConfig()

INetWorkDefinition

Interface de définition de réseau, cette interface fournit une série de fonctions permettant aux développeurs de construire un réseau de neurones à partir de zéro, y compris la taille dimensionnelle des tenseurs d'entrée et de sortie, le type et la fonction d'activation de chaque couche, etc. Elle fournit également une interface permettant aux développeurs de ajouter Un calque personnalisé est une interface très puissante. Cependant , aucune de ses fonctions n'est fondamentalement utilisée dans l'utilisation réelle générale. Parce que la définition du réseau est automatiquement générée à partir du fichier de modèle de réseau formé tel que le fichier ONNX.

Les étapes générales d'utilisation de cette interface :

  1. Générez une INetWorkDefinition via IBuilder::createNetwork().
  2. Utilisez l'interface NvOnnxParser::createParser(&INetWorkDefinition,...) pour créer un objet IPaser lié à cette INetWorkDefinition.
  3. L'appel de IPaser::parseFromFile("path.onnx") construira un objet INetWorkDefinition à partir du fichier modèle.

IParseur

ONNX Parser, analyse le fichier de modèle formé et construit l'objet INetWorkDefinition lié en fonction du fichier de modèle.

Méthode d'obtention : NvOnnxParser::createParser(&INetWorkDefinition,...)

Fonction principale : IPaser::parseFromFile("path.onnx")

IOptimizationProfile

Spécifiez les dimensions de chaque tenseur d'entrée et de sortie pour le modèle dynamique, la fonction est IOptimizationProfile::setDimensions().

Il doit y avoir au moins un IOptimizationProfile lors de la construction de CudaEngine, car chaque ExecutionContext doit spécifier un IOptimizationProfile avant de pouvoir effectuer des opérations d'inférence.

Comment obtenir IBuilder ::createOptimizationProfile(void)

Interfaces associées :

  • IBuilderConfig, chaque IBuilderConfig doit avoir au moins un IOptimizationProfile, IOptimizationProfile sera construit dans CudaEngine avec IBuilderConfig et spécifié par ExecutionContext. La fonction associée est IBuilderConfig::addOptimizationProfile(IOptimizationProfile)
  • IExecutionContext, après la création de chaque contexte, vous devez spécifier un IOptimizationProfile, IExecutionContext::setOptimizationProfile(index), cet index est le numéro de série de IOptimizationProfile dans IBuilderConfig, l'ordre est conforme à l'ordre d'appel de addOptimizationProfile.

IBuilderConfig

Pour construire les paramètres de configuration de CudaEngine, vous pouvez ajouter la configuration IOptimizationProfile pour définir l'espace mémoire de travail maximal, la taille de lot maximale, le niveau de précision minimal acceptable et les opérations de précision à virgule flottante.

Comment obtenir IBuilder ::createBuilderConfig(void)

Interfaces associées :

  • IBuilder, construit CudaEngine selon NetworkDefinision et BuilderConfig, fonction : IBuilder::buildEngineWithConfig(INetworkDefinision,IBuilderConfig)

Je Bâtisseur

L'interface IBuilder est principalement utilisée pour construire CudaEngine, et elle est également utilisée pour générer des objets d'interface INetWorkDefinition, des objets d'interface IOptimizationProfile et IBuilderConfig.

ILogger

L'interface de journalisation est utilisée pour afficher certains messages, avertissements, erreurs et autres informations à l'intérieur de TensorRT.

Lors de la création d'IBuilder et d'IRuntime, vous devez transmettre l'objet ILogger. Nous devons implémenter cette interface et créer un objet à leur transmettre. L'implémentation la plus simple d'une interface est la suivante :

class Logger : public ILogger           
 {
     void log(Severity severity, const char* msg) override
     {
         // suppress info-level messages
         if (severity != Severity::kINFO)
             std::cout << msg << std::endl;
     }
 } gLogger;

organigramme

Résumer

Cet article présente les interfaces nécessaires à l'utilisation de TensorRT, maîtrise la relation d'appel entre ces interfaces et comprend le flux de travail de TensorRT. À l'avenir, les détails spécifiques de chaque étape seront présentés en détail en combinaison avec le projet réel.

référence

https://docs.nvidia.com/deeplearning/tensorrt/developer-guide/index.html

 

Je suppose que tu aimes

Origine blog.csdn.net/Ango_/article/details/116140436
conseillé
Classement