basic_usage.rst 12.2 KB
Newer Older
L
Liangliang He 已提交
1
Basic usage
L
liutuo 已提交
2
=============
L
Liangliang He 已提交
3

L
liutuo 已提交
4 5 6 7

Build and run an example model
--------------------------------

L
liutuo 已提交
8
At first, make sure the environment has been set up correctly already (refer to :doc:`installation`).
L
liutuo 已提交
9

L
liutuo 已提交
10
The followings are instructions about  how to quickly build and run a provided model in *MACE Model Zoo*.
L
liutuo 已提交
11

L
liutuo 已提交
12
Here we use the mobilenet-v2 model as an example.
L
liutuo 已提交
13

L
liutuo 已提交
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
**Commands**

    1. Pull *MACE* project.

    .. code:: sh

        git clone https://github.com/XiaoMi/mace.git
        git fetch --all --tags --prune

        # Checkout the latest tag (i.e. release version)
        tag_name=`git describe --abbrev=0 --tags`
        git checkout tags/${tag_name}

    .. note::

        It's highly recommanded to use a release version instead of master branch.


    2. Pull *MACE Model Zoo* project.

    .. code:: sh

        git clone https://github.com/XiaoMi/mace-models.git


    3. Build MACE.

    .. code:: sh
L
liutuo 已提交
42

L
liutuo 已提交
43 44 45
        cd path/to/mace
        # Build library
        python tools/converter.py build --config=path/to/mace-models/mobilenet-v2/mobilenet-v2.yml
L
liutuo 已提交
46 47


L
liutuo 已提交
48
    4. Convert the model to MACE format model.
L
liutuo 已提交
49

L
liutuo 已提交
50
    .. code:: sh
L
liutuo 已提交
51

L
liutuo 已提交
52 53 54
        cd path/to/mace
        # Build library
        python tools/converter.py build --config=path/to/mace-models/mobilenet-v2/mobilenet-v2.yml
L
liutuo 已提交
55 56


L
liutuo 已提交
57
    5. Run the model.
L
liutuo 已提交
58

L
liutuo 已提交
59 60 61 62 63 64 65 66
    .. code:: sh

    	# Test model run time
        python tools/converter.py run --config=path/to/mace-models/mobilenet-v2/mobilenet-v2.yml --round=100

    	# Validate the correctness by comparing the results against the
    	# original model and framework, measured with cosine distance for similarity.
    	python tools/converter.py run --config=path/to/mace-models/mobilenet-v2/mobilenet-v2.yml --validate
L
liutuo 已提交
67 68 69 70


Build your own model
----------------------------
L
liutuo 已提交
71 72 73

This part will show you how to use your pre-trained model in MACE.

L
liutuo 已提交
74 75 76 77
==================================
1. Prepare your model
==================================

L
liutuo 已提交
78
Mace now supports models from Tensorflow and Caffe(more frameworks will be supported).
L
liutuo 已提交
79 80 81

-  TensorFlow

L
liutuo 已提交
82
   Prepare your pre-trained Tensorflow model.pb file.
L
liutuo 已提交
83 84

   Use `Graph Transform Tool <https://github.com/tensorflow/tensorflow/blob/master/tensorflow/tools/graph_transforms/README.md>`__
L
liutuo 已提交
85
   to optimize your model for inference.
L
liutuo 已提交
86
   This tool will improve the efficiency of inference by making several optimizations like operators
L
liutuo 已提交
87
   folding, redundant node removal etc. We strongly recommend MACE users to use it before building.
L
liutuo 已提交
88

L
liutuo 已提交
89
   Usage for CPU/GPU,
L
liutuo 已提交
90 91 92 93 94

   .. code:: bash

       # CPU/GPU:
       ./transform_graph \
L
liutuo 已提交
95 96 97 98
           --in_graph=/path/to/your/tf_model.pb \
           --out_graph=/path/to/your/output/tf_model_opt.pb \
           --inputs='input node name' \
           --outputs='output node name' \
L
liutuo 已提交
99 100 101 102 103 104 105 106 107 108 109 110
           --transforms='strip_unused_nodes(type=float, shape="1,64,64,3")
               strip_unused_nodes(type=float, shape="1,64,64,3")
               remove_nodes(op=Identity, op=CheckNumerics)
               fold_constants(ignore_errors=true)
               flatten_atrous_conv
               fold_batch_norms
               fold_old_batch_norms
               strip_unused_nodes
               sort_by_execution_order'

-  Caffe

L
liutuo 已提交
111 112 113
   Caffe 1.0+ models are supported in MACE converter tool.

   If your model is from lower version Caffe, you need to upgrade it by using the Caffe built-in tool before converting.
L
liutuo 已提交
114 115 116 117 118 119 120 121 122

   .. code:: bash

       # Upgrade prototxt
       $CAFFE_ROOT/build/tools/upgrade_net_proto_text MODEL.prototxt MODEL.new.prototxt

       # Upgrade caffemodel
       $CAFFE_ROOT/build/tools/upgrade_net_proto_binary MODEL.caffemodel MODEL.new.caffemodel

L
liutuo 已提交
123

L
liutuo 已提交
124 125 126 127
============================================
2. Create a deployment file for your model
============================================

L
liutuo 已提交
128 129 130 131 132 133 134
When converting a model or building a library, MACE needs to read a YAML file which is called model deployment file here.

A model deployment file contains all the information of your model(s) and building options. There are several example
deployment files in *MACE Model Zoo* project.

The following shows two basic usage of deployment files for Tensorflow and Caffe models.
Modify one of them and use it for your own case.
L
liutuo 已提交
135 136 137 138 139 140 141 142 143 144 145

-  Tensorflow

   .. literalinclude:: models/demo_app_models_tf.yml
      :language: yaml

-  Caffe

   .. literalinclude:: models/demo_app_models_caffe.yml
      :language: yaml

L
liutuo 已提交
146
More details about model deployment file, please refer to :doc:`advanced_usage`.
L
liutuo 已提交
147 148

======================================
L
liutuo 已提交
149
3. Convert your model
L
liutuo 已提交
150 151
======================================

L
liutuo 已提交
152
When the deployment file is ready for your model, you can use MACE converter tool to convert your model(s).
L
liutuo 已提交
153

L
liutuo 已提交
154
To convert your pre-trained model to a MACE model, you need to set ``build_type:proto`` in your model deployment file.
L
liutuo 已提交
155

L
liutuo 已提交
156
And then run this command:
L
liutuo 已提交
157

L
liutuo 已提交
158
.. code:: bash
L
liutuo 已提交
159

L
liutuo 已提交
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
    python tools/converter.py convert --config=path/to/your/model_deployment.yml

This command will download or load your pre-trained model and convert it to a MACE model proto file and weights file.
The generated model files will be stored in ``build/${library_name}/model`` folder.

.. warning::

    Please set ``build_type:proto`` in your deployment file before converting.
    The usage of ``build_type:code`` will be demonstrated in :doc:`advanced_usage`.

======================================
4. Build MACE into a library
======================================

MACE can be built into either a static or a shared library (which is
specified by ``linkshared`` in YAML model deployment file).

Use bazel to build MACE source code into a library.
L
liutuo 已提交
178 179 180 181 182

    .. code:: sh

        cd path/to/mace
        # Build library
L
liutuo 已提交
183 184 185 186 187 188 189 190
        bazel build --config=path/to/your/model_deployment_file.yml

The above command will generate library files in the ``build/${library_name}/libs`` folder.

    .. warning::

        1. Please verify the target_abis params in the above command and the deployment file are the same.
        2. If you want to build a library for a specific soc, please refer to :doc:`advanced_usage`.
L
liutuo 已提交
191 192


L
liutuo 已提交
193 194 195 196 197 198 199 200 201
======================================
5. Run your model
======================================

With the converted model, *.so or *.a library and header files, you can use the following commands to run and validate your model.

* **run**

    run the model.
L
liutuo 已提交
202 203 204 205 206 207 208 209 210 211

    .. code:: sh

    	# Test model run time
        python tools/converter.py run --config=path/to/your/model_deployment_file.yml --round=100

    	# Validate the correctness by comparing the results against the
    	# original model and framework, measured with cosine distance for similarity.
    	python tools/converter.py run --config=path/to/your/model_deployment_file.yml --validate

L
liutuo 已提交
212
* **benchmark**
L
liutuo 已提交
213

L
liutuo 已提交
214
    benchmark and profile the model.
L
liutuo 已提交
215 216 217 218 219 220 221

    .. code:: sh

        # Benchmark model, get detailed statistics of each Op.
        python tools/converter.py benchmark --config=path/to/your/model_deployment_file.yml


L
liutuo 已提交
222 223 224
========================================================
6. Deploy your model into applications
========================================================
L
liutuo 已提交
225

L
liutuo 已提交
226 227 228
In the converting and building steps, you've got the static/shared library, model files and
header files. All of these generated files have been packaged into
``build/${library_name}/libmace_${library_name}.tar.gz`` when building.
L
liutuo 已提交
229

L
liutuo 已提交
230
``${library_name}`` is the name you defined in the first line of your deployment YAML file.
L
liutuo 已提交
231 232 233 234 235 236

-  The generated ``static`` library files are organized as follows,

.. code::

      build/
L
liutuo 已提交
237
      └── mobilenet-v2
L
liutuo 已提交
238 239 240 241 242
          ├── include
          │   └── mace
          │       └── public
          │           ├── mace.h
          │           └── mace_runtime.h
L
liutuo 已提交
243
          ├── libmace_mobilenet-v2.tar.gz
L
liutuo 已提交
244 245
          ├── lib
          │   ├── arm64-v8a
L
liutuo 已提交
246
          │   │   └── libmace_mobilenet-v2.MI6.msm8998.a
L
liutuo 已提交
247
          │   └── armeabi-v7a
L
liutuo 已提交
248
          │       └── libmace_mobilenet-v2.MI6.msm8998.a
L
liutuo 已提交
249 250 251 252 253
          ├── model
          │   ├── mobilenet_v2.data
          │   └── mobilenet_v2.pb
          └── opencl
              ├── arm64-v8a
L
liutuo 已提交
254
              │   └── mobilenet-v2_compiled_opencl_kernel.MI6.msm8998.bin
L
liutuo 已提交
255
              └── armeabi-v7a
L
liutuo 已提交
256
                  └── mobilenet-v2_compiled_opencl_kernel.MI6.msm8998.bin
L
liutuo 已提交
257 258 259 260 261 262

-  The generated ``shared`` library files are organized as follows,

.. code::

      build
L
liutuo 已提交
263
      └── mobilenet-v2
L
liutuo 已提交
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
          ├── include
          │   └── mace
          │       └── public
          │           ├── mace.h
          │           └── mace_runtime.h
          ├── lib
          │   ├── arm64-v8a
          │   │   ├── libgnustl_shared.so
          │   │   └── libmace.so
          │   └── armeabi-v7a
          │       ├── libgnustl_shared.so
          │       └── libmace.so
          ├── model
          │   ├── mobilenet_v2.data
          │   └── mobilenet_v2.pb
          └── opencl
              ├── arm64-v8a
L
liutuo 已提交
281
              │   └── mobilenet-v2_compiled_opencl_kernel.MI6.msm8998.bin
L
liutuo 已提交
282
              └── armeabi-v7a
L
liutuo 已提交
283
                  └── mobilenet-v2_compiled_opencl_kernel.MI6.msm8998.bin
L
liutuo 已提交
284 285 286


Unpack the generated libmace_${library_name}.tar.gz file and copy all of the uncompressed files into your project.
L
liutuo 已提交
287

L
liutuo 已提交
288
Please refer to \ ``mace/examples/example.cc``\ for full usage. The following list the key steps.
L
liutuo 已提交
289 290 291 292 293 294 295 296 297 298 299 300

.. code:: cpp

    // Include the headers
    #include "mace/public/mace.h"
    #include "mace/public/mace_runtime.h"

    // 0. Set pre-compiled OpenCL binary program file paths when available
    if (device_type == DeviceType::GPU) {
      mace::SetOpenCLBinaryPaths(opencl_binary_paths);
    }

L
liutuo 已提交
301 302 303 304 305
    // 1. Set compiled OpenCL kernel cache, this is used to reduce the
    // initialization time since the compiling is too slow. It's suggested
    // to set this even when pre-compiled OpenCL program file is provided
    // because the OpenCL version upgrade may also leads to kernel
    // recompilations.
L
liutuo 已提交
306 307 308 309 310
    const std::string file_path ="path/to/opencl_cache_file";
    std::shared_ptr<KVStorageFactory> storage_factory(
        new FileStorageFactory(file_path));
    ConfigKVStorageFactory(storage_factory);

L
liutuo 已提交
311
    // 2. Declare the device type (must be same with ``runtime`` in configuration file)
L
liutuo 已提交
312 313 314 315 316 317 318 319 320
    DeviceType device_type = DeviceType::GPU;

    // 3. Define the input and output tensor names.
    std::vector<std::string> input_names = {...};
    std::vector<std::string> output_names = {...};

    // 4. Create MaceEngine instance
    std::shared_ptr<mace::MaceEngine> engine;
    MaceStatus create_engine_status;
L
liutuo 已提交
321 322

    // Create Engine from model file
L
liutuo 已提交
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359
    create_engine_status =
        CreateMaceEngineFromProto(model_pb_data,
                                  model_data_file.c_str(),
                                  input_names,
                                  output_names,
                                  device_type,
                                  &engine);
    if (create_engine_status != MaceStatus::MACE_SUCCESS) {
      // Report error
    }

    // 5. Create Input and Output tensor buffers
    std::map<std::string, mace::MaceTensor> inputs;
    std::map<std::string, mace::MaceTensor> outputs;
    for (size_t i = 0; i < input_count; ++i) {
      // Allocate input and output
      int64_t input_size =
          std::accumulate(input_shapes[i].begin(), input_shapes[i].end(), 1,
                          std::multiplies<int64_t>());
      auto buffer_in = std::shared_ptr<float>(new float[input_size],
                                              std::default_delete<float[]>());
      // Load input here
      // ...

      inputs[input_names[i]] = mace::MaceTensor(input_shapes[i], buffer_in);
    }

    for (size_t i = 0; i < output_count; ++i) {
      int64_t output_size =
          std::accumulate(output_shapes[i].begin(), output_shapes[i].end(), 1,
                          std::multiplies<int64_t>());
      auto buffer_out = std::shared_ptr<float>(new float[output_size],
                                               std::default_delete<float[]>());
      outputs[output_names[i]] = mace::MaceTensor(output_shapes[i], buffer_out);
    }

    // 6. Run the model
L
liutuo 已提交
360
    MaceStatus status = engine.Run(inputs, &outputs);
L
liutuo 已提交
361

L
liutuo 已提交
362
More details are in :doc:`advanced_usage`.