Skip to content

Commit

Permalink
Fix some bugs about supporting multiple versions
Browse files Browse the repository at this point in the history
  • Loading branch information
shiyingjin committed Dec 30, 2019
1 parent 9de0e1f commit bbdd279
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 40 deletions.
2 changes: 1 addition & 1 deletion adlik_serving/framework/domain/model_options.cc
Expand Up @@ -6,7 +6,7 @@
namespace adlik {
namespace serving {

ModelOptions::ModelOptions() : intervalInSecond(1) {
ModelOptions::ModelOptions() : intervalInSecond(10) {
}

void ModelOptions::subscribe(cub::ProgramOptions& prog) {
Expand Down
1 change: 1 addition & 0 deletions adlik_serving/framework/domain/version_list.cc
Expand Up @@ -14,6 +14,7 @@ VersionList::VersionList(const std::vector<int>& versions) : versions(versions)

void VersionList::add(int version) {
versions.push_back(version);
std::sort(versions.begin(), versions.end());
}

inline void VersionList::latest(int max, VersionList& result) const {
Expand Down
6 changes: 4 additions & 2 deletions adlik_serving/framework/manager/managed_store.cc
Expand Up @@ -129,8 +129,10 @@ cub::Status ManagedStore::unload(const ModelId& id) {

cub::Status ManagedStore::unaspired(const ModelId& id) {
auto unaspiring = [&id](AspiredState& state) {
INFO_LOG << "unaspired model" << id.to_s();
state.unaspired();
if (state.wasAspired()) {
INFO_LOG << "unaspired model" << id.to_s();
state.unaspired();
}
return cub::Success;
};
return process(id, unaspiring);
Expand Down
55 changes: 32 additions & 23 deletions model_compiler/src/model_compiler/runtime/compiler_base.py
Expand Up @@ -7,6 +7,7 @@
from abc import abstractmethod
import os
import shutil
import uuid

import tensorflow as tf

Expand Down Expand Up @@ -56,12 +57,13 @@ def __init__(self, config):

self.source_type, self.model_path = self._get_source_model()
self.model_info = ModelInfo(self.model_name, self.max_batch_size, self.source_type)
self.model_dir = self._make_model_dir()
self.version, self.version_dir = self._get_version_dir()
self.target_dir = self._make_target_dir()
self.version_dir = self._make_version_dir()
self.inputs = []
self.outputs = []
self.custom_object = None
_LOGGER.info('Output dir is: %s, version: %s', self.target_dir, self.version)
_LOGGER.info('Output dir is: %s, version: %s', self.model_dir, self.version)

def _get_source_model(self):
if self.h5_path is not None and os.path.exists(self.h5_path):
Expand Down Expand Up @@ -93,31 +95,32 @@ def compile(self):
"""
try:
self._do_compile()
self._export_config()
zip_path = self._compress()
config_path = self._export_config()
os.rename(self.target_dir, self.version_dir)
zip_path = self._compress([self.version_dir, config_path])
return success(zip_path)
except Exception as error: # pylint:disable=broad-except
_LOGGER.error('Compile model failure, error: %s', error)
_LOGGER.exception(error)
shutil.rmtree(self.version_dir)
self._cleanup()
return fail(str(error))

def _export_config(self):
"""
Export config.pbtxt, which use to do inference in servinglite
:return:
"""
exporter = ModelProtoExporter(self.target_dir, self.model_info, self.get_platform)
exporter.export()
exporter = ModelProtoExporter(self.model_dir, self.model_info, self.get_platform)
return exporter.export()

def _compress(self):
def _compress(self, source_list):
"""
Compress model to .zip
:return:
"""
# self.target_dir -> modelName_version.zip
zip_file_path = os.path.join(self.export_path, self.model_name + '_' + str(self.version) + '.zip')
return compress_dir(self.target_dir, zip_file_path)
return compress_dir(source_list, zip_file_path)

def _do_compile(self):
if self.source_type == 'ONNX':
Expand Down Expand Up @@ -159,38 +162,44 @@ def _to_frozen_graph(session, frozen_pb_path, outputs):
_LOGGER.info('_to_frozen_graph:: convert to frozen graph success, output file: %s', frozen_pb_path)
return frozen_pb_path

def _make_target_dir(self):
def _make_model_dir(self):
"""
Make target dir, the structure of export dir is:
Make model dir, the structure of export dir is:
export_dir
└── model_name(target_dir)
└── model_name
├── config.pbtxt
├── version_1(version_dir)
│   └── serving model, TensorRT model or others
└── version_2
   └── serving model, TensorRT model or others
:return:
"""
_LOGGER.info('make_target_dir: export base path: %s', self.export_path)
_LOGGER.info('make_model_dir: export base path: %s', self.export_path)
if not os.path.exists(self.export_path):
os.makedirs(self.export_path, exist_ok=True)
target_dir = os.path.join(self.export_path, self.model_name)
os.makedirs(target_dir, exist_ok=True)
return target_dir
model_dir = os.path.join(self.export_path, self.model_name)
os.makedirs(model_dir, exist_ok=True)
return model_dir

def _make_version_dir(self):
def _get_version_dir(self):
version = getattr(self, "version", None)
if version is None:
self.version = self._get_model_default_version()
self.version = str(self.version)
version_dir = os.path.join(self.target_dir, self.version)
version = self._get_model_default_version()
version = str(version)
version_dir = os.path.join(self.model_dir, version)
_LOGGER.info("Export model version : %s, dir: %s", version, version_dir)
if os.path.exists(version_dir):
raise Exception('Output version is already exist: {}'.format(version_dir))
return version_dir
return version, version_dir

def _make_target_dir(self):
temp_dir_name = str(uuid.uuid3(uuid.NAMESPACE_URL, '_'.join([self.model_name, self.version])))
_LOGGER.info("temporary export dir: %s, %s", temp_dir_name, os.path.join(self.model_dir, temp_dir_name))
return os.path.join(self.model_dir, temp_dir_name)

def _get_model_default_version(self):
sub_dirs = [int(child) for child in os.listdir(self.target_dir)
if os.path.isdir(os.path.join(self.target_dir, child)) and child.isdigit()]
sub_dirs = [int(child) for child in os.listdir(self.model_dir)
if os.path.isdir(os.path.join(self.model_dir, child)) and child.isdigit()]
sub_dirs.sort()
version = str(sub_dirs[-1] + 1) if sub_dirs else "1"
return version
18 changes: 11 additions & 7 deletions model_compiler/src/model_compiler/runtime/compressor.py
Expand Up @@ -9,17 +9,21 @@
import zipfile


def compress_dir(source_dir, zip_file_path):
def compress_dir(source_list, zip_file_path):
"""
Compress a directory into .zip file
:param source_dir: path of directory to be compressed
Compress a source list into .zip file
:param source_list: source path list to be compressed
:param zip_file_path: path of zip file
:return:
"""
zip_file = zipfile.ZipFile(zip_file_path, "w", zipfile.ZIP_DEFLATED)
for path, _, filenames in os.walk(source_dir):
fpath = path.replace(source_dir, '')
for filename in filenames:
zip_file.write(os.path.join(path, filename), os.path.join(fpath, filename))
for source in source_list:
basename = os.path.basename(source)
zip_file.write(source, basename)
if os.path.isdir(source):
for path, _, filenames in os.walk(source):
fpath = path.replace(source, basename)
for filename in filenames:
zip_file.write(os.path.join(path, filename), os.path.join(fpath, filename))
zip_file.close()
return zip_file_path
Expand Up @@ -34,6 +34,7 @@ def export(self):
with open(self._config_path, "w") as config_file:
config_file.write(text_format.MessageToString(config_proto))
_LOGGER.info("Save config.pbtxt success, path: %s", self._config_path)
return self._config_path
else:
raise Exception("Not generate config proto, can't save config.pbtxt!")

Expand Down
Expand Up @@ -23,7 +23,7 @@ class Compiler(BaseCompiler):
def __init__(self, config):
super(Compiler, self).__init__(config)
self.sdk_dir = os.getenv('INTEL_CVSDK_DIR', '/opt/intel/computer_vision_sdk_2018.5.455')
self.frozen_pb_path = os.path.join(self.target_dir, 'frozen.pb')
self.frozen_pb_path = os.path.join(self.model_dir, 'frozen.pb')

def _after_load_model(self, session, inputs, outputs):
return self._to_frozen_graph(session, self.frozen_pb_path, outputs)
Expand All @@ -43,7 +43,7 @@ def _convert_model(self, model_info, model_path):
popenargs = ['python3', convert_file_path]
popenargs.extend(['--input_model', model_path])
popenargs.extend(['--model_name', 'model'])
popenargs.extend(['--output_dir', self.version_dir])
popenargs.extend(['--output_dir', self.target_dir])
popenargs.extend(['--batch', str(model_info.max_batch_size)])
popenargs.extend(['--input', ','.join([i.name for i in model_info.inputs])])
popenargs.extend(['--output', ','.join(o.name for o in model_info.outputs)])
Expand Down
Expand Up @@ -26,11 +26,11 @@ class Compiler(BaseCompiler):

def __init__(self, config):
super(Compiler, self).__init__(config)
self.uff_path = os.path.join(self.target_dir, 'model.uff')
os.makedirs(self.version_dir, exist_ok=True)
self.plan_path = os.path.join(self.version_dir, 'model.plan')
self.uff_path = os.path.join(self.model_dir, 'model.uff')
os.makedirs(self.target_dir, exist_ok=True)
self.plan_path = os.path.join(self.target_dir, 'model.plan')
self.max_workspace_size_byte = 1 << 25
self.frozen_pb_path = os.path.join(self.target_dir, 'frozen.pb')
self.frozen_pb_path = os.path.join(self.model_dir, 'frozen.pb')

def _after_load_model(self, session, inputs, outputs):
return self._to_frozen_graph(session, self.frozen_pb_path, outputs)
Expand Down
2 changes: 1 addition & 1 deletion model_compiler/src/model_compiler/runtime/tf/compiler.py
Expand Up @@ -53,7 +53,7 @@ def _after_load_model(self, session, inputs, outputs):
signature = tf.compat.v1.saved_model.signature_def_utils.predict_signature_def(inputs=inputs_dict,
outputs=outputs_dict)
_LOGGER.info('Create signature def success')
builder = tf.compat.v1.saved_model.builder.SavedModelBuilder(self.version_dir)
builder = tf.compat.v1.saved_model.builder.SavedModelBuilder(self.target_dir)
builder.add_meta_graph_and_variables(sess=session, tags=[tf.saved_model.SERVING],
signature_def_map={'predict': signature}, clear_devices=True)

Expand Down

0 comments on commit bbdd279

Please sign in to comment.