沉思语录

取次花丛懒回顾,半缘修道半缘君


  • 首页

  • 归档

  • 标签

  • 搜索

tensorflow_benchmark_机制分析

发表于 2020-09-26 |

介绍

本文介绍Tensorflow Op 级别的benchmark的用法以及代码调用

用法

1
2
3
4
5
6
7
8
9
10
11
* 编译并运行
bazel --output_user_root=$build_dir run --config=mkl --copt=-O3 //tensorflow/core/kernels/image:non_max_suppression_op_benchmark_test --benchmarks=../
* 先编译再运行
bazel --output_user_root=$build_dir build --config=mkl --copt=-O3 //tensorflow/core/kernels/image:non_max_suppression_op_benchmark_test
设置环境变量
TF_NUM_INTEROP_THREADS=1 TF_NUM_INTRAOP_THREADS=28 OMP_NUM_THREADS=28
numactl --localalloc --physcpubind 0-27 ./bazel-bin/tensorflow/core/kernels/image/non_max_suppression_op_benchmark_test --benchmarks=../
* 编译静态链接可移植的二进制
bazel --output_user_root=$build_dir build --config=monolithic --copt=-O3 //tensorflow/core/kernels/image:non_max_suppression_op_benchmark_test

代码分析

Benchmark文件

https://github.com/tensorflow/tensorflow/blob/e8598ce0454c440fca64e4ebc4aeedfa7afd5c97/tensorflow/core/kernels/image/non_max_suppression_op_benchmark_test.cc

1
2
3
4
5
6
7
#define BM_CombinedNonMaxSuppressionDev(DEVICE, B, BN, CN, Q) \
static void BM_CombinedNMS_##DEVICE##_##B##_##BN##_##CN##_##Q(int iters) { \
testing::ItemsProcessed(iters* B); \
test::Benchmark(#DEVICE, BM_CombinedNonMaxSuppression(B, BN, CN, Q)) \
.Run(iters); \
} \
BENCHMARK(BM_CombinedNMS_##DEVICE##_##B##_##BN##_##CN##_##Q);

封装构造testing::Benchmark

Step1:

BENCHMARK(BMCombinedNMS##DEVICE####B####BN####CN####Q);

Step2 注册benchmark 进入all_benchmark这个全局变量:

https://github.com/tensorflow/tensorflow/blob/e8598ce0454c440fca64e4ebc4aeedfa7afd5c97/tensorflow/core/platform/default/test_benchmark.h#L28-L33

  • TF_ATTRIBUTE_UNUSED attribute((unused)) 忽略GCC 告警: https://www.jianshu.com/p/21aef14340a8
  • new ::tensorflow::testing::Benchmark(#n, (n)) 将这个函数注册到all_benchmark这个全局变量里面 里面 https://github.com/tensorflow/tensorflow/blob/e8598ce0454c440fca64e4ebc4aeedfa7afd5c97/tensorflow/core/platform/default/test_benchmark.cc#L39-L43
阅读全文 »

tensorflow_lite

发表于 2020-09-20 |

介绍

tfllite 有两个部分组成:

convert: 用于将模型转换成tflite格式,可以从keras模型,也可以从各种tf1.x的模型转换出来(比如save model, pb model)
interpreter: tflite 运行时,调试的时候可以直接用集成在tf里面,部署的时候有单独的whl包作为更小的一个运行时(https://www.tensorflow.org/lite/guide/python)

转换模型

推荐用SavedModel的格式
https://www.tensorflow.org/lite/guide/get_started#2_convert_the_model_format
https://www.tensorflow.org/lite/convert

TF1.x
https://www.tensorflow.org/api_docs/python/tf/compat/v1/lite/TFLiteConverter#from_frozen_graph
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/g3doc/r1/convert/python_api.md#checkpoints

如何单独编译tflite的运行时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# only build C++ so
bazel --output_user_root=$build_dir build -c opt //tensorflow/lite:tensorflowlite
# Build whl package
https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/tools/pip_package
# install dependecy and run script
yum install swig libjpeg-devel
pip install numpy pybind11
tensorflow/lite/tools/make/download_dependencies.sh
tensorflow/lite/tools/pip_package/build_pip_package.sh
从中setup.py提取出C++ build的命令
make SHELL=/bin/bash BUILD_WITH_NNAPI=false BUILD_WITH_RUY=true -C /home/lesliefang/tflite/tensorflow_test/tensorflow-2.3.0 -f tensorflow/lite/tools/make/Makefile -j 220
看build_pip_package.sh 的输出日志或者
在代码目录下搜索:tflite_runtime-2.1.0-cp36-cp36m-linux_x86_64.whl
可以找到对应的生成的whl package

一个tflite模型可以被多个解释器调用,每个解释器需要独占一个线程(多线程不能共享解释器)

阅读全文 »

tensorflow_dataset

发表于 2020-04-24 |

介绍

tensorflow dataset是一个pipline,应该使用pipeline的思想去认识它
reference 资料:

  • <<简单粗暴 TensorFlow 2.0>> 的第三章 https://tf.wiki/zh/basic/tools.html#tf-data
  • 官方API:https://www.tensorflow.org/api_docs/python/tf/data

    结构

    示例代码 TF2.0:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    fake_data = np.arange(1500)
    dataset = tf.data.Dataset.from_tensor_slices(fake_data)
    if is_mpi:
    dataset = dataset.shard(hvd.size(), hvd.rank())
    dataset = dataset.shuffle(buffer_size=100)
    dataset = dataset.repeat(num_epochs)
    dataset = dataset.batch(batch_size=10)
    dataset = dataset.map(parse_csv, num_parallel_calls=28)
    dataset = dataset.prefetch(1)
    for images, labels in dataset:
    images
    labels

tensorflow dataset 的使用代码可以分成三个阶段

阶段1:定义数据集的建立

  • tf.data.Dataset.from_tensor_slices
    直接从内存中的数据来创建dataset,数据全部在内存,适用于小数据集

  • tf.data.TextLineDataset
    传入文本文件名,创建的这个dataset时候,并不会将整个文件一起读到内存中

  • tf.data.TFRecordDataset
    传入tfrecord格式数据,

阶段2:数据集的转换

有很多转换的方法,根据需要我们可以选几种方法,推介使用这些方法的顺序:

  • dataset.shard
    利用horovod做分布式训练的时候,做数据并行化,shard数据集,每个train的实例分到一部分数据集来训练

  • shuffle
    设定一个buffersize的缓存区,取数据集前buffersize个数据放进来,每次要取数据的时候,从这个缓存区随机取batchsize的数据出来,然后在从dataset里面顺序补进来batchsize数据

buffersize的值设定很重要,否则可能起不到shuffle的作用

  • repeat
    repeat 几个epoch的数据,在后面真实在使用dataset的时候,
    比如 estimator.train(input_fn=dataset) 或者 for images, labels in dataset:
    如果repeat的epoch数据对应计算出来的我们可以train的steps 小于 指定train的steps
    会产生tf.errors.OutOfRange,从而没有达到我们指定的steps就终止train
    https://www.tensorflow.org/api_docs/python/tf/estimator/Estimator#train

  • batch
    将batchsize个样本组成一个batch数据,也可以叫做example

  • map
    设定我们原始dataset数据进行预处理的方法,返回一个新的dataset 也是(images,labels)元组的格式,num_parallel_calls指定预处理数据的时候可以使用多少个core
    预处理不会立即执行,只有当我们访问dataset的iter去获取数据的时候才会执行

  • prefetch
    有个buffsize的参数,可以存buffersize个example到prefetch buffer里面,一个example是batchsize个样本
    刚刚初始化的时候,就先取buffersize个example 执行map函数指定的预处理,将预处理之后的结果放入prefetch buffer里面

在访问一次iter的时候,会从这个prefetch buffer里面取一个example的数据(batchsize个样本),这些数据送进去开始step的计算,同时后台执行map的预处理函数生成一个新的样本放入到prefetch buffer里面 重要 这两个操作是overlap的

数据的真实读取

  • method1: 创建dataset_iter, 调用next(it)
    调用一次,返回一个batchsize的数据

  • method2: TF2.0:

    1
    2
    for images, labels in dataset:
    返回一个batchsize的数据

这里有一点很重要,如果设置了dataset.prefetch, 每一次遍历的时候只是从prefetch的buffer里面读取数据,不会阻塞的去做数据的预处理(执行dataset.map里面的函数),(下个step数据的预处理和这个step的计算同步做,填入到prefetch buffer)
如果没有设置prefetch,这里则会阻塞的去做数据的预处理,只有预处理好的数据才能读出来

123…28
Leslie

Leslie

记录心情与能力的成长

82 日志
15 标签
© 2021 Leslie
由 Hexo 强力驱动
主题 - NexT.Pisces
本站访客数 本站总访问量