> For the complete documentation index, see [llms.txt](https://docs.degirum.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.degirum.com/hailo/basics/specifying-a-model/model-properties.md).

# Model properties

See what you can tune on your model—and why it matters. This page introduces the model\_properties field and shows how to inspect, change, and group model settings by task.

*Estimated read time: 5 minutes*

This section focuses on the `model_properties` field in `ModelSpec` (and the matching writable properties on the `model` after loading). It shows what you can change on a DeGirum model and why—without drowning you in code.

First, quickly inspect your model to see which attributes are writable on your build. Then jump into focused subpages:

* [Device selection](/hailo/intermediate-guides/model-properties/device-selection.md): pick hardware targets, batching, queues, and timeouts
* [Input preprocessing](/hailo/intermediate-guides/model-properties/input-preprocessing.md): control resize, crop, pad, and colorspace handling
* [Output postprocessing](/hailo/intermediate-guides/model-properties/output-postprocessing.md): adjust confidence thresholds, NMS, class filters, and caps
* [Image overlay](/hailo/intermediate-guides/model-properties/image-overlay.md): tune how detections render in demos or reviews

## Two ways to specify model properties

* **During load (stable defaults)**: pass durable choices via `ModelSpec(model_properties={...})`. Great for reproducible runs and team consistency.
* **After load (live tuning)**: set `model.<property>` at runtime to explore and iterate.

{% hint style="success" %}
Use `ModelSpec` for hardware and standard preprocessing choices.

Use the live model for tuning outputs, overlays, and experiments.
{% endhint %}

## Inspect your model

After loading a model, run:

{% code overflow="wrap" %}

```python
# What attributes & methods exist?
dir(model)
```

{% endcode %}

You'll see output like this:

{% code overflow="wrap" %}

```python
[
    "__call__",
    "custom_postprocessor",
    "device_type",
    "devices_available",
    "devices_selected",
    "eager_batch_size",
    "extra_device_params",
    "frame_queue_depth",
    "image_backend",
    "inference_results_type",
    "inference_timeout_s",
    "input_crop_percentage",
    "input_image_format",
    "input_letterbox_fill_color",
    "input_numpy_colorspace",
    "input_pad_method",
    "input_resize_method",
    "input_shape",
    "label_dictionary",
    "measure_time",
    "model_info",
    "non_blocking_batch_predict",
    "output_class_set",
    "output_confidence_threshold",
    "output_max_classes_per_detection",
    "output_max_detections",
    "output_max_detections_per_class",
    "output_nms_threshold",
    "output_pose_threshold",
    "output_postprocess_type",
    "output_top_k",
    "output_use_regular_nms",
    "overlay_alpha",
    "overlay_blur",
    "overlay_color",
    "overlay_font_scale",
    "overlay_line_width",
    "overlay_show_labels",
    "overlay_show_probabilities",
    "predict",
    "predict_batch",
    "predict_dir",
    "reset_time_stats",
    "save_model_image",
    "supported_device_types",
    "time_stats",
]
```

{% endcode %}

To check which ones are writable, use this helper:

{% code overflow="wrap" %}

```python
def list_properties_with_setters(obj):
    ro, rw = [], []
    cls = obj.__class__
    for name in dir(cls):
        attr = getattr(cls, name, None)
        if isinstance(attr, property):
            (ro if attr.fset is None else rw).append(name)
    return ro, rw


ro, rw = list_properties_with_setters(model)
print("READ‑ONLY:", sorted(ro))
print("WRITABLE:", sorted(rw))
```

{% endcode %}

Running this function on a loaded model will output:

* `READ-ONLY`: properties you can inspect but can't modify
* `WRITABLE`: properties you can update at runtime

{% code overflow="wrap" %}

```python
READ‑ONLY: [
    "devices_available",
    "label_dictionary",
    "model_info",
    "supported_device_types",
]
WRITABLE: [
    "custom_postprocessor",
    "device_type",
    "devices_selected",
    "eager_batch_size",
    "extra_device_params",
    "frame_queue_depth",
    "image_backend",
    "inference_results_type",
    "inference_timeout_s",
    "input_crop_percentage",
    "input_image_format",
    "input_letterbox_fill_color",
    "input_numpy_colorspace",
    "input_pad_method",
    "input_resize_method",
    "input_shape",
    "measure_time",
    "non_blocking_batch_predict",
    "output_class_set",
    "output_confidence_threshold",
    "output_max_classes_per_detection",
    "output_max_detections",
    "output_max_detections_per_class",
    "output_nms_threshold",
    "output_pose_threshold",
    "output_postprocess_type",
    "output_top_k",
    "output_use_regular_nms",
    "overlay_alpha",
    "overlay_blur",
    "overlay_color",
    "overlay_font_scale",
    "overlay_line_width",
    "overlay_show_labels",
    "overlay_show_probabilities",
    "save_model_image",
]
```

{% endcode %}

{% hint style="info" %}
Treat this output as ground truth for your build. Use it to verify assumptions before wiring up UI elements or CLI options based on these properties.
{% endhint %}

## What’s changeable—by category

Use this section as a reference. The most common writable properties are grouped by use case. Confirm actual writability using your own read-only (ro) / read/write (rw) output.

#### [Device selection & runtime](/hailo/intermediate-guides/model-properties/device-selection.md)

* **Target runtime(s)**: `device_type` (str | list\[str]) – set hardware preferences; if a list, the first available is selected
* **Choose indices**: `devices_selected` (list\[int]) – which device IDs to run on
* **Discoveries (inspect)**: `supported_device_types` (ro), `devices_available` (ro)
* **Latency/throughput knobs**: `eager_batch_size`, `frame_queue_depth`, `inference_timeout_s`, `non_blocking_batch_predict`
* **Runtime-specific knobs**: `extra_device_params` (dict) – pass vendor settings such as `{"HAILO_BATCH_SIZE": 8}`; overrides `eager_batch_size` on Hailo runtimes

#### [Input preprocessing](/hailo/intermediate-guides/model-properties/input-preprocessing.md)

* **Resize strategy**: `input_pad_method` – `"stretch"`, `"letterbox"` (default), `"crop-first"`, `"crop-last"`
* **Interpolation**: `input_resize_method` – `"bilinear"` (default) `"nearest"`, `"area"`, `"bicubic"`, `"lanczos"`
* **Cropping control**: `input_crop_percentage` – for crop‑first/crop‑last modes
* **Pad color**: `input_letterbox_fill_color` – defaults to black; use `(114,114,114)` for neutral gray
* **Colorspace/format**: `input_numpy_colorspace` (RGB/BGR), `input_image_format`
* **Image library**: `image_backend` – `"opencv"` (default), `"pil"`
* **Extras:** `save_model_image`
* **Model‑fixed (often ro)**: `input_shape`

#### [Output postprocessing](/hailo/intermediate-guides/model-properties/output-postprocessing.md)

* **Filter thresholds**: `output_confidence_threshold`, `output_nms_threshold`
* **Caps**: `output_max_detections`, `output_max_detections_per_class`, `output_max_classes_per_detection`, `output_top_k`
* **Focus filters**: `output_class_set`
* **Advanced controls**: `output_use_regular_nms`, `output_postprocess_type`, `output_pose_threshold`, `inference_results_type`, `custom_postprocessor`

#### [Image overlay](/hailo/intermediate-guides/model-properties/image-overlay.md) (rendering-only)

* **Toggles**: `overlay_show_labels`, `overlay_show_probabilities`
* **Styling**: `overlay_line_width`, `overlay_font_scale`, `overlay_alpha`, `overlay_color`, `overlay_blur`

#### Time statistics

* **Enable/disable**: `measure_time`
* **Read stats**: `time_stats` (ro)
* **Reset**: `reset_time_stats`

#### Predict APIs (reference-only)

* **Sync**: `predict`, `__call__`
* **Batch**: `predict_batch`
* **Folders**: `predict_dir`

{% hint style="info" %}
You’ll also see helpful read-only properties like `label_dictionary`, and `model_info`.
{% endhint %}
