@camstack/addon-pipeline 1.2.333 → 1.2.334
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/THIRD_PARTY_MODELS.md +3 -8
- package/dist/audio-analyzer/index.js +2 -2
- package/dist/audio-analyzer/index.mjs +2 -2
- package/dist/{default-detection-model-Biwf5-ML.js → custom-model-catalog-CVeosmYm.js} +236 -165
- package/dist/{default-detection-model-CDffuH2m.mjs → custom-model-catalog-DoOVE7kz.mjs} +225 -166
- package/dist/detection-pipeline/index.js +70 -104
- package/dist/detection-pipeline/index.mjs +18 -52
- package/dist/{dist-DJV7Z6Bb.js → dist-C7v30DMP.js} +69 -22
- package/dist/{dist-BsT15i7i.mjs → dist-Dn3knu_K.mjs} +69 -22
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/{node-CkmucLYG.js → node-DWdekhW3.js} +1 -1
- package/dist/{node-Crsi_8ea.mjs → node-_BruMF4L.mjs} +1 -1
- package/dist/pipeline-runner/index.js +228 -42
- package/dist/pipeline-runner/index.mjs +206 -20
- package/dist/{process-memory-BJb7Ihdp.js → process-memory-CaDpfUdM.js} +1 -1
- package/dist/{process-memory-1mAUV8S1.mjs → process-memory-Dp-4bFOp.mjs} +1 -1
- package/dist/recorder/index.js +2 -2
- package/dist/recorder/index.mjs +2 -2
- package/dist/{segment-demux-js-B_tboBcJ.mjs → segment-demux-js-B_-zBECg.mjs} +1 -1
- package/dist/{segment-demux-js-mK9IBGLf.js → segment-demux-js-BqPTLFZG.js} +1 -1
- package/dist/stream-broker/_stub.js +1 -1
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-a3HMFtd5.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-BP8FFU2i.mjs} +2 -2
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CpjKK9II.mjs +26 -0
- package/dist/stream-broker/demux-worker-child.js +1 -1
- package/dist/stream-broker/demux-worker-child.mjs +1 -1
- package/dist/stream-broker/{hostInit-DChPnZ5C.mjs → hostInit-BEh-hm1x.mjs} +2 -2
- package/dist/stream-broker/index.js +3 -3
- package/dist/stream-broker/index.mjs +3 -3
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/package.json +1 -1
- package/python/postprocessors/test_yolo_seg_root.py +109 -0
- package/python/postprocessors/yolo.py +52 -13
- package/python/postprocessors/yolo_seg.py +79 -156
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DPbj3ML4.mjs +0 -26
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Tt as inferModelProvider, X as audioKindId, b as DEVICE_BACKEND_TO_FORMAT, f as COCO_80_LABELS, i as AUDIO_MACRO_LABELS, k as LABEL_SUPPLY_VOCABULARIES, on as stepModelRunsOnFormat, p as COCO_TO_MACRO, wt as hfModelUrl } from "./dist-
|
|
1
|
+
import { Tt as inferModelProvider, X as audioKindId, b as DEVICE_BACKEND_TO_FORMAT, f as COCO_80_LABELS, i as AUDIO_MACRO_LABELS, k as LABEL_SUPPLY_VOCABULARIES, on as stepModelRunsOnFormat, p as COCO_TO_MACRO, wt as hfModelUrl } from "./dist-Dn3knu_K.mjs";
|
|
2
2
|
import { t as isWorkerReply } from "./worker-protocol-D_NzPcnh.mjs";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
//#region src/detection-pipeline/registry/effective-confidence.ts
|
|
@@ -447,6 +447,10 @@ var yolo26Reduced = (tier, res, sizes) => {
|
|
|
447
447
|
formats: { openvino: ovFormat(hf(`objectDetection/yolo26/openvino/camstack-yolo26${tier}-${res}-int8.xml`), sizes.ovInt8) }
|
|
448
448
|
}];
|
|
449
449
|
};
|
|
450
|
+
/** Variant family of the YOLO26 builds with an instance-segmentation head. */
|
|
451
|
+
var YOLO26_SEG_FAMILY = "yolo26-seg";
|
|
452
|
+
/** What choosing a seg build as the root means, in the catalog's own words. */
|
|
453
|
+
var YOLO26_SEG_ROOT_NOTE = "As the root model it detects like YOLO26 and also supplies the Segmentation step its masks (detection + masks, slightly heavier).";
|
|
450
454
|
var OBJECT_DETECTION_MODELS = [
|
|
451
455
|
{
|
|
452
456
|
id: "yolo26n",
|
|
@@ -617,6 +621,102 @@ var OBJECT_DETECTION_MODELS = [
|
|
|
617
621
|
runtimes: ["python"]
|
|
618
622
|
} }
|
|
619
623
|
},
|
|
624
|
+
{
|
|
625
|
+
id: "yolo26n-seg",
|
|
626
|
+
license: licensed(ULTRALYTICS_AGPL, { modifications: "exported to ONNX, OpenVINO IR and CoreML" }),
|
|
627
|
+
group: {
|
|
628
|
+
family: YOLO26_SEG_FAMILY,
|
|
629
|
+
tier: "n",
|
|
630
|
+
resolution: 640
|
|
631
|
+
},
|
|
632
|
+
name: "YOLO26-seg Nano",
|
|
633
|
+
description: `YOLO26 Nano with its instance-segmentation head — ultra-lightweight. ${YOLO26_SEG_ROOT_NOTE}`,
|
|
634
|
+
inputSize: {
|
|
635
|
+
width: 640,
|
|
636
|
+
height: 640
|
|
637
|
+
},
|
|
638
|
+
labels: [],
|
|
639
|
+
preprocessMode: "letterbox",
|
|
640
|
+
postprocessor: "yolo-seg",
|
|
641
|
+
formats: {
|
|
642
|
+
onnx: {
|
|
643
|
+
url: hf("segmentation/yolo26-seg/onnx/camstack-yolo26n-seg.onnx"),
|
|
644
|
+
sizeMB: 11
|
|
645
|
+
},
|
|
646
|
+
coreml: {
|
|
647
|
+
url: hf("segmentation/yolo26-seg/coreml/camstack-yolo26n-seg.mlpackage"),
|
|
648
|
+
sizeMB: 6,
|
|
649
|
+
isDirectory: true,
|
|
650
|
+
files: [...MLPACKAGE_FILES],
|
|
651
|
+
runtimes: ["python"]
|
|
652
|
+
},
|
|
653
|
+
openvino: ovFormat(hf("segmentation/yolo26-seg/openvino/camstack-yolo26n-seg.xml"), 11)
|
|
654
|
+
}
|
|
655
|
+
},
|
|
656
|
+
{
|
|
657
|
+
id: "yolo26s-seg",
|
|
658
|
+
license: licensed(ULTRALYTICS_AGPL, { modifications: "exported to ONNX, OpenVINO IR and CoreML" }),
|
|
659
|
+
group: {
|
|
660
|
+
family: YOLO26_SEG_FAMILY,
|
|
661
|
+
tier: "s",
|
|
662
|
+
resolution: 640
|
|
663
|
+
},
|
|
664
|
+
name: "YOLO26-seg Small",
|
|
665
|
+
description: `YOLO26 Small with its instance-segmentation head — balanced. ${YOLO26_SEG_ROOT_NOTE}`,
|
|
666
|
+
inputSize: {
|
|
667
|
+
width: 640,
|
|
668
|
+
height: 640
|
|
669
|
+
},
|
|
670
|
+
labels: [],
|
|
671
|
+
preprocessMode: "letterbox",
|
|
672
|
+
postprocessor: "yolo-seg",
|
|
673
|
+
formats: {
|
|
674
|
+
onnx: {
|
|
675
|
+
url: hf("segmentation/yolo26-seg/onnx/camstack-yolo26s-seg.onnx"),
|
|
676
|
+
sizeMB: 40
|
|
677
|
+
},
|
|
678
|
+
coreml: {
|
|
679
|
+
url: hf("segmentation/yolo26-seg/coreml/camstack-yolo26s-seg.mlpackage"),
|
|
680
|
+
sizeMB: 20,
|
|
681
|
+
isDirectory: true,
|
|
682
|
+
files: [...MLPACKAGE_FILES],
|
|
683
|
+
runtimes: ["python"]
|
|
684
|
+
},
|
|
685
|
+
openvino: ovFormat(hf("segmentation/yolo26-seg/openvino/camstack-yolo26s-seg.xml"), 40)
|
|
686
|
+
}
|
|
687
|
+
},
|
|
688
|
+
{
|
|
689
|
+
id: "yolo26m-seg",
|
|
690
|
+
license: licensed(ULTRALYTICS_AGPL, { modifications: "exported to ONNX, OpenVINO IR and CoreML" }),
|
|
691
|
+
group: {
|
|
692
|
+
family: YOLO26_SEG_FAMILY,
|
|
693
|
+
tier: "m",
|
|
694
|
+
resolution: 640
|
|
695
|
+
},
|
|
696
|
+
name: "YOLO26-seg Medium",
|
|
697
|
+
description: `YOLO26 Medium with its instance-segmentation head — high accuracy. ${YOLO26_SEG_ROOT_NOTE}`,
|
|
698
|
+
inputSize: {
|
|
699
|
+
width: 640,
|
|
700
|
+
height: 640
|
|
701
|
+
},
|
|
702
|
+
labels: [],
|
|
703
|
+
preprocessMode: "letterbox",
|
|
704
|
+
postprocessor: "yolo-seg",
|
|
705
|
+
formats: {
|
|
706
|
+
onnx: {
|
|
707
|
+
url: hf("segmentation/yolo26-seg/onnx/camstack-yolo26m-seg.onnx"),
|
|
708
|
+
sizeMB: 90
|
|
709
|
+
},
|
|
710
|
+
coreml: {
|
|
711
|
+
url: hf("segmentation/yolo26-seg/coreml/camstack-yolo26m-seg.mlpackage"),
|
|
712
|
+
sizeMB: 45,
|
|
713
|
+
isDirectory: true,
|
|
714
|
+
files: [...MLPACKAGE_FILES],
|
|
715
|
+
runtimes: ["python"]
|
|
716
|
+
},
|
|
717
|
+
openvino: ovFormat(hf("segmentation/yolo26-seg/openvino/camstack-yolo26m-seg.xml"), 90)
|
|
718
|
+
}
|
|
719
|
+
},
|
|
620
720
|
ovPrecisionVariant("yolo26n", "objectDetection/yolo26/openvino", "YOLO26 Nano", "fp16", 5, true),
|
|
621
721
|
ovPrecisionVariant("yolo26n", "objectDetection/yolo26/openvino", "YOLO26 Nano", "int8", 3),
|
|
622
722
|
ovPrecisionVariant("yolo26s", "objectDetection/yolo26/openvino", "YOLO26 Small", "fp16", 19, true),
|
|
@@ -1030,86 +1130,13 @@ var SEGMENTATION_REFINER_MODELS = [{
|
|
|
1030
1130
|
openvino: ovFormat(hf("segmentationRefiner/u2netp/openvino/camstack-u2netp.xml"), 2.5)
|
|
1031
1131
|
}
|
|
1032
1132
|
}];
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
width: 640,
|
|
1041
|
-
height: 640
|
|
1042
|
-
},
|
|
1043
|
-
labels: [],
|
|
1044
|
-
preprocessMode: "letterbox",
|
|
1045
|
-
formats: {
|
|
1046
|
-
onnx: {
|
|
1047
|
-
url: hf("segmentation/yolo26-seg/onnx/camstack-yolo26n-seg.onnx"),
|
|
1048
|
-
sizeMB: 11
|
|
1049
|
-
},
|
|
1050
|
-
coreml: {
|
|
1051
|
-
url: hf("segmentation/yolo26-seg/coreml/camstack-yolo26n-seg.mlpackage"),
|
|
1052
|
-
sizeMB: 6,
|
|
1053
|
-
isDirectory: true,
|
|
1054
|
-
files: [...MLPACKAGE_FILES],
|
|
1055
|
-
runtimes: ["python"]
|
|
1056
|
-
},
|
|
1057
|
-
openvino: ovFormat(hf("segmentation/yolo26-seg/openvino/camstack-yolo26n-seg.xml"), 11)
|
|
1058
|
-
}
|
|
1059
|
-
},
|
|
1060
|
-
{
|
|
1061
|
-
id: "yolo26s-seg",
|
|
1062
|
-
license: licensed(ULTRALYTICS_AGPL, { modifications: "exported to ONNX, OpenVINO IR and CoreML" }),
|
|
1063
|
-
name: "YOLO26 Small Seg",
|
|
1064
|
-
description: "YOLO26 Small Segmentation — balanced instance segmentation",
|
|
1065
|
-
inputSize: {
|
|
1066
|
-
width: 640,
|
|
1067
|
-
height: 640
|
|
1068
|
-
},
|
|
1069
|
-
labels: [],
|
|
1070
|
-
preprocessMode: "letterbox",
|
|
1071
|
-
formats: {
|
|
1072
|
-
onnx: {
|
|
1073
|
-
url: hf("segmentation/yolo26-seg/onnx/camstack-yolo26s-seg.onnx"),
|
|
1074
|
-
sizeMB: 40
|
|
1075
|
-
},
|
|
1076
|
-
coreml: {
|
|
1077
|
-
url: hf("segmentation/yolo26-seg/coreml/camstack-yolo26s-seg.mlpackage"),
|
|
1078
|
-
sizeMB: 20,
|
|
1079
|
-
isDirectory: true,
|
|
1080
|
-
files: [...MLPACKAGE_FILES],
|
|
1081
|
-
runtimes: ["python"]
|
|
1082
|
-
},
|
|
1083
|
-
openvino: ovFormat(hf("segmentation/yolo26-seg/openvino/camstack-yolo26s-seg.xml"), 40)
|
|
1084
|
-
}
|
|
1085
|
-
},
|
|
1086
|
-
{
|
|
1087
|
-
id: "yolo26m-seg",
|
|
1088
|
-
license: licensed(ULTRALYTICS_AGPL, { modifications: "exported to ONNX, OpenVINO IR and CoreML" }),
|
|
1089
|
-
name: "YOLO26 Medium Seg",
|
|
1090
|
-
description: "YOLO26 Medium Segmentation — high-accuracy instance segmentation",
|
|
1091
|
-
inputSize: {
|
|
1092
|
-
width: 640,
|
|
1093
|
-
height: 640
|
|
1094
|
-
},
|
|
1095
|
-
labels: [],
|
|
1096
|
-
preprocessMode: "letterbox",
|
|
1097
|
-
formats: {
|
|
1098
|
-
onnx: {
|
|
1099
|
-
url: hf("segmentation/yolo26-seg/onnx/camstack-yolo26m-seg.onnx"),
|
|
1100
|
-
sizeMB: 90
|
|
1101
|
-
},
|
|
1102
|
-
coreml: {
|
|
1103
|
-
url: hf("segmentation/yolo26-seg/coreml/camstack-yolo26m-seg.mlpackage"),
|
|
1104
|
-
sizeMB: 45,
|
|
1105
|
-
isDirectory: true,
|
|
1106
|
-
files: [...MLPACKAGE_FILES],
|
|
1107
|
-
runtimes: ["python"]
|
|
1108
|
-
},
|
|
1109
|
-
openvino: ovFormat(hf("segmentation/yolo26-seg/openvino/camstack-yolo26m-seg.xml"), 90)
|
|
1110
|
-
}
|
|
1111
|
-
}
|
|
1112
|
-
];
|
|
1133
|
+
/**
|
|
1134
|
+
* The dormant `instance-segmentation` step's catalog: the YOLO26-seg entries of
|
|
1135
|
+
* {@link OBJECT_DETECTION_MODELS}, by reference. One entry per model (D703) —
|
|
1136
|
+
* the artifact lives once, in the root's catalog, where it can be selected as
|
|
1137
|
+
* the camera root and supply the `segmentation` step's masks (D737).
|
|
1138
|
+
*/
|
|
1139
|
+
var INSTANCE_SEGMENTATION_MODELS = OBJECT_DETECTION_MODELS.filter((m) => m.group?.family === YOLO26_SEG_FAMILY);
|
|
1113
1140
|
var CLIP_EMBEDDING_MODELS = [{
|
|
1114
1141
|
id: "siglip2-b16-224",
|
|
1115
1142
|
license: SIGLIP2_APACHE,
|
|
@@ -1391,7 +1418,7 @@ var AnimalClassifierStep = class {
|
|
|
1391
1418
|
labelTier: 1,
|
|
1392
1419
|
models: [...ANIMAL_CLASSIFIER_MODELS],
|
|
1393
1420
|
defaultModelId: "animal-classifier",
|
|
1394
|
-
enabledByDefault:
|
|
1421
|
+
enabledByDefault: true,
|
|
1395
1422
|
defaultConfidence: .5,
|
|
1396
1423
|
labels: [...ANIMAL_10_LABELS],
|
|
1397
1424
|
cadence: {
|
|
@@ -1705,7 +1732,7 @@ var STEP_VEHICLE_CLASSIFIER = new VehicleClassifierStep({
|
|
|
1705
1732
|
labelTier: 1,
|
|
1706
1733
|
models: [...VEHICLE_CLASSIFIER_MODELS],
|
|
1707
1734
|
defaultModelId: "vehicle-type-v1",
|
|
1708
|
-
enabledByDefault:
|
|
1735
|
+
enabledByDefault: true,
|
|
1709
1736
|
defaultConfidence: .5,
|
|
1710
1737
|
cadence: {
|
|
1711
1738
|
trigger: "once",
|
|
@@ -2959,6 +2986,120 @@ function rootObjectGate(steps) {
|
|
|
2959
2986
|
return (steps?.find((s) => s.enabled !== false))?.settings;
|
|
2960
2987
|
}
|
|
2961
2988
|
//#endregion
|
|
2989
|
+
//#region src/detection-pipeline/default-detection-model.ts
|
|
2990
|
+
/** The object-detection step id — the only slot this resolver applies to. */
|
|
2991
|
+
var OBJECT_DETECTION_STEP_ID = "object-detection";
|
|
2992
|
+
/**
|
|
2993
|
+
* Balanced default object-detection model per accelerator class. `'cpu'` maps to
|
|
2994
|
+
* `null` → the caller substitutes the step's own `defaultModelId` (`yolo26n`).
|
|
2995
|
+
* INTEL NPU + iGPU default to the Ultralytics YOLOv9 re-export (int8 @320): yolo26 does NOT compile on
|
|
2996
|
+
* the Intel NPU (arch incompat → 0 frames), while yolov9 runs on it (~298 fps
|
|
2997
|
+
* measured). Apple ANE uses the CoreML yolov9 @320 build.
|
|
2998
|
+
*
|
|
2999
|
+
* Do **not** promote these ids to `yolov9m-640` / `*-640`. The controlled
|
|
3000
|
+
* evaluation recovered 0/3 misses at the current 0.50 threshold and failed the
|
|
3001
|
+
* false-positive and capacity gates — see
|
|
3002
|
+
* `docs/benchmarks/pipeline-frame-model-eval.md`. 640 remains an explicit
|
|
3003
|
+
* operator pick, not a hardware-aware default.
|
|
3004
|
+
*/
|
|
3005
|
+
var MODEL_BY_CLASS = {
|
|
3006
|
+
"apple-ane": "yolov9m-320",
|
|
3007
|
+
"intel-npu": "yolov9m-320-int8",
|
|
3008
|
+
"intel-gpu": "yolov9m-320-int8",
|
|
3009
|
+
cpu: null
|
|
3010
|
+
};
|
|
3011
|
+
/**
|
|
3012
|
+
* Classify a node's engine into an {@link AcceleratorClass} from its resolved
|
|
3013
|
+
* `backend` + `device`. Pure, total, never throws.
|
|
3014
|
+
*
|
|
3015
|
+
* OpenVINO's default device is `'auto'` (the python pool resolves NPU > GPU >
|
|
3016
|
+
* CPU at load). Because OpenVINO is only ever OFFERED when an Intel iGPU is
|
|
3017
|
+
* present, the GPU is the guaranteed accelerator while the NPU is an explicit
|
|
3018
|
+
* opt-in — so `'auto'` (and any non-cpu/non-npu device) is treated as
|
|
3019
|
+
* GPU-class conservatively. An operator who explicitly pins `device: 'npu'`
|
|
3020
|
+
* gets the NPU-tuned m-320.
|
|
3021
|
+
*
|
|
3022
|
+
* Also accepts the accelerator carried in the `backend` slot (e.g. `'ane'`,
|
|
3023
|
+
* `'mps'`, `'npu'`, `'intel-gpu'`) so a caller passing a device-style backend
|
|
3024
|
+
* still classifies correctly — real callers pass onnx/openvino/coreml.
|
|
3025
|
+
*/
|
|
3026
|
+
function classifyAccelerator(backend, device) {
|
|
3027
|
+
const b = backend.toLowerCase();
|
|
3028
|
+
const d = device?.toLowerCase() ?? null;
|
|
3029
|
+
if (b === "coreml" || b === "ane" || b === "mps") return "apple-ane";
|
|
3030
|
+
if (b === "openvino") {
|
|
3031
|
+
if (d === "npu") return "intel-npu";
|
|
3032
|
+
if (d === "cpu") return "cpu";
|
|
3033
|
+
return "intel-gpu";
|
|
3034
|
+
}
|
|
3035
|
+
if (b === "npu" || b === "intel-npu") return "intel-npu";
|
|
3036
|
+
if (b === "gpu" || b === "intel-gpu" || b === "gpu-openvino") return "intel-gpu";
|
|
3037
|
+
return "cpu";
|
|
3038
|
+
}
|
|
3039
|
+
/**
|
|
3040
|
+
* Resolve the hardware-aware default object-detection model id for a node's
|
|
3041
|
+
* engine `(backend, device, format)`.
|
|
3042
|
+
*
|
|
3043
|
+
* Guarantees:
|
|
3044
|
+
* - never throws (hot default-tree path);
|
|
3045
|
+
* - never returns a model id without a build for `format` (unless the step
|
|
3046
|
+
* has ZERO builds for `format`, which is unloadable regardless of pick and
|
|
3047
|
+
* flagged by `collectZeroBuildIssues`) — an unmapped backend, a `'cpu'`
|
|
3048
|
+
* class, a mapped id missing from the catalog, or a mapped id without a
|
|
3049
|
+
* `format` build all fall back to the step's PER-FORMAT default
|
|
3050
|
+
* (`getDefaultModelForFormatFromDef`), NOT the bare `defaultModelId`.
|
|
3051
|
+
*
|
|
3052
|
+
* `getStepDef` is injectable (defaults to the real catalog lookup) so the
|
|
3053
|
+
* missing-build fallback branch is unit-testable without a live catalog —
|
|
3054
|
+
* mirrors `collectZeroBuildIssues`' injection seam.
|
|
3055
|
+
*/
|
|
3056
|
+
function resolveDefaultDetectionModel(backend, device, format, getStepDef = getStepDefinition) {
|
|
3057
|
+
let def;
|
|
3058
|
+
try {
|
|
3059
|
+
def = getStepDef(OBJECT_DETECTION_STEP_ID);
|
|
3060
|
+
} catch {
|
|
3061
|
+
return "yolo26n";
|
|
3062
|
+
}
|
|
3063
|
+
const candidate = MODEL_BY_CLASS[classifyAccelerator(backend, device)];
|
|
3064
|
+
if (candidate !== null) {
|
|
3065
|
+
const entry = def.models.find((m) => m.id === candidate);
|
|
3066
|
+
if (entry && entry.formats[format] !== void 0) return candidate;
|
|
3067
|
+
}
|
|
3068
|
+
return getDefaultModelForFormatFromDef(def, format);
|
|
3069
|
+
}
|
|
3070
|
+
//#endregion
|
|
3071
|
+
//#region src/detection-pipeline/engine/resolve-device-engine.ts
|
|
3072
|
+
/**
|
|
3073
|
+
* Resolve a Phase-1 device key (`<backend>:<device>`, or bare `cpu`) into the
|
|
3074
|
+
* {@link PipelineEngineChoice} used to build that device's inference pool.
|
|
3075
|
+
* Throws on an unknown backend token so a bad `deviceKey` fails loud rather
|
|
3076
|
+
* than silently building a wrong pool. Format comes from the shared
|
|
3077
|
+
* {@link DEVICE_BACKEND_TO_FORMAT} SSOT (`@camstack/types`) — no local copy.
|
|
3078
|
+
*/
|
|
3079
|
+
function resolveDeviceEngine(deviceKey) {
|
|
3080
|
+
const colon = deviceKey.indexOf(":");
|
|
3081
|
+
const backend = colon >= 0 ? deviceKey.slice(0, colon) : deviceKey;
|
|
3082
|
+
const device = colon >= 0 ? deviceKey.slice(colon + 1) : deviceKey;
|
|
3083
|
+
const format = DEVICE_BACKEND_TO_FORMAT[backend];
|
|
3084
|
+
if (format === void 0) throw new Error(`resolveDeviceEngine: unknown backend "${backend}" in deviceKey "${deviceKey}"`);
|
|
3085
|
+
return {
|
|
3086
|
+
runtime: "python",
|
|
3087
|
+
backend,
|
|
3088
|
+
format,
|
|
3089
|
+
device
|
|
3090
|
+
};
|
|
3091
|
+
}
|
|
3092
|
+
/**
|
|
3093
|
+
* The inverse of {@link resolveDeviceEngine}: the `<backend>:<device>` key that
|
|
3094
|
+
* names the pool an engine belongs to. Every pool-level log line carries this —
|
|
3095
|
+
* without it a default pool logs anonymously and six hours of logs cannot tell
|
|
3096
|
+
* "the NPU is unused" from "the NPU IS the anonymous default pool".
|
|
3097
|
+
* Falls back to the bare backend when the engine carries no device.
|
|
3098
|
+
*/
|
|
3099
|
+
function deviceKeyOf(engine) {
|
|
3100
|
+
return engine.device ? `${engine.backend}:${engine.device}` : engine.backend;
|
|
3101
|
+
}
|
|
3102
|
+
//#endregion
|
|
2962
3103
|
//#region src/pipeline-runner/device-jump.ts
|
|
2963
3104
|
/**
|
|
2964
3105
|
* Step-tree device jump (same-node, phase 1) — the PURE resolution core.
|
|
@@ -3268,86 +3409,4 @@ var CustomModelCatalog = class {
|
|
|
3268
3409
|
stepDefinition = (stepId) => mergedStepDefinition(stepId, this.byStep);
|
|
3269
3410
|
};
|
|
3270
3411
|
//#endregion
|
|
3271
|
-
|
|
3272
|
-
/** The object-detection step id — the only slot this resolver applies to. */
|
|
3273
|
-
var OBJECT_DETECTION_STEP_ID = "object-detection";
|
|
3274
|
-
/**
|
|
3275
|
-
* Balanced default object-detection model per accelerator class. `'cpu'` maps to
|
|
3276
|
-
* `null` → the caller substitutes the step's own `defaultModelId` (`yolo26n`).
|
|
3277
|
-
* INTEL NPU + iGPU default to the Ultralytics YOLOv9 re-export (int8 @320): yolo26 does NOT compile on
|
|
3278
|
-
* the Intel NPU (arch incompat → 0 frames), while yolov9 runs on it (~298 fps
|
|
3279
|
-
* measured). Apple ANE uses the CoreML yolov9 @320 build.
|
|
3280
|
-
*
|
|
3281
|
-
* Do **not** promote these ids to `yolov9m-640` / `*-640`. The controlled
|
|
3282
|
-
* evaluation recovered 0/3 misses at the current 0.50 threshold and failed the
|
|
3283
|
-
* false-positive and capacity gates — see
|
|
3284
|
-
* `docs/benchmarks/pipeline-frame-model-eval.md`. 640 remains an explicit
|
|
3285
|
-
* operator pick, not a hardware-aware default.
|
|
3286
|
-
*/
|
|
3287
|
-
var MODEL_BY_CLASS = {
|
|
3288
|
-
"apple-ane": "yolov9m-320",
|
|
3289
|
-
"intel-npu": "yolov9m-320-int8",
|
|
3290
|
-
"intel-gpu": "yolov9m-320-int8",
|
|
3291
|
-
cpu: null
|
|
3292
|
-
};
|
|
3293
|
-
/**
|
|
3294
|
-
* Classify a node's engine into an {@link AcceleratorClass} from its resolved
|
|
3295
|
-
* `backend` + `device`. Pure, total, never throws.
|
|
3296
|
-
*
|
|
3297
|
-
* OpenVINO's default device is `'auto'` (the python pool resolves NPU > GPU >
|
|
3298
|
-
* CPU at load). Because OpenVINO is only ever OFFERED when an Intel iGPU is
|
|
3299
|
-
* present, the GPU is the guaranteed accelerator while the NPU is an explicit
|
|
3300
|
-
* opt-in — so `'auto'` (and any non-cpu/non-npu device) is treated as
|
|
3301
|
-
* GPU-class conservatively. An operator who explicitly pins `device: 'npu'`
|
|
3302
|
-
* gets the NPU-tuned m-320.
|
|
3303
|
-
*
|
|
3304
|
-
* Also accepts the accelerator carried in the `backend` slot (e.g. `'ane'`,
|
|
3305
|
-
* `'mps'`, `'npu'`, `'intel-gpu'`) so a caller passing a device-style backend
|
|
3306
|
-
* still classifies correctly — real callers pass onnx/openvino/coreml.
|
|
3307
|
-
*/
|
|
3308
|
-
function classifyAccelerator(backend, device) {
|
|
3309
|
-
const b = backend.toLowerCase();
|
|
3310
|
-
const d = device?.toLowerCase() ?? null;
|
|
3311
|
-
if (b === "coreml" || b === "ane" || b === "mps") return "apple-ane";
|
|
3312
|
-
if (b === "openvino") {
|
|
3313
|
-
if (d === "npu") return "intel-npu";
|
|
3314
|
-
if (d === "cpu") return "cpu";
|
|
3315
|
-
return "intel-gpu";
|
|
3316
|
-
}
|
|
3317
|
-
if (b === "npu" || b === "intel-npu") return "intel-npu";
|
|
3318
|
-
if (b === "gpu" || b === "intel-gpu" || b === "gpu-openvino") return "intel-gpu";
|
|
3319
|
-
return "cpu";
|
|
3320
|
-
}
|
|
3321
|
-
/**
|
|
3322
|
-
* Resolve the hardware-aware default object-detection model id for a node's
|
|
3323
|
-
* engine `(backend, device, format)`.
|
|
3324
|
-
*
|
|
3325
|
-
* Guarantees:
|
|
3326
|
-
* - never throws (hot default-tree path);
|
|
3327
|
-
* - never returns a model id without a build for `format` (unless the step
|
|
3328
|
-
* has ZERO builds for `format`, which is unloadable regardless of pick and
|
|
3329
|
-
* flagged by `collectZeroBuildIssues`) — an unmapped backend, a `'cpu'`
|
|
3330
|
-
* class, a mapped id missing from the catalog, or a mapped id without a
|
|
3331
|
-
* `format` build all fall back to the step's PER-FORMAT default
|
|
3332
|
-
* (`getDefaultModelForFormatFromDef`), NOT the bare `defaultModelId`.
|
|
3333
|
-
*
|
|
3334
|
-
* `getStepDef` is injectable (defaults to the real catalog lookup) so the
|
|
3335
|
-
* missing-build fallback branch is unit-testable without a live catalog —
|
|
3336
|
-
* mirrors `collectZeroBuildIssues`' injection seam.
|
|
3337
|
-
*/
|
|
3338
|
-
function resolveDefaultDetectionModel(backend, device, format, getStepDef = getStepDefinition) {
|
|
3339
|
-
let def;
|
|
3340
|
-
try {
|
|
3341
|
-
def = getStepDef(OBJECT_DETECTION_STEP_ID);
|
|
3342
|
-
} catch {
|
|
3343
|
-
return "yolo26n";
|
|
3344
|
-
}
|
|
3345
|
-
const candidate = MODEL_BY_CLASS[classifyAccelerator(backend, device)];
|
|
3346
|
-
if (candidate !== null) {
|
|
3347
|
-
const entry = def.models.find((m) => m.id === candidate);
|
|
3348
|
-
if (entry && entry.formats[format] !== void 0) return candidate;
|
|
3349
|
-
}
|
|
3350
|
-
return getDefaultModelForFormatFromDef(def, format);
|
|
3351
|
-
}
|
|
3352
|
-
//#endregion
|
|
3353
|
-
export { getStep as _, buildSubtreeCanRun as a, landmarkPrecisionVerdict as b, macroGateVerdict as c, isSessionDecodeReadGone as d, createSessionDecodeCoordinator as f, getDefaultModelForFormat as g, ALL_STEPS as h, mergeCustomModels as i, rootObjectGate as l, ALL_PIPELINE_STEPS as m, resolveDefaultDetectionModel as n, placeDetailStep as o, resolveFrameViewGeometry as p, CustomModelCatalog as r, stepsForElectedPool as s, OBJECT_DETECTION_STEP_ID as t, localFrameRegistry as u, getStepDefinition as v, resolveModelDefaultConfidence as x, resolveModelForFormat as y };
|
|
3412
|
+
export { resolveModelDefaultConfidence as C, landmarkPrecisionVerdict as S, ALL_STEPS as _, stepsForElectedPool as a, getStepDefinition as b, OBJECT_DETECTION_STEP_ID as c, rootObjectGate as d, localFrameRegistry as f, ALL_PIPELINE_STEPS as g, resolveFrameViewGeometry as h, placeDetailStep as i, resolveDefaultDetectionModel as l, createSessionDecodeCoordinator as m, mergeCustomModels as n, deviceKeyOf as o, isSessionDecodeReadGone as p, buildSubtreeCanRun as r, resolveDeviceEngine as s, CustomModelCatalog as t, macroGateVerdict as u, getDefaultModelForFormat as v, resolveModelForFormat as x, getStep as y };
|