Introduction à DirectML

Résumé

Direct Machine Learning (DirectML) est une API de bas niveau pour l’apprentissage automatique (ML). Les primitives d’apprentissage automatique accélérées par le matériel (appelées opérateurs) sont les blocs de construction de DirectML. À partir de ces blocs de construction, vous pouvez développer des techniques d’apprentissage automatique telles que la mise à l’échelle, l’anticrénelage et le transfert de style pour ne nommer que ces techniques. Le débruitage et la super résolution, par exemple, vous permettent d’obtenir des effets de ray-tracing impressionnants avec moins de rayons par pixel.

Vous pouvez intégrer l’apprentissage machine par le biais d’inférences de charges de travail dans votre jeu, votre moteur, votre intergiciel (middleware), votre serveur principal ou toute autre application. DirectML dispose d’une interface de programmation et d’un flux de travail familier (C++ natif, nano-COM) DirectX 12, et est prise en charge par tout le matériel compatible avec DirectX 12. Pour les exemples d’applications DirectML, notamment un exemple d’application DirectML minimale, consultez Exemples d’applications DirectML. Veillez également à passer en revue notre page d’accueil.

DirectML est introduit dans Windows 10, version 1903 et dans la version correspondante du Kit de développement logiciel (SDK) Windows.

DirectML est-il approprié pour mon projet ?

DirectML est un composant d’apprentissage automatique Windows. L’API WinML de niveau supérieur est principalement axée sur le modèle, avec son flux de travail d’évaluation de liaison de charge. Mais les domaines tels que les jeux et les moteurs ont généralement besoin d’un niveau inférieur d’abstraction, et d’un degré de contrôle du développeur plus élevé, afin de tirer pleinement parti du silicium. Si vous comptez des millisecondes et que vous essayez de placer le plus de frame possible, DirectML répond à vos besoins d’apprentissage automatique.

Pour des scénarios fiables en temps réel, de hautes performances, à faible latence et/ou avec des contraintes de ressources, utilisez DirectML (plutôt que WinML). Vous pouvez intégrer DirectML directement dans votre moteur ou votre pipeline de rendu existants. Ou, à un niveau supérieur pour les frameworks et intergiciels d’apprentissage automatique personnalisés, DirectML peut fournir un back-end de haute performance sur Windows.

WinML est lui-même implémenté à l’aide de DirectML en tant que back-end.

Que fait DirectML ? Quel travail dois-je faire en tant que développeur ?

DirectML exécute efficacement les couches individuelles de votre modèle d’inférence sur le GPU (ou sur les cœurs d’accélération IA, le cas échéant). Chaque couche est un opérateur et DirectML vous fournit une bibliothèque d’opérateurs primitifs d’apprentissage automatique de bas niveau et à accélération matérielle. Vous pouvez exécuter des opérations DirectML de manière isolée ou en tant que graphe (voir la section Flux de travail en couche par couche et en graphe dans DirectML).

Les opérateurs et les graphes appliquent des optimisations spécifiques au matériel et à l’architecture. Pendant ce temps-là, vous, en tant que développeur, vous voyez une interface unique et indépendante du fournisseur pour l’exécution de ces opérateurs.

La bibliothèque d’opérateurs dans DirectML fournit toutes les opérations habituelles auxquelles vous pouvez vous attendre lors d’une charge de travail d'apprentissage automatique.

  • Opérateurs d’activation, tels que linear, ReLU, sigmoid, tanh, etc.
  • Opérateurs à l’échelle de l’élément, tels que add, exp, log, max, min, sub, etc.
  • Opérateurs de convolution, tels que la convolution 2D et 3D, etc.
  • Opérateurs de réduction, tels que argmin, average, l2, sum, etc.
  • Opérateurs de regroupement, tels que average, lp et max.
  • Opérateurs de réseau neuronal (NN), tels que gemm, gru, lstm et rnn.
  • Et bien plus encore.

Pour des performances maximales et pour ne payer que ce dont vous vous servez, DirectML place le contrôle entre vos mains en tant que développeur sur la façon dont votre charge de travail d’apprentissage automatique est exécutée sur le matériel. Déterminer quels opérateurs doivent être exécutés et à quel moment relève de votre responsabilité en tant que développeur. Les tâches qui sont laissées à votre discrétion sont les suivantes : transcrire le modèle, simplifier et optimiser vos couches, les poids de chargement, l’allocation de ressources, la liaison, la gestion de la mémoire (comme avec Direct3D 12) et l’exécution du graphe.

Vous conservez une connaissance générale de vos graphes (vous pouvez coder en dur votre modèle directement ou écrire votre propre chargeur de modèle). Vous pouvez concevoir un modèle de mise à l’échelle, par exemple, en utilisant plusieurs couches des opérateurs upsample, convolution, normalization et activation . Avec cette familiarité, la planification minutieuse et la gestion des barrières, vous pouvez extraire plus de parallélisme et de performances du matériel. Si vous développez un jeu, votre gestion minutieuse des ressources et votre contrôle sur la planification vous permettent d’intercaler les charges de travail d’apprentissage automatique et le travail de rendu traditionnel afin de saturer le GPU.

Qu’est-ce que le flux de travail DirectML de haut niveau ?

Voici la recette de haut niveau concernant la manière dont nous prévoyons que DirectML soit utilisé. Dans les deux phases principales de l’initialisation et de l’exécution, vous enregistrez le travail dans les listes de commandes, puis vous les exécutez sur une file d’attente.

Initialisation

  1. Créez vos ressources Direct3D 12 : appareil Direct3D 12, file d’attente de commandes, liste de commandes et ressources telles que les tas du descripteur.
  2. Étant donné que vous effectuez une inférence d’apprentissage automatique et une charge de travail de rendu, créez des ressources DirectML : appareil DirectML et instances d’opérateur. Si vous avez un modèle Machine Learning dans lequel vous devez effectuer un type particulier de convolution avec une taille particulière de tenseur de filtre avec un type de données particulier, tous sont des paramètres dans l’opérateur de convolution DirectML.
  3. DirectML enregistre le travail dans une liste de commandes Direct3D 12. Par conséquent, une fois l’initialisation effectuée, vous enregistrez la liaison et l’initialisation de (par exemple) votre opérateur de convolution dans votre liste de commandes. Ensuite, fermez et exécutez votre liste de commandes sur votre file d’attente comme d’habitude.

Exécution

  1. Chargez vos tenseurs de poids dans les ressources. Un tenseur dans DirectML est représenté à l’aide d’une ressource Direct3D 12 standard. Par exemple, si vous souhaitez charger vos données de poids sur le GPU, vous pouvez les modifier de la même manière que vous modifieriez n’importe quelle autre ressource Direct3D 12 (utilisez un tas de téléchargement ou la file d’attente de copie).
  2. Ensuite, vous devez lier ces ressources Direct3D 12 en tant que tenseurs d’entrée et de sortie. Enregistrez la liaison et l’exécution de vos opérateurs dans votre liste de commandes.
  3. Fermez et exécutez votre liste de commandes.

Comme avec Direct3D 12, la durée de vie des ressources et la synchronisation sont de votre responsabilité. Par exemple, ne libérez pas vos objets DirectML tant qu’ils sont toujours en cours d’exécution sur le GPU.

Flux de travail couche par couche et flux de travail basé sur les graphes dans DirectML

DirectML prend en charge les approches couche par couche et basée sur les graphes pour l’exécution du modèle. Lors de l’exécution couche par couche, vous êtes responsable de la création et de l’initialisation de chaque opérateur DirectML. Vous devez également les enregistrer individuellement pour l’exécution sur une liste de commandes. En revanche, lors de l’exécution d’un graphe, vous créez plutôt un ensemble de nœuds et de d’arêtes, où chaque nœud représente un opérateur DirectML, et les arêtes représentent des données de tenseur qui circulent entre les nœuds. L’intégralité du graphe est ensuite envoyée pour l’initialisation ou l’exécution en une seule fois, et DirectML gère la planification et l’enregistrement des opérateurs individuels pour vous.

Les deux modèles sont utiles dans différentes situations. Une approche de couche par couche vous offre un contrôle maximal sur l’ordre et la planification du travail de calcul. Par exemple, ce niveau de contrôle vous permet d’interlacer les charges de travail de rendu Direct3D 12 avec vos répartitions de calcul DirectML. Cela peut être utile pour tirer parti des unités de calcul asynchrones ou des nuanceur sur votre GPU qui seraient autrement inactifs. L’exécution manuelle couche par couche donne également un contrôle explicite aux développeurs sur les dispositions de tenseur et l’utilisation de la mémoire.

** Toutefois, les modèles d’apprentissage automatique sont souvent exprimés en termes de graphes de couches. En guise d’alternative à l’approche de couche par couche, DirectML vous permet d’exprimer votre modèle en tant que graphique orienté acyclique de nœuds (opérateurs DirectML) et d’arêtes entre eux (descriptions des tenseurs). Après avoir généré une description du graphe, vous pouvez compiler et envoyer tout cela en même temps à DirectML pour l’initialisation et l’exécution. Dans cette approche, DirectML décide d’un ordre de parcours, et gère chaque opérateur individuel et le flux de données entre eux pour vous. Il s’agit souvent d’un moyen plus simple et plus naturel d’exprimer un modèle d’apprentissage automatique et de permettre l’application automatique d’optimisations spécifiques à l’architecture. En outre, la bibliothèque d’assistance DirectMLX fournit une syntaxe propre et pratique pour créer des graphes complexes d’opérateurs DirectML.

Quelle que soit l’approche que vous choisissez, vous aurez toujours accès à la même suite étendue d’opérateurs DirectML. Cela signifie que vous n’avez jamais à sacrifier la fonctionnalité, que vous choisissiez le contrôle affiné offert par l’approche couche par couche, ou la commodité de l’approche de graphe.

Voir aussi