环境安装
tensorflow 安装,一直不太想用mace的部分原因是不支持tensorflow2.模型, 但为了GPU(OpenCL)还是要用啊。
Shell
set -e
tput
asan
bazel
绿色记忆:Bazel学习笔记https://blog.gmem.cc/bazel-study-note
Docker:
配置编译环境,真的很麻烦,还是直接使用docker
apt-get install docker.io //安装docker
docker pull registry.cn-hangzhou.aliyuncs.com/xiaomimace/mace-dev //下载mace docker
git clone https://github.com/XiaoMi/mace.git //下载mace代码,
关联docker到本地代码,一般使用docker的编译环境,而代码是本地的,如果编译环境编译、改变了本地的代码,就和本地编译没有什么区别了,最起码对开发任务透明了。
本地下载mace后,git 会自动创建 mace 目录,cd mace: 然后执行
mace git:(master) sudo docker run -it -v $PWD:/mace registry.cn-hangzhou.aliyuncs.com/xiaomimace/mace-dev
进入docker后会看到bin, home等目录这些是docker里的不是本地的,本地的目录是mace, 也是docker的目录,这样就可以使用docker 环境操作mace共享目录了
root@700c5afbd9fd:/# ls
bin boot dev etc home lib lib64 mace
mace/examples/android/build.sh文件分析
mace/tools/python/convert.py
python tools/python/convert.py --config ../mace-models/mobilenet-v2/mobilenet-v2.yml
参数相对简单
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument(
'--config',
type=str,
default="",
required=True,
help="the path of model yaml configuration file.")
parser.add_argument(
'--output',
type=str,
default="build",
help="output dir")
parser.add_argument(
"--enable_micro",
action="store_true",
help="enable convert micro.")
flgs, _ = parser.parse_known_args()
return flgs
if __name__ == '__main__':
flags = parse_args() //解析输入参数到flags
conf = config_parser.parse(flags.config) // from utils import config_parser解析yaml文件
convert(conf, flags.output, flags.enable_micro)
功能就是解析config yaml 文件,生成/输出
def convert(conf, output, enable_micro=False):
----
output_model_file = model_output + "/" + model_name + ".pb"
output_params_file = model_output + "/" + model_name + ".data"
(output_model_file + "_txt") 也是描述model file
解析保存到文件
python tools/converter.py convert --config=examples/android/mobilenet.yml --target_abis=$TARGET_ABI --debug_mode --mace_lib_type=dynamic(不起作用)
mace/tools/converter.py
pushd ../..
python tools/converter.py convert --config=examples/android/mobilenet.yml --target_abis=$TARGET_ABI
//调用了pythont/convert.py
convert.convert(configs, MODEL_CODEGEN_DIR, flags.enable_micro)
./tools/common.py:477:CODEGEN_BASE_DIR = 'mace/codegen'
./tools/common.py:478:MODEL_CODEGEN_DIR = CODEGEN_BASE_DIR + '/models'
./tools/common.py:479:ENGINE_CODEGEN_DIR = CODEGEN_BASE_DIR + '/engine'
./tools/common.py:480:LIB_CODEGEN_DIR = CODEGEN_BASE_DIR + '/lib'
./tools/common.py:481:OPENCL_CODEGEN_DIR = CODEGEN_BASE_DIR + '/opencl'
python tools/converter.py convert/run
python文件后面的 convert是输入参数吗?是怎么样解析的?
convert
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
convert = subparsers.add_parser(
'convert',
parents=[all_type_parent_parser, convert_run_parent_parser],
help='convert to mace model (file or code)')
convert.add_argument(
"--enable_micro",
action="store_true",
help="enable convert micro.")
convert.set_defaults(func=convert_func)
all_type_parent_parser.add_argument(
"--model_graph_format",
type=str,
default="",
help="[file, code], MACE Model graph format.")
all_type_parent_parser.add_argument(
"--model_data_format",
type=str,
default="",
help="['file', 'code'], MACE Model data format.")
def convert_func(flags):
configs = config_parser.parse(flags.config)
print(configs)
//model_graph_format: code 来着yml file
//model_data_format: code
embed_graph_def = model_graph_format == ModelFormat.code
if embed_graph_def:
os.makedirs(model_header_dir)
sh_commands.gen_mace_engine_factory_source( //生成了c++ and .h files?
configs[YAMLKeyword.models].keys(),
embed_model_data)
sh.cp("-f", glob.glob("mace/codegen/engine/*.h"),
model_header_dir)
convert.convert(configs, MODEL_CODEGEN_DIR, flags.enable_micro)
for model_name, model_config in configs[YAMLKeyword.models].items():
if flags.enable_micro:
data_type = model_config.get(YAMLKeyword.data_type, "")
if data_type != FPDataType.bf16_fp32.value:
data_type = FPDataType.fp32_fp32.value
model_codegen_dir = "%s/%s" % (MODEL_CODEGEN_DIR, model_name)
# encrypt file
encrypt.encrypt(model_name,
"%s/model/%s.pb" % (model_codegen_dir, model_name),
"%s/model/%s.data" % (model_codegen_dir, model_name),
model_codegen_dir,
bool(model_config.get(YAMLKeyword.obfuscate, 1)),
model_graph_format == "code",
model_data_format == "code")
# code then build
if model_graph_format == ModelFormat.code:
build_model_lib(configs, flags.address_sanitizer, flags.debug_mode)
print_library_summary(configs)
生成的文件for model
mace/mace/codegen/engine
mace/mace/codegen/models/xxx/ code, model, org_model
cc_library(
name = "generated_models",
srcs = glob(["models/**/*.cc"]),
hdrs = glob(["models/**/*.h"]),
copts = [
"-Werror",
"-Wextra",
"-Wno-missing-field-initializers",
],
deps = [
"//mace/core",
],
)
cc_library( //使用model的接口
name = "generated_mace_engine_factory", 怎么copy到另一个路径下的
hdrs = glob(["engine/*.h"]),
copts = [
"-Werror",
"-Wextra",
"-Wno-missing-field-initializers",
],
deps = [
"//include:public_headers",
],
)
codegen
➜ codegen git:(master) ✗ ls -al
-rw-rw-r-- 1 ws ws 1590 12月 20 19:46 BUILD.bazel
-rw-rw-r-- 1 ws ws 2174 12月 20 19:46 CMakeLists.txt
-rw-rw-r-- 1 ws ws 199 12月 20 19:46 model_version_script.lds
drwxrwxr-x 2 ws ws 4096 12月 20 19:46 tools
生成的文件
➜ codegen git:(master) ✗ ls -al
total 32
-rw-rw-r-- 1 ws ws 1590 12月 20 19:46 BUILD.bazel
-rw-rw-r-- 1 ws ws 2174 12月 20 19:46 CMakeLists.txt
drwxr-xr-x 2 root root 4096 12月 21 13:22 engine
drwxr-xr-x 6 root root 4096 12月 21 13:23 models
-rw-rw-r-- 1 ws ws 199 12月 20 19:46 model_version_script.lds
drwxrwxr-x 2 ws ws 4096 12月 20 19:46 tools
生成两个文件夹: engine and models 其中models 里又包含了多个文件夹,其中文件夹的名字由yaml 文件中的model的name 决定的
其中engine
➜ codegen git:(master) ✗ tree engine
engine
└── mace_engine_factory.h (yaml里的所有model都用这个接口头文件)
➜ models git:(master) ✗ ls -al
drwxr-xr-x 5 root root 4096 12月 21 13:23 mobilenet_v1
drwxr-xr-x 5 root root 4096 12月 2