Section courante

A propos

Section administrative du site

Fonctionnalités pour les déploiements à grande échelle

Cette page présente plusieurs points d'extension et astuces utiles pour l'exécution de PyTorch au sein d'un système plus vaste ou pour l'exploitation de plusieurs systèmes utilisant PyTorch au sein d'une organisation plus importante.

Elle n'aborde pas le déploiement de modèles en production. Consultez torch.jit ou l'un des tutoriels correspondants.

Cette page suppose que vous compilez PyTorch à partir des sources dans votre organisation ou que vous avez la possibilité de lier statiquement du code supplémentaire à charger lors de l'utilisation de PyTorch. Par conséquent, de nombreux hooks sont exposés sous forme d'API C++ pouvant être déclenchées une seule fois de manière centralisée, par exemple dans le code d'initialisation statique.

Profilage des opérateurs à l'échelle du parc

PyTorch est fourni avec torch.autograd.profiler, capable de mesurer le temps de chaque opérateur à la demande. Ce même mécanisme permet d'effectuer des mesures «toujours actives» pour tout processus exécutant PyTorch. Cela peut s'avérer utile pour collecter des informations sur les charges de travail PyTorch exécutées dans un processus donné ou sur l'ensemble des machines.

De nouveaux rappels pour chaque appel d'opérateur peuvent être ajoutés avec torch::addGlobalCallback. Les hooks seront appelés avec la structure torch::RecordFunction décrivant le contexte d'appel (par exemple, le nom). Si cette fonction est activée, RecordFunction::inputs() contient les paramètres de la fonction représentée par le type variant torch::IValue. Notez que la journalisation des entrées est relativement coûteuse et doit donc être activée explicitement.

Les rappels d'opérateur ont également accès à l'interface c10::ThreadLocalDebugInfo::get() renvoyant un pointeur vers la structure contenant les informations de débogage. Ces informations de débogage peuvent être définies plus tôt à l'aide de l'objet at::DebugInfoGuard. Elles sont propagées via les passes avant (y compris les tâches de fork désynchronisée) et arrière et peuvent être utiles pour transmettre des informations supplémentaires sur l'environnement d'exécution (par exemple, l'identifiant du modèle) des couches supérieures de l'application aux rappels d'opérateurs.

L'appel de rappels ajoute une surcharge ; il est donc généralement utile d'échantillonner aléatoirement les appels d'opérateurs. Cette option peut être activée pour chaque rappel avec une fréquence d'échantillonnage optionnelle transmise à torch::addGlobalCallback.

Notez que addGlobalCallback n'est pas thread-safe et ne peut être appelé que lorsqu'aucun opérateur PyTorch n'est en cours d'exécution. Il est généralement conseillé de les appeler une fois lors de l'initialisation.

Voici un exemple :

  1. // Appelé quelque part au début du programme
  2. void init() {
  3.     // Un échantillon sur cent s'exécute de manière aléatoire
  4.     addGlobalCallback(
  5.       RecordFunctionCallback(
  6.         &onFunctionEnter,
  7.         &onFunctionExit)
  8.       .needsInputs(true)
  9.       .samplingProb(0.01)
  10.     );
  11.     // Remarque : pour activer les observateurs dans le thread d'appel du modèle, appelez enableRecordFunction() dans le processus léger avant d'exécuter un modèle.
  12. }
  13.  
  14. void onFunctionEnter(const RecordFunction& fn) {
  15.     std::cerr << "Avant la fonction" << fn.name()
  16.               << " avec " << fn.inputs().size() << " entrées" << std::endl;
  17. }
  18.  
  19. void onFunctionExit(const RecordFunction& fn) {
  20.     std::cerr << "Après la fonction " << fn.name();
  21. }

Journalisation de l'utilisation des API

Lors d'une exécution dans un écosystème plus large, par exemple dans un planificateur de tâches géré, il est souvent utile de suivre les binaires appelant des API PyTorch spécifiques. Une instrumentation simple, injectée à plusieurs points importants de l'API, déclenche un rappel donné. Comme PyTorch est généralement invoqué dans des scripts Python ponctuels, le rappel ne se déclenche qu'une seule fois pour un processus donné et pour chaque API.

c10::SetAPIUsageHandler peut être utilisé pour enregistrer le gestionnaire d'instrumentation de l'utilisation des API. Le paramètre passé sera une «clef API» identifiant le point utilisé, par exemple python.import pour l'importation d'une extension PyTorch ou torch.script.compile si la compilation TorchScript a été déclenchée.

  1. SetAPIUsageLogger([](const std::string& event_name) {
  2.     std::cerr << "L'API a été utilisée :" << event_name << std::endl;
  3. });

Note aux développeurs : de nouveaux points de déclenchement d'API peuvent être ajoutés au code avec C10_LOG_API_USAGE_ONCE("my_api") en C++ ou torch._C._log_api_usage_once("my.api") en Python.

Attachement de métadonnées aux modèles TorchScript enregistrés

Les modules TorchScript peuvent être enregistrés sous forme d'archive regroupant les paramètres sérialisés et le code du module au format TorchScript (voir torch.jit.save()). Il est souvent pratique d'associer des informations supplémentaires au modèle, par exemple la description du générateur de modèle ou des artefacts auxiliaires.

Pour ce faire, passez l'argument _extra_files à torch.jit.save() et torch::jit::load pour entreposer et récupérer des blobs binaires arbitraires lors de l'enregistrement. Les fichiers TorchScript étant des archives ZIP classiques, les informations supplémentaires sont stockées sous forme de fichiers classiques dans le répertoire extra/ de l'archive.

Un hook global permet également d'attacher des fichiers supplémentaires à toute archive TorchScript produite lors du processus en cours. Il pourrait être utile d'étiqueter les modèles avec des métadonnées de production, similaires aux métadonnées JPEG produites par les appareils photo numériques. Voici un exemple d'utilisation :

  1. SetExportModuleExtraFilesHook([](const Module&) {
  2.     ExtraFilesMap files;
  3.     files["producer_info.json"] = "{\"user\": \"" + getenv("USER") + "\}";
  4.     return files;
  5. });

Considérations relatives à l'environnement de compilation

La compilation de TorchScript doit avoir accès aux fichiers Python d'origine, car elle utilise l'appel inspect.getsource de Python. Dans certains environnements de production, le déploiement explicite de fichiers .py et de fichiers .pyc précompilés peut être nécessaire.

Points d'extension courants

Les API PyTorch sont généralement faiblement couplées et il est facile de remplacer une composante par une version spécialisée. Points d'extension courants :



Dernière mise à jour : Samedi, le 7 juin 2025