The budget is the specification
ICCS is specified the way an air-gapped installation is actually bought: one GPU node, procured once, with no option to add a second when the model list grows. Eighty configured cameras. Up to four autonomous drones over MAVLink and ArduPilot. Eleven capability domains, all competing for the same host. The compute budget is therefore not a constraint discovered during optimisation — it is the specification the detection stack is designed against from the first line of it.
The full stack occupies approximately 28 GB of VRAM. That figure is a design target the stack is held to, not a number discovered at the end. Every model admitted to the ensemble justifies its share of it, and admitting a ninth means finding headroom or removing something. Publishing the number is a commitment: a head of engineering can hold it against a card they already own and work out whether this runs on their hardware before they speak to us.
What follows is how eight models fit inside that envelope while still processing live feeds — the fusion step that makes an ensemble worth having, the gating that decides when to run it at all, the tile budget that bounds the worst case, and the reason the first resource to saturate on a node like this is the CPU.
Why eight models rather than one good one
A single detector is a set of blind spots you have agreed to live with. A primary detector trained on a closed label set is fast and dependable on the classes it knows, and silent on everything else. A transformer detector reads context differently and holds up where the primary loses a partially occluded object. Open-vocabulary and grounding models answer for the things nobody enumerated at training time, described in language rather than as a class index.
The rest of the stack exists because a perimeter is not one sensing problem. Thermal and infrared inference covers the hours when the visible-light models are working with almost nothing. Sliced-tile inference finds the small distant object that collapses into a handful of pixels at full-frame scale. A counter-UAS tracker follows an airborne track that behaves nothing like a person on the ground. Pose and behaviour inference separates someone walking a fence line from someone climbing it.
Eight specialised models with overlapping coverage beat one general model at a fixed budget — provided their disagreements are resolved properly. Without that, an ensemble is eight opinions and an operator left to arbitrate between them at three in the morning, which is not a detection system but a queue. The arbitration has to happen in software, before anything reaches a screen.
Weighted Box Fusion, and what it buys
Eight models looking at one frame produce eight sets of boxes that mostly agree and occasionally do not. Weighted Box Fusion resolves them into one set, merging overlapping detections into a single box weighted by the confidence behind each contributor rather than keeping the strongest and discarding the rest. The distinction matters: suppression throws away agreement, and agreement between independently trained models is the most useful signal in the whole system.
Fusion is also where per-model trust is expressed. A detector that is reliable on its own classes and unreliable outside them contributes accordingly. Two weak but independent detections of the same object reinforce each other; one confident detection no other model supports is graded lower than it would be alone. This is what turns an ensemble into a single confidence figure an alerting policy can act on without further interpretation.
Downstream, one fused output means one alert path. Three-level grading, a priority queue, auto-pin of the alerting feed and 50 ms WebSocket batching all operate on fused detections rather than on per-model output. The operator sees an event, not an ensemble. ARGUS, a separate air-gapped programme on a different detection stack, was measured at 97.8% detection accuracy and a 0.18% false-positive rate across more than forty concurrent feeds. That is a figure for ARGUS and not for this ensemble; we publish no accuracy number for ICCS, because we have not measured one we would be willing to defend.
Motion gating: the cheapest inference is the one you skip
Eighty cameras running eight models on every frame is arithmetic that does not close on one node, and it is also mostly waste. A perimeter camera spends most of its life looking at a static scene. Motion gating puts a cheap decision in front of an expensive one: the ensemble runs on a feed when something in it has changed, and does not run when nothing has. Everything else in the budget is bought with what that saves.
The gate has to be cheap enough to be worth having and honest enough to be trusted. Too permissive and it gates nothing, so the budget is spent on empty scenes; too aggressive and it discards the slow-moving object that mattered, which is the failure nobody forgives. Day and night handling is per-camera for the same reason — a gate tuned for daylight behaves differently under infrared illumination, and one global threshold serves neither case well.
Gating is what converts a fixed hardware budget into elastic capability. On a quiet perimeter the gate keeps ensemble work off almost every one of the eighty configured feeds. Under simultaneous activity across many sectors the ensemble is running on many feeds at once, and the budget has to hold there too — which is what the tile budget is for. Designing only for the quiet case produces a system that degrades exactly when it is being used.
The global tile budget
Sliced-tile inference is the expensive member of the ensemble. To find a small object at distance, the frame is divided into tiles and each tile is inferred at higher effective resolution. Cost scales with tile count, and tile count scales with the number of active feeds — so the feature that makes distant detection possible is also the one that can consume the entire node during a busy minute.
So the budget is global rather than per-camera. There is a ceiling on tiles processed across the whole system, and tiles are allocated against it instead of handed out as a fixed allowance per feed. A per-camera cap looks fairer and behaves worse: it under-serves the sector where something is happening while reserving capacity for the sectors where nothing is, which is the opposite of what a perimeter needs.
A global ceiling also makes the worst case bounded and testable. The maximum load the detection stack can place on the node becomes a known quantity rather than an emergent property of how many cameras happened to see motion at the same moment. Per-camera circuit breakers and an engine liveness heartbeat cover the remainder: a feed that misbehaves is isolated, and a stalled engine is detected rather than assumed healthy.
Why eighty cameras on one node is CPU-bound
The expectation is that a detection platform is limited by its GPU. On this profile it is not. Eighty configured cameras run on a single GPU node with roughly fifteen to twenty concurrently active 1440p streams, and the resource that runs out first is the CPU. Inference is only one stage of the pipeline: every stream is pulled over the network, demuxed, decoded, colour-converted and resized before a model sees a tensor, then re-encoded for recording and for the operator’s view.
Decode at 1440p dominates, and it is paid per active stream whether or not the ensemble ever runs on that frame. Gating saves GPU work; it does not save the decode that produced the frame the gate examined. That is why the honest figure is fifteen to twenty concurrently active streams rather than eighty simultaneous ones, and why both numbers are published — configured capacity and concurrent activity are different questions, and a buyer needs the second.
Knowing which resource binds changes what you buy. A larger card does not raise the concurrent stream count on this profile; core count, decode capability and how the video path is written do. It is the kind of finding that only comes out of running the entire loop — ingest, gate, fuse, alert, record, stream — on one machine, which is the only configuration the customer is ever going to have.
Programmes referenced by codename are classified engagements. Capability, engineering and measured outcome are described in full; the client, the installation and the unit are not named anywhere — disclosure policy.