Construction et utilisation de l'environnement TPU-MLIR

1. Configuration de l'environnement de développement

  • Environnement de développement Linux
    1. Un hôte x86 avec Ubuntu 16.04/18.04/20.04 installé, il est recommandé que la mémoire courante soit supérieure à 12 Go
    2. Téléchargez le package de développement SophonSDK (v23.03.01)

insérez la description de l'image ici

(1) Décompressez le package SDK

sudo apt-get install p7zip
sudo apt-get install p7zip-full
7z x Release_<date>-public.zip
cd Release_<date>-public

(2) Installation de Docker - Initialisation de l'environnement TPU-MLIR

# 安装docker
sudo apt-get install docker.io
# docker命令免root权限执行
# 创建docker用户组,若已有docker组会报错,没关系可忽略
sudo groupadd docker
# 将当前用户加入docker组
sudo gpasswd -a ${USER} docker
# 重启docker服务
sudo service docker restart
# 切换当前会话到新group或重新登录重启X会话
newgrp docker
提示:需要logout系统然后重新登录,再使用docker就不需要sudo了。

(3) Créez un conteneur docker et entrez Docker

docker run -v $PWD/:/workspace -p 8001:8001 -it sophgo/tpuc_dev:latest

insérez la description de l'image ici

(4) Charger tpu-mlir - activer les variables d'environnement

Les opérations suivantes doivent être dans un conteneur Docker. Pour l'utilisation de Docker, veuillez vous référer à Start Docker Container .

$ tar zxf tpu-mlir_xxxx.tar.gz
$ source tpu-mlir_xxxx/envsetup.sh

_xxxx représente le numéro de version de tpu-mlir, et envsetup.shles variables d'environnement suivantes seront ajoutées :

Nom de variable valeur illustrer
TPUC_ROOT tpu-mlir_xxx L'emplacement du package SDK après décompression
MODEL_ZOO_PATH ${TPUC_ROOT}/…/model-zoo L'emplacement du dossier model-zoo, qui se trouve au même niveau que le SDK

envsetup.shLe contenu modifié de la variable d'environnement est :

export PATH=${TPUC_ROOT}/bin:$PATH
export PATH=${TPUC_ROOT}/python/tools:$PATH
export PATH=${TPUC_ROOT}/python/utils:$PATH
export PATH=${TPUC_ROOT}/python/test:$PATH
export PATH=${TPUC_ROOT}/python/samples:$PATH
export LD_LIBRARY_PATH=$TPUC_ROOT/lib:$LD_LIBRARY_PATH
export PYTHONPATH=${TPUC_ROOT}/python:$PYTHONPATH
export MODEL_ZOO_PATH=${TPUC_ROOT}/../model-zoo

insérez la description de l'image ici

2. Compiler le modèle de format ONNX

Ce chapitre prend comme yolov5s.onnxexemple pour présenter comment compiler et migrer un modèle onnx à exécuter sur la plate-forme TPU BM1684X.

Le modèle provient du site officiel de yolov5 : https://github.com/ultralytics/yolov5/releases/download/v6.0/yolov5s.onnx

(1) Préparer le répertoire de travail, les fichiers modèles et les données

Créez model_yolov5sun répertoire, notez qu'il s'agit du même répertoire de niveau que tpu-mlir ; et placez les fichiers de modèle et les fichiers d'image dans model_yolov5sle répertoire.

La commande de fonctionnement est la suivante :

$ mkdir model_yolov5s && cd model_yolov5s
$ cp $TPUC_ROOT/regression/model/yolov5s.onnx .
$ cp -rf $TPUC_ROOT/regression/dataset/COCO2017 .
$ cp -rf $TPUC_ROOT/regression/image .
$ mkdir workspace && cd workspace

Voici $TPUC_ROOTla variable d'environnement, correspondant au répertoire tpu-mlir_xxxx.

Le modèle de conversion est principalement divisé en deux étapes (exécutées en docker)

(2) ONNX vers MLIR

La première consiste à model_transform.pyconvertir le modèle d'origine en un fichier mlir ;

Si le modèle est une entrée d'image, nous devons comprendre le prétraitement du modèle avant de convertir le modèle. Si le modèle utilise le fichier npz prétraité comme entrée, il n'est pas nécessaire d'envisager le prétraitement. Le processus de prétraitement est exprimé comme suit (x représente l'entrée) :

insérez la description de l'image ici

L'image de yolov5 sur le site officiel est rgb, chaque valeur sera multipliée 1/255, convertie en moyenne et échelle correspondant à 0.0,0.0,0.0et 0.0039216,0.0039216,0.0039216.

La commande de conversion de modèle est la suivante :

$ model_transform.py \
    --model_name yolov5s \
    --model_def ../yolov5s.onnx \
    --input_shapes [[1,3,640,640]] \
    --mean 0.0,0.0,0.0 \
    --scale 0.0039216,0.0039216,0.0039216 \
    --keep_aspect_ratio \
    --pixel_format rgb \
    --output_names 350,498,646 \
    --test_input ../image/dog.jpg \
    --test_result yolov5s_top_outputs.npz \
    --mlir yolov5s.mlir \
    --post_handle_type yolo

Résultat du processus de conversion :

insérez la description de l'image ici
insérez la description de l'image ici
insérez la description de l'image ici

Les fichiers générés finaux ${model_name}_in_f32.npzsont les suivants :
insérez la description de l'image ici

(3) MLIR à FP32

La seconde consiste à model_deploy.pyconvertir le fichier mlir en un bmodel .

Pour convertir le fichier mlir en f32 bmodel, la commande est la suivante :

$ model_deploy.py \
    --mlir yolov5s.mlir \
    --quantize F32 \
    --chip bm1684x \
    --test_input yolov5s_in_f32.npz \
    --test_reference yolov5s_top_outputs.npz \
    --tolerance 0.99,0.99 \
    --model yolov5s_1684x_f32.bmodel

Les fichiers finaux générés ${model_name}_1684x_f32.bmodelet autres fichiers connexes sont les suivants :
insérez la description de l'image ici

(4) Modèle MLIR à INT8

Générer un tableau d'étalonnage

Avant de convertir en modèle INT8, vous devez exécuter l'étalonnage pour obtenir la table d'étalonnage ; le nombre de données d'entrée est préparé en fonction de la situation. Environ 100 à 1 000 feuilles.

Puis avec la table de calibrage, un bmodel symétrique ou asymétrique est généré. Si la symétrie répond aux exigences, il n'est généralement pas recommandé d'utiliser le modèle asymétrique, car les performances du modèle asymétrique seront légèrement inférieures à celles du modèle symétrique.

Ici, nous utilisons les 100 images existantes de COCO2017 comme exemple pour effectuer l'étalonnage :

$ run_calibration.py yolov5s.mlir \
    --dataset ../COCO2017 \
    --input_num 100 \
    -o yolov5s_cali_table

Diagramme de processus de fonctionnement :

insérez la description de l'image ici

${model_name}_cali_tableUne fois l'opération terminée , un fichier nommé sera généré , qui sera utilisé comme fichier d'entrée pour la compilation ultérieure du modèle INT8.
insérez la description de l'image ici

Compiler vers le modèle de quantification symétrique INT8

Pour convertir en modèle de quantification symétrique INT8, exécutez la commande suivante :

$ model_deploy.py \
    --mlir yolov5s.mlir \
    --quantize INT8 \
    --calibration_table yolov5s_cali_table \
    --chip bm1684x \
    --test_input yolov5s_in_f32.npz \
    --test_reference yolov5s_top_outputs.npz \
    --tolerance 0.85,0.45 \
    --model yolov5s_1684x_int8_sym.bmodel

Le résultat du processus de conversion est le suivant :
insérez la description de l'image ici

insérez la description de l'image ici

Les fichiers finaux générés ${model_name}_1684x_int8_sym.bmodelet autres fichiers connexes sont les suivants :

insérez la description de l'image ici

Compiler vers le modèle de quantification asymétrique INT8

Pour convertir en modèle de quantification asymétrique INT8, exécutez la commande suivante :

$ model_deploy.py \
    --mlir yolov5s.mlir \
    --quantize INT8 \
    --asymmetric \
    --calibration_table yolov5s_cali_table \
    --chip bm1684x \
    --test_input yolov5s_in_f32.npz \
    --test_reference yolov5s_top_outputs.npz \
    --tolerance 0.90,0.55 \
    --model yolov5s_1684x_int8_asym.bmodel

Une fois la compilation terminée, ${model_name}_1684x_int8_asym.bmodelun fichier nommé sera généré.

insérez la description de l'image ici

insérez la description de l'image ici

Comparaison des effets

Dans ce package de version, il existe des cas d'utilisation yolov5 et des chemins de code source écrits en python $TPUC_ROOT/python/samples/detect_yolov5.py, qui sont utilisés pour la détection d'objets sur les images. Lisez le code pour comprendre comment le modèle est utilisé : faites d'abord un pré-traitement pour obtenir l'entrée du modèle, puis inférez pour obtenir la sortie, et enfin effectuez un post-traitement. Utilisez les codes suivants pour vérifier les résultats d'exécution de onnx/f32/int8 respectivement.

L'implémentation du modèle onnx est la suivante, pour obtenir dog_onnx.jpg:

$ detect_yolov5.py \
    --input ../image/dog.jpg \
    --model ../yolov5s.onnx \
    --output dog_onnx.jpg

La méthode d'exécution de f32 bmodel est la suivante, et on obtient dog_f32.jpg:

$ detect_yolov5.py \
    --input ../image/dog.jpg \
    --model yolov5s_1684x_f32.bmodel \
    --output dog_f32.jpg

La méthode d'exécution de bmodel symétrique int8 est la suivante, et on obtient dog_int8_sym.jpg:

$ detect_yolov5.py \
    --input ../image/dog.jpg \
    --model yolov5s_1684x_int8_sym.bmodel \
    --output dog_int8_sym.jpg

L'implémentation de bmodel asymétrique int8 est la suivante, get dog_int8_asym.jpg:

$ detect_yolov5.py \
    --input ../image/dog.jpg \
    --model yolov5s_1684x_int8_asym.bmodel \
    --output dog_int8_asym.jpg

Le fichier image de détection final est généré comme suit :

insérez la description de l'image ici

La comparaison de la précision de détection des quatre images est la suivante :

insérez la description de l'image ici

由于运行环境不同, 最终的效果和精度与上图会有些差异。

solution du problème

L'erreur d'information de sortie rencontrée lors du transfert de mlir vers F32 :

insérez la description de l'image ici

processus de résolution

Résolution de l'erreur 1 :

[Analyse de la cause] En raison model_transform.pydu post-traitement du fichier par yolo, les formes des deux fichiers npz générés sont différentes, ce qui entraîne une erreur de fonctionnement.

[Solution] model_transform.pyModifiez la commande en cours d'exécution et traitez les étapes de l'opération.

(Supprimez l'option yolo –post_handle_type, la forme du fichier npz généré par le post-traitement par défaut peut être cohérente et le modèle de format FP32 est généré avec succès)

[Processus de solution] - analysez l'erreur et suivez la cause de l'erreur étape par étape

mlir_shell.pyL'erreur d'exécution

insérez la description de l'image ici
insérez la description de l'image ici

3. Compiler le modèle de format TFlite

Tout d'abord, configurez selon la configuration de l'environnement en 1 ;

En prenant resnet50_int8.tflitele modèle comme exemple, il présente comment compiler et migrer un modèle TFLite pour qu'il s'exécute sur la plate-forme TPU BM1684X.

(1) Préparer le répertoire de travail, les fichiers modèles et les données

Créez model_resnet50_tfun répertoire, notez qu'il s'agit du même répertoire de niveau que tpu-mlir ; et placez le fichier image de test dans model_resnet50_tfle répertoire.

Le fonctionnement est le suivant :

$ mkdir model_resnet50_tf && cd model_resnet50_tf
$ cp $TPUC_ROOT/regression/model/resnet50_int8.tflite .
$ cp -rf $TPUC_ROOT/regression/image .
$ mkdir workspace && cd workspace

Voici $TPUC_ROOTla variable d'environnement, correspondant au répertoire tpu-mlir_xxxx.

(2) TFLite à MLIR

Le modèle dans cet exemple est l'entrée bgr, la moyenne est 103.939,116.779,123.68, l'échelle est1.0,1.0,1.0

La commande de conversion de modèle est la suivante :

$ model_transform.py \
    --model_name resnet50_tf \
    --model_def  ../resnet50_int8.tflite \
    --input_shapes [[1,3,224,224]] \
    --mean 103.939,116.779,123.68 \
    --scale 1.0,1.0,1.0 \
    --pixel_format bgr \
    --test_input ../image/cat.jpg \
    --test_result resnet50_tf_top_outputs.npz \
    --mlir resnet50_tf.mlir

Après la conversion en fichier mlir, un resnet50_tf_in_f32.npzfichier sera généré, qui est le fichier d'entrée du modèle.

resnet50_tf_in_f32.npzLe fichier de sortie est le suivant : Après la conversion en fichier mlir, un fichier sera généré , qui est le fichier d'entrée du modèle.
insérez la description de l'image ici

(3) MLIR pour modéliser

Ce modèle est un modèle de quantification asymétrique tflite, qui peut être converti en modèle selon les paramètres suivants :

$ model_deploy.py \
    --mlir resnet50_tf.mlir \
    --quantize INT8 \
    --asymmetric \
    --chip bm1684x \
    --test_input resnet50_tf_in_f32.npz \
    --test_reference resnet50_tf_top_outputs.npz \
    --model resnet50_tf_1684x.bmodel

Une fois la compilation terminée, resnet50_tf_1684x.bmodelun fichier nommé sera généré.
insérez la description de l'image ici

4. Compiler le modèle de format Caffe

Tout d'abord, configurez selon la configuration de l'environnement en 1 ;

Ce chapitre prend mobilenet_v2_deploy.prototxtet mobilenet_v2.caffemodelcomme exemples pour présenter comment compiler et migrer un modèle caffe à exécuter sur la plate-forme TPU BM1684X.

(1) Préparer le répertoire de travail, les fichiers modèles et les données

Créez mobilenet_v2un répertoire, notez qu'il s'agit du même répertoire de niveau que tpu-mlir ; et placez les fichiers de modèle et les fichiers d'image dans mobilenet_v2le répertoire.

Le fonctionnement est le suivant :

$ mkdir mobilenet_v2 && cd mobilenet_v2
$ cp $TPUC_ROOT/regression/model/mobilenet_v2_deploy.prototxt .
$ cp $TPUC_ROOT/regression/model/mobilenet_v2.caffemodel .
$ cp -rf $TPUC_ROOT/regression/dataset/ILSVRC2012 .
$ cp -rf $TPUC_ROOT/regression/image .
$ mkdir workspace && cd workspace

Voici $TPUC_ROOTla variable d'environnement, correspondant au répertoire tpu-mlir_xxxx.

(2) Caffe à MLIR

103.94,116.78,123.68Le modèle dans cet exemple est l'entrée BGR, la moyenne et l'échelle sont et , respectivement 0.017,0.017,0.017.

La commande de conversion de modèle est la suivante :

$ model_transform.py \
    --model_name mobilenet_v2 \
    --model_def ../mobilenet_v2_deploy.prototxt \
    --model_data ../mobilenet_v2.caffemodel \
    --input_shapes [[1,3,224,224]] \
    --resize_dims=256,256 \
    --mean 103.94,116.78,123.68 \
    --scale 0.017,0.017,0.017 \
    --pixel_format bgr \
    --test_input ../image/cat.jpg \
    --test_result mobilenet_v2_top_outputs.npz \
    --mlir mobilenet_v2.mlir

${model_name}_in_f32.npzAprès la conversion, le fichier de sortie est le suivant : Après la conversion en fichier mlir, un fichier sera généré , qui est le fichier d'entrée du modèle.
insérez la description de l'image ici

(3) Modèle MLIR à F32

Convertissez le fichier mlir en f32 bmodel, la méthode de fonctionnement est la suivante :

$ model_deploy.py \
    --mlir mobilenet_v2.mlir \
    --quantize F32 \
    --chip bm1684x \
    --test_input mobilenet_v2_in_f32.npz \
    --test_reference mobilenet_v2_top_outputs.npz \
    --tolerance 0.99,0.99 \
    --model mobilenet_v2_1684x_f32.bmodel

Une fois la compilation terminée, ${model_name}_1684x_f32.bmodelun fichier nommé sera généré.
insérez la description de l'image ici

(4) Modèle MLIR à INT8

Générer un tableau d'étalonnage

Avant de convertir en modèle INT8, vous devez exécuter l'étalonnage pour obtenir la table d'étalonnage ; le nombre de données d'entrée est préparé en fonction de la situation. Environ 100 à 1 000 feuilles.

Puis avec la table de calibrage, un bmodel symétrique ou asymétrique est généré. Si la symétrie répond aux exigences, il n'est généralement pas recommandé d'utiliser le modèle asymétrique, car les performances du modèle asymétrique seront légèrement inférieures à celles du modèle symétrique.

Ici, nous utilisons les 100 images existantes de l'ILSVRC2012 comme exemple pour effectuer l'étalonnage :

$ run_calibration.py mobilenet_v2.mlir \
    --dataset ../ILSVRC2012 \
    --input_num 100 \
    -o mobilenet_v2_cali_table

Processus de génération de la table d'étalonnage :

insérez la description de l'image ici
Une fois
l'opération terminée, ${model_name}_cali_tableun fichier nommé sera généré, qui sera utilisé comme fichier d'entrée pour la compilation ultérieure du modèle INT8.
insérez la description de l'image ici

Compiler vers le modèle de quantification symétrique INT8

Pour convertir en modèle de quantification symétrique INT8, exécutez la commande suivante :

$ model_deploy.py \
    --mlir mobilenet_v2.mlir \
    --quantize INT8 \
    --calibration_table mobilenet_v2_cali_table \
    --chip bm1684x \
    --test_input mobilenet_v2_in_f32.npz \
    --test_reference mobilenet_v2_top_outputs.npz \
    --tolerance 0.96,0.70 \
    --model mobilenet_v2_1684x_int8_sym.bmodel

Une fois la compilation terminée, ${model_name}_1684x_int8_sym.bmodelun fichier nommé sera généré.

Compiler vers le modèle de quantification asymétrique INT8

Pour convertir en modèle de quantification asymétrique INT8, exécutez la commande suivante :

$ model_deploy.py \
    --mlir mobilenet_v2.mlir \
    --quantize INT8 \
    --asymmetric \
    --calibration_table mobilenet_v2_cali_table \
    --chip bm1684x \
    --test_input mobilenet_v2_in_f32.npz \
    --test_reference mobilenet_v2_top_outputs.npz \
    --tolerance 0.95,0.69 \
    --model mobilenet_v2_1684x_int8_asym.bmodel

Une fois la compilation terminée, ${model_name}_1684x_int8_asym.bmodelun fichier nommé sera généré.

5. Comment utiliser la précision mixte

Tout d'abord, configurez selon la configuration de l'environnement en 1 ;

Ce chapitre prend le yolov3 tinymodèle de réseau de détection comme exemple pour présenter comment utiliser la précision mixte. Le modèle provient de https://github.com/onnx/models/tree/main/vision/object_detection_segmentation/tiny-yolov3.

(1) Préparer le répertoire de travail, les fichiers modèles et les données

Créez yolov3_tinyun répertoire, notez qu'il s'agit du même répertoire de niveau que tpu-mlir ; et placez les fichiers de modèle et les fichiers d'image dans yolov3_tinyle répertoire.

Le fonctionnement est le suivant :

$ mkdir yolov3_tiny && cd yolov3_tiny
$ wget https://github.com/onnx/models/raw/main/vision/object_detection_segmentation/tiny-yolov3/model/tiny-yolov3-11.onnx
$ cp -rf $TPUC_ROOT/regression/dataset/COCO2017 .
$ mkdir workspace && cd workspace

Voici $TPUC_ROOTla variable d'environnement, correspondant au répertoire tpu-mlir_xxxx. Notez que si tiny-yolov3-11.onnxle téléchargement avec wget échoue, vous pouvez télécharger le package d'origine en visitant github et le mettre dans yolov3_tinyle dossier.

(2) Vérifier le modèle d'origine

detect_yolov3.pyIl s'agit d'un programme de vérification qui a été écrit et qui peut être utilisé pour yolov3_tinyvérifier le réseau. Le processus d'exécution est le suivant :

$ detect_yolov3.py \
     --model ../tiny-yolov3-11.onnx \
     --input ../COCO2017/000000366711.jpg \
     --output yolov3_onnx.jpg

Après exécution, imprimez les résultats détectés comme suit :

person:60.7%
orange:77.5%

Et obtenir l'image yolov3_onnx.jpg, comme suit

insérez la description de l'image ici

(3) Convertir en modèle de quantification symétrique INT8

Comme dans la méthode du modèle de transfert introduite dans le chapitre précédent, il n'y a pas de description des paramètres ici, seulement le processus de fonctionnement.

Étape 1 : convertir en F32 mlir
$ model_transform.py \
    --model_name yolov3_tiny \
    --model_def ../tiny-yolov3-11.onnx \
    --input_shapes [[1,3,416,416]] \
    --scale 0.0039216,0.0039216,0.0039216 \
    --pixel_format rgb \
    --keep_aspect_ratio \
    --pad_value 128 \
    --output_names=transpose_output1,transpose_output \
    --mlir yolov3_tiny.mlir

insérez la description de l'image ici

Le fichier final généré est le suivant :
insérez la description de l'image ici

Étape 2 : Générer une table d'étalonnage
$ run_calibration.py yolov3_tiny.mlir \
    --dataset ../COCO2017 \
    --input_num 100 \
    -o yolov3_cali_table

insérez la description de l'image ici

Générez le fichier de table d'étalonnage comme suit :
insérez la description de l'image ici

Étape 3 : Modèle quantifié à symétrie de rotation
$ model_deploy.py \
    --mlir yolov3_tiny.mlir \
    --quantize INT8 \
    --calibration_table yolov3_cali_table \
    --chip bm1684x \
    --model yolov3_int8.bmodel

Le fichier de sortie final est le suivant :

insérez la description de l'image ici

Étape 4 : Valider le modèle
$ detect_yolov3.py \
     --model yolov3_int8.bmodel \
     --input ../COCO2017/000000366711.jpg \
     --output yolov3_int8.jpg

Après exécution, les informations d'impression suivantes s'affichent :

person:64.0%
orange:73.0%

[

Obtenez l'image yolov3_int8.jpg, comme suit
insérez la description de l'image ici

On peut voir que par rapport au modèle original, le modèle de quantification symétrique int8 a un faible effet de détection sur les individus orange dans cette image.

(4) Convertir en un modèle de quantification à précision mixte

Sur la base de la conversion en modèle de quantification symétrique int8, effectuez les étapes suivantes.

Étape 1 : Générer une table de quantification à précision mixte

Utilisez pour run_qtable.pygénérer une table de quantification à précision mixte, et les paramètres pertinents sont décrits comme suit :

le nom du paramètre requis? illustrer
aucun Oui spécifier le fichier mlir
base de données Non Spécifiez le répertoire de l'échantillon d'entrée, le chemin pour mettre l'image correspondante, ou npz, ou npy
data_list Non Spécifiez la liste d'échantillons et l'ensemble de données doit choisir l'un des deux
table_calibrage Oui Accéder au tableau d'étalonnage
ébrécher Oui Spécifiez la plate-forme que le modèle utilisera, prend en charge bm1684x/bm1684/cv183x/cv182x/cv181x/cv180x
type_fp Non Spécifie le type flottant utilisé en précision mixte, prend en charge auto, F16, F32, BF16, la valeur par défaut est auto, ce qui signifie qu'il est automatiquement sélectionné par le programme
input_num Non Spécifiez le nombre d'échantillons d'entrée, la valeur par défaut est 10
cos_attendu Non Spécifiez la valeur cos minimale de la couche de sortie finale du réseau attendu, généralement la valeur par défaut est de 0,99, plus la valeur est petite, plus les couches peuvent être définies comme calculs en virgule flottante
min_layer_cos Non Spécifiez la valeur minimale du cos de sortie attendu de chaque couche. En dessous de cette valeur, il essaiera de définir un calcul en virgule flottante. Généralement, la valeur par défaut est 0,99.
debug_cmd Non Spécifiez la chaîne de commande de débogage, pour une utilisation en développement, la valeur par défaut est vide
o Oui Table de quantification de précision mixte en sortie

Dans cet exemple, les 10 images par défaut sont utilisées pour l'étalonnage et la commande d'exécution est la suivante (pour les puces de la série CV18xx, définissez la puce sur le nom de puce correspondant) :

$ run_qtable.py yolov3_tiny.mlir \
    --dataset ../COCO2017 \
    --calibration_table yolov3_cali_table \
    --chip bm1684x \
    --min_layer_cos 0.999 \ #若这里使用默认的0.99时,程序会检测到原始int8模型已满足0.99的cos,从而直接不再搜素
    --expected_cos 0.9999 \
    -o yolov3_qtable

Après l'exécution, la sortie finale est imprimée comme suit : (Les informations de sortie des différents hôtes de compilation peuvent être légèrement différentes)
insérez la description de l'image ici

L'int8 outputs_cos ci-dessus indique la similarité cos entre la sortie réseau d'origine du modèle int8 et fp32, le modèle mix outputs_cos indique la similarité cos de la sortie réseau après que certaines couches utilisent une précision mixte, et le temps total indique que le temps de recherche est de 11,2 De plus, la table de quantification de précision mixte générée yolov3_qtable.
insérez la description de l'image ici

yolov3_qtableLe contenu est le suivant :
insérez la description de l'image ici

Dans ce tableau, la première colonne indique la couche correspondante, la deuxième colonne indique le type et les types pris en charge sont F32/F16/BF16/INT8. De plus, un fichier de tableau des pertes sera également généré en même temps full_loss_table.txt.

full_loss_table.txtLe contenu est le suivant :

insérez la description de l'image ici

Le tableau est organisé en douceur selon le cos de petit à grand, ce qui signifie qu'après que la couche précédente de cette couche a été changée en mode virgule flottante correspondant en fonction de son cos respectif, le cos calculé par cette couche, si le cos est toujours plus petit que le paramètre min_layer_cos précédent, ce seront les calques et les calques successeurs immédiats sont définis sur des calculs en virgule flottante. run_qtable.pyIl continuera à calculer le cos de sortie de l'ensemble du réseau après avoir défini à chaque fois 2 couches adjacentes comme calcul en virgule flottante. Si le cos est supérieur au cos attendu spécifié, la recherche se terminera. Par conséquent, si vous définissez un cos_attendu plus grand, vous essaierez de définir davantage de couches pour les calculs en virgule flottante.

Étape 2 : Générer un modèle de quantification à précision mixte
$ model_deploy.py \
    --mlir yolov3_tiny.mlir \
    --quantize INT8 \
    --quantize_table yolov3_qtable \
    --calibration_table yolov3_cali_table \
    --chip bm1684x \
    --model yolov3_mix.bmodel

Le fichier final généré est le suivant :
insérez la description de l'image ici

Étape 3 : Valider le modèle de précision mixte
$ detect_yolov3.py \
     --model yolov3_mix.bmodel \
     --input ../COCO2017/000000366711.jpg \
     --output yolov3_mix.jpg

Après exécution, le résultat imprimé est :

person:64.0%
orange:72.9%

Obtenez l'image yolov3_mix.jpg, comme suit
insérez la description de l'image ici

Il convient de noter qu'en plus d'utiliser run_qtable pour générer la table de quantification, vous pouvez également définir le nom et le type de quantification de l'OP qui doit être quantifié avec une précision mixte dans la table de quantification en fonction des résultats de comparaison de similarité de chaque couche. dans le modèle.

6. Exemple de déploiement de modèle

(1) Utiliser le TPU pour le prétraitement

À l'heure actuelle, les deux principales séries de puces prises en charge par TPU-MLIR, BM168x et CV18xx, prennent toutes deux en charge le prétraitement d'image commun à ajouter au modèle pour le calcul. Le développeur peut passer les paramètres de prétraitement correspondants via l'option de compilation pendant l'étape de compilation du modèle, et le compilateur insère directement l'opérateur de prétraitement correspondant avant l'opération de modèle, et le bmodel ou cvimodel généré peut directement utiliser l'image prétraitée comme entrée. utiliser le TPU pour traiter l'opération de prétraitement avec le processus de raisonnement du modèle.

type de prétraitement BM168x CV18xx
recadrage d'image Vrai Vrai
Calcul normalisé Vrai Vrai
NHWC à NCHW Vrai Vrai
Conversion BGR/RVB Vrai Vrai

Parmi eux, le recadrage de l'image ajustera d'abord l'image à la taille correspondante en fonction du paramètre "–resize_dims" saisi lors de l'utilisation de l'outil model_transform, puis le recadrera à la taille saisie par le modèle. Le calcul de normalisation prend en charge la normalisation directe des données d'image qui n'ont pas été prétraitées (c'est-à-dire les données au format int8 non signé).

Pour incorporer le prétraitement dans le modèle, vous devez utiliser le paramètre "--fuse_preprocess" lors du déploiement avec l'outil model_deploy. Si la vérification doit être effectuée, l'entrée test_input doit être entrée dans le format d'origine de l'image (c'est-à-dire les formats jpg, jpeg et png), et en conséquence, un fichier npz correspondant à l'entrée d'image d'origine sera généré, nommé ${model_name}_in_ori.npz.

De plus, lorsque le format d'entrée externe réel est différent du format du modèle, utilisez "–customization_format" pour spécifier le format d'entrée externe réel. Les formats pris en charge sont décrits comme suit :

format_personnalisation illustrer BM1684X CV18xx
Aucun Conformément à l'entrée du modèle d'origine, aucun traitement n'est effectué. défaut Vrai Vrai
RVB_PLANAIRE commande rgb, passée selon nchw Vrai Vrai
RVB_PACKED commande rgb, passée selon nhwc Vrai Vrai
BGR_PLANAR commande bgr, passée selon nchw Vrai Vrai
BGR_PACKED commande bgr, passée selon nhwc Vrai Vrai
NIVEAUX DE GRIS Il n'y a qu'un seul canal gris, appuyez sur nchw Vrai Vrai
YUV420_PLANAIRE format de planificateur yuv420, entrée de vpss FAUX Vrai
YUV_NV21 Format NV21 de yuv420, entrée de vpss FAUX Vrai
YUV_NV12 Format NV12 de yuv420, entrée de vpss FAUX Vrai
RVBA_PLANAR format rgba, placé selon nchw FAUX Vrai

Parmi eux, le format de type "YUV*" est le format d'entrée unique des puces de la série CV18xx. Lorsque l'ordre des canaux de couleur dans personnalisation_format est différent de l'entrée du modèle, une opération de conversion de canal sera effectuée. Si le paramètre Personalization_format n'est pas défini dans la commande, le Personalization_format correspondant sera automatiquement obtenu en fonction des paramètres pixel_format et channel_format définis lors de l'utilisation de l'outil model_transform.

Prenez le modèle mobilenet_v2 comme exemple, reportez-vous au chapitre "Compiler le modèle Caffe", utilisez l'outil model_transform dans le répertoire tpu-mlir/regression/regression_out/ pour générer le mlir d'origine, et utilisez l'outil run_calibration pour générer la table de calibration .

(2) Déploiement BM1684X

La commande pour générer le modèle bmodel quantifié symétrique INT8 prétraité par fusion est la suivante :

$ model_deploy.py \
    --mlir mobilenet_v2.mlir \
    --quantize INT8 \
    --calibration_table mobilenet_v2_cali_table \
    --chip bm1684x \
    --test_input ../image/cat.jpg \
    --test_reference mobilenet_v2_top_outputs.npz \
    --tolerance 0.96,0.70 \
    --fuse_preprocess \
    --model mobilenet_v2_bm1684x_int8_sym_fuse_preprocess.bmodel

Le diagramme de sortie du processus est le suivant :

insérez la description de l'image ici

Le fichier final généré est le suivant :
insérez la description de l'image ici

7. Transférez chaque modèle de cadre à ONNX pour référence

Ce chapitre se réfère principalement à la façon de convertir les modèles PyTorch, TensorFlow et PaddlePaddle en modèles ONNX.Les lecteurs peuvent également se référer au tutoriel de conversion de modèle fourni par l'entrepôt officiel ONNX : https://github.com/onnx/tutorials.

Toutes les opérations de ce chapitre sont effectuées dans le conteneur Docker. Pour la méthode de configuration de l'environnement spécifique, veuillez vous référer au chapitre 1.

(1) Modèle PyTorch vers ONNX

Cette section prend un modèle PyTorch simple auto-construit comme exemple pour effectuer la conversion onnx, et la configuration de l'environnement et le répertoire sont cohérents avec la section 1.

Étape 0 : Créer un répertoire de travail

Créez et entrez le répertoire torch_model sur la ligne de commande.

$ mkdir torch_model
$ cd torch_model
Étape 1 : Créer et enregistrer le modèle

Créez un script nommé simple_net.py dans ce répertoire et exécutez-le. Le contenu spécifique du script est le suivant :

#!/usr/bin/env python3
import torch
 
# Build a simple nn model
class SimpleModel(torch.nn.Module):
 
   def __init__(self):
       super(SimpleModel, self).__init__()
       self.m1 = torch.nn.Conv2d(3, 8, 3, 1, 0)
      self.m2 = torch.nn.Conv2d(8, 8, 3, 1, 1)

   def forward(self, x):
      y0 = self.m1(x)
      y1 = self.m2(y0)
      y2 = y0 + y1
      return y2

# Create a SimpleModel and save its weight in the current directory
model = SimpleModel()
torch.save(model.state_dict(), "weight.pth")

Après l'exécution, nous obtiendrons un fichier de poids weight.pth dans le répertoire courant.
insérez la description de l'image ici

Étape 2 : Exporter le modèle ONNX

Créez un autre script nommé export_onnx.py dans ce répertoire et exécutez-le. Le contenu spécifique du script est le suivant :

 #!/usr/bin/env python3
 import torch
 from simple_net import SimpleModel
 
 # Load the pretrained model and export it as onnx
 model = SimpleModel()
 model.eval()
 checkpoint = torch.load("weight.pth", map_location="cpu")
 model.load_state_dict(checkpoint)

# Prepare input tensor
input = torch.randn(1, 3, 16, 16, requires_grad=True)

# Export the torch model as onnx
torch.onnx.export(model,
                  input,
                  'model.onnx', # name of the exported onnx model
                  opset_version=13,
                  export_params=True,
                  do_constant_folding=True)

Après avoir exécuté le script, nous pouvons obtenir le modèle onnx nommé model.onnx dans le répertoire courant.

(2) Modèle TensorFlow vers ONNX

Cette section utilise le modèle mobilenet_v1_0.25_224 fourni dans le référentiel officiel TensorFlow comme exemple de conversion.

Étape 0 : Créer un répertoire de travail

Créez et entrez le répertoire tf_model sur la ligne de commande.

$ mkdir tf_model
$ cd tf_model
Étape 1 : préparer et convertir le modèle

Téléchargez le modèle avec la commande suivante sur la ligne de commande et utilisez l'outil tf2onnx pour l'exporter en tant que modèle ONNX :

$ wget -nc http://download.tensorflow.org/models/mobilenet_v1_2018_08_02/mobilenet_v1_0.25_224.tgz
# tar to get "*.pb" model def file
$ tar xzf mobilenet_v1_0.25_224.tgz

[

$ python -m tf2onnx.convert --graphdef mobilenet_v1_0.25_224_frozen.pb \
    --output mnet_25.onnx --inputs input:0 \
    --inputs-as-nchw input:0 \
    --outputs MobilenetV1/Predictions/Reshape_1:0

Après avoir exécuté toutes les commandes ci-dessus, nous pouvons obtenir le modèle onnx nommé mnet_25.onnx dans le répertoire courant.

(3) Modèle PaddlePaddle vers ONNX

Cette section utilise le modèle SqueezeNet1_1 fourni dans le référentiel officiel PaddlePaddle comme exemple de conversion.

Étape 0 : Créer un répertoire de travail

Créez et entrez le répertoire pp_model sur la ligne de commande.

$ mkdir pp_model
$ cd pp_model
Étape 1 : Préparer le modèle

Téléchargez le modèle avec la commande suivante sur la ligne de commande :

$ wget https://bj.bcebos.com/paddlehub/fastdeploy/SqueezeNet1_1_infer.tgz
$ tar xzf SqueezeNet1_1_infer.tgz
$ cd SqueezeNet1_1_infer

Et utilisez le script paddle_infer_shape.py dans le projet PaddlePaddle pour effectuer l'inférence de forme sur le modèle. Ici, la forme d'entrée est définie sur [1,3,224,224] au format NCHW :

$ wget https://raw.githubusercontent.com/PaddlePaddle/Paddle2ONNX/develop/tools/paddle/paddle_infer_shape.py
$ python paddle_infer_shape.py  --model_dir . \
                          --model_filename inference.pdmodel \
                          --params_filename inference.pdiparams \
                          --save_dir new_model \
                          --input_shape_dict="{'inputs':[1,3,224,224]}"

Après avoir exécuté toutes les commandes ci-dessus, nous serons dans le répertoire SqueezeNet1_1_infer, et il y aura un répertoire new_model sous ce répertoire.
insérez la description de l'image ici

Étape 2 : Convertir le modèle

Installez l'outil paddle2onnx via la commande suivante sur la ligne de commande et utilisez cet outil pour convertir le modèle PaddlePaddle en modèle ONNX :

$ pip install paddle2onnx
$ paddle2onnx  --model_dir new_model \
          --model_filename inference.pdmodel \
          --params_filename inference.pdiparams \
          --opset_version 13 \
          --save_file squeezenet1_1.onnx

Après avoir exécuté toutes les commandes ci-dessus, nous obtiendrons un modèle onnx nommé squeezenet1_1.onnx.

8. Guide de test BM168x

(1) Configurer l'environnement système

Si vous utilisez Docker pour la première fois, veuillez utiliser la méthode dans la configuration de l'environnement de développement pour installer et configurer Docker.

Pour la première utilisation git-lfs, vous pouvez exécuter les commandes suivantes pour installer et configurer

[Seulement pour la première fois, et la configuration est dans le propre système de l'utilisateur , pas dans le conteneur Docker ]

$ sudo apt install curl
$ curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
$ sudo apt-get install git-lfs

insérez la description de l'image ici

Mode PCIE de la plate-forme cloud BM1684X :
insérez la description de l'image ici

(2) Obtenir le modèle model-zoo

Dans tpu-mlir_xxxx.tar.gzle même répertoire de niveau (package de version tpu-mlir), utilisez la commande suivante pour cloner model-zoole projet :

$ git clone --depth=1 https://github.com/sophgo/model-zoo
$ cd model-zoo
$ git lfs pull --include "*.onnx,*.jpg,*.JPEG" --exclude=""
$ cd ../

Le processus d'extraction de lfs en mode PCIE de la plate-forme cloud BM1684X :

insérez la description de l'image ici

S'il a été cloné, model-zoovous pouvez exécuter la commande suivante pour synchroniser le modèle avec le dernier état :

$ cd model-zoo
$ git pull
$ git lfs pull --include "*.onnx,*.jpg,*.JPEG" --exclude=""
$ cd ../

Ce processus GitHubtélécharge une grande quantité de données depuis . En raison des différences dans les environnements réseau spécifiques, ce processus peut prendre beaucoup de temps.

(3) Obtenir l'outil tpu-perf

Téléchargez le dernier tpu-perfpackage d'installation de la roue à partir de l'adresse https://github.com/sophgo/tpu-perf/releases. Par exemple : tpu_perf-xxx-py3-none-manylinux2014_x86_64.whl . Et tpu-perfplacez le package dans model-zoole même répertoire que . La structure du répertoire à ce stade doit être la suivante :

├── tpu_perf-x.x.x-py3-none-manylinux2014_x86_64.whl
├── tpu-mlir_xxxx
└── model-zoo

insérez la description de l'image ici

(4) Essai de déploiement

Entrez dans le conteneur docker et activez la variable d'environnement de tpu-mlir, où XXXX indique le répertoire où tpu_mlir est stocké.

$ docker exec -it 容器id /bin/bash
$ source XXXX/XXXX/XXXX/envsetup.sh

insérez la description de l'image ici

Installertpu-perf

$ pip3 install ../tpu_perf-x.x.x-py3-none-manylinux2014_x86_64.whl

(5) Compiler le modèle

model-zooLa configuration pertinente confg.yamldu contenu du test SDK. Par exemple : Le fichier de configuration pour resnet18 est model-zoo/vision/classification/resnet18-v2/config.yaml.

Exécutez la commande suivante pour exécuter tous les exemples de test :

$ cd ../model-zoo
$ python3 -m tpu_perf.build --mlir -l full_cases.txt

À ce stade, les modèles suivants sont compilés :

* efficientnet-lite4
* mobilenet_v2
* resnet18
* resnet50_v2
* shufflenet_v2
* squeezenet1.0
* vgg16
* yolov5s

Une fois la commande terminée normalement, vous verrez le outputdossier nouvellement généré (le contenu de la sortie de test se trouve dans ce dossier). Modifiez outputles propriétés du dossier pour vous assurer qu'il est accessible aux systèmes extérieurs à Docker.

$ chmod -R a+rw output

(6) Test de fonctionnement en mode PCIE

L'exécution du test doit être effectuée dans un environnement en dehors de Docker (ici, on suppose que vous avez installé et configuré le périphérique et le pilote 1684X), et vous pouvez quitter l'environnement Docker :

$ exit

Exécutez la commande suivante sous la carte PCIE pour tester les bmodelperformances générées.

$ pip3 install ./tpu_perf-*-py3-none-manylinux2014_x86_64.whl
$ cd model-zoo
$ python3 -m tpu_perf.run --mlir -l full_cases.txt

Remarque : si plusieurs cartes accélératrices SOPHGO sont installées sur l'hôte, vous pouvez spécifier l'appareil en cours d'exécution tpu_perfen ajoutant lors de l'utilisation de . comme:--devices idtpu_perf

$ python3 -m tpu_perf.run --devices 2 --mlir -l full_cases.txt

Installertpu-perf

$ pip3 install ../tpu_perf-x.x.x-py3-none-manylinux2014_x86_64.whl

Je suppose que tu aimes

Origine blog.csdn.net/lily_19861986/article/details/131213536
conseillé
Classement