Skip to content

Commit

Permalink
abstract object detection ms to ms dir
Browse files Browse the repository at this point in the history
Signed-off-by: greg pereira <[email protected]>
  • Loading branch information
Gregory-Pereira committed Apr 15, 2024
1 parent dc33008 commit 87c3d80
Show file tree
Hide file tree
Showing 26 changed files with 412 additions and 72 deletions.
10 changes: 9 additions & 1 deletion .github/workflows/model_servers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ jobs:
directory: whispercpp
platforms: linux/amd64,linux/arm64
no_gpu: 1
- image_name: object_detection_python
model: facebook-detr-resnet-101
flavor: base
directory: object_detection_python
platforms: linux/amd64
no_gpu: 1
runs-on: ubuntu-latest
permissions:
contents: read
Expand Down Expand Up @@ -98,7 +104,9 @@ jobs:
- name: Run non-gpu tests
working-directory: ./model_servers/${{ matrix.directory }}/
if: ${{ matrix.no_gpu }}
run: make test REGISTRY=${{ env.REGISTRY }} IMAGE_NAME=${{ env.REGISTRY_ORG }}/${{ matrix.image_name}}:latest
run: make test
env:
IMAGE_NAME=${{ env.REGISTRY_ORG }}/${{ matrix.image_name}}:${{ steps.build_image.outputs.tags }}

# - name: Run cuda test # we dont have cuda tests
# working-directory: ./model_servers/${{ matrix.directory }}/
Expand Down
87 changes: 87 additions & 0 deletions .github/workflows/object_detection.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
name: object_detection

on:
pull_request:
branches:
- main
paths:
- ./recipes/computer_vision/object_detection/**
- .github/workflows/object_detection.yaml
push:
branches:
- main
paths:
- ./recipes/computer_vision/object_detection/**
- .github/workflows/object_detection.yaml

workflow_dispatch:

env:
REGISTRY: ghcr.io
IMAGE_NAME: object_detection
COMPONENT: app

jobs:
build-and-push-image:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
services:
registry:
image: registry:2.8.3
ports:
- 5000:5000
steps:
- uses: actions/[email protected]

- name: Install qemu dependency
run: |
sudo apt-get update
sudo apt-get install -y qemu-user-static
- name: Build Image
id: build_image
uses: redhat-actions/[email protected]
with:
image: ${{ env.REGISTRY }}/${{ github.event.repository.name }}/${{ env.COMPONENT }}/${{ env.IMAGE_NAME }}
tags: latest
platforms: linux/amd64, linux/arm64
containerfiles: ./recipes/computer_vision/${{ env.IMAGE_NAME }}/app/Containerfile
context: recipes/computer_vision/${{ env.IMAGE_NAME }}/app

- name: Set up Python
uses: actions/[email protected]
with:
python-version: '3.11'

- name: Install Dependencies
working-directory: ./recipes/computer_vision/${{ env.IMAGE_NAME }}
run: make install

- name: Download model
working-directory: ./model_servers/object_detection_python
run: make download-model-facebook-detr-resnet-101

# COMING SOON
# - name: Run Functional Tests
# shell: bash
# run: make functional-tests
# working-directory: ./recipes/computer_vision/${{ env.IMAGE_NAME }}

- name: Login to Registry
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
uses: redhat-actions/[email protected]
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Push Image
id: push_image
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
uses: redhat-actions/[email protected]
with:
image: ${{ steps.build_image.outputs.image }}
tags: ${{ steps.build_image.outputs.tags }}
registry: ${{ env.REGISTRY }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ port_check.lock
models/*
!models/Makefile
!models/README.md
model_servers/object_detection_python/detr-resnet-101
convert_models/converted_models
recipes/common/bin/*
*/.venv/
3 changes: 1 addition & 2 deletions convert_models/download_huggingface.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,4 @@

snapshot_download(repo_id=args.model,
local_dir=f"converted_models/{args.model}",
local_dir_use_symlinks=True,
cache_dir=f"converted_models/cache")
local_dir_use_symlinks=True)
15 changes: 11 additions & 4 deletions model_servers/common/Makefile.common
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ REGISTRY ?= quay.io
REGISTRY_ORG ?= ai-lab
COMPONENT ?= model_servers

IMAGE_NAME ?= $(REGISTRY_ORG)/$(COMPONENT)/$(APP):latest
IMAGE := $(REGISTRY)/$(IMAGE_NAME)
CUDA_IMAGE := $(REGISTRY)/$(REGISTRY_ORG)/$(COMPONENT)/$(APP)_cuda:latest
VULKAN_IMAGE := $(REGISTRY)/$(REGISTRY_ORG)/$(COMPONENT)/$(APP)_vulkan:latest


BIND_MOUNT_OPTIONS := ro
OS := $(shell uname -s)
ifeq ($(OS),Linux)
Expand All @@ -10,7 +16,8 @@ endif

.PHONY: build
build:
podman build --squash-all --build-arg $(PORT) -t $(IMAGE) . -f base/Containerfile
-$(MAKE) clean -i
podman build --squash-all --build-arg PORT=$(PORT) -t $(IMAGE) . -f base/Containerfile

.PHONY: install
install:
Expand All @@ -35,13 +42,13 @@ clean:
.PHONY: run
run:
cd ../../models && \
podman run -it -d -p $(PORT):$(PORT) -v ./$(MODEL_NAME):$(MODELS_PATH)/$(MODEL_NAME):$(BIND_MOUNT_OPTIONS) -e MODEL_PATH=$(MODELS_PATH)/$(MODEL_NAME) -e HOST=0.0.0.0 -e PORT=$(PORT) $(IMAGE)
podman run -it -d -p $(PORT):$(PORT) -v ./$(MODEL_NAME):$(MODEL_PATH)/$(MODEL_NAME):$(BIND_MOUNT_OPTIONS) -e MODEL_PATH=$(MODEL_PATH)/$(MODEL_NAME) -e HOST=0.0.0.0 -e PORT=$(PORT) $(IMAGE)

.PHONY: podman-clean
podman-clean:
@container_ids=$$(podman ps --format "{{.ID}} {{.Image}}" | awk '$$2 == "$(IMAGE)" {print $$1}'); \
@container_ids=$$(podman ps -a --format "{{.ID}} {{.Image}}" | awk '$$2 == "$(IMAGE)" {print $$1}'); \
echo "removing all containers with IMAGE=$(IMAGE)"; \
for id in $$container_ids; do \
echo "Removing container: $$id,"; \
echo "Removing container: $$id"; \
podman rm -f $$id; \
done
5 changes: 0 additions & 5 deletions model_servers/llamacpp_python/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@ PORT ?= 8001

include ../common/Makefile.common

IMAGE_NAME ?= $(REGISTRY_ORG)/$(COMPONENT)/$(APP):latest
IMAGE := $(REGISTRY)/$(IMAGE_NAME)
CUDA_IMAGE := $(REGISTRY)/$(REGISTRY_ORG)/$(COMPONENT)/$(APP)_cuda:latest
VULKAN_IMAGE := $(REGISTRY)/$(REGISTRY_ORG)/$(COMPONENT)/$(APP)_vulkan:latest

MODELS_PATH := /locallm/models
MODEL_NAME ?= mistral-7b-instruct-v0.1.Q4_K_M.gguf

Expand Down
23 changes: 23 additions & 0 deletions model_servers/object_detection_python/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
APP := object_detection_python
PORT ?= 8000

include ../../model_servers/common/Makefile.common

MODEL_NAME ?= detr-resnet-101
MODEL_PATH := /app/models

.PHONY: all
all: build download-model-facebook-detr-resnet-101 run

.PHONY: download-model-facebook-detr-resnet-101
download-model-facebook-detr-resnet-101:
pip install -r ../../convert_models/requirements.txt
cd ../../convert_models/ && \
python3 download_huggingface.py -m facebook/detr-resnet-101
cp -r ../../convert_models/converted_models/facebook/detr-resnet-101 ../../models/detr-resnet-101

.PHONY: test
test:
$(MAKE) download-model-facebook-detr-resnet-101
ln -s ../../models/detr-resnet-101 ./
PORT=$(PORT) MODEL_NAME=$(MODEL_NAME) MODEL_PATH=$(MODEL_PATH) IMAGE=$(IMAGE) PULL_ALWAYS=0 pytest -s -vvv
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
FROM registry.access.redhat.com/ubi9/python-311:1-52
WORKDIR /locallm
COPY requirements.txt /locallm/requirements.txt
ARG PORT=8000
WORKDIR /app
COPY src/requirements.txt .
RUN pip install --upgrade pip && \
pip install --no-cache-dir --upgrade -r requirements.txt
COPY object_detection_server.py object_detection_server.py
EXPOSE 8000
COPY src/object_detection_server.py .
EXPOSE $PORT
ENTRYPOINT [ "uvicorn", "object_detection_server:app", "--host", "0.0.0.0" ]
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@


app = FastAPI()
model = os.getenv("MODEL_PATH", default="facebook/detr-resnet-101")
model_path = os.getenv("MODEL_PATH", default="/app/models")
model_name = os.getenv("MODEL_NAME", default="detr-resnet-101")
model = os.path.abspath(f"{model_path}/{model_name}")
revision = os.getenv("MODEL_REVISION", default="no_timm")

processor = AutoImageProcessor.from_pretrained(model, revision=revision)
Expand Down
36 changes: 36 additions & 0 deletions model_servers/object_detection_python/src/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
annotated-types==0.6.0
anyio==4.3.0
certifi==2024.2.2
charset-normalizer==3.3.2
click==8.1.7
fastapi==0.110.1
filelock==3.13.4
fsspec==2024.3.1
h11==0.14.0
huggingface-hub==0.22.2
idna==3.7
Jinja2==3.1.3
MarkupSafe==2.1.5
mpmath==1.3.0
networkx==3.3
numpy==1.26.4
packaging==24.0
pillow==10.3.0
pydantic==2.6.4
pydantic_core==2.16.3
PyYAML==6.0.1
regex==2023.12.25
requests==2.31.0
safetensors==0.4.2
sniffio==1.3.1
starlette==0.37.2
sympy==1.12
timm==0.9.16
tokenizers==0.15.2
torch==2.2.2
torchvision==0.17.2
tqdm==4.66.2
transformers==4.39.3
typing_extensions==4.11.0
urllib3==2.2.1
uvicorn==0.29.0
Empty file.
56 changes: 56 additions & 0 deletions model_servers/object_detection_python/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import pytest_container
import pytest
import os
import logging
import platform

if 'PORT' not in os.environ:
PORT = 8000
else:
PORT = os.environ['PORT']
try:
PORT = int(PORT)
except:
PORT = 8000

if 'IMAGE' not in os.environ:
IMAGE = 'ghcr.io/containers/model_servers/object_detection_python:latest'
else:
IMAGE = os.environ['IMAGE']

MODEL_NAME=os.environ['MODEL_NAME']
MODEL_PATH=os.environ['MODEL_PATH']

BIND_MOUNT_OPTIONS = 'ro'
if platform.system() == 'Linux':
BIND_MOUNT_OPTIONS = 'ro,Z'

MS = pytest_container.Container(
url=f"containers-storage:{IMAGE}",
volume_mounts=[
pytest_container.container.BindMount(
container_path=f"{MODEL_PATH}/{MODEL_NAME}",
host_path=f"./{MODEL_NAME}",
flags=[BIND_MOUNT_OPTIONS]
)
],
extra_environment_variables={
"MODEL_NAME": f"{MODEL_NAME}",
"MODEL_PATH": f"{MODEL_PATH}",
"HOST": "0.0.0.0",
"PORT": f"{PORT}"
},
forwarded_ports=[
pytest_container.PortForwarding(
container_port=PORT,
host_port=PORT
)
],
)

def pytest_addoption(parser):
pytest_container.add_logging_level_options(parser)


def pytest_generate_tests(metafunc):
pytest_container.auto_container_parametrize(metafunc)
8 changes: 8 additions & 0 deletions model_servers/object_detection_python/tests/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
pip==24.0
pytest-container==0.4.0
pytest-selenium==4.1.0
pytest-testinfra==10.1.0
pytest==8.1.1
requests==2.31.0
selenium==4.19.0
tenacity==8.2.3
13 changes: 13 additions & 0 deletions model_servers/object_detection_python/tests/test_alive.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import pytest_container
from .conftest import MS
import tenacity

CONTAINER_IMAGES = [MS]


def test_etc_os_release_present(auto_container: pytest_container.container.ContainerData):
assert auto_container.connection.file("/etc/os-release").exists

@tenacity.retry(stop=tenacity.stop_after_attempt(5), wait=tenacity.wait_exponential())
def test_alive(auto_container: pytest_container.container.ContainerData, host):
host.run_expect([0],f"curl http://localhost:{auto_container.forwarded_ports[0].host_port}",).stdout.strip()
8 changes: 5 additions & 3 deletions recipes/common/Makefile.common
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ IMAGE_NAME ?= $(REGISTRY_ORG)/${APP}:latest
APP_IMAGE ?= $(REGISTRY)/$(IMAGE_NAME)
CHROMADB_IMAGE ?= $(REGISTRY)/$(REGISTRY_ORG)/chromadb:latest
MODEL_IMAGE ?= $(REGISTRY)/$(REGISTRY_ORG)/mistral-7b-instruct:latest
MODEL_SERVER_PORT ?= 8001
MODEL_ENDPOINT ?= http://10.88.0.1:$(MODEL_SERVER_PORT)
SERVER_IMAGE ?= $(REGISTRY)/$(REGISTRY_ORG)/llamacpp-python:latest
SSH_PUBKEY ?= $(shell cat ${HOME}/.ssh/id_rsa.pub;)
BOOTC_IMAGE ?= quay.io/$(REGISTRY_ORG)/${APP}-bootc:latest
Expand Down Expand Up @@ -54,8 +56,8 @@ CHROME_MIRROR := https://www.slimjet.com/chrome/files/$(CHROMEDRIVER_VERSION)/$(
LOCAL_CHROMEDRIVER_EXISTS ?= $(shell command -v $(RECIPE_BINARIES_PATH)/chromedriver)
UNZIP_EXISTS ?= $(shell command -v unzip)

RELATIVE_MODELS_PATH := ?=
RELATIVE_TESTS_PATH := ?=
RELATIVE_MODELS_PATH ?=
RELATIVE_TESTS_PATH ?=

MISTRAL_MODEL_NAME := mistral-7b-instruct-v0.1.Q4_K_M.gguf
MISTRAL_MODEL_URL := https://huggingface.co/TheBloke/Mistral-7B-Instruct-v0.1-GGUF/resolve/main/mistral-7b-instruct-v0.1.Q4_K_M.gguf
Expand Down Expand Up @@ -171,7 +173,7 @@ quadlet:

.PHONY: run
run:
podman run -it -p $(PORT):$(PORT) -e MODEL_ENDPOINT=http://10.88.0.1:8001 ${APP_IMAGE}
podman run -it -p $(PORT):$(PORT) -e MODEL_ENDPOINT=$(MODEL_ENDPOINT) ${APP_IMAGE}

.PHONY: clean
clean:
Expand Down
Loading

0 comments on commit 87c3d80

Please sign in to comment.