Skip to content

Commit 34e9377

Browse files
Comments
1 parent 102d9fa commit 34e9377

6 files changed

Lines changed: 38 additions & 27 deletions

File tree

.ci/scripts/test_yolo26.sh

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,14 @@ prepare_artifacts_upload() {
167167

168168

169169
# Export model.
170-
EXPORTED_MODEL_NAME="${MODEL_NAME}_fp32_${MODE}.pte"
171-
echo "Exporting ${EXPORTED_MODEL_NAME}"
172170
EXPORT_ARGS="--model_name=${MODEL_NAME} --backend=${MODE}"
171+
if [[ -n "${PT2E_QUANTIZE}" ]]; then
172+
EXPORTED_MODEL_NAME="${MODEL_NAME}_int8_${MODE}.pte"
173+
EXPORT_ARGS="${EXPORT_ARGS} --quantize --video_path=${VIDEO_PATH}"
174+
else
175+
EXPORTED_MODEL_NAME="${MODEL_NAME}_fp32_${MODE}.pte"
176+
fi
177+
echo "Exporting ${EXPORTED_MODEL_NAME}"
173178

174179
# Add dynamically linked library location
175180
cmake_install_executorch_libraries

backends/openvino/quantizer/quantizer.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,14 +192,18 @@ def set_ignored_scope(
192192
:param validate: If set to True, then a RuntimeError will be raised if any ignored scope does not match
193193
in the model graph.
194194
"""
195+
subgraphs_ = []
195196
if subgraphs:
196-
subgraphs = [nncf.Subgraph(inputs=subgraph[0], outputs=subgraph[1]) for subgraph in subgraphs]
197+
subgraphs_ = [
198+
nncf.Subgraph(inputs=subgraph[0], outputs=subgraph[1])
199+
for subgraph in subgraphs
200+
]
197201
self._algo.set_ignored_scope(
198202
nncf.IgnoredScope(
199203
names=names or [],
200204
patterns=patterns or [],
201205
types=types or [],
202-
subgraphs=subgraphs or [],
206+
subgraphs=subgraphs_,
203207
validate=validate,
204208
)
205209
)

docs/source/success-stories.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ Automate PyTorch model deployment to iOS, Android, and edge devices with ExecuTo
156156

157157
- **LoRA adapter** - Export two LoRA adapters that share a single foundation weight file, saving memory and disk space. [Try →](https://github.com/meta-pytorch/executorch-examples/tree/main/program-data-separation/cpp/lora_example)
158158

159-
- **OpenVINO from Intel** - Deploy [Yolo12](https://github.com/pytorch/executorch/tree/main/examples/models/yolo12), [Llama](https://github.com/pytorch/executorch/tree/main/examples/openvino/llama), and [Stable Diffusion](https://github.com/pytorch/executorch/tree/main/examples/openvino/stable_diffusion) on [OpenVINO from Intel](https://www.intel.com/content/www/us/en/developer/articles/community/optimizing-executorch-on-ai-pcs.html).
159+
- **OpenVINO from Intel** - Deploy [Yolo26](https://github.com/pytorch/executorch/tree/main/examples/models/yolo26), [Llama](https://github.com/pytorch/executorch/tree/main/examples/openvino/llama), and [Stable Diffusion](https://github.com/pytorch/executorch/tree/main/examples/openvino/stable_diffusion) on [OpenVINO from Intel](https://www.intel.com/content/www/us/en/developer/articles/community/optimizing-executorch-on-ai-pcs.html).
160160

161161
- **Audio Generation** - Generate audio from text prompts using Stable Audio Open Small on Arm CPUs with XNNPACK and KleidiAI. [Try →](https://github.com/Arm-Examples/ML-examples/tree/main/kleidiai-examples/audiogen-et)[Video →](https://www.youtube.com/watch?v=q2P0ESVxhAY) <!-- @lint-ignore -->
162162

examples/models/yolo26/README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,6 @@ XNNPACK:
4646
python export_and_validate.py --model_name yolo26s --input_dims=[1920,1080] --backend xnnpack
4747
```
4848

49-
> **_NOTE:_** Quantization for XNNPACK backend is WIP. Please refere to <https://github.com/pytorch/executorch/issues/11523> for more details.
50-
5149
Exported model could be validated using the `--validate` key:
5250

5351
```bash

examples/models/yolo26/export_and_validate.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,10 @@ def lower_to_openvino(
7676
subset_size: int,
7777
quantize: bool,
7878
) -> ExecutorchProgramManager:
79+
import nncf
7980
from executorch.backends.openvino.partitioner import OpenvinoPartitioner
8081
from executorch.backends.openvino.quantizer import OpenVINOQuantizer
8182
from executorch.backends.openvino.quantizer.quantizer import QuantizationMode
82-
import nncf
8383
from nncf.experimental.torch.fx import quantize_pt2e
8484

8585
if quantize:
@@ -269,7 +269,7 @@ def transform_fn(frame):
269269
if val_dataset_yaml_path is not None:
270270
if input_dims != [640, 640]:
271271
raise NotImplementedError(
272-
f"Validation with the custom input shape {input_dims} is not implmenented."
272+
f"Validation with the custom input shape {input_dims} is not implemented."
273273
" Please use the default --input_dims=[640,640] for the validation."
274274
)
275275
stats = validate_yolo(model, exec_prog, val_dataset_yaml_path)
@@ -288,7 +288,6 @@ def _prepare_validation(
288288
} # highest priority args on the right
289289

290290
validator = model._smart_load("validator")(args=args, _callbacks=model.callbacks)
291-
validator.device = torch.device("cpu")
292291
stride = 32 # default stride
293292
validator.stride = stride # used in get_dataloader() for padding
294293
validator.data = check_det_dataset(dataset_yaml_path)

examples/models/yolo26/inference.h

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ struct DetectionConfig {
3232
};
3333

3434
cv::Mat scale_with_padding(
35-
cv::Mat& source,
35+
const cv::Mat& source,
3636
int* pad_x,
3737
int* pad_y,
3838
float* scale,
@@ -41,13 +41,16 @@ cv::Mat scale_with_padding(
4141
int row = source.rows;
4242
int m_inputWidth = img_dims.width;
4343
int m_inputHeight = img_dims.height;
44-
if (col == m_inputWidth and row == m_inputHeight) {
44+
if (col == m_inputWidth && row == m_inputHeight) {
45+
*pad_x = 0;
46+
*pad_y = 0;
47+
*scale = 1.f;
4548
return source;
4649
}
4750

48-
*scale = std::min(m_inputWidth / (float)col, m_inputHeight / (float)row);
49-
int resized_w = col * *scale;
50-
int resized_h = row * *scale;
51+
*scale = std::min(m_inputWidth / static_cast<float>(col), m_inputHeight / static_cast<float>(row));
52+
int resized_w = static_cast<int>(col * *scale);
53+
int resized_h = static_cast<int>(row * *scale);
5154
*pad_x = (m_inputWidth - resized_w) / 2;
5255
*pad_y = (m_inputHeight - resized_h) / 2;
5356

@@ -63,7 +66,7 @@ std::vector<Detection> infer_yolo_once(
6366
Module& module,
6467
cv::Mat input,
6568
cv::Size img_dims,
66-
const DetectionConfig yolo_config) {
69+
const DetectionConfig& yolo_config) {
6770
int pad_x, pad_y;
6871
float scale;
6972
input = scale_with_padding(input, &pad_x, &pad_y, &scale, img_dims);
@@ -72,15 +75,15 @@ std::vector<Detection> infer_yolo_once(
7275
cv::dnn::blobFromImage(
7376
input, blob, 1.0 / 255.0, img_dims, cv::Scalar(), true, false);
7477
const auto t_input = from_blob(
75-
(void*)blob.data,
78+
static_cast<void*>(blob.data),
7679
std::vector<int>(blob.size.p, blob.size.p + blob.dims),
7780
ScalarType::Float);
7881
const auto result = module.forward(t_input);
7982

8083
ET_CHECK_MSG(
8184
result.ok(),
8285
"Execution of method forward failed with status 0x%" PRIx32,
83-
(uint32_t)result.error());
86+
static_cast<uint32_t>(result.error()));
8487

8588
// Yolo26 end-to-end (post-NMS) output format: [1, N, 6]
8689
// Each detection row: [x1, y1, x2, y2, confidence, class_id]
@@ -89,12 +92,11 @@ std::vector<Detection> infer_yolo_once(
8992
t.dim() == 3 && t.sizes()[2] == 6,
9093
"Unexpected output shape: expected [1, N, 6] (end-to-end post-NMS format)");
9194

92-
const int num_detections = t.sizes()[1];
95+
const int64_t num_detections = t.sizes()[1];
9396
const int num_classes = static_cast<int>(yolo_config.classes.size());
9497
const float* data = static_cast<const float*>(t.const_data_ptr());
95-
9698
std::vector<Detection> detections;
97-
for (int i = 0; i < num_detections; ++i) {
99+
for (int64_t i = 0; i < num_detections; ++i) {
98100
const float* det = data + i * 6;
99101
const float x1 = det[0];
100102
const float y1 = det[1];
@@ -106,18 +108,21 @@ std::vector<Detection> infer_yolo_once(
106108
if (confidence <= yolo_config.modelScoreThreshold)
107109
continue;
108110

111+
if (class_id < 0 || class_id >= num_classes)
112+
continue;
113+
109114
// Map coordinates back to original image space
110115
const int left = static_cast<int>((x1 - pad_x) / scale);
111116
const int top = static_cast<int>((y1 - pad_y) / scale);
112117
const int width = static_cast<int>((x2 - x1) / scale);
113118
const int height = static_cast<int>((y2 - y1) / scale);
114119

115-
Detection result;
116-
result.class_id = class_id;
117-
result.confidence = confidence;
118-
result.className = yolo_config.classes[class_id];
119-
result.box = cv::Rect(left, top, width, height);
120-
detections.push_back(result);
120+
Detection detection;
121+
detection.class_id = class_id;
122+
detection.confidence = confidence;
123+
detection.className = yolo_config.classes[class_id];
124+
detection.box = cv::Rect(left, top, width, height);
125+
detections.push_back(detection);
121126
}
122127

123128
return detections;

0 commit comments

Comments
 (0)