-
Notifications
You must be signed in to change notification settings - Fork 240
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
### Changes - Add pattern based on file extension to gitignore for examples - Use pathlib style instead os.path - Fix issue with creating ../nncf/~/.cache/datasets directory - Replace tqdm to nncf.common.logging.track_progress - Remove unused function arguments and if conditions - Clean logs, disable progress bar, remove log of validataion - Pass list of command arguments to subprocess instead of string - Remove nncf dependencies from tests/cross_fw/examples - Add `--reuse-venv` to use venv from example directory - Add progress bar to collect_values_for_each_item_using_prepared_model ### Tests https://github.com/openvinotoolkit/nncf/actions/runs/11900403097 nightly/job/test_examples/618 nightly/job/windows/job/test-examples/278/
- Loading branch information
1 parent
75ba2f7
commit b1ea59d
Showing
22 changed files
with
349 additions
and
320 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,28 +13,32 @@ | |
from pathlib import Path | ||
from typing import Any, Dict, Tuple | ||
|
||
import numpy as np | ||
import onnx | ||
import onnxruntime | ||
import torch | ||
from tqdm import tqdm | ||
from rich.progress import track | ||
from ultralytics.cfg import get_cfg | ||
from ultralytics.data.converter import coco80_to_coco91_class | ||
from ultralytics.data.utils import check_det_dataset | ||
from ultralytics.engine.validator import BaseValidator as Validator | ||
from ultralytics.models.yolo import YOLO | ||
from ultralytics.models.yolo.segment.val import SegmentationValidator | ||
from ultralytics.utils import DATASETS_DIR | ||
from ultralytics.utils import DEFAULT_CFG | ||
from ultralytics.utils import ops | ||
from ultralytics.utils.metrics import ConfusionMatrix | ||
|
||
import nncf | ||
|
||
MODEL_NAME = "yolov8n-seg" | ||
|
||
ROOT = Path(__file__).parent.resolve() | ||
|
||
|
||
def validate( | ||
model: onnx.ModelProto, data_loader: torch.utils.data.DataLoader, validator: Validator, num_samples: int = None | ||
model: onnx.ModelProto, | ||
data_loader: torch.utils.data.DataLoader, | ||
validator: SegmentationValidator, | ||
num_samples: int = None, | ||
) -> Tuple[Dict, int, int]: | ||
validator.seen = 0 | ||
validator.jdict = [] | ||
|
@@ -49,7 +53,7 @@ def validate( | |
output_names = [output.name for output in session.get_outputs()] | ||
num_outputs = len(output_names) | ||
|
||
for batch_i, batch in enumerate(data_loader): | ||
for batch_i, batch in enumerate(track(data_loader, description="Validating")): | ||
if num_samples is not None and batch_i == num_samples: | ||
break | ||
batch = validator.preprocess(batch) | ||
|
@@ -71,7 +75,7 @@ def validate( | |
return stats, validator.seen, validator.nt_per_class.sum() | ||
|
||
|
||
def print_statistics(stats: np.ndarray, total_images: int, total_objects: int) -> None: | ||
def print_statistics(stats: Dict[str, float], total_images: int, total_objects: int) -> None: | ||
print("Metrics(Box):") | ||
mp, mr, map50, mean_ap = ( | ||
stats["metrics/precision(B)"], | ||
|
@@ -84,38 +88,35 @@ def print_statistics(stats: np.ndarray, total_images: int, total_objects: int) - | |
pf = "%20s" + "%12i" * 2 + "%12.3g" * 4 # print format | ||
print(pf % ("all", total_images, total_objects, mp, mr, map50, mean_ap)) | ||
|
||
# print the mask metrics for segmentation | ||
if "metrics/precision(M)" in stats: | ||
print("Metrics(Mask):") | ||
s_mp, s_mr, s_map50, s_mean_ap = ( | ||
stats["metrics/precision(M)"], | ||
stats["metrics/recall(M)"], | ||
stats["metrics/mAP50(M)"], | ||
stats["metrics/mAP50-95(M)"], | ||
) | ||
# Print results | ||
s = ("%20s" + "%12s" * 6) % ("Class", "Images", "Labels", "Precision", "Recall", "[email protected]", "[email protected]:.95") | ||
print(s) | ||
pf = "%20s" + "%12i" * 2 + "%12.3g" * 4 # print format | ||
print(pf % ("all", total_images, total_objects, s_mp, s_mr, s_map50, s_mean_ap)) | ||
|
||
|
||
def prepare_validation(model: YOLO, args: Any) -> Tuple[Validator, torch.utils.data.DataLoader]: | ||
validator = model.task_map[model.task]["validator"](args=args) | ||
validator.data = check_det_dataset(args.data) | ||
validator.stride = 32 | ||
print("Metrics(Mask):") | ||
s_mp, s_mr, s_map50, s_mean_ap = ( | ||
stats["metrics/precision(M)"], | ||
stats["metrics/recall(M)"], | ||
stats["metrics/mAP50(M)"], | ||
stats["metrics/mAP50-95(M)"], | ||
) | ||
# Print results | ||
s = ("%20s" + "%12s" * 6) % ("Class", "Images", "Labels", "Precision", "Recall", "[email protected]", "[email protected]:.95") | ||
print(s) | ||
pf = "%20s" + "%12i" * 2 + "%12.3g" * 4 # print format | ||
print(pf % ("all", total_images, total_objects, s_mp, s_mr, s_map50, s_mean_ap)) | ||
|
||
data_loader = validator.get_dataloader(f"{DATASETS_DIR}/coco128-seg", 1) | ||
|
||
def prepare_validation(model: YOLO, args: Any) -> Tuple[SegmentationValidator, torch.utils.data.DataLoader]: | ||
validator: SegmentationValidator = model.task_map[model.task]["validator"](args=args) | ||
validator.data = check_det_dataset(args.data) | ||
validator.stride = 32 | ||
validator.is_coco = True | ||
validator.class_map = coco80_to_coco91_class() | ||
validator.names = model.model.names | ||
validator.metrics.names = validator.names | ||
validator.nc = model.model.model[-1].nc | ||
validator.nm = 32 | ||
validator.process = ops.process_mask | ||
validator.plot_masks = [] | ||
|
||
coco_data_path = DATASETS_DIR / "coco128-seg" | ||
data_loader = validator.get_dataloader(coco_data_path.as_posix(), 1) | ||
|
||
return validator, data_loader | ||
|
||
|
||
|
@@ -129,7 +130,7 @@ def prepare_onnx_model(model: YOLO, model_name: str) -> Tuple[onnx.ModelProto, P | |
|
||
|
||
def quantize_ac( | ||
model: onnx.ModelProto, data_loader: torch.utils.data.DataLoader, validator_ac: Validator | ||
model: onnx.ModelProto, data_loader: torch.utils.data.DataLoader, validator_ac: SegmentationValidator | ||
) -> onnx.ModelProto: | ||
input_name = model.graph.input[0].name | ||
|
||
|
@@ -140,7 +141,7 @@ def transform_fn(data_item: Dict): | |
def validation_ac( | ||
val_model: onnx.ModelProto, | ||
validation_loader: torch.utils.data.DataLoader, | ||
validator: Validator, | ||
validator: SegmentationValidator, | ||
num_samples: int = None, | ||
) -> float: | ||
validator.seen = 0 | ||
|
@@ -155,7 +156,6 @@ def validation_ac( | |
output_names = [output.name for output in session.get_outputs()] | ||
num_outputs = len(output_names) | ||
|
||
counter = 0 | ||
for batch_i, batch in enumerate(validation_loader): | ||
if num_samples is not None and batch_i == num_samples: | ||
break | ||
|
@@ -172,13 +172,12 @@ def validation_ac( | |
] | ||
preds = validator.postprocess(preds) | ||
validator.update_metrics(preds, batch) | ||
counter += 1 | ||
|
||
stats = validator.get_stats() | ||
if num_outputs == 1: | ||
stats_metrics = stats["metrics/mAP50-95(B)"] | ||
else: | ||
stats_metrics = stats["metrics/mAP50-95(M)"] | ||
print(f"Validate: dataset length = {counter}, metric value = {stats_metrics:.3f}") | ||
return stats_metrics, None | ||
|
||
quantization_dataset = nncf.Dataset(data_loader, transform_fn) | ||
|
@@ -213,8 +212,6 @@ def validation_ac( | |
|
||
|
||
def run_example(): | ||
MODEL_NAME = "yolov8n-seg" | ||
|
||
model = YOLO(ROOT / f"{MODEL_NAME}.pt") | ||
args = get_cfg(cfg=DEFAULT_CFG) | ||
args.data = "coco128-seg.yaml" | ||
|
@@ -231,11 +228,11 @@ def run_example(): | |
print(f"[2/5] Save INT8 model: {int8_model_path}") | ||
|
||
print("[3/5] Validate ONNX FP32 model:") | ||
fp_stats, total_images, total_objects = validate(fp32_model, tqdm(data_loader), validator) | ||
fp_stats, total_images, total_objects = validate(fp32_model, data_loader, validator) | ||
print_statistics(fp_stats, total_images, total_objects) | ||
|
||
print("[4/5] Validate ONNX INT8 model:") | ||
q_stats, total_images, total_objects = validate(int8_model, tqdm(data_loader), validator) | ||
q_stats, total_images, total_objects = validate(int8_model, data_loader, validator) | ||
print_statistics(q_stats, total_images, total_objects) | ||
|
||
print("[5/5] Report:") | ||
|
1 change: 1 addition & 0 deletions
1
...es/post_training_quantization/onnx/yolov8_quantize_with_accuracy_control/requirements.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
ultralytics==8.3.22 | ||
onnx==1.17.0 | ||
onnxruntime==1.19.2 | ||
openvino==2024.5 |
Oops, something went wrong.