TensorFlow Custom Op

C'est un guide pour les utilisateurs qui veulent écrire c++ op personnalisé pour TensorFlow et distribuer l'op comme un paquet de pip. Ce repository sert à la fois d'un exemple de travail du processus de construction et d'emballage op, ainsi qu'un modèle/point de démarrage pour écrire vos propres op. La façon dont ce repository est configuré vous permet de construire vos op personnalisés du paquet de pip de TensorFlow au lieu de construire TensorFlow à partir de scratch. Cette garantie que la bibliothèque partagée que vous construisez sera binaire compatible avec les paquets de pip de TensorFlow.

Ce guide soutient actuellement les options personnalisées d'Ubuntu et Windows, et il comprend des exemples pour les options CPU et GPU.

À partir du 1er août 2019, prévisions nocturnestf-nightlyettf-nightly-gpuEt aussi Résumé officieltensorflowettensorflow-gpuLa version précédente 1.14.0 est maintenant construite avec un différents environnements (Ubuntu 16.04 par rapport à Ubuntu 14.04, par exemple) dans le cadre de nos efforts pour créer des paquets de pipes de TensorFlow manylinux2010 compatible.Afin de vous aider à construire des options personnalisées sur Linux, ici nous fournissons notre chaîne d'outils dans le format d'une combinaison d'une image Docker et des configurations de base.Veuillez vérifier la table ci-dessous pour le nom d'image Docker nécessaire pour construire vos options personnalisées.

Coup d'appareil op GPU personnalisé op
TF de nuit Résumé de l'op-ubuntu16 Mise à jour op-gpu-ubuntu16
TF > = 2.3 2.3.0-custom-op-ubuntu 16 2.3.0-custom-op-gpu-ubuntu 16
TF 1.5 et 2.0 Téléchargement sur Ubuntu16-cuda10.0 Mise à jour de GPU-Ubuntu16
TF = 1.4 Mise à jour sur Ubuntu14 Mise à jour du GPU-Ubuntu14

Remarque : toutes les images Docker ci-dessus ont un préfixtensorflow/tensorflow:

Les configurations de basel sont inclus dans ce stockage.

Construire Example zero_out Op (CPU uniquement)

Si vous voulez essayer le processus de construire un paquet de pip pour op personnalisé, vous pouvez utiliser le code source de ce stockage suivant les instructions ci-dessous.

Pour les utilisateurs de Windows

Vous pouvez échapper à cette section si vous ne construisez pas sur Windows. Si vous construisez des options personnalisées pour la plate-forme Windows, vous aurez besoin d'une configuration similaire à celle de construire TensorFlow de la source mentionnéeiciEn outre, vous pouvez échapper à toutes les étapes Docker des instructions ci-dessous. sinon, les commandes de base pour construire et tester les options personnalisées demeurent les mêmes.

Déploiement du conteneur Docker

Vous allez construire l'op à l'intérieur d'un conteneur Docker. Plongez l'image Docker fournie du hub Docker de TensorFlow et démarrez un conteneur.

Utilisez le commandement suivant si le pack de pipes TensorFlow que vous construisez contre n'est pas encore compatible manylinux2010 :

  docker pull tensorflow/tensorflow:custom-op-ubuntu14
  docker run -it tensorflow/tensorflow:custom-op-ubuntu14 /bin/bash

Et ce qui suit au lieu s'il est manylinux2010 compatible:

  docker pull tensorflow/tensorflow:custom-op-ubuntu16
  docker run -it tensorflow/tensorflow:custom-op-ubuntu16 /bin/bash

Dans le récipient Docker, clonez ce récipient.Le code dans ce récipient vient duAjouter une opLe guide.

git clone https://github.com/tensorflow/custom-op.git
cd custom-op

Créer un paquet PIP

Vous pouvez construire le paquet de pip avec soit Bazel ou faire.

Avec le baseball :

  ./configure.sh
  bazel build build_pip_pkg
  bazel-bin/build_pip_pkg artifacts

Avec le maquillage :

  make zero_out_pip_pkg

Installer et tester le paquet PIP

Une fois que le pack de pip a été construit, vous pouvez l'installer avec,

pip3 install artifacts/*.whl

Testez ensuite le paquet de pip

cd ..
python3 -c "import tensorflow as tf;import tensorflow_zero_out;print(tensorflow_zero_out.zero_out([[1,2], [3,4]]))"

Et vous devriez voir le op nullé tous les éléments d'entrée sauf le premier:

[[1 0]
 [0 0]]

Créer et distribuer des Ops personnalisés

Maintenant, vous êtes prêt à écrire et à distribuer vos propres options. L'exemple dans ce repository a fait le travail de boisson pour configurer les systèmes de construction et les fichiers de package nécessaires à la création d'un paquet de pip. Nous recommandons d'utiliser ce repository comme un modèle.

Télécharger Template

Tout d’abord, passons par un aperçu rapide de la structure des dossiers de ce repository de modèle.

├── gpu  # Set up crosstool and CUDA libraries for Nvidia GPU, only needed for GPU ops
│   ├── crosstool/
│   ├── cuda/
│   ├── BUILD
│   └── cuda_configure.bzl
|
├── tensorflow_zero_out  # A CPU only op
│   ├── cc
│   │   ├── kernels  # op kernel implementation
│   │   │   └── zero_out_kernels.cc
│   │   └── ops  # op interface definition
│   │       └── zero_out_ops.cc
│   ├── python
│   │   ├── ops
│   │   │   ├── __init__.py
│   │   │   ├── zero_out_ops.py   # Load and extend the ops in python
│   │   │   └── zero_out_ops_test.py  # tests for ops
│   │   └── __init__.py
|   |
│   ├── BUILD  # BUILD file for all op targets
│   └── __init__.py  # top level __init__ file that imports the custom op
│
├── tensorflow_time_two  # A GPU op
│   ├── cc
│   │   ├── kernels  # op kernel implementation
│   │   │   |── time_two.h
│   │   │   |── time_two_kernels.cc
│   │   │   └── time_two_kernels.cu.cc  # GPU kernel
│   │   └── ops  # op interface definition
│   │       └── time_two_ops.cc
│   ├── python
│   │   ├── ops
│   │   │   ├── __init__.py
│   │   │   ├── time_two_ops.py   # Load and extend the ops in python
│   │   │   └── time_two_ops_test.py  # tests for ops
│   │   └── __init__.py
|   |
│   ├── BUILD  # BUILD file for all op targets
│   └── __init__.py  # top level __init__ file that imports the custom op
|
├── tf  # Set up TensorFlow pip package as external dependency for Bazel
│   ├── BUILD
│   ├── BUILD.tpl
│   └── tf_configure.bzl
|
├── BUILD  # top level Bazel BUILD file that contains pip package build target
├── build_pip_pkg.sh  # script to build pip package for Bazel and Makefile
├── configure.sh  # script to install TensorFlow and setup action_env for Bazel
├── LICENSE
├── Makefile  # Makefile for building shared library and pip package
├── setup.py  # file for creating pip package
├── MANIFEST.in  # files for creating pip package
├── README.md
└── WORKSPACE  # Used by Bazel to specify tensorflow pip package as an external dependency

La mise en œuvre op, y compris le code C++ et Python, se déroule soustensorflow_zero_outpour le CPU seulement ops, outensorflow_time_twoDir pour GPU ops. Vous voulez remplacer l'une ou l'autre des directory avec le contenu correspondant de vos propres ops.tfLe dossier contient le code pour configurer le package TensorFlow en tant que dépendance externe pour Bazel seulement. Vous ne devriez pas modifier le contenu de ce dossier. Vous n'avez pas besoin de ce dossier si vous utilisez d'autres systèmes de construction, tels que Makefile.gpuLe dossier contient le code pour configurer les bibliothèques CUDA et la chaîne d'outils.gpupour créer un pack pip pour votre op, vous aurez également à mettre à jour quelques fichiers au niveau supérieur du modèle, par exemple,setup.py,MANIFEST.inetbuild_pip_pkg.sh.

La configuration

Tout d’abord, clonez ce modèle de repo.

git clone https://github.com/tensorflow/custom-op.git my_op
cd my_op

Docteur

Ensuite, installez un conteneur Docker en utilisant l'image Docker fournie pour construire et tester les options. Nous fournissons deux ensembles d'images Docker pour différentes versions des paquets de pip. Si le paquet de pip que vous construisez contre a été publié avant le 1er août 2019 et a le tag manylinux1, veuillez utiliser les images Dockertensorflow/tensorflow:custom-op-ubuntu14ettensorflow/tensorflow:custom-op-gpu-ubuntu14, qui sont basés sur Ubuntu 14.04. Autrement, pour les nouveaux paquets manylinux2010, veuillez utiliser les images Dockertensorflow/tensorflow:custom-op-ubuntu16ettensorflow/tensorflow:custom-op-gpu-ubuntu16Tous les images Docker viennent avec Bazel pré-installé, ainsi que la chaîne d'outils correspondante utilisée pour construire les paquets TensorFlow libérés. Nous avons vu de nombreux cas où les différences de version de dépendance et les incompatibilités de l'ABI causent les utilisateurs de l'extension op personnalisée construite pour ne pas fonctionner correctement avec les paquets de pip TensorFlow libérés.fortement recommandépour utiliser l’image Docker fournie pour construire votre image personnalisée op. Pour obtenir l’image Docker CPU, exécutez l’une des commandes suivantes sur la base du pack pip que vous construisez contre:

# For pip packages labeled manylinux1
docker pull tensorflow/tensorflow:custom-op-ubuntu14

# For manylinux2010
docker pull tensorflow/tensorflow:custom-op-ubuntu16

Pour GPU, Run

# For pip packages labeled manylinux1
docker pull tensorflow/tensorflow:custom-op-gpu-ubuntu14

# For manylinux2010
docker pull tensorflow/tensorflow:custom-op-gpu-ubuntu16

Vous pourriez vouloir utiliser les volumes Docker pour cartographier unwork_dirde l'hébergement au conteneur, afin que vous puissiez éditer les fichiers sur l'hébergement, et construire avec les dernières modifications dans le conteneur Docker.

# For pip packages labeled manylinux1
docker run -it -v ${PWD}:/working_dir -w /working_dir  tensorflow/tensorflow:custom-op-ubuntu14

# For manylinux2010
docker run -it -v ${PWD}:/working_dir -w /working_dir  tensorflow/tensorflow:custom-op-ubuntu16

Pour GPU, vous voulez utilisernvidia-dockerà :

# For pip packages labeled manylinux1
docker run --runtime=nvidia --privileged  -it -v ${PWD}:/working_dir -w /working_dir  tensorflow/tensorflow:custom-op-gpu-ubuntu14

# For manylinux2010
docker run --runtime=nvidia --privileged  -it -v ${PWD}:/working_dir -w /working_dir  tensorflow/tensorflow:custom-op-gpu-ubuntu16

Réaliser configure.sh

Dernière étape avant de commencer à mettre en œuvre les options, vous voulez configurer l'environnement de construction. Les options personnalisées devraient dépendre des titres TensorFlow et de la bibliothèque partagée libtensorflow_framework.so, qui sont distribués avec le package officiel de pipes TensorFlow. Si vous voulez utiliser Bazel pour construire vos options, vous pourriez également vouloir configurer quelques actions_envs afin que Bazel puisse trouver le TensorFlow installé.configureLe scénario qui fait ces choses pour vous../configure.shdans le conteneur de docker et vous êtes bon à aller.

Ajouter à la mise en œuvre

Vous êtes maintenant prêt à mettre en œuvre votre op. Suivez les instructions àAjouter une nouvelle op, ajoutez la définition de votre interface op<your_op>/cc/ops/La mise en œuvre du kernel sous<your_op>/cc/kernels/.

Créer et tester CPU Op

Bâle

Pour créer la bibliothèque op partagée personnalisée avec Bazel, suivez l'exemple cc_binaire danstensorflow_zero_out/BUILDVous aurez besoin de dépendre des fichiers de clavier et libtensorflow_framework.so de TensorFlow pip package pour construire votre op. Plus tôt nous avons mentionné que le modèle a déjà configuré TensorFlow pip package comme une dépendance externe danstfla catégorie, et le paquet pip est énuméré commelocal_config_tfdansWORKSPACEVotre op peut dépendre directement des fichiers de titre TensorFlow et 'libtensorflow_framework.so' avec les éléments suivants:

    deps = [
        "@local_config_tf//:libtensorflow_framework",
        "@local_config_tf//:tf_header_lib",
    ],

Vous devrez garder les deux dépendances ci-dessus pour votre op. Pour construire la bibliothèque partagée avec Bazel, exécutez le commandement suivant dans votre conteneur Docker

bazel build tensorflow_zero_out:python/ops/_zero_out_ops.so

Maquillage

Pour construire la bibliothèque personnalisée op partagée avec make, suivez l'exemple dansMakefilePour_zero_out_ops.soet exécuter les commandes suivantes dans votre conteneur Docker:

make op

Étendre et tester l’op en Python

Une fois que vous avez construit votre bibliothèque personnalisée op partagée, vous pouvez suivre l'exemple danstensorflow_zero_out/python/opset les instructionsicipour créer un module en Python pour votre op. Les deux guides utilisent TensorFlow APItf.load_op_library, qui charge la bibliothèque partagée et enregistre les ops avec le cadre TensorFlow.

from tensorflow.python.framework import load_library
from tensorflow.python.platform import resource_loader

_zero_out_ops = load_library.load_op_library(
    resource_loader.get_path_to_datafile('_zero_out_ops.so'))
zero_out = _zero_out_ops.zero_out

Vous pouvez également ajouter des tests Python comme ce que nous avons fait danstensorflow_zero_out/python/ops/zero_out_ops_test.pyVérifier que votre op fonctionne comme prévu.

Tests avec Bazel

Pour ajouter la bibliothèque de python et les cibles de test à Bazel, veuillez suivre les exemples pourpy_libraryObjectiftensorflow_zero_out:zero_out_ops_pyetpy_testObjectiftensorflow_zero_out:zero_out_ops_py_testdanstensorflow_zero_out/BUILDPour effectuer votre test avec basel, faites ce qui suit dans le conteneur Docker,

bazel test tensorflow_zero_out:zero_out_ops_py_test
Faire des tests avec Make

Pour ajouter l’objectif de test à faire, veuillez suivre l’exempleMakefilePour exécuter votre test Python, exécuter simplement ce qui suit dans le conteneur Docker,

make test_zero_out

Construire et tester le GPU Op

Bâle

Pour construire la bibliothèque personnalisée GPU op partagée avec Bazel, suivez l'exemple cc_binaire danstensorflow_time_two/BUILDDe même que les options personnalisées de la CPU, vous pouvez dépendre directement des fichiers de titre TensorFlow et de 'libtensorflow_framework.so' avec les éléments suivants:

    deps = [
        "@local_config_tf//:libtensorflow_framework",
        "@local_config_tf//:tf_header_lib",
    ],

En outre, lorsque vous effectuez la configuration à l'intérieur du conteneur GPU,config=cudaIl sera configuré pour le commandement de base, qui comprend également automatiquement la bibliothèque partagée de cuda et les rubriques de cuda dans le cadre des dépendances uniquement pour la version GPU de l'op:if_cuda_is_configured([":cuda", "@local_config_cuda//cuda:cuda_headers"]).

Pour construire la bibliothèque partagée avec Bazel, exécutez le commandement suivant dans votre conteneur Docker

bazel build tensorflow_time_two:python/ops/_time_two_ops.so

Maquillage

Pour construire la bibliothèque personnalisée op partagée avec make, suivez l'exemple dansMakefilePour_time_two_ops.soet exécuter les commandes suivantes dans votre conteneur Docker:

make time_two_op

Étendre et tester l’op en Python

Une fois que vous avez construit votre bibliothèque personnalisée op partagée, vous pouvez suivre l'exemple danstensorflow_time_two/python/opset les instructionsicipour créer un module en Python pour votre op. Cette partie est la même que celle de la CPU personnalisée op comme indiqué ci-dessus.

Tests avec Bazel

Similaire à la CPU personnalisée op, pour exécuter votre test avec basel, faites ce qui suit dans le conteneur Docker,

bazel test tensorflow_time_two:time_two_ops_py_test
Faire des tests avec Make

Pour ajouter l’objectif de test à faire, veuillez suivre l’exempleMakefilePour exécuter votre test Python, exécuter simplement ce qui suit dans le conteneur Docker,

make time_two_test

Créer un paquet PIP

Maintenant que votre op fonctionne, vous pourriez vouloir construire un paquet de pip pour cela afin que la communauté puisse également bénéficier de votre travail. Ce modèle fournit la configuration de base nécessaire pour construire votre paquet de pip. Tout d'abord, vous devrez mettre à jour les fichiers de niveau supérieur suivants en fonction de votre op.

  • setup.pycontient des informations sur votre paquet (tels que le nom et la version) ainsi que les fichiers de code à inclure.
  • MANIFEST.incontient la liste des fichiers supplémentaires que vous voulez inclure dans la distribution source. Ici vous voulez vous assurer que la bibliothèque partagée pour votre op personnalisée est inclus dans le paquet pip.
  • build_pip_pkg.shCréer la hiérarchie du paquet, et appelerbdist_wheelAssembler votre paquet de pip.

Vous pouvez utiliser le Bazel ou le Makefile pour construire le paquet de pip.

Construit avec Basel

Vous pouvez trouver l'objectif pour le package pip au niveau supérieurBUILDdans la liste des données de cettebuild_pip_pkgcible, vous voulez inclure la cible de la bibliothèque Python//tensorflow_zero_out:zero_out_pyen plus des fichiers de niveau supérieur. Pour construire le constructeur de paquets de pip, exécuter le commandement suivant dans le conteneur Docker,

bazel build :build_pip_pkg

Le commandement de construction de base crée un binaire appelé build_pip_package, que vous pouvez utiliser pour construire le package de pip.artifactsDirecteur :

bazel-bin/build_pip_pkg artifacts

Construire avec faire

Construire avec faire aussi invoke le mêmebuild_pip_pkg.shVous pouvez courir, vous pouvez courir,

make pip_pkg

Test de package PIP

Avant de publier votre paquet de pip, testez votre paquet de pip.

pip3 install artifacts/*.whl
python3 -c "import tensorflow as tf;import tensorflow_zero_out;print(tensorflow_zero_out.zero_out([[1,2], [3,4]]))"

Publication du package PIP

Une fois que votre paquet de pip a été soigneusement testé, vous pouvez distribuer votre paquet en téléchargant votre paquet à l'indice de paquet Python.Instructions officiellesde la Pype.

FAQ

Voici quelques problèmes que nos utilisateurs ont rencontrés et des solutions possibles.Sentez-vous libre de nous envoyer un PR pour ajouter plus d'inscriptions.

Problème Comment à?
Ai-je besoin de la chaîne d’outils et de l’image du docker? Oui, vous aurez besoin des deux pour obtenir la même configuration que nous utilisons pour construire le package officiel de pipes de TensorFlow.
Comment puis-je créer un manylinux2010 binaire? Vous pouvez utiliserAuditeurversion 2.0 ou plus récente.
Que faire si j'obtiensValueError: Cannot repair wheel, because required library "libtensorflow_framework.so.1" could not be locatedouValueError: Cannot repair wheel, because required library "libtensorflow_framework.so.2" could not be locatedAvec AuditWheel? Veuillez voirCe sujet lié.
Que faire si j'obtiensIn file included from tensorflow_time_two/cc/kernels/time_two_kernels.cu.cc:21:0: /usr/local/lib/python3.6/dist-packages/tensorflow/include/tensorflow/core/util/gpu_kernel_helper.h:22:10: fatal error: third_party/gpus/cuda/include/cuda_fp16.h: No such file or directory Copiez les fichiers de titre CUDA pour cibler le catalogue.mkdir -p /usr/local/lib/python3.6/dist-packages/tensorflow/include/third_party/gpus/cuda/include && cp -r /usr/local/cuda/targets/x86_64-linux/include/* /usr/local/lib/python3.6/dist-packages/tensorflow/include/third_party/gpus/cuda/include