File size: 3,947 Bytes
7c6dbfb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
826f77b
 
 
 
 
 
 
 
 
 
 
 
7c6dbfb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/usr/bin/env bash
# SPDX-License-Identifier: MIT
# Copyright (C) Intel Corporation
#
# Export a YOLO26 detector to OpenVINO IR for the object-counting use case.
# Usage: ./export_and_quantize.sh [MODEL_VARIANT] [PRECISION]
# Example: ./export_and_quantize.sh yolo26n FP16
#
# Supported precisions:
#   FP32  -- Full-precision floating-point weights
#   FP16  -- Half-precision floating-point weights (default)
#   INT8  -- Quantized 8-bit integer weights (requires NNCF)
#
# Precision / device compatibility:
#   | Precision | CPU | GPU | NPU |
#   |-----------|-----|-----|-----|
#   | FP32      | Yes | Yes | No  |
#   | FP16      | Yes | Yes | Yes |
#   | INT8      | Yes | Yes | Yes |

set -euo pipefail

MODEL_NAME="${1:-yolo26n}"
PRECISION="${2:-FP16}"
PRECISION="$(echo "${PRECISION}" | tr '[:lower:]' '[:upper:]')"

if [[ "${PRECISION}" != "FP32" && "${PRECISION}" != "FP16" && "${PRECISION}" != "INT8" ]]; then
    echo "ERROR: unsupported precision '${PRECISION}'. Choose FP32, FP16, or INT8." >&2
    exit 1
fi

echo "--- Installing dependencies ---"
if [[ "${PRECISION}" == "INT8" ]]; then
    pip install -qU openvino nncf ultralytics
else
    pip install -qU openvino ultralytics
fi

# Ask for approval before downloading models and sample files
echo ""
echo "This script will download:"
echo "  - Model weights and/or sample files"
echo ""
read -p "Continue with downloads? (yes/no): " APPROVAL
if [[ "${APPROVAL}" != "yes" ]]; then
    echo "Download cancelled by user."
    exit 0
fi

# Ping the HuggingFace repo to register a tracked download of config.json.
# This is best-effort: a failure (offline, or before the repo is published)
# must not stop the export.
echo "--- Registering HuggingFace download (tracking ping) ---"
HF_REPO_ID="Intel/object-counting"
HF_CONFIG_URL="https://huggingface.co/${HF_REPO_ID}/resolve/main/config.json"
if curl -fsSL -o /dev/null "${HF_CONFIG_URL}"; then
    echo "Registered HuggingFace download for ${HF_REPO_ID}"
else
    echo "WARNING: HuggingFace tracking ping failed (offline?); continuing." >&2
fi
echo ""
echo "--- Downloading sample test image ---"
if [[ ! -f test.jpg ]]; then
    wget -q -O test.jpg https://ultralytics.com/images/bus.jpg
    echo "Downloaded: test.jpg"
else
    echo "Already present: test.jpg"
fi
echo ""
echo "--- Downloading sample test video ---"
if [[ ! -f test_video.mp4 ]]; then
    wget -q -O test_video.mp4 \
        "https://raw.githubusercontent.com/intel-iot-devkit/sample-videos/master/person-bicycle-car-detection.mp4"
    echo "Downloaded: test_video.mp4"
else
    echo "Already present: test_video.mp4"
fi

if [[ "${PRECISION}" == "FP32" ]]; then
    HALF_FLAG="False"
    EXPORT_LABEL="FP32"
else
    HALF_FLAG="True"
    EXPORT_LABEL="FP16"
fi

echo "--- Exporting ${MODEL_NAME} to OpenVINO IR (${EXPORT_LABEL}) ---"
python3 -c "
from ultralytics import YOLO

model = YOLO('${MODEL_NAME}.pt')
model.export(format='openvino', half=${HALF_FLAG}, dynamic=False, imgsz=640)
print('Export complete: ${MODEL_NAME}_openvino_model/')
"

if [[ "${PRECISION}" == "INT8" ]]; then
    echo "--- Quantizing to INT8 with NNCF ---"
    python3 -c "
import nncf
import openvino as ov
import numpy as np
import cv2

core = ov.Core()
model = core.read_model('${MODEL_NAME}_openvino_model/${MODEL_NAME}.xml')

# Use the downloaded test image for calibration instead of random noise.
img = cv2.imread('test.jpg')
img = cv2.resize(img, (640, 640))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32) / 255.0
img = img.transpose(2, 0, 1)[np.newaxis, ...]  # NCHW

def transform_fn(data_item):
    return img

calibration_dataset = nncf.Dataset(list(range(300)), transform_fn)

quantized = nncf.quantize(
    model,
    calibration_dataset,
    preset=nncf.QuantizationPreset.MIXED,
    subset_size=300,
)

ov.save_model(quantized, '${MODEL_NAME}_objcount_int8.xml')
print('Quantization complete: ${MODEL_NAME}_objcount_int8.xml')
"
fi
echo "--- Done ---"