Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding container to update models on a schedule #46

Merged
merged 22 commits into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ WORKDIR ${APP_ROOT}

# Copy the remaining files
COPY /app ${APP_ROOT}/app/

# Copy model updating code
COPY model_updater ${APP_ROOT}/model_updater

COPY --from=production-dependencies-build-stage ${APP_ROOT}/configs/nginx.conf /etc/nginx/nginx.conf

# Remove default nginx config
Expand Down
8 changes: 4 additions & 4 deletions app/core/configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ class LocalInferenceConfig(BaseModel):
"""

enabled: bool = Field(False, description="Determines if local edge inference is enabled for a specific detector.")
refresh_every: float = Field(
3600.0,
refresh_rate: float = Field(
120.0,
description=(
"The refresh rate for the inference server (in seconds). This means how often to check for an updated model"
" binary (currently unused)."
" binary."
),
)

Expand Down Expand Up @@ -80,7 +80,7 @@ def validate_templates(
'local_inference_templates': {
'default': LocalInferenceConfig(
enabled=True,
refresh_every=3600.0
refresh_rate=120.0
)
}
}
Expand Down
16 changes: 0 additions & 16 deletions app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,3 @@
app.include_router(router=ping_router)

app.state.app_state = AppState()


@app.on_event("startup")
async def on_startup():
"""
On startup, update edge inference models.
"""
if not os.environ.get("DEPLOY_DETECTOR_LEVEL_INFERENCE", None):
return

for detector_id, inference_config in app.state.app_state.edge_inference_manager.inference_config.items():
if inference_config.enabled:
try:
app.state.app_state.edge_inference_manager.update_model(detector_id)
except Exception:
logging.error(f"Failed to update model for {detector_id}", exc_info=True)
6 changes: 1 addition & 5 deletions configs/edge-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,7 @@ local_inference_templates:
default:
enabled: true
# How often to fetch a new model binary (in seconds)
refresh_every: 3600

super-fast-refresh:
enabled: true
refresh_every: 60
refresh_rate: 120

disabled:
enabled: false
Expand Down
25 changes: 23 additions & 2 deletions deploy/k3s/edge_deployment/edge_deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ spec:
serviceAccountName: edge-endpoint-service-account
containers:
- name: edge-endpoint
image: 723181461334.dkr.ecr.us-west-2.amazonaws.com/edge-endpoint:13361241c-state-management-via-k3s
image: 723181461334.dkr.ecr.us-west-2.amazonaws.com/edge-endpoint:6ef532de5-model-updater
imagePullPolicy: IfNotPresent
ports:
- containerPort: 6717
Expand All @@ -56,12 +56,33 @@ spec:
key: api-token
volumeMounts:
- name: edge-config-volume
# This is a path inside the container not the host
mountPath: /etc/groundlight/edge-config
- name: inference-deployment-template-volume
mountPath: /etc/groundlight/inference-deployment
- name: model-repo
mountPath: /mnt/models

- name: inference-model-updater
image: 723181461334.dkr.ecr.us-west-2.amazonaws.com/edge-endpoint:6ef532de5-model-updater
imagePullPolicy: IfNotPresent
command: ["/bin/bash", "-c"]
args: ["poetry run python -m model_updater.update_models"]
env:
- name: LOG_LEVEL
value: "INFO"
- name: DEPLOY_DETECTOR_LEVEL_INFERENCE
value: "True"
- name: GROUNDLIGHT_API_TOKEN
valueFrom:
secretKeyRef:
name: groundlight-secrets
key: api-token
volumeMounts:
- name: edge-config-volume
mountPath: /etc/groundlight/edge-config
- name: model-repo
mountPath: /mnt/models

imagePullSecrets:
- name: registry-credentials
volumes:
Expand Down
Empty file added model_updater/__init__.py
Empty file.
45 changes: 45 additions & 0 deletions model_updater/update_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import os
import logging
import time
from app.core.app_state import load_edge_config
from app.core.configs import RootEdgeConfig
from app.core.edge_inference import EdgeInferenceManager

log_level = os.environ.get("LOG_LEVEL", "INFO").upper()
logging.basicConfig(level=log_level)


def update_models(edge_inference_manager: EdgeInferenceManager):
if not os.environ.get("DEPLOY_DETECTOR_LEVEL_INFERENCE", None) or not edge_inference_manager.inference_config:
return

inference_config = edge_inference_manager.inference_config

# All detectors should have the same refresh rate.
refresh_rates = [config.refresh_rate for config in inference_config.values()]
if set(refresh_rates) != 1:
logging.error(f"Detectors have different refresh rates.")

refresh_rate = refresh_rates[0]

while True:
for detector_id, config in inference_config.items():
if config.enabled:
try:
edge_inference_manager.update_model(detector_id=detector_id)
except Exception as e:
logging.error(f"Failed to update model for {detector_id}. {e}", exc_info=True)

time.sleep(refresh_rate)


if __name__ == "__main__":
edge_config: RootEdgeConfig = load_edge_config()
edge_inference_templates = edge_config.local_inference_templates
inference_config = {
detector.detector_id: edge_inference_templates[detector.local_inference_template]
for detector in edge_config.detectors
}
edge_inference_manager = EdgeInferenceManager(config=inference_config, verbose=True)

update_models(edge_inference_manager=edge_inference_manager)
1 change: 1 addition & 0 deletions test/setup_inference_test_env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ motion_detection_templates:
local_inference_templates:
default:
enabled: true
refresh_rate: 120
disabled:
enabled: false

Expand Down