itlab-vision / dl-benchmark

Deep Learning Inference benchmark. Supports OpenVINO™ toolkit, TensorFlow, TensorFlow Lite, ONNX Runtime, OpenCV DNN, MXNet, PyTorch, Apache TVM, ncnn, PaddlePaddle, etc.
http://hpc-education.unn.ru/dli
Apache License 2.0
27 stars 37 forks source link

[TensorFlow] формат saved_model #513

Open ismukhin opened 8 months ago

ismukhin commented 8 months ago

@n-berezina-nn, пытаюсь написать квантизацию nncf. Данный фреймворк поддерживает несколько бэкендов: onnx, pytorch, openvino и tensorflow. Чтобы передать модель для квантизации из tensorflow, нужно сделать так, чтобы загруженная модель была наследником класса tf.Module. Этого можно достичь, если считать saved_model формат через tf.keras.models.load_model(...). Попробовал сконвертировать модели efficientnet-b0, googlenet-v4-tf и densenet-121-tf. Строка для googlenet-v4-tf: python3 tf_converter.py --model_path /home/vanya/projects/dl-benchmark/public/googlenet-v4-tf/inception_v4.frozen.pb --input_name input --output_names InceptionV4/Logits/Predictions Строка для efficientnet-b0: python3 tf_converter.py --model_path /home/vanya/projects/dl-benchmark/public/efficientnet-b0/efficientnet-b0/model.ckpt.meta --input_name sub --output_names logits Модели переходят в этот формат, но в обоих случаях возникают логи:

INFO:tensorflow:No assets to save.
[ INFO ] No assets to save.
INFO:tensorflow:No assets to write.
[ INFO ] No assets to write.

После этого я попытался загрузить модели с помощью tf.keras.models.load_model(...) и выдало такую ошибку:

  File "/home/vanya/projects/dl-benchmark/src/quantization/nncf/model_readers.py", line 63, in _read_model
    mm = tf.keras.models.load_model(Path(self.model_path))
  File "/home/vanya/anaconda3/envs/dl_benchmark_env/lib/python3.9/site-packages/keras/src/saving/saving_api.py", line 262, in load_model
    return legacy_sm_saving_lib.load_model(
  File "/home/vanya/anaconda3/envs/dl_benchmark_env/lib/python3.9/site-packages/keras/src/utils/traceback_utils.py", line 70, in error_handler
    raise e.with_traceback(filtered_tb) from None
  File "/home/vanya/anaconda3/envs/dl_benchmark_env/lib/python3.9/site-packages/keras/src/saving/legacy/saved_model/load.py", line 253, in _generate_object_paths
    for reference in object_graph_def.nodes[current_node].children:
IndexError: list index (0) out of range

Версии библиотек:

tensorflow                   2.15.0
tensorflow-addons            0.22.0
tensorflow-estimator         2.15.0
tensorflow-io-gcs-filesystem 0.34.0
tensorflow-probability       0.22.0

При этом модель densenet-121-tf уже при загрузке через omz была в формате saved_model, ее получилось загрузить через tf.keras.models.load_model(...) и структура saved_model формата идентична тому, что создается скриптом tf_converter.py. В чем может проблема? Заранее спасибо!

ismukhin commented 7 months ago

Разобрался в проблеме: keras и tf не обладают обратной совместимостью, то есть, если модель изначально была в сохранена через tf.saved_model.save, то ее не получится загрузить через tf.keras.models.load_models, но при этом верно обратное: если сохранили через tf.keras.saving.save_model, то мы сможем ее загрузить через tf.saved_model.load и работать с inference_function. С другой стороны, мы можем сделать обертку над inference_function, получаемую через tf.saved_model.loadс помощью tf.Module, однако в общем случае это задача не тривиальная, поскольку существуют отличия, например, между именами операций и слоев, плюс, возвращаясь к nncf, нужны определенные атрибуты класса за что-то отвечающие. После этого действия сохранить как keras модель.