NPU使用示例

优质
小牛编辑
128浏览
2023-12-01

MNIST 示例

MNIST是一个入门级的计算机视觉数据集,它的输入是像素为28x28的手写数字图片,输出是图片对应的0-9数字的概率。下面以TensorFlow自带的mnist 模型(TensorFlow v1.0)为例,说明gxDNN的使用。

生成NPU文件

这个示例的MNIST计算模型非常简单,可以用一个公式来表示: y = x * W + b (训练的过程中还会去计算softmax,但由于我们正式使用时只需要获取结果中最大值的索引,而softmax是个单调递增函数,因此省去这个函数不会对结果有影响)。其中x为输入数据,y为输出数据,Wb为训练的参数。训练的过程就是不断通过计算出来的y和期望的y_去调整Wb的过程。 在NPU上,我们只需要用到训练好的Wb,而不需要训练的过程。

生成ckpt和pb文件

为了方便的获取到输入结点和输出结点,我们给输入结点和输出结点取个名字,把x取名为input_x,把y取名为result: 把mnist_softmax.py第40行

x = tf.placeholder(tf.float32, [None, 784])

修改为

x = tf.placeholder(tf.float32, [None, 784], name="input_x")

把第43行

y = tf.matmul(x, W) + b

修改为

y = tf.add(tf.matmul(x, W), b, name="result")

为了生成ckpt和pb文件,在main函数末尾添加:

saver = tf.train.Saver() 
saver.save(sess, "mnist.ckpt") 
tf.train.write_graph(sess.graph_def, "./", "mnist.pb")

运行程序后,当前路径下会生成mnist.ckpt.*mnist.pb文件。

把ckpt和pb文件合并成一个pb文件

使用freeze_graph.py脚本将mnist.ckpt.*mnist.pb合并为一个pb文件。 注意:不同TensorFlow版本的freeze_graph.py脚本可能不同。

执行命令

python freeze_graph.py --input_graph=mnist.pb --input_checkpoint=./mnist.ckpt --output_graph=mnist_with_ckpt.pb --output_node_names=result

生成mnist_with_ckpt.pb文件。 其中,--input_graph后跟输入pb名,--input_checkpoint后跟输入ckpt名,--output_graph后跟合成的pb文件名,--output_node_names后跟输出结点名称,如有多个,用逗号分隔。 执行完成后,在当前路径下生成mnist_with_ckpt.pb文件。

如果是saved_model方式保存的模型,使用如下命令合成pb文件

python freeze_graph.py --input_saved_model_dir=./saved_model_dir --output_graph=mnist_with_ckpt.pb --output_node_names=result

编辑NPU配置文件

编辑配置文件mnist_config.yaml文件,含义见注释。

CORENAME: LEO # 芯片型号
PB_FILE: mnist_with_ckpt.pb # 输入的pb文件
OUTPUT_FILE: mnist.npu # 输出的NPU文件名
SECURE: false # 不开启内容保护
NPU_UNIT: NPU64 # NPU设备类型
COMPRESS: true # 压缩模型
COMPRESS_QUANT_BITS: 8 # 量化成8bits
OUTPUT_TYPE: raw # NPU文件的类型
INPUT_OPS:
    input_x: [1, 784] # 输入结点名称和数据维度,每运行一次输入数据为1x784,即一幅图
OUTPUT_OPS: [result] # 输出结点名称

编译

使用gxnpuc工具编译

gxnpuc mnist_config.yaml

如果 gxnpuc 的版本在1.0之前

gxnpuc --config=./mnist_config.yaml

生成NPU文件mnist.npu

执行NPU文件

NPU文件生成后,需要调用API,把模型部署到GX8010开发板上运行。

调用SDK流程

  1. 打开NPU设备。
  2. 传入模型文件,得到模型task.
  3. 获取task的输入输出信息。
  4. 拷贝输入数据到模型内存中。
  5. 运行模型。
  6. 释放模型task.
  7. 关闭NPU设备。

mnist示例

代码请参考这里。程序要求用户输入一个保存有28x28个像素值的二进制文件,输出识别的数字。

images中存放的是若干个二进制测试文件。其内容为28x28的已做归一化的像素值。

执行make生成可执行文件test_mnist.elf

mnist.nputest_mnist.elfimages目录放到GX8010开发板上,并运行,打印如下:

./test_mnist.elf images/image0
Digit: 7
./test_mnist.elf images/image1
Digit: 2
./test_mnist.elf images/image2
Digit: 1
./test_mnist.elf images/image3
Digit: 0
./test_mnist.elf images/image4
Digit: 4
./test_mnist.elf images/image5
Digit: 1