//  [python]
def optimize(model_path, save_path, opt_config=None, data_type=BF16, calib_file=None):
    saved_model = loader_impl._parse_saved_model(model_path)
    tags = saved_model.meta_graphs[0].meta_info_def.tags
    with tf.Session() as sess:
        meta_graph_def = tf.saved_model.loader.load(sess, tags, model_path)
        signature_keys = list(meta_graph_def.signature_def.keys())
        signature_def = meta_graph_def.signature_def[signature_keys[0]]
        model_inputs = [_nd(v.name) for v in signature_def.inputs.values()]
        model_outputs = [_nd(v.name) for v in signature_def.outputs.values()]
        init_op = loader_impl.get_init_op(meta_graph_def)
        if init_op is not None:
            model_outputs.append(init_op.name)
        frozen_gdef = tf.graph_util.convert_variables_to_constants(
            sess, sess.graph_def, model_outputs
        )

        # Embedding & Dense optimization
        dense_opt_dict = dense_opt(sess, frozen_gdef, opt_config, data_type, calib_file)
        variable_path = f'{model_path}/variables/variables'
        embed_opt_dict = embedding_opt(
            sess, frozen_gdef, opt_config, data_type, variable_path
        )
        ev_dict = update_embedding_vars(sess)
        if len(ev_dict) > 0:
            global_step = tf.train.get_global_step()
            model_outputs.append(_nd(global_step.name))
            if isinstance(global_step, tf.Variable):
                sess.run(tf.variables_initializer([global_step]))

        def _extract_sub_graph(outputs):
            graph_def = sess.graph.as_graph_def(add_shapes=True)
            util.remove_underscore_class_attr(graph_def)
            return tf.graph_util.extract_sub_graph(graph_def, outputs)

        def _save(save_path):
            sub_graph_def = _extract_sub_graph(model_inputs + model_outputs)
            node_names = [node.name for node in sub_graph_def.node]
            variables = [v for v in get_all_variables() if _nd(v.name) in node_names]
            init_name = tf.variables_initializer(variables).name
            saver = tf.train.Saver(variables, sharded=True, allow_empty=True)
            saver.save(sess, save_path, write_meta_graph=False, write_state=False)
            return saver, init_name

        # Create Saver
        tmp_path = tempfile.mkdtemp(dir='.')
        variable_path = f'{tmp_path}/variables'
        saver, init_name = _save(variable_path)
        # Optimize embedding variables
        ev_opt_dict, opt_variable_path = embedding_var_opt(
            sess, frozen_gdef, opt_config, data_type, variable_path
        )
        if len(ev_opt_dict) > 0:
            saver, init_name = _save(variable_path)
            variable_path = opt_variable_path

        saver_nodes = [
            saver.saver_def.restore_op_name,
            _nd(saver.saver_def.filename_tensor_name),
            _nd(saver.saver_def.save_tensor_name),
        ]
        outputs = model_inputs + model_outputs + saver_nodes + [init_name]
        graph_def = _extract_sub_graph(outputs)
        graph = sess.graph

    # Create new meta graph def
    new_mgd = create_new_meta_graph_def(graph, meta_graph_def, graph_def, saver)

    # Export saved_model
    tf.reset_default_graph()
    with tf.Session(graph=tf.Graph()) as sess:
        meta_graph.import_scoped_meta_graph(new_mgd)
        restore_feed_dict = {new_mgd.saver_def.filename_tensor_name: variable_path}
        sess.run(new_mgd.saver_def.restore_op_name, restore_feed_dict)
        # Update embedding variables
        update_embedding_vars(sess)
        # Update assets file
        assets_collection = None
        asset_dict = loader_impl.get_asset_tensors(model_path, meta_graph_def)
        if asset_dict is not None:
            for tensor_name, filename in asset_dict.items():
                node_name = _nd(tensor_name)
                if node_name in [nd.name for nd in sess.graph_def.node]:
                    asset_op = sess.graph.get_operation_by_name(node_name)
                    ts_proto = TensorProto(
                        tensor_shape=asset_op.get_attr('value').tensor_shape,
                        dtype=asset_op.get_attr('value').dtype,
                        string_val=[filename],
                    )
                    asset_op._set_attr('value', tf.AttrValue(tensor=ts_proto))
                    asset_name = asset_op.outputs[0]
                else:
                    asset_name = tf.constant(filename, name=node_name)
                tf.add_to_collection(tf.GraphKeys.ASSET_FILEPATHS, asset_name)
            assets_collection = tf.get_collection(tf.GraphKeys.ASSET_FILEPATHS)
        main_op = sess.graph.get_operation_by_name(init_op.name) if init_op else None
        if tf.io.gfile.exists(save_path):
            tf.io.gfile.rmtree(save_path)
        builder = tf.saved_model.builder.SavedModelBuilder(save_path)
        builder.add_meta_graph_and_variables(
            sess=sess,
            tags=new_mgd.meta_info_def.tags,
            signature_def_map=new_mgd.signature_def,
            assets_collection=assets_collection,
            main_op=main_op,
        )
        clear_saver_devices(builder._saved_model.meta_graphs[0], meta_graph_def)
        builder.save()
        if len(ev_opt_dict) > 0:
            target_path = f'{save_path}/variables'
            tf.io.gfile.rmtree(target_path)
            _recursive_copy(os.path.dirname(variable_path), target_path)
            tf.io.gfile.rmtree(os.path.dirname(variable_path))
        tf.io.gfile.rmtree(tmp_path)

        print('Optmization Result:')
        for key, value in dense_opt_dict.items():
            print(f'Optimize dense op to {value[-1]}: {key}')
        for key, value in embed_opt_dict.items():
            print(f'Optimize embedding to {value[-1]}: {key}')
        for key, value in ev_opt_dict.items():
            print(f'Optimize embedding variable to {value[-1]}: {key}')