Skip to content

Commit

Permalink
🧹 Enable more ruff rules (#221)
Browse files Browse the repository at this point in the history
* enable pycodestyle

Signed-off-by: Ashwin Vaidya <ashwinnitinvaidya@gmail.com>

* enable more rules

Signed-off-by: Ashwin Vaidya <ashwinnitinvaidya@gmail.com>

* disable pyupgrade

Signed-off-by: Ashwin Vaidya <ashwinnitinvaidya@gmail.com>

* Fix incorrect type check in ListValue validation

Signed-off-by: Ashwin Vaidya <ashwinnitinvaidya@gmail.com>

---------

Signed-off-by: Ashwin Vaidya <ashwinnitinvaidya@gmail.com>
  • Loading branch information
ashwinvaidya17 authored Oct 31, 2024
1 parent 23620d1 commit c5d0dbe
Show file tree
Hide file tree
Showing 16 changed files with 99 additions and 58 deletions.
2 changes: 1 addition & 1 deletion model_api/python/model_api/adapters/inference_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from typing import Any, Dict, List, Set, Tuple
from typing import Any


@dataclass
Expand Down
6 changes: 3 additions & 3 deletions model_api/python/model_api/adapters/openvino_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ def await_any(self) -> None:
def _get_meta_from_ngraph(self, layers_info):
for node in self.model.get_ordered_ops():
layer_name = node.get_friendly_name()
if layer_name not in layers_info.keys():
if layer_name not in layers_info:
continue
layers_info[layer_name].meta = node.get_attributes()
layers_info[layer_name].type = node.get_type_name()
Expand Down Expand Up @@ -339,9 +339,9 @@ def embed_preprocessing(
ppp = PrePostProcessor(self.model)

# Change the input type to the 8-bit image
if dtype == int:
if dtype is int:
ppp.input(input_idx).tensor().set_element_type(Type.u8)
elif dtype == float:
elif dtype is float:
ppp.input(input_idx).tensor().set_element_type(Type.f32)

ppp.input(input_idx).tensor().set_layout(ov.Layout("NHWC")).set_color_format(
Expand Down
2 changes: 1 addition & 1 deletion model_api/python/model_api/adapters/ovms_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ def _verify_model_available(client, model_name, model_version):
def _prepare_inputs(dict_data, inputs_meta):
inputs = {}
for input_name, input_data in dict_data.items():
if input_name not in inputs_meta.keys():
if input_name not in inputs_meta:
raise ValueError("Input data does not match model inputs")
input_info = inputs_meta[input_name]
model_precision = _tf2np_precision[input_info["dtype"]]
Expand Down
2 changes: 1 addition & 1 deletion model_api/python/model_api/adapters/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
from __future__ import annotations # TODO: remove when Python3.9 support is dropped

import math
from collections.abc import Callable
from functools import partial
from typing import Callable, Optional

import cv2
import numpy as np
Expand Down
5 changes: 4 additions & 1 deletion model_api/python/model_api/models/action_classification.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,10 @@ def parameters(cls) -> dict[str, Any]:
description="Path to file with labels. Overrides the labels, if they sets via 'labels' parameter",
),
"mean_values": ListValue(
description="Normalization values, which will be subtracted from image channels for image-input layer during preprocessing",
description=(
"Normalization values, which will be subtracted from image channels "
"for image-input layer during preprocessing"
),
default_value=[],
),
"pad_value": NumericalValue(
Expand Down
9 changes: 7 additions & 2 deletions model_api/python/model_api/models/classification.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,11 @@ def resolve_labels(self, predictions):
"""

def get_predecessors(lbl, candidates):
"""Returns all the predecessors of the input label or an empty list if one of the predecessors is not a candidate."""
"""Return all predecessors.
Returns all the predecessors of the input label or an empty list if one of the predecessors is not a
candidate.
"""
predecessors = []

last_parent = self.label_tree.get_parent(lbl)
Expand Down Expand Up @@ -517,7 +521,8 @@ def _resolve_exclusive_labels(
For labels in `label_to_probability` sets labels that are most likely (maximum probability) in their exclusive
group to 1.0 and other (non-max) labels to probability 0.
"""
# actual exclusive group selection should happen when extracting initial probs (apply argmax to exclusive groups)
# actual exclusive group selection should happen when extracting initial probs
# (apply argmax to exclusive groups)
hard_classification = {}
for label, probability in label_to_probability.items():
hard_classification[label] = float(probability > 0.0)
Expand Down
5 changes: 4 additions & 1 deletion model_api/python/model_api/models/image_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,10 @@ def parameters(cls):
default_value=False,
),
"mean_values": ListValue(
description="Normalization values, which will be subtracted from image channels for image-input layer during preprocessing",
description=(
"Normalization values, which will be subtracted from image "
"channels for image-input layer during preprocessing"
),
default_value=[],
),
"orig_height": NumericalValue(
Expand Down
5 changes: 2 additions & 3 deletions model_api/python/model_api/models/instance_segmentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,8 @@ def postprocess(self, outputs, meta):
output_mask,
),
)
if has_feature_vector_name:
if confidence > self.confidence_threshold:
saliency_maps[cls - 1].append(resized_mask)
if has_feature_vector_name and confidence > self.confidence_threshold:
saliency_maps[cls - 1].append(resized_mask)
return InstanceSegmentationResult(
objects,
_average_and_normalize(saliency_maps),
Expand Down
16 changes: 10 additions & 6 deletions model_api/python/model_api/models/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

import logging as log
import re
from abc import ABC
from contextlib import contextmanager

from model_api.adapters.inference_adapter import InferenceAdapter
Expand Down Expand Up @@ -135,9 +134,11 @@ def create_model(
Args:
model (str): model name from OpenVINO Model Zoo, path to model, OVMS URL
configuration (:obj:`dict`, optional): dictionary of model config with model properties, for example confidence_threshold, labels
configuration (:obj:`dict`, optional): dictionary of model config with model properties, for example
confidence_threshold, labels
model_type (:obj:`str`, optional): name of model wrapper to create (e.g. "ssd")
preload (:obj:`bool`, optional): whether to call load_model(). Can be set to false to reshape model before loading
preload (:obj:`bool`, optional): whether to call load_model(). Can be set to false to reshape model before
loading.
core (optional): openvino.Core instance, passed to OpenvinoAdapter
weights_path (:obj:`str`, optional): path to .bin file with model weights
adaptor_parameters (:obj:`dict`, optional): parameters of ModelAdaptor
Expand All @@ -147,7 +148,8 @@ def create_model(
max_num_requests (:obj:`int`, optional): number of infer requests for asynchronous inference
precision (:obj:`str`, optional): inference precision (e.g. "FP16")
download_dir (:obj:`str`, optional): directory where to store downloaded models
cache_dir (:obj:`str`, optional): directory where to store compiled models to reduce the load time before the inference
cache_dir (:obj:`str`, optional): directory where to store compiled models to reduce the load time before
the inference.
Returns:
Model object
Expand Down Expand Up @@ -482,11 +484,13 @@ def log_layers_info(self):
"""Prints the shape, precision and layout for all model inputs/outputs."""
for name, metadata in self.inputs.items():
self.logger.info(
f"\tInput layer: {name}, shape: {metadata.shape}, precision: {metadata.precision}, layout: {metadata.layout}",
f"\tInput layer: {name}, shape: {metadata.shape}, "
f"precision: {metadata.precision}, layout: {metadata.layout}",
)
for name, metadata in self.outputs.items():
self.logger.info(
f"\tOutput layer: {name}, shape: {metadata.shape}, precision: {metadata.precision}, layout: {metadata.layout}",
f"\tOutput layer: {name}, shape: {metadata.shape}, "
f"precision: {metadata.precision}, layout: {metadata.layout}",
)

def save(self, xml_path, bin_path="", version="UNSPECIFIED"):
Expand Down
5 changes: 4 additions & 1 deletion model_api/python/model_api/models/segmentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,10 @@ def parameters(cls):
),
"soft_threshold": NumericalValue(
value_type=float,
description="Probability threshold value for bounding box filtering. inf value means no blurring and no soft_threshold",
description=(
"Probability threshold value for bounding box filtering. "
"inf value means no blurring and no soft_threshold"
),
default_value=float("-inf"),
),
"return_soft_prediction": BooleanValue(
Expand Down
13 changes: 6 additions & 7 deletions model_api/python/model_api/models/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,12 @@ def validate(self, value):
),
)
return errors
if len(self.choices):
if value not in self.choices:
errors.append(
ConfigurableValueError(
f"Incorrect value {value}: out of allowable list - {self.choices}",
),
)
if len(self.choices) and value not in self.choices:
errors.append(
ConfigurableValueError(
f"Incorrect value {value}: out of allowable list - {self.choices}",
),
)
if self.min is not None and value < self.min:
errors.append(
ConfigurableValueError(
Expand Down
21 changes: 16 additions & 5 deletions model_api/python/model_api/models/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ class ClassificationResult(
def __str__(self):
labels = ", ".join(f"{idx} ({label}): {confidence:.3f}" for idx, label, confidence in self.top_labels)
return (
f"{labels}, [{','.join(str(i) for i in self.saliency_map.shape)}], [{','.join(str(i) for i in self.feature_vector.shape)}], "
f"{labels}, "
f"[{','.join(str(i) for i in self.saliency_map.shape)}], "
f"[{','.join(str(i) for i in self.feature_vector.shape)}], "
f"[{','.join(str(i) for i in self.raw_scores.shape)}]"
)

Expand Down Expand Up @@ -76,7 +78,9 @@ def __str__(self):
obj_str = "; ".join(str(obj) for obj in self.objects)
if obj_str:
obj_str += "; "
return f"{obj_str}[{','.join(str(i) for i in self.saliency_map.shape)}]; [{','.join(str(i) for i in self.feature_vector.shape)}]"
saliency_map_shape = ",".join(str(i) for i in self.saliency_map.shape)
feature_vector_shape = ",".join(str(i) for i in self.feature_vector.shape)
return f"{obj_str}[{saliency_map_shape}]; [{feature_vector_shape}]"


class SegmentedObject(Detection):
Expand Down Expand Up @@ -194,14 +198,18 @@ class DetectedKeypoints(NamedTuple):
scores: np.ndarray

def __str__(self):
return f"keypoints: {self.keypoints.shape}, keypoints_x_sum: {np.sum(self.keypoints[:, :1]):.3f}, scores: {self.scores.shape}"
return (
f"keypoints: {self.keypoints.shape}, "
f"keypoints_x_sum: {np.sum(self.keypoints[:, :1]):.3f}, "
f"scores: {self.scores.shape}"
)


def add_rotated_rects(segmented_objects):
objects_with_rects = []
for segmented_object in segmented_objects:
mask = segmented_object.mask.astype(np.uint8)
contours, hierarchies = cv2.findContours(
contours, _ = cv2.findContours(
mask,
cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE,
Expand Down Expand Up @@ -269,7 +277,10 @@ def __str__(self):
for i, count in enumerate(outHist):
if count > 0:
hist += f"{i}: {count[0] / self.resultImage.size:.3f}, "
return f"{hist}[{','.join(str(i) for i in self.soft_prediction.shape)}], [{','.join(str(i) for i in self.saliency_map.shape)}], [{','.join(str(i) for i in self.feature_vector.shape)}]"
soft_pred_shape = ",".join(str(i) for i in self.soft_prediction.shape)
saliency_map_shape = ",".join(str(i) for i in self.saliency_map.shape)
feature_vector_shape = ",".join(str(i) for i in self.feature_vector.shape)
return f"{hist}[{soft_pred_shape}], " f"[{saliency_map_shape}], " f"[{feature_vector_shape}]"


class DetectionWithLandmarks(Detection):
Expand Down
30 changes: 19 additions & 11 deletions model_api/python/model_api/models/visual_prompting.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ def __init__(
encoder_model (SAMImageEncoder): initialized decoder wrapper
decoder_model (SAMDecoder): initialized encoder wrapper
reference_features (VisualPromptingFeatures | None, optional): Previously generated reference features.
Once the features are passed, one can skip learn() method, and start predicting masks right away. Defaults to None.
Once the features are passed, one can skip learn() method, and start predicting masks right away.
Defaults to None.
threshold (float, optional): Threshold to match vs reference features on infer(). Greater value means a
stricter matching. Defaults to 0.65.
"""
Expand Down Expand Up @@ -213,7 +214,8 @@ def learn(
reset_features (bool, optional): Forces learning from scratch. Defaults to False.
Returns:
tuple[VisualPromptingFeatures, np.ndarray]: return values are the updated VPT reference features and reference masks.
tuple[VisualPromptingFeatures, np.ndarray]: return values are the updated VPT reference features and
reference masks.
The shape of the reference mask is N_labels x H x W, where H and W are the same as in the input image.
"""
if boxes is None and points is None and polygons is None:
Expand Down Expand Up @@ -317,26 +319,32 @@ def infer(
Args:
image (np.ndarray): HWC-shaped image
reference_features (VisualPromptingFeatures | None, optional): Reference features object obtained during previous learn() calls.
If not passed, object internal state is used, which reflects the last learn() call. Defaults to None.
apply_masks_refinement (bool, optional): Flag controlling additional refinement stage on inference. Once enabled, decoder will
be launched 2 extra times to refine the masks obtained with the first decoder call. Defaults to True.
reference_features (VisualPromptingFeatures | None, optional): Reference features object obtained during
previous learn() calls. If not passed, object internal state is used, which reflects the last learn()
call. Defaults to None.
apply_masks_refinement (bool, optional): Flag controlling additional refinement stage on inference.
Once enabled, decoder will be launched 2 extra times to refine the masks obtained with the first decoder
call. Defaults to True.
Returns:
ZSLVisualPromptingResult: Mapping label -> predicted mask. Each mask object contains a list of binary masks, and a list of
related prompts. Each binary mask corresponds to one prompt point. Class mask can be obtained by applying OR operation to all
mask corresponding to one label.
ZSLVisualPromptingResult: Mapping label -> predicted mask. Each mask object contains a list of binary masks,
and a list of related prompts. Each binary mask corresponds to one prompt point. Class mask can be
obtained by applying OR operation to all mask corresponding to one label.
"""
if reference_features is None:
if self._reference_features is None:
raise RuntimeError(
"Reference features are not defined. This parameter can be passed via SAMLearnableVisualPrompter constructor, or as an argument of infer() method",
(
"Reference features are not defined. This parameter can be passed via "
"SAMLearnableVisualPrompter constructor, or as an argument of infer() method"
),
)
reference_feats = self._reference_features

if self._used_indices is None:
raise RuntimeError(
"Used indices are not defined. This parameter can be passed via SAMLearnableVisualPrompter constructor, or as an argument of infer() method",
"Used indices are not defined. This parameter can be passed via "
"SAMLearnableVisualPrompter constructor, or as an argument of infer() method"
)
used_idx = self._used_indices
else:
Expand Down
12 changes: 9 additions & 3 deletions model_api/python/model_api/models/yolo.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ def iou(box_1, box_2):

def _parse_outputs(self, outputs, meta):
detections = []
for layer_name in self.yolo_layer_params.keys():
for layer_name in self.yolo_layer_params:
out_blob = outputs[layer_name]
layer_params = self.yolo_layer_params[layer_name]
out_blob.shape = layer_params[0]
Expand Down Expand Up @@ -630,7 +630,10 @@ def _get_outputs(self):
)
if self.outputs[bboxes_blob_name].shape[1] != self.outputs[scores_blob_name].shape[2]:
self.raise_error(
f"Expected the same dimension for boxes and scores, but got {self.outputs[bboxes_blob_name].shape[1]} and {self.outputs[scores_blob_name].shape[2]}",
(
f"Expected the same dimension for boxes and scores, but got "
f"{self.outputs[bboxes_blob_name].shape[1]} and {self.outputs[scores_blob_name].shape[2]}"
),
)
return bboxes_blob_name, scores_blob_name, indices_blob_name

Expand Down Expand Up @@ -745,7 +748,10 @@ def parameters(cls):
parameters.update(
{
"agnostic_nms": BooleanValue(
description="If True, the model is agnostic to the number of classes, and all classes are considered as one",
description=(
"If True, the model is agnostic to the number of classes, "
"and all classes are considered as one"
),
default_value=False,
),
"iou_threshold": NumericalValue(
Expand Down
2 changes: 1 addition & 1 deletion model_api/python/model_api/pipelines/async_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from time import perf_counter

from ..performance_metrics import PerformanceMetrics
from model_api.performance_metrics import PerformanceMetrics


class AsyncPipeline:
Expand Down
Loading

0 comments on commit c5d0dbe

Please sign in to comment.