Skip to content

Commit

Permalink
Fix config checker for inference element with engine file specified (#…
Browse files Browse the repository at this point in the history
…196)

* Add implicit setup of engine options

* Add skip of calib file check for built engine

* Update car classification sample config
  • Loading branch information
abramov-oleg authored May 4, 2023
1 parent be315d0 commit 6d41cec
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ pipeline:
model:
format: caffe
engine_file: resnet10.caffemodel_b1_gpu0_int8.engine
precision: int8
int8_calib_file: cal_trt.bin
batch_size: 1
input:
scale_factor: 0.0039215697906911373
output:
Expand Down Expand Up @@ -52,9 +49,6 @@ pipeline:
engine_file: resnet18.caffemodel_b16_gpu0_int8.engine
mean_file: mean.ppm
label_file: labels.txt
precision: int8
int8_calib_file: cal_trt.bin
batch_size: 16
input:
object: Primary_Detector.Car
object_min_width: 64
Expand All @@ -74,9 +68,6 @@ pipeline:
engine_file: resnet18.caffemodel_b16_gpu0_int8.engine
mean_file: mean.ppm
label_file: labels.txt
precision: int8
int8_calib_file: cal_trt.bin
batch_size: 16
input:
object: Primary_Detector.Car
object_min_width: 64
Expand All @@ -96,9 +87,6 @@ pipeline:
engine_file: resnet18.caffemodel_b16_gpu0_int8.engine
mean_file: mean.ppm
label_file: labels.txt
precision: int8
int8_calib_file: cal_trt.bin
batch_size: 16
input:
object: Primary_Detector.Car
object_min_width: 64
Expand Down
13 changes: 12 additions & 1 deletion savant/base/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,13 @@ class Model:
"""

batch_size: int = 1
"""Number of frames or objects to be inferred together in a batch."""
"""Number of frames or objects to be inferred together in a batch.
.. note:: In case the model is an NvInferModel and it is configured to
use the TRT engine file directly, the default value for ``batch_size``
will be taken from the engine file name, by parsing it according to the scheme
{model_name}_b{batch_size}_gpu{gpu_id}_{precision}.engine
"""

precision: ModelPrecision = ModelPrecision.FP16
"""Data format to be used by inference.
Expand All @@ -376,6 +382,11 @@ class Model:
precision: fp16
# precision: int8
# precision: fp32
.. note:: In case the model is an NvInferModel and it is configured to
use the TRT engine file directly, the default value for ``precision``
will be taken from the engine file name, by parsing it according to the scheme
{model_name}_b{batch_size}_gpu{gpu_id}_{precision}.engine
"""

input: ModelInput = ModelInput()
Expand Down
95 changes: 72 additions & 23 deletions savant/deepstream/nvinfer/element_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
from typing import Type, Optional
import logging
from omegaconf import OmegaConf, DictConfig
from savant.base.model import ModelPrecision, ObjectModel, AttributeModel
from savant.base.model import (
ModelPrecision,
ObjectModel,
AttributeModel,
ModelColorFormat,
)
from savant.config.schema import get_element_name
from savant.parameter_storage import param_storage
from savant.remote_file import process_remote
Expand Down Expand Up @@ -43,6 +48,7 @@ def process(self, msg, kwargs):
logging.getLogger(__name__), dict(element_name=element_name)
)

logger.debug('Configuring nvinfer element %s', element_config)
# check model type
try:
model_type: Type[NvInferModel] = NVINFER_MODEL_TYPE_REGISTRY.get(
Expand Down Expand Up @@ -78,15 +84,25 @@ def process(self, msg, kwargs):
and model_config.precision
and isinstance(model_config.precision, str)
):
model_config.precision = model_config.precision.upper()
new_val = ModelPrecision[model_config.precision.upper()]
logger.debug(
'Preparing model.precision: %s -> %s', model_config.precision, new_val
)
model_config.precision = new_val
if (
'input' in model_config
and model_config.input
and 'color_format' in model_config.input
and model_config.input.color_format
and isinstance(model_config.input.color_format, str)
):
model_config.input.color_format = model_config.input.color_format.upper()
new_val = ModelColorFormat[model_config.input.color_format.upper()]
logger.debug(
'Preparing model.input.color_format: %s -> %s',
model_config.input.color_format,
new_val,
)
model_config.input.color_format = new_val

# setup path for the model files
if not model_config.get('local_path'):
Expand All @@ -107,6 +123,7 @@ def process(self, msg, kwargs):
nvinfer_config_file = model_config.get('config_file')
if nvinfer_config_file:
config_file_path = model_path / nvinfer_config_file
logger.debug('Trying to load nvinfer config file %s', config_file_path)
if config_file_path.is_file():
nvinfer_config = NvInferConfig.read_file(config_file_path)
logger.info(
Expand All @@ -121,29 +138,60 @@ def process(self, msg, kwargs):
f'Configuration file "{config_file_path}" not found.'
)

model_config = OmegaConf.merge(model, model_config)

# try to parse engine file and check for a match
if model_config.engine_file:
parse_result = NvInferConfig.parse_model_engine_file(model_config.engine_file)
if parse_result and (
model_config.batch_size,
model_config.gpu_id,
model_config.precision,
) != (
parse_result['batch_size'],
parse_result['gpu_id'],
parse_result['precision'],
):
logger.info(
'Specified engine file "%s" does not match configuration: '
'batch_size=%d, gpu_id=%d, precision=%s.',
model_config.engine_file,
if parse_result:
# if engine options are not set explicitly
# get their values from engine file name
if (
not hasattr(model_config, 'batch_size')
or model_config.batch_size is None
):
model_config.batch_size = parse_result['batch_size']
logger.debug(
'Model batch size is taken from engine file name and set to %d',
parse_result['batch_size'],
)
if not hasattr(model_config, 'gpu_id') or model_config.gpu_id is None:
model_config.gpu_id = parse_result['gpu_id']
logger.debug(
'Model gpu_id is taken from engine file name and set to %d',
parse_result['gpu_id'],
)
if not hasattr(model_config, 'precision') or model_config.precision is None:
model_config.precision = parse_result['precision']
logger.debug(
'Model precision is taken from engine file name and set to %s',
parse_result['precision'].name,
)

if (
model_config.batch_size,
model_config.gpu_id,
model_config.precision.name,
)
model_config.engine_file = None
model_config.precision,
) != (
parse_result['batch_size'],
parse_result['gpu_id'],
parse_result['precision'],
):
logger.info(
'Specified engine file "%s" does not match configuration: '
'batch_size=%d, gpu_id=%d, precision=%s.',
model_config.engine_file,
model_config.batch_size,
model_config.gpu_id,
model_config.precision.name,
)
model_config.engine_file = None

logger.debug(
'Merging model with model config\nmodel %s\nmodel config %s',
model,
model_config,
)
model_config = OmegaConf.merge(model, model_config)
logger.debug('Merging complete, result\n%s', model_config)

# model or engine file must be specified
model_file_required = True
Expand Down Expand Up @@ -241,8 +289,9 @@ def process(self, msg, kwargs):
model_config.tlt_model_key,
)

# calibration file required for model in INT8
if model_config.precision == ModelPrecision.INT8:
# model_file_required is True when the engine file is not built
# calibration file is required to build model in INT8
if model_config.precision == ModelPrecision.INT8 and model_file_required:
if not model_config.int8_calib_file:
raise NvInferConfigException(
'INT8 calibration file (model.int8_calib_file) required.'
Expand Down
8 changes: 7 additions & 1 deletion savant/deepstream/nvinfer/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,13 @@ class NvInferModel(Model):
"""Key for the TAO toolkit encoded model."""

gpu_id: int = 0
"""Device ID of GPU to use for pre-processing/inference (dGPU only)."""
"""Device ID of GPU to use for pre-processing/inference (dGPU only).
.. note:: In case the model is configured to
use the TRT engine file directly, the default value for ``gpu_id``
will be taken from the :py:attr:`.engine_file`, by parsing it
according to the scheme {model_name}_b{batch_size}_gpu{gpu_id}_{precision}.engine
"""

# TODO: Add support for custom models.
# Currently it is supported for regular detector and classifier only.
Expand Down

0 comments on commit 6d41cec

Please sign in to comment.