Spaces:
Running
Running
ExecuTorch optimization, UI improvements..
Browse files- .gitattributes +1 -0
- README.md +1 -1
- backend/model.py +7 -7
- frontend/initial.html +9 -10
- frontend/vehicles.html +19 -6
- requirements.txt +1 -4
.gitattributes
CHANGED
|
@@ -21,6 +21,7 @@
|
|
| 21 |
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 22 |
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 23 |
*.pt filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 24 |
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 25 |
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 26 |
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 21 |
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 22 |
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 23 |
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 24 |
+
*.pte filter=lfs diff=lfs merge=lfs -text
|
| 25 |
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 26 |
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 27 |
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
README.md
CHANGED
|
@@ -18,7 +18,7 @@ Full-stack traffic analytics dashboard. YOLO + ByteTrack backend processes uploa
|
|
| 18 |
|
| 19 |
## Stack
|
| 20 |
|
| 21 |
-
- **Backend**: FastAPI, Ultralytics YOLO (
|
| 22 |
- **Frontend**: Vanilla HTML/JS, TailwindCSS CDN, Chart.js
|
| 23 |
- **Infra**: Docker, CPU-only inference
|
| 24 |
|
|
|
|
| 18 |
|
| 19 |
## Stack
|
| 20 |
|
| 21 |
+
- **Backend**: FastAPI, Ultralytics YOLO (ExecuTorch), ByteTrack, OpenCV
|
| 22 |
- **Frontend**: Vanilla HTML/JS, TailwindCSS CDN, Chart.js
|
| 23 |
- **Infra**: Docker, CPU-only inference
|
| 24 |
|
backend/model.py
CHANGED
|
@@ -7,10 +7,10 @@ load_dotenv()
|
|
| 7 |
|
| 8 |
MODEL_DIR = Path(__file__).parent / "weights"
|
| 9 |
PT_PATH = MODEL_DIR / "best.pt"
|
| 10 |
-
|
| 11 |
|
| 12 |
|
| 13 |
-
def
|
| 14 |
MODEL_DIR.mkdir(exist_ok=True)
|
| 15 |
|
| 16 |
if not PT_PATH.exists():
|
|
@@ -21,11 +21,11 @@ def ensure_openvino():
|
|
| 21 |
f'https://huggingface.co/Perception365/VehicleNet-Y26s/resolve/main/weights/best.pt'
|
| 22 |
)
|
| 23 |
|
| 24 |
-
# https://docs.ultralytics.com/
|
| 25 |
-
if not
|
| 26 |
-
YOLO(str(PT_PATH)).export(format="
|
| 27 |
|
| 28 |
|
| 29 |
def load_model():
|
| 30 |
-
|
| 31 |
-
return YOLO(str(
|
|
|
|
| 7 |
|
| 8 |
MODEL_DIR = Path(__file__).parent / "weights"
|
| 9 |
PT_PATH = MODEL_DIR / "best.pt"
|
| 10 |
+
ET_DIR = MODEL_DIR / "yolo26n_executorch_model"
|
| 11 |
|
| 12 |
|
| 13 |
+
def ensure_executorch():
|
| 14 |
MODEL_DIR.mkdir(exist_ok=True)
|
| 15 |
|
| 16 |
if not PT_PATH.exists():
|
|
|
|
| 21 |
f'https://huggingface.co/Perception365/VehicleNet-Y26s/resolve/main/weights/best.pt'
|
| 22 |
)
|
| 23 |
|
| 24 |
+
# https://docs.ultralytics.com/integrations/executorch/
|
| 25 |
+
if not ET_DIR.exists():
|
| 26 |
+
YOLO(str(PT_PATH)).export(format="executorch", device='cpu')
|
| 27 |
|
| 28 |
|
| 29 |
def load_model():
|
| 30 |
+
ensure_executorch()
|
| 31 |
+
return YOLO(str(ET_DIR), task="detect")
|
frontend/initial.html
CHANGED
|
@@ -85,7 +85,7 @@
|
|
| 85 |
</h1>
|
| 86 |
<p class="font-bold mb-8 text-sm uppercase tracking-[0.2em] text-neutral-500 flex items-center">
|
| 87 |
<span class="core-badge px-3 py-1 rounded-full text-[10px] mr-3">v1.0 CORE</span>
|
| 88 |
-
Powered by Deep Learning
|
| 89 |
</p>
|
| 90 |
<ul class="space-y-4 xl:space-y-5 text-base xl:text-lg font-medium text-neutral-400">
|
| 91 |
<li class="flex items-center"><i class="fa-solid fa-check text-white mr-5 text-xl"></i> Real-time
|
|
@@ -107,7 +107,7 @@
|
|
| 107 |
<!-- STEP: Modules -->
|
| 108 |
<div id="step-modules" class="w-full flex flex-col fade-in">
|
| 109 |
<h2 class="text-3xl font-bold mb-2 text-white text-center">UrbanFlow</h2>
|
| 110 |
-
<p class="text-[13px] font-medium text-neutral-500 mb-8 text-center">Select
|
| 111 |
proceed.</p>
|
| 112 |
|
| 113 |
<div class="flex justify-center w-full">
|
|
@@ -115,7 +115,7 @@
|
|
| 115 |
class="group relative border-2 border-white rounded-[2rem] p-8 cursor-pointer hover:-translate-y-1 transition-all duration-300 text-center max-w-sm w-full traffic-dynamics-card">
|
| 116 |
<div
|
| 117 |
class="absolute top-4 right-6 bg-white text-black text-[9px] font-bold px-2.5 py-1 rounded-full uppercase tracking-wider">
|
| 118 |
-
|
| 119 |
<i class="fa-solid fa-car-side text-4xl text-white mb-4 block mx-auto"></i>
|
| 120 |
<h3 class="font-bold text-lg mb-2 leading-tight text-white">Traffic <br>Dynamics</h3>
|
| 121 |
<p class="text-[10px] text-neutral-500 font-medium leading-relaxed">Detect, track, and analyze
|
|
@@ -128,11 +128,10 @@
|
|
| 128 |
<div id="step-upload" class="hidden w-full flex flex-col fade-in">
|
| 129 |
<button onclick="showStep('modules')"
|
| 130 |
class="text-neutral-500 hover:text-white transition flex items-center text-xs font-bold uppercase tracking-widest mb-6 w-fit">
|
| 131 |
-
<i class="fa-solid fa-arrow-left mr-2"></i> Back
|
| 132 |
</button>
|
| 133 |
-
<h2 class="text-3xl font-bold mb-2 text-white text-center">Define Media
|
| 134 |
-
<p class="text-[13px] font-medium text-neutral-500 mb-8 text-center">Provide
|
| 135 |
-
initialize the pipeline.</p>
|
| 136 |
|
| 137 |
<input id="file-input" type="file" accept="video/*" class="hidden">
|
| 138 |
<div id="dropzone" onclick="document.getElementById('file-input').click()"
|
|
@@ -160,8 +159,8 @@
|
|
| 160 |
<!-- STEP: Draw -->
|
| 161 |
<div id="step-draw" class="hidden w-full flex flex-col fade-in">
|
| 162 |
<h2 class="text-3xl font-bold mb-2 text-white text-center">Define Boundary</h2>
|
| 163 |
-
<p class="text-[11px] font-bold uppercase tracking-widest text-neutral-500 mb-6 text-center">
|
| 164 |
-
counting threshold
|
| 165 |
|
| 166 |
<div
|
| 167 |
class="relative w-full aspect-video bg-neutral-950 rounded-3xl overflow-hidden cursor-crosshair mb-6">
|
|
@@ -179,7 +178,7 @@
|
|
| 179 |
<button onclick="resetCanvas()"
|
| 180 |
class="w-1/3 py-3.5 bg-neutral-900 border border-neutral-800 text-white rounded-full font-bold hover:bg-neutral-800 transition-all text-sm">Reset</button>
|
| 181 |
<button id="btn-proceed" onclick="startRun()"
|
| 182 |
-
class="w-2/3 py-3.5 bg-
|
| 183 |
→</button>
|
| 184 |
</div>
|
| 185 |
</div>
|
|
|
|
| 85 |
</h1>
|
| 86 |
<p class="font-bold mb-8 text-sm uppercase tracking-[0.2em] text-neutral-500 flex items-center">
|
| 87 |
<span class="core-badge px-3 py-1 rounded-full text-[10px] mr-3">v1.0 CORE</span>
|
| 88 |
+
Powered by Deep Learning
|
| 89 |
</p>
|
| 90 |
<ul class="space-y-4 xl:space-y-5 text-base xl:text-lg font-medium text-neutral-400">
|
| 91 |
<li class="flex items-center"><i class="fa-solid fa-check text-white mr-5 text-xl"></i> Real-time
|
|
|
|
| 107 |
<!-- STEP: Modules -->
|
| 108 |
<div id="step-modules" class="w-full flex flex-col fade-in">
|
| 109 |
<h2 class="text-3xl font-bold mb-2 text-white text-center">UrbanFlow</h2>
|
| 110 |
+
<p class="text-[13px] font-medium text-neutral-500 mb-8 text-center">Select below analytical pipeline to
|
| 111 |
proceed.</p>
|
| 112 |
|
| 113 |
<div class="flex justify-center w-full">
|
|
|
|
| 115 |
class="group relative border-2 border-white rounded-[2rem] p-8 cursor-pointer hover:-translate-y-1 transition-all duration-300 text-center max-w-sm w-full traffic-dynamics-card">
|
| 116 |
<div
|
| 117 |
class="absolute top-4 right-6 bg-white text-black text-[9px] font-bold px-2.5 py-1 rounded-full uppercase tracking-wider">
|
| 118 |
+
V1.0</div>
|
| 119 |
<i class="fa-solid fa-car-side text-4xl text-white mb-4 block mx-auto"></i>
|
| 120 |
<h3 class="font-bold text-lg mb-2 leading-tight text-white">Traffic <br>Dynamics</h3>
|
| 121 |
<p class="text-[10px] text-neutral-500 font-medium leading-relaxed">Detect, track, and analyze
|
|
|
|
| 128 |
<div id="step-upload" class="hidden w-full flex flex-col fade-in">
|
| 129 |
<button onclick="showStep('modules')"
|
| 130 |
class="text-neutral-500 hover:text-white transition flex items-center text-xs font-bold uppercase tracking-widest mb-6 w-fit">
|
| 131 |
+
<i class="fa-solid fa-arrow-left mr-2"></i> Back
|
| 132 |
</button>
|
| 133 |
+
<h2 class="text-3xl font-bold mb-2 text-white text-center">Define Media</h2>
|
| 134 |
+
<p class="text-[13px] font-medium text-neutral-500 mb-8 text-center">Provide a target video footage. </p>
|
|
|
|
| 135 |
|
| 136 |
<input id="file-input" type="file" accept="video/*" class="hidden">
|
| 137 |
<div id="dropzone" onclick="document.getElementById('file-input').click()"
|
|
|
|
| 159 |
<!-- STEP: Draw -->
|
| 160 |
<div id="step-draw" class="hidden w-full flex flex-col fade-in">
|
| 161 |
<h2 class="text-3xl font-bold mb-2 text-white text-center">Define Boundary</h2>
|
| 162 |
+
<p class="text-[11px] font-bold uppercase tracking-widest text-neutral-500 mb-6 text-center">Mark two
|
| 163 |
+
points to define counting threshold</p>
|
| 164 |
|
| 165 |
<div
|
| 166 |
class="relative w-full aspect-video bg-neutral-950 rounded-3xl overflow-hidden cursor-crosshair mb-6">
|
|
|
|
| 178 |
<button onclick="resetCanvas()"
|
| 179 |
class="w-1/3 py-3.5 bg-neutral-900 border border-neutral-800 text-white rounded-full font-bold hover:bg-neutral-800 transition-all text-sm">Reset</button>
|
| 180 |
<button id="btn-proceed" onclick="startRun()"
|
| 181 |
+
class="w-2/3 py-3.5 bg-white text-black rounded-full font-bold transition-all text-center text-sm">Continue
|
| 182 |
→</button>
|
| 183 |
</div>
|
| 184 |
</div>
|
frontend/vehicles.html
CHANGED
|
@@ -421,7 +421,7 @@
|
|
| 421 |
<ul class="text-xs space-y-3 pl-1">
|
| 422 |
<li class="flex items-start gap-3"><i
|
| 423 |
class="fa-solid fa-circle text-[5px] mt-1.5 text-slate-400"></i>
|
| 424 |
-
<span>
|
| 425 |
</li>
|
| 426 |
<li class="flex items-start gap-3"><i
|
| 427 |
class="fa-solid fa-circle text-[5px] mt-1.5 text-slate-400"></i>
|
|
@@ -574,7 +574,7 @@
|
|
| 574 |
</div>
|
| 575 |
|
| 576 |
<!-- Technical Context Row -->
|
| 577 |
-
<div class="grid grid-cols-
|
| 578 |
<div class="bg-white rounded-xl border border-slate-200 shadow-sm flex flex-col overflow-hidden">
|
| 579 |
<div class="px-6 py-4 border-b border-slate-100 bg-slate-50/50">
|
| 580 |
<h3 class="font-bold text-slate-800 text-sm">Stream Source Profile</h3>
|
|
@@ -589,10 +589,16 @@
|
|
| 589 |
</div>
|
| 590 |
<div class="bg-white rounded-xl border border-slate-200 shadow-sm flex flex-col overflow-hidden">
|
| 591 |
<div class="px-6 py-4 border-b border-slate-100 bg-slate-50/50">
|
| 592 |
-
<h3 class="font-bold text-slate-800 text-sm">Model Architecture & Logic</h3>
|
| 593 |
</div>
|
| 594 |
<div class="p-6 space-y-4" id="panel-model"></div>
|
| 595 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 596 |
</div>
|
| 597 |
|
| 598 |
</div>
|
|
@@ -882,14 +888,18 @@
|
|
| 882 |
<a href="https://huggingface.co/Perception365/VehicleNet-Y26s" target="_blank" class="text-sm font-bold text-white mono-font hover:text-slate-300 transition underline underline-offset-4 decoration-slate-700">Perception365/VehicleNet-Y26s</a>
|
| 883 |
</div>` +
|
| 884 |
detailRow('task', 'detect') +
|
| 885 |
-
detailRow('format', '
|
| 886 |
detailRow('tracker', 'ByteTrack');
|
| 887 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 888 |
document.getElementById('panel-infer').innerHTML =
|
| 889 |
infoRow('imgsz', c.imgsz, 'Input image resolution for model inference.') +
|
| 890 |
infoRow('vid_stride', c.detect_stride, 'Frames skipped between consecutive detections relative to the spatial boundary.') +
|
| 891 |
-
infoRow('conf', c.conf || 0.12, 'Minimum confidence threshold for valid detections.') +
|
| 892 |
-
infoRow('iou', c.iou || 0.60, 'Intersection-over-Union threshold for non-max suppression.') +
|
| 893 |
infoRow('stream', 'TRUE', 'Frame-by-frame processing for constant memory usage.') +
|
| 894 |
infoRow('verbose', 'FALSE', 'Console logging suppressed during inference.');
|
| 895 |
}
|
|
@@ -1218,6 +1228,9 @@
|
|
| 1218 |
_params.config.iou = iou;
|
| 1219 |
_params.config.detect_stride = stride;
|
| 1220 |
|
|
|
|
|
|
|
|
|
|
| 1221 |
// Lock settings
|
| 1222 |
lockSettings();
|
| 1223 |
|
|
|
|
| 421 |
<ul class="text-xs space-y-3 pl-1">
|
| 422 |
<li class="flex items-start gap-3"><i
|
| 423 |
class="fa-solid fa-circle text-[5px] mt-1.5 text-slate-400"></i>
|
| 424 |
+
<span>ExecuTorch Performance Optimization</span>
|
| 425 |
</li>
|
| 426 |
<li class="flex items-start gap-3"><i
|
| 427 |
class="fa-solid fa-circle text-[5px] mt-1.5 text-slate-400"></i>
|
|
|
|
| 574 |
</div>
|
| 575 |
|
| 576 |
<!-- Technical Context Row -->
|
| 577 |
+
<div class="grid grid-cols-2 gap-6">
|
| 578 |
<div class="bg-white rounded-xl border border-slate-200 shadow-sm flex flex-col overflow-hidden">
|
| 579 |
<div class="px-6 py-4 border-b border-slate-100 bg-slate-50/50">
|
| 580 |
<h3 class="font-bold text-slate-800 text-sm">Stream Source Profile</h3>
|
|
|
|
| 589 |
</div>
|
| 590 |
<div class="bg-white rounded-xl border border-slate-200 shadow-sm flex flex-col overflow-hidden">
|
| 591 |
<div class="px-6 py-4 border-b border-slate-100 bg-slate-50/50">
|
| 592 |
+
<h3 class="font-bold text-slate-800 text-sm">Model Architecture & Logic</h3>
|
| 593 |
</div>
|
| 594 |
<div class="p-6 space-y-4" id="panel-model"></div>
|
| 595 |
</div>
|
| 596 |
+
<div class="bg-white rounded-xl border border-slate-200 shadow-sm flex flex-col overflow-hidden">
|
| 597 |
+
<div class="px-6 py-4 border-b border-slate-100 bg-slate-50/50">
|
| 598 |
+
<h3 class="font-bold text-slate-800 text-sm">Inference Parameters</h3>
|
| 599 |
+
</div>
|
| 600 |
+
<div class="p-6 space-y-4" id="panel-infer"></div>
|
| 601 |
+
</div>
|
| 602 |
</div>
|
| 603 |
|
| 604 |
</div>
|
|
|
|
| 888 |
<a href="https://huggingface.co/Perception365/VehicleNet-Y26s" target="_blank" class="text-sm font-bold text-white mono-font hover:text-slate-300 transition underline underline-offset-4 decoration-slate-700">Perception365/VehicleNet-Y26s</a>
|
| 889 |
</div>` +
|
| 890 |
detailRow('task', 'detect') +
|
| 891 |
+
detailRow('format', 'ExecuTorch') +
|
| 892 |
detailRow('tracker', 'ByteTrack');
|
| 893 |
|
| 894 |
+
populateInferPanel(c);
|
| 895 |
+
}
|
| 896 |
+
|
| 897 |
+
function populateInferPanel(c) {
|
| 898 |
document.getElementById('panel-infer').innerHTML =
|
| 899 |
infoRow('imgsz', c.imgsz, 'Input image resolution for model inference.') +
|
| 900 |
infoRow('vid_stride', c.detect_stride, 'Frames skipped between consecutive detections relative to the spatial boundary.') +
|
| 901 |
+
infoRow('conf', (c.conf || 0.12).toFixed(2), 'Minimum confidence threshold for valid detections.') +
|
| 902 |
+
infoRow('iou', (c.iou || 0.60).toFixed(2), 'Intersection-over-Union threshold for non-max suppression.') +
|
| 903 |
infoRow('stream', 'TRUE', 'Frame-by-frame processing for constant memory usage.') +
|
| 904 |
infoRow('verbose', 'FALSE', 'Console logging suppressed during inference.');
|
| 905 |
}
|
|
|
|
| 1228 |
_params.config.iou = iou;
|
| 1229 |
_params.config.detect_stride = stride;
|
| 1230 |
|
| 1231 |
+
// Reflect final resolved params in Run tab
|
| 1232 |
+
populateInferPanel(_params.config);
|
| 1233 |
+
|
| 1234 |
// Lock settings
|
| 1235 |
lockSettings();
|
| 1236 |
|
requirements.txt
CHANGED
|
@@ -7,10 +7,7 @@ ultralytics>=8.3.0
|
|
| 7 |
numpy==1.24.3
|
| 8 |
python-dotenv==1.0.0
|
| 9 |
websockets==12.0
|
| 10 |
-
|
| 11 |
-
openvino>=2024.0.0
|
| 12 |
-
onnx>=1.12.0
|
| 13 |
-
onnxslim>=0.1.71
|
| 14 |
lap>=0.5.12
|
| 15 |
torch==2.1.0+cpu
|
| 16 |
torchvision==0.16.0+cpu
|
|
|
|
| 7 |
numpy==1.24.3
|
| 8 |
python-dotenv==1.0.0
|
| 9 |
websockets==12.0
|
| 10 |
+
executorch
|
|
|
|
|
|
|
|
|
|
| 11 |
lap>=0.5.12
|
| 12 |
torch==2.1.0+cpu
|
| 13 |
torchvision==0.16.0+cpu
|