chore(ml): uv ()

* poetry to uv

* update ci

* remove caching

* add typeshed to dev

* no need for `--non-interactive`

* move backends to extras

* oopsie

* update ci
This commit is contained in:
Mert 2025-03-09 22:30:16 -04:00 committed by GitHub
parent 573d9a7733
commit 6da77600e5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 2748 additions and 3834 deletions

View file

@ -41,8 +41,8 @@ jobs:
with: with:
token: ${{ steps.generate-token.outputs.token }} token: ${{ steps.generate-token.outputs.token }}
- name: Install Poetry - name: Install uv
run: pipx install poetry uses: astral-sh/setup-uv@v5
- name: Bump version - name: Bump version
run: misc/release/pump-version.sh -s "${{ inputs.serverBump }}" -m "${{ inputs.mobileBump }}" run: misc/release/pump-version.sh -s "${{ inputs.serverBump }}" -m "${{ inputs.mobileBump }}"
@ -74,7 +74,7 @@ jobs:
with: with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:

View file

@ -380,27 +380,28 @@ jobs:
working-directory: ./machine-learning working-directory: ./machine-learning
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Install poetry - name: Install uv
run: pipx install poetry uses: astral-sh/setup-uv@v5
- uses: actions/setup-python@v5 - uses: actions/setup-python@v5
with: # TODO: add caching when supported (https://github.com/actions/setup-python/pull/818)
python-version: 3.11 # with:
cache: 'poetry' # python-version: 3.11
# cache: 'uv'
- name: Install dependencies - name: Install dependencies
run: | run: |
poetry install --with dev --with cpu uv sync --extra cpu
- name: Lint with ruff - name: Lint with ruff
run: | run: |
poetry run ruff check --output-format=github app export uv run ruff check --output-format=github app export
- name: Check black formatting - name: Check black formatting
run: | run: |
poetry run black --check app export uv run black --check app export
- name: Run mypy type checking - name: Run mypy type checking
run: | run: |
poetry run mypy --install-types --non-interactive --strict app/ uv run mypy --strict app/
- name: Run tests and coverage - name: Run tests and coverage
run: | run: |
poetry run pytest app --cov=app --cov-report term-missing uv run pytest app --cov=app --cov-report term-missing
shellcheck: shellcheck:
name: ShellCheck name: ShellCheck

View file

@ -19,20 +19,16 @@ FROM builder-${DEVICE} AS builder
ARG DEVICE ARG DEVICE
ENV PYTHONDONTWRITEBYTECODE=1 \ ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \ PYTHONUNBUFFERED=1
PIP_NO_CACHE_DIR=true \ WORKDIR /usr/src/app
VIRTUAL_ENV="/opt/venv" \
PATH="/opt/venv/bin:${PATH}"
RUN apt-get update && apt-get install -y --no-install-recommends g++ RUN apt-get update && apt-get install -y --no-install-recommends g++
RUN pip install --upgrade pip && pip install poetry COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
RUN poetry config installer.max-workers 10 && \ RUN --mount=type=cache,target=/root/.cache/uv \
poetry config virtualenvs.create false --mount=type=bind,source=uv.lock,target=uv.lock \
RUN python3 -m venv /opt/venv --mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv sync --frozen --extra ${DEVICE} --no-dev --no-editable --no-install-project --compile-bytecode --no-progress
COPY poetry.lock pyproject.toml ./
RUN poetry install --sync --no-interaction --no-ansi --no-root --with ${DEVICE} --without dev
FROM python:3.11-slim-bookworm@sha256:614c8691ab74150465ec9123378cd4dde7a6e57be9e558c3108df40664667a4c AS prod-cpu FROM python:3.11-slim-bookworm@sha256:614c8691ab74150465ec9123378cd4dde7a6e57be9e558c3108df40664667a4c AS prod-cpu
@ -93,7 +89,7 @@ WORKDIR /usr/src/app
ENV TRANSFORMERS_CACHE=/cache \ ENV TRANSFORMERS_CACHE=/cache \
PYTHONDONTWRITEBYTECODE=1 \ PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \ PYTHONUNBUFFERED=1 \
PATH="/opt/venv/bin:$PATH" \ PATH="/usr/src/app/.venv/bin:$PATH" \
PYTHONPATH=/usr/src \ PYTHONPATH=/usr/src \
DEVICE=${DEVICE} DEVICE=${DEVICE}
@ -102,7 +98,7 @@ RUN echo "hard core 0" >> /etc/security/limits.conf && \
echo "fs.suid_dumpable 0" >> /etc/sysctl.conf && \ echo "fs.suid_dumpable 0" >> /etc/sysctl.conf && \
echo 'ulimit -S -c 0 > /dev/null 2>&1' >> /etc/profile echo 'ulimit -S -c 0 > /dev/null 2>&1' >> /etc/profile
COPY --from=builder /opt/venv /opt/venv COPY --from=builder /usr/src/app/.venv /usr/src/app/.venv
COPY ann/ann.py /usr/src/ann/ann.py COPY ann/ann.py /usr/src/ann/ann.py
COPY start.sh log_conf.json gunicorn_conf.py ./ COPY start.sh log_conf.json gunicorn_conf.py ./
COPY app . COPY app .

View file

@ -5,13 +5,12 @@
# Setup # Setup
This project uses [Poetry](https://python-poetry.org/docs/#installation), so be sure to install it first. This project uses [uv](https://docs.astral.sh/uv/getting-started/installation/), so be sure to install it first.
Running `poetry install --no-root --with dev --with cpu` will install everything you need in an isolated virtual environment. Running `uv sync --extra cpu` will install everything you need in an isolated virtual environment.
CUDA and OpenVINO are supported as acceleration APIs. To use them, you can replace `--with cpu` with either of `--with cuda` or `--with openvino`. In the case of CUDA, a [compute capability](https://developer.nvidia.com/cuda-gpus) of 5.2 or higher is required. CUDA and OpenVINO are supported as acceleration APIs. To use them, you can replace `--group cpu` with either of `--group cuda` or `--group openvino`. In the case of CUDA, a [compute capability](https://developer.nvidia.com/cuda-gpus) of 5.2 or higher is required.
To add or remove dependencies, you can use the commands `poetry add $PACKAGE_NAME` and `poetry remove $PACKAGE_NAME`, respectively.
Be sure to commit the `poetry.lock` and `pyproject.toml` files with `poetry lock --no-update` to reflect any changes in dependencies.
To add or remove dependencies, you can use the commands `uv add $PACKAGE_NAME` and `uv remove $PACKAGE_NAME`, respectively.
Be sure to commit the `uv.lock` and `pyproject.toml` files with `uv lock` to reflect any changes in dependencies.
# Load Testing # Load Testing
@ -19,22 +18,25 @@ To measure inference throughput and latency, you can use [Locust](https://locust
Locust works by querying the model endpoints and aggregating their statistics, meaning the app must be deployed. Locust works by querying the model endpoints and aggregating their statistics, meaning the app must be deployed.
You can change the models or adjust options like score thresholds through the Locust UI. You can change the models or adjust options like score thresholds through the Locust UI.
To get started, you can simply run `locust --web-host 127.0.0.1` and open `localhost:8089` in a browser to access the UI. See the [Locust documentation](https://docs.locust.io/en/stable/index.html) for more info on running Locust. To get started, you can simply run `locust --web-host 127.0.0.1` and open `localhost:8089` in a browser to access the UI. See the [Locust documentation](https://docs.locust.io/en/stable/index.html) for more info on running Locust.
Note that in Locust's jargon, concurrency is measured in `users`, and each user runs one task at a time. To achieve a particular per-endpoint concurrency, multiply that number by the number of endpoints to be queried. For example, if there are 3 endpoints and you want each of them to receive 8 requests at a time, you should set the number of users to 24. Note that in Locust's jargon, concurrency is measured in `users`, and each user runs one task at a time. To achieve a particular per-endpoint concurrency, multiply that number by the number of endpoints to be queried. For example, if there are 3 endpoints and you want each of them to receive 8 requests at a time, you should set the number of users to 24.
# Facial Recognition # Facial Recognition
## Acknowledgements ## Acknowledgements
This project utilizes facial recognition models from the [InsightFace](https://github.com/deepinsight/insightface/tree/master/model_zoo) project. We appreciate the work put into developing these models, which have been beneficial to the machine learning part of this project. This project utilizes facial recognition models from the [InsightFace](https://github.com/deepinsight/insightface/tree/master/model_zoo) project. We appreciate the work put into developing these models, which have been beneficial to the machine learning part of this project.
### Used Models ### Used Models
* antelopev2
* buffalo_l - antelopev2
* buffalo_m - buffalo_l
* buffalo_s - buffalo_m
- buffalo_s
## License and Use Restrictions ## License and Use Restrictions
We have received permission to use the InsightFace facial recognition models in our project, as granted via email by Jia Guo (guojia@insightface.ai) on 18th March 2023. However, it's important to note that this permission does not extend to the redistribution or commercial use of their models by third parties. Users and developers interested in using these models should review the licensing terms provided in the InsightFace GitHub repository. We have received permission to use the InsightFace facial recognition models in our project, as granted via email by Jia Guo (guojia@insightface.ai) on 18th March 2023. However, it's important to note that this permission does not extend to the redistribution or commercial use of their models by third parties. Users and developers interested in using these models should review the licensing terms provided in the InsightFace GitHub repository.
For more information on the capabilities of the InsightFace models and to ensure compliance with their license, please refer to their [official repository](https://github.com/deepinsight/insightface). Adhering to the specified licensing terms is crucial for the respectful and lawful use of their work. For more information on the capabilities of the InsightFace models and to ensure compliance with their license, please refer to their [official repository](https://github.com/deepinsight/insightface). Adhering to the specified licensing terms is crucial for the respectful and lawful use of their work.

File diff suppressed because it is too large Load diff

View file

@ -1,72 +1,77 @@
[tool.poetry] [project]
name = "machine-learning" name = "machine-learning"
version = "1.129.0" version = "1.129.0"
description = "" description = ""
authors = ["Hau Tran <alex.tran1502@gmail.com>"] authors = [{ name = "Hau Tran", email = "alex.tran1502@gmail.com" }]
requires-python = ">=3.10,<4.0"
readme = "README.md" readme = "README.md"
packages = [{include = "app"}] dependencies = [
"aiocache>=0.12.1,<1.0",
"fastapi>=0.95.2,<1.0",
"ftfy>=6.1.1",
"gunicorn>=21.1.0",
"huggingface-hub>=0.20.1,<1.0",
"insightface>=0.7.3,<1.0",
"opencv-python-headless>=4.7.0.72,<5.0",
"orjson>=3.9.5",
"pillow>=9.5.0,<11.0",
"pydantic>=2.0.0,<3",
"pydantic-settings>=2.5.2,<3",
"python-multipart>=0.0.6,<1.0",
"rich>=13.4.2",
"tokenizers>=0.15.0,<1.0",
"uvicorn[standard]>=0.22.0,<1.0",
]
[tool.poetry.dependencies] [dependency-groups]
python = ">=3.10,<4.0" test = [
insightface = ">=0.7.3,<1.0" "httpx>=0.24.1",
opencv-python-headless = ">=4.7.0.72,<5.0" "pytest>=7.3.1",
pillow = ">=9.5.0,<11.0" "pytest-asyncio>=0.21.0",
fastapi = ">=0.95.2,<1.0" "pytest-cov>=4.1.0",
uvicorn = {extras = ["standard"], version = ">=0.22.0,<1.0"} "pytest-mock>=3.11.1",
pydantic = "^2.0.0" ]
pydantic-settings = "^2.5.2" types = [
aiocache = ">=0.12.1,<1.0" "types-pyyaml>=6.0.12.20241230",
rich = ">=13.4.2" "types-requests>=2.32.0.20250306",
ftfy = ">=6.1.1" "types-setuptools>=75.8.2.20250305",
python-multipart = ">=0.0.6,<1.0" "types-simplejson>=3.20.0.20250218",
orjson = ">=3.9.5" "types-ujson>=5.10.0.20240515",
gunicorn = ">=21.1.0" ]
huggingface-hub = ">=0.20.1,<1.0" lint = [
tokenizers = ">=0.15.0,<1.0" "black>=23.3.0",
"mypy>=1.3.0",
"ruff>=0.0.272",
{ include-group = "types" },
]
dev = ["locust>=2.15.1", { include-group = "test" }, { include-group = "lint" }]
[tool.poetry.group.dev.dependencies] [project.optional-dependencies]
mypy = ">=1.3.0" cpu = ["onnxruntime>=1.15.0,<2"]
black = ">=23.3.0" cuda = ["onnxruntime-gpu>=1.17.0,<2"]
pytest = ">=7.3.1" openvino = ["onnxruntime-openvino>=1.17.1,<1.19.0"]
locust = ">=2.15.1" armnn = ["onnxruntime>=1.15.0,<2"]
httpx = ">=0.24.1"
pytest-asyncio = ">=0.21.0"
pytest-cov = ">=4.1.0"
ruff = ">=0.0.272"
pytest-mock = ">=3.11.1"
[tool.poetry.group.cpu] [tool.uv]
optional = true compile-bytecode = true
[tool.poetry.group.cpu.dependencies] [[tool.uv.index]]
onnxruntime = "^1.15.0"
[tool.poetry.group.cuda]
optional = true
[tool.poetry.group.cuda.dependencies]
onnxruntime-gpu = {version = "^1.17.0", source = "cuda12"}
[tool.poetry.group.openvino]
optional = true
[tool.poetry.group.openvino.dependencies]
onnxruntime-openvino = ">=1.17.1,<1.19.0"
[tool.poetry.group.armnn]
optional = true
[tool.poetry.group.armnn.dependencies]
onnxruntime = "^1.15.0"
[[tool.poetry.source]]
name = "cuda12" name = "cuda12"
url = "https://aiinfra.pkgs.visualstudio.com/PublicPackages/_packaging/onnxruntime-cuda-12/pypi/simple/" url = "https://aiinfra.pkgs.visualstudio.com/PublicPackages/_packaging/onnxruntime-cuda-12/pypi/simple/"
priority = "explicit" explicit = true
[tool.uv.sources]
onnxruntime-gpu = { index = "cuda12" }
[tool.hatch.build.targets.sdist]
include = ["app"]
[tool.hatch.build.targets.wheel]
include = ["app"]
[build-system] [build-system]
requires = ["poetry-core"] requires = ["hatchling"]
build-backend = "poetry.core.masonry.api" build-backend = "hatchling.build"
[tool.mypy] [tool.mypy]
python_version = "3.11" python_version = "3.11"

2648
machine-learning/uv.lock generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -73,7 +73,7 @@ if [ "$CURRENT_SERVER" != "$NEXT_SERVER" ]; then
npm --prefix web i --package-lock-only npm --prefix web i --package-lock-only
npm --prefix e2e version "$SERVER_PUMP" npm --prefix e2e version "$SERVER_PUMP"
npm --prefix e2e i --package-lock-only npm --prefix e2e i --package-lock-only
poetry --directory machine-learning version "$SERVER_PUMP" uvx --from=toml-cli toml set --toml-path=pyproject.toml project.version "$SERVER_PUMP"
fi fi
if [ "$CURRENT_MOBILE" != "$NEXT_MOBILE" ]; then if [ "$CURRENT_MOBILE" != "$NEXT_MOBILE" ]; then