Show message with suggestion to try legacy FE in case of conversion error (#17088)
* Moved exception checks to _convert(), added suggestion to try legacy TF in case of conversion fail. * Added test. * Added send_conversion_result() method. * Small correction. * Update tools/mo/openvino/tools/mo/convert_impl.py Co-authored-by: Roman Kazantsev <roman.kazantsev@intel.com> * Moved test_suggest_legacy_fe() test to check_info_messages_test.py. * Removed not needed import. * Small correction. --------- Co-authored-by: Roman Kazantsev <roman.kazantsev@intel.com>
This commit is contained in:
parent
57d4ca27e6
commit
acd424bb5e
@ -348,6 +348,6 @@ def convert_model(
|
||||
del params['args']
|
||||
params.update(args)
|
||||
cli_parser = get_all_cli_parser()
|
||||
ov_model, _ = _convert(cli_parser, framework, params)
|
||||
ov_model, _ = _convert(cli_parser, framework, params, True)
|
||||
restore_logger_state(logger_state)
|
||||
return ov_model
|
||||
|
@ -7,6 +7,7 @@ import logging as log
|
||||
import os
|
||||
import platform
|
||||
import sys
|
||||
import traceback
|
||||
from collections import OrderedDict
|
||||
from copy import deepcopy
|
||||
from distutils.version import LooseVersion
|
||||
@ -36,14 +37,17 @@ from openvino.tools.mo.utils.cli_parser import check_available_transforms, \
|
||||
get_model_name_from_args, depersonalize, get_mo_convert_params, input_to_input_cut_info, \
|
||||
input_shape_to_input_cut_info, freeze_placeholder_to_input_cut_info
|
||||
|
||||
from openvino.tools.mo.utils.error import Error
|
||||
from openvino.tools.mo.utils.error import Error, FrameworkError
|
||||
from openvino.tools.mo.utils.get_ov_update_message import get_ov_update_message, get_ov_api20_message, \
|
||||
get_tf_fe_message, get_try_legacy_fe_message, get_compression_message
|
||||
from openvino.tools.mo.utils.model_analysis import AnalysisResults
|
||||
from openvino.tools.mo.utils.version import VersionChecker
|
||||
from openvino.tools.mo.utils.guess_framework import deduce_legacy_frontend_by_namespace
|
||||
from openvino.tools.mo.utils.logger import init_logger, progress_printer
|
||||
from openvino.tools.mo.utils.utils import refer_to_faq_msg
|
||||
from openvino.tools.mo.utils.telemetry_utils import send_params_info, send_framework_info
|
||||
from openvino.tools.mo.utils.telemetry_utils import send_params_info, send_framework_info, send_conversion_result, \
|
||||
get_tid
|
||||
from openvino.tools.mo.utils.versions_checker import check_requirements, get_environment_setup # pylint: disable=no-name-in-module
|
||||
from openvino.tools.mo.utils.telemetry_utils import get_tid
|
||||
from openvino.tools.mo.moc_frontend.check_config import legacy_extensions_used
|
||||
from openvino.tools.mo.moc_frontend.pytorch_frontend_utils import get_pytorch_decoder, convert_pytorch_via_onnx
|
||||
from openvino.tools.mo.moc_frontend.shape_utils import parse_input_shapes, get_static_shape
|
||||
@ -812,10 +816,8 @@ def pack_params_to_args_namespace(args: dict, cli_parser: argparse.ArgumentParse
|
||||
# so we need to set them in argv separately
|
||||
if value is not None and getattr(argv, key, None) != value:
|
||||
setattr(argv, key, value)
|
||||
argv.is_python_api_used = True
|
||||
else:
|
||||
argv = cli_parser.parse_args()
|
||||
argv.is_python_api_used = False
|
||||
return argv
|
||||
|
||||
|
||||
@ -835,7 +837,20 @@ def update_args_for_saved_model_dir(args: dict):
|
||||
args['input_model'] = None
|
||||
|
||||
|
||||
def _convert(cli_parser: argparse.ArgumentParser, framework, args):
|
||||
def silent_is_false(argv: argparse.Namespace):
|
||||
return argv is not None and hasattr(argv, 'silent') and argv.silent is False
|
||||
|
||||
|
||||
def framework_is_tf(args, argv):
|
||||
if input_model_is_object(args) and check_model_object(args) == "tf":
|
||||
return True
|
||||
if argv is not None:
|
||||
is_tf, _, _, _, _ = deduce_legacy_frontend_by_namespace(argv)
|
||||
return is_tf
|
||||
return False
|
||||
|
||||
|
||||
def _convert(cli_parser: argparse.ArgumentParser, framework, args, python_api_used):
|
||||
if 'help' in args and args['help']:
|
||||
show_mo_convert_help()
|
||||
return None, None
|
||||
@ -846,6 +861,7 @@ def _convert(cli_parser: argparse.ArgumentParser, framework, args):
|
||||
# Initialize logger with 'ERROR' as default level to be able to form nice messages
|
||||
# before arg parser deliver log_level requested by user
|
||||
init_logger('ERROR', False)
|
||||
argv = None
|
||||
try:
|
||||
model_framework = None
|
||||
inp_model_is_object = input_model_is_object(args)
|
||||
@ -869,6 +885,7 @@ def _convert(cli_parser: argparse.ArgumentParser, framework, args):
|
||||
update_args_for_saved_model_dir(args)
|
||||
|
||||
argv = pack_params_to_args_namespace(args, cli_parser)
|
||||
argv.is_python_api_used = python_api_used
|
||||
|
||||
argv.feManager = FrontEndManager()
|
||||
frameworks = list(set(['tf', 'caffe', 'mxnet', 'kaldi', 'onnx'] + (get_available_front_ends(argv.feManager)
|
||||
@ -909,12 +926,54 @@ def _convert(cli_parser: argparse.ArgumentParser, framework, args):
|
||||
for key, value in non_default_params.items():
|
||||
ov_model.set_rt_info(str(value), ["conversion_parameters", str(key)])
|
||||
|
||||
telemetry.send_event('mo', 'conversion_result', 'success')
|
||||
telemetry.end_session('mo')
|
||||
telemetry.force_shutdown(1.0)
|
||||
if silent_is_false(argv) or not python_api_used:
|
||||
if 'compress_to_fp16' in argv and argv.compress_to_fp16:
|
||||
print(get_compression_message())
|
||||
|
||||
ov_update_message = get_ov_update_message()
|
||||
ov_api20_message = get_ov_api20_message()
|
||||
if ov_update_message is not None:
|
||||
print(ov_update_message)
|
||||
if ov_api20_message is not None and ov_model is not None:
|
||||
print(ov_api20_message)
|
||||
is_fallback = getattr(argv, 'is_fallback', False)
|
||||
if not argv.use_legacy_frontend and framework_is_tf(args, argv) and not is_fallback:
|
||||
# now TF FE is default frontend for TensorFlow models conversion
|
||||
print(get_tf_fe_message())
|
||||
|
||||
send_conversion_result('success')
|
||||
return ov_model, argv
|
||||
|
||||
except Exception as e:
|
||||
telemetry.send_event('mo', 'conversion_result', 'fail')
|
||||
telemetry.end_session('mo')
|
||||
telemetry.force_shutdown(1.0)
|
||||
raise e.with_traceback(None)
|
||||
if silent_is_false(argv) or not python_api_used:
|
||||
if isinstance(e, (FileNotFoundError, NotADirectoryError)):
|
||||
log.error('File {} was not found'.format(str(e).split('No such file or directory:')[1]))
|
||||
log.debug(traceback.format_exc())
|
||||
elif isinstance(e, Error):
|
||||
analysis_results = AnalysisResults()
|
||||
if analysis_results.get_messages() is not None:
|
||||
for el in analysis_results.get_messages():
|
||||
log.error(el, extra={'analysis_info': True})
|
||||
log.error(e)
|
||||
log.debug(traceback.format_exc())
|
||||
elif isinstance(e, FrameworkError):
|
||||
log.error(e, extra={'framework_error': True})
|
||||
log.debug(traceback.format_exc())
|
||||
else:
|
||||
log.error("-------------------------------------------------")
|
||||
log.error("----------------- INTERNAL ERROR ----------------")
|
||||
log.error("Unexpected exception happened.")
|
||||
log.error("Please contact Model Optimizer developers and forward the following information:")
|
||||
log.error(str(e))
|
||||
log.error(traceback.format_exc())
|
||||
log.error("---------------- END OF BUG REPORT --------------")
|
||||
log.error("-------------------------------------------------")
|
||||
is_fallback = getattr(argv, 'is_fallback', False) if argv is not None else False
|
||||
if not argv.use_legacy_frontend and framework_is_tf(args, argv) and not is_fallback:
|
||||
print(get_try_legacy_fe_message())
|
||||
|
||||
send_conversion_result('fail')
|
||||
if python_api_used:
|
||||
raise e.with_traceback(None)
|
||||
else:
|
||||
return None, argv
|
||||
|
@ -2,7 +2,6 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import argparse
|
||||
import logging as log
|
||||
import os
|
||||
import sys
|
||||
|
||||
@ -10,69 +9,15 @@ try:
|
||||
import openvino_telemetry as tm
|
||||
except ImportError:
|
||||
import openvino.tools.mo.utils.telemetry_stub as tm
|
||||
from openvino.tools.mo.utils.get_ov_update_message import get_compression_message
|
||||
from openvino.tools.mo.convert_impl import _convert
|
||||
from openvino.tools.mo.pipeline.common import get_ir_version
|
||||
from openvino.tools.mo.utils.logger import init_logger
|
||||
from openvino.tools.mo.utils.error import Error, FrameworkError
|
||||
import traceback
|
||||
from openvino.tools.mo.utils.get_ov_update_message import get_ov_update_message, get_ov_api20_message, \
|
||||
get_tf_fe_message
|
||||
from openvino.tools.mo.utils.model_analysis import AnalysisResults
|
||||
from openvino.tools.mo.utils.guess_framework import deduce_legacy_frontend_by_namespace
|
||||
|
||||
# pylint: disable=no-name-in-module,import-error
|
||||
from openvino.frontend import FrontEndManager
|
||||
from openvino.runtime import serialize
|
||||
|
||||
|
||||
def main(cli_parser: argparse.ArgumentParser, framework=None):
|
||||
# Initialize logger with 'ERROR' as default level to be able to form nice messages
|
||||
# before arg parser deliver log_level requested by user
|
||||
init_logger('ERROR', False)
|
||||
|
||||
ngraph_function = None
|
||||
argv = None
|
||||
try:
|
||||
ngraph_function, argv = _convert(cli_parser, framework, {})
|
||||
is_tf, _, _, _, _ = deduce_legacy_frontend_by_namespace(argv)
|
||||
if 'compress_to_fp16' in argv and argv.compress_to_fp16:
|
||||
print(get_compression_message())
|
||||
|
||||
ov_update_message = get_ov_update_message()
|
||||
ov_api20_message = get_ov_api20_message()
|
||||
if ov_update_message is not None:
|
||||
print(ov_update_message)
|
||||
if ov_api20_message is not None and ngraph_function is not None:
|
||||
print(ov_api20_message)
|
||||
is_fallback = getattr(argv, 'is_fallback', False)
|
||||
if not argv.use_legacy_frontend and is_tf and not is_fallback:
|
||||
# now TF FE is default frontend for TensorFlow models conversion
|
||||
print(get_tf_fe_message())
|
||||
|
||||
except (FileNotFoundError, NotADirectoryError) as e:
|
||||
log.error('File {} was not found'.format(str(e).split('No such file or directory:')[1]))
|
||||
log.debug(traceback.format_exc())
|
||||
except Error as err:
|
||||
analysis_results = AnalysisResults()
|
||||
if analysis_results.get_messages() is not None:
|
||||
for el in analysis_results.get_messages():
|
||||
log.error(el, extra={'analysis_info': True})
|
||||
log.error(err)
|
||||
log.debug(traceback.format_exc())
|
||||
except FrameworkError as err:
|
||||
log.error(err, extra={'framework_error': True})
|
||||
log.debug(traceback.format_exc())
|
||||
except Exception as err:
|
||||
log.error("-------------------------------------------------")
|
||||
log.error("----------------- INTERNAL ERROR ----------------")
|
||||
log.error("Unexpected exception happened.")
|
||||
log.error("Please contact Model Optimizer developers and forward the following information:")
|
||||
log.error(str(err))
|
||||
log.error(traceback.format_exc())
|
||||
log.error("---------------- END OF BUG REPORT --------------")
|
||||
log.error("-------------------------------------------------")
|
||||
|
||||
ngraph_function, argv = _convert(cli_parser, framework, {}, False)
|
||||
if ngraph_function is None:
|
||||
return 1
|
||||
|
||||
|
@ -138,7 +138,7 @@ def convert_pytorch_via_onnx(args, example_inputs, cli_parser, framework, main_c
|
||||
|
||||
args['input_model'] = model_onnx
|
||||
|
||||
ov_model, argv = main_convert(cli_parser, framework, args)
|
||||
ov_model, argv = main_convert(cli_parser, framework, args, True)
|
||||
except Exception as e:
|
||||
raise e
|
||||
finally:
|
||||
|
@ -41,3 +41,8 @@ def get_compression_message():
|
||||
'by removing argument --compress_to_fp16 or set it to false --compress_to_fp16=False.\n' \
|
||||
'Find more information about compression to FP16 at {}'.format(link)
|
||||
return message
|
||||
|
||||
|
||||
def get_try_legacy_fe_message():
|
||||
message = '[ INFO ] You can also try to use legacy TensorFlow Frontend by using argument --use_legacy_frontend.\n'
|
||||
return message
|
||||
|
@ -103,3 +103,11 @@ def get_tid():
|
||||
This function returns the ID of the database to send telemetry.
|
||||
"""
|
||||
return telemetry_params['TID']
|
||||
|
||||
|
||||
def send_conversion_result(conversion_result: str, need_shutdown=True):
|
||||
t = tm.Telemetry()
|
||||
t.send_event('mo', 'conversion_result', conversion_result)
|
||||
t.end_session('mo')
|
||||
if need_shutdown:
|
||||
t.force_shutdown(1.0)
|
||||
|
@ -9,7 +9,8 @@ from contextlib import redirect_stdout
|
||||
from unittest.mock import patch
|
||||
|
||||
from openvino.tools.mo.main import main
|
||||
from openvino.tools.mo.utils.get_ov_update_message import get_tf_fe_message, get_compression_message
|
||||
from openvino.tools.mo.utils.get_ov_update_message import get_tf_fe_message, get_compression_message, \
|
||||
get_try_legacy_fe_message
|
||||
|
||||
|
||||
def arg_parse_helper(input_model,
|
||||
@ -68,6 +69,22 @@ class TestInfoMessagesTFFE(unittest.TestCase):
|
||||
tf_fe_message_found = get_tf_fe_message() in std_out
|
||||
assert tf_fe_message_found
|
||||
|
||||
@patch('openvino.tools.mo.convert_impl.driver', side_effect=Exception('MESSAGE'))
|
||||
def run_fail_tf_fe(self, mock_driver):
|
||||
from openvino.tools.mo import convert_model
|
||||
path = os.path.dirname(__file__)
|
||||
convert_model(os.path.join(path, "test_models", "model_int32.pbtxt"), silent=False)
|
||||
|
||||
def test_suggest_legacy_fe(self):
|
||||
f = io.StringIO()
|
||||
with redirect_stdout(f):
|
||||
try:
|
||||
self.run_fail_tf_fe()
|
||||
except:
|
||||
pass
|
||||
std_out = f.getvalue()
|
||||
assert get_try_legacy_fe_message() in std_out
|
||||
|
||||
|
||||
class TestInfoMessagesTFFEWithFallback(unittest.TestCase):
|
||||
@patch('argparse.ArgumentParser.parse_args',
|
||||
|
Loading…
Reference in New Issue
Block a user