diff --git a/docker-compose.raspberrypi.yml b/docker-compose.raspberrypi.yml deleted file mode 100644 index 2e40584c..00000000 --- a/docker-compose.raspberrypi.yml +++ /dev/null @@ -1,33 +0,0 @@ -services: - edge_db: - image: webhippie/mongodb:latest-arm32v7 - container_name: edge_db - ports: - - 27017:27017 - - edge_model_serving: - container_name: edge_model_serving - image: ghcr.io/octo-technology/vio/edge_tflite_serving.raspberrypi:latest - environment: - - TF_CPP_MIN_VLOG_LEVEL=0 - ports: - - 8501:8501 - volumes: - - ./edge_model_serving:/models - - edge_orchestrator: - container_name: edge_orchestrator - image: ghcr.io/octo-technology/vio/edge_orchestrator.raspberrypi:latest - privileged: true - volumes: - - ./edge_orchestrator/data:/edge_orchestrator/data - - ./edge_orchestrator/config:/edge_orchestrator/config - - /opt/vc:/opt/vc - ports: - - 8000:8000 - - edge_interface: - container_name: edge_interface - image: ghcr.io/octo-technology/vio/edge_interface.raspberrypi:latest - ports: - - 8080:80 diff --git a/docker-compose.yml b/docker-compose.yml index 82e2596c..6e79b175 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,18 +1,8 @@ services: edge_model_serving: - container_name: edge_model_serving - build: - context: edge_model_serving - dockerfile: tflite_serving/Dockerfile - args: - BUILDOS: ${BUILDOS:-linux} - environment: - TF_CPP_MIN_VLOG_LEVEL: 0 - ports: - - 8501:8501 - profiles: [edge] - volumes: - - ./edge_model_serving/models:/models + extends: + file: edge_model_serving/tflite_serving/edge_model_serving.yml + service: edge_model_serving edge_orchestrator: extends: @@ -34,13 +24,9 @@ services: profiles: [hub] edge_interface: - container_name: edge_interface - build: - context: edge_interface - dockerfile: Dockerfile - ports: - - 8080:80 - profiles: [edge] + extends: + file: edge_interface/edge_interface.yml + service: edge_interface hub_streamlit: container_name: hub_streamlit diff --git a/edge_interface/Makefile b/edge_interface/Makefile new file mode 100644 index 00000000..854bf2bf --- /dev/null +++ b/edge_interface/Makefile @@ -0,0 +1,34 @@ +SHELL := /bin/bash +.SHELLFLAGS = -ec +.ONESHELL: +.SILENT: + +.EXPORT_ALL_VARIABLES: +.DEFAULT_GOAL: help + +REPO_DIRECTORY:=$(shell pwd) +PYTHONPATH:=${PYTHONPATH}:${REPO_DIRECTORY} +BUILDOS=$(shell uname -s | tr '[:upper:]' '[:lower:]') + + +.PHONY: help +help: + echo "❓ Use \`make '" + grep -E '^\.PHONY: [a-zA-Z0-9_-]+ .*?## .*$$' $(MAKEFILE_LIST) | \ + awk 'BEGIN {FS = "(: |##)"}; {printf "\033[36m%-30s\033[0m %s\n", $$2, $$3}' + +.PHONY: install ## ⏬ Install development dependencies +install: + npm install + +.PHONY: run_edge_interface ## ✅ Launch the tflite serving app +run_edge_interface: + npm run serve + +.PHONY: start_edge_interface ## 🕵 Start edge_interface service (Docker container) +start_edge_interface: + BUILDOS=${BUILDOS} docker compose --file edge_interface.yml up edge_interface -d --build + +.PHONY: stop_edge_interface ## 🕵 Stop edge_interface service (Docker container) +stop_edge_interface: + docker compose --file edge_interface.yml down edge_interface diff --git a/edge_interface/edge_interface.yml b/edge_interface/edge_interface.yml new file mode 100644 index 00000000..03aba74b --- /dev/null +++ b/edge_interface/edge_interface.yml @@ -0,0 +1,9 @@ +services: + edge_interface: + container_name: edge_interface + build: + context: . + dockerfile: Dockerfile + ports: + - 8080:80 + profiles: [edge] diff --git a/edge_model_serving/tflite_serving/Makefile b/edge_model_serving/tflite_serving/Makefile index b1677b13..3e6dc338 100644 --- a/edge_model_serving/tflite_serving/Makefile +++ b/edge_model_serving/tflite_serving/Makefile @@ -4,8 +4,11 @@ SHELL := /bin/bash .SILENT: .EXPORT_ALL_VARIABLES: +.DEFAULT_GOAL: help + REPO_DIRECTORY:=$(shell pwd) PYTHONPATH:=${PYTHONPATH}:${REPO_DIRECTORY} +BUILDOS=$(shell uname -s | tr '[:upper:]' '[:lower:]') .PHONY: help help: @@ -42,3 +45,11 @@ tflite_tests: .PHONY: run_tflite_serving ## ✅ Launch the tflite serving app run_tflite_serving: uvicorn tflite_serving.tflite_server:app --reload --port 8501 --host 0.0.0.0 + +.PHONY: start_edge_model_serving ## 🕵 Start edge_model_serving service (Docker container) +start_edge_model_serving: + BUILDOS=${BUILDOS} docker compose --file edge_model_serving.yml up edge_model_serving -d --build + +.PHONY: stop_edge_model_serving ## 🕵 Stop edge_model_serving service (Docker container) +stop_edge_model_serving: + docker compose --file edge_model_serving.yml down edge_model_serving diff --git a/edge_model_serving/tflite_serving/edge_model_serving.yml b/edge_model_serving/tflite_serving/edge_model_serving.yml new file mode 100644 index 00000000..9ff2963a --- /dev/null +++ b/edge_model_serving/tflite_serving/edge_model_serving.yml @@ -0,0 +1,15 @@ +services: + edge_model_serving: + container_name: edge_model_serving + build: + context: .. + dockerfile: tflite_serving/Dockerfile + args: + BUILDOS: ${BUILDOS:-linux} + volumes: + - ../models:/models + ports: + - 8501:8501 + environment: + TF_CPP_MIN_VLOG_LEVEL: 0 + profiles: [edge] diff --git a/edge_orchestrator/Makefile b/edge_orchestrator/Makefile index af81da5c..f461c63f 100644 --- a/edge_orchestrator/Makefile +++ b/edge_orchestrator/Makefile @@ -83,8 +83,7 @@ pyramid_and_badges: .PHONY: start_edge_orchestrator ## 🕵 Start edge_orchestrator service (Docker container) start_edge_orchestrator: - BUILDOS=${BUILDOS} docker compose --file edge_orchestrator.yml --build up edge_orchestrator -d - + BUILDOS=${BUILDOS} docker compose --file edge_orchestrator.yml up edge_orchestrator -d --build .PHONY: stop_edge_orchestrator ## 🕵 Stop edge_orchestrator service (Docker container) stop_edge_orchestrator: diff --git a/edge_orchestrator/src/edge_orchestrator/domain/models/model_forwarder/model_forwarder_config.py b/edge_orchestrator/src/edge_orchestrator/domain/models/model_forwarder/model_forwarder_config.py index e28a7aef..5ad9993b 100644 --- a/edge_orchestrator/src/edge_orchestrator/domain/models/model_forwarder/model_forwarder_config.py +++ b/edge_orchestrator/src/edge_orchestrator/domain/models/model_forwarder/model_forwarder_config.py @@ -1,5 +1,5 @@ from pathlib import Path -from typing import List, Optional +from typing import List, Optional, Union from pydantic import BaseModel, Field, computed_field, model_validator from pydantic_core import Url @@ -12,7 +12,7 @@ class ModelForwarderConfig(BaseModel): - model_name: ModelName + model_name: Union[str, ModelName] model_type: ModelType expected_image_resolution: ImageResolution model_version: Optional[str] = "1" @@ -23,7 +23,7 @@ class ModelForwarderConfig(BaseModel): @computed_field @property def model_id(self) -> str: - return f"{self.model_name.value}_{self.model_type.value}_{self.model_version}" + return f"{self.model_name}_{self.model_type.value}_{self.model_version}" @model_validator(mode="after") def check_class_names_path(self): diff --git a/edge_orchestrator/src/edge_orchestrator/domain/ports/model_forwarder/i_model_forwarder.py b/edge_orchestrator/src/edge_orchestrator/domain/ports/model_forwarder/i_model_forwarder.py index ec57f2a4..348ed31c 100644 --- a/edge_orchestrator/src/edge_orchestrator/domain/ports/model_forwarder/i_model_forwarder.py +++ b/edge_orchestrator/src/edge_orchestrator/domain/ports/model_forwarder/i_model_forwarder.py @@ -44,7 +44,7 @@ def _build_model_url(base_url: str, model_name: str, model_version: str) -> str: def _get_model_url(self) -> str: return self._build_model_url( str(self._model_forwarder_config.model_serving_url), - self._model_forwarder_config.model_name.value, + self._model_forwarder_config.model_name, self._model_forwarder_config.model_version, ) diff --git a/edge_orchestrator/src/edge_orchestrator/infrastructure/adapters/model_forwarder/object_detection_model_forwarder.py b/edge_orchestrator/src/edge_orchestrator/infrastructure/adapters/model_forwarder/object_detection_model_forwarder.py index e7c1a692..2c672aab 100644 --- a/edge_orchestrator/src/edge_orchestrator/infrastructure/adapters/model_forwarder/object_detection_model_forwarder.py +++ b/edge_orchestrator/src/edge_orchestrator/infrastructure/adapters/model_forwarder/object_detection_model_forwarder.py @@ -37,6 +37,7 @@ def _pre_process_binary(self, binary: bytes) -> np.ndarray: return np.expand_dims(image_array, axis=0).astype(np.uint8)[:, :, :, :3] async def _predict(self, preprocessed_binary: np.ndarray) -> Dict[str, Any]: + # TODO: refactor edge_model_serving to remove model_type from the request model_type = None if self._model_forwarder_config.model_name == ModelName.yolo_coco_nano: model_type = "yolo"