From 563334da5de5fdaea621a9d4b1a1a33368cfc1fc Mon Sep 17 00:00:00 2001 From: "Jona T. Feucht" <14951074+jonafeucht@users.noreply.github.com> Date: Sat, 9 Nov 2024 18:02:40 +0100 Subject: [PATCH] Revert "Merge pull request #12 from doppeltilde/opencl" This reverts commit ab740ffe59fb903fa8d9c00feda0e91611cb6260, reversing changes made to 3ee1a121c2f7e4925278e136232273373925ff56. --- .github/workflows/dev.opencl.yml | 67 --------- .github/workflows/dev.yml | 68 --------- .github/workflows/prod.opencl.yml | 65 --------- .github/workflows/publish.yml | 11 +- Dockerfile.opencl.amd.clover | 83 ----------- Dockerfile.opencl.amd.rusticl | 92 ------------ Dockerfile.opencl.nvidia | 36 ----- README.md | 131 ++---------------- docker-compose.dev.opencl.amd.yml | 27 ---- docker-compose.dev.opencl.nvidia.yml | 25 ---- ...pose.dev.cpu.yml => docker-compose.dev.yml | 0 docker-compose.yml | 22 +++ requirements.txt | 8 +- src/routes/api/image_classification.py | 15 +- src/routes/api/image_query_classification.py | 17 +-- src/routes/api/video_classification.py | 7 +- src/shared/shared.py | 44 ++---- test/opencl_test.py | 4 - 18 files changed, 69 insertions(+), 653 deletions(-) delete mode 100644 .github/workflows/dev.opencl.yml delete mode 100644 .github/workflows/dev.yml delete mode 100644 .github/workflows/prod.opencl.yml delete mode 100644 Dockerfile.opencl.amd.clover delete mode 100644 Dockerfile.opencl.amd.rusticl delete mode 100644 Dockerfile.opencl.nvidia delete mode 100644 docker-compose.dev.opencl.amd.yml delete mode 100644 docker-compose.dev.opencl.nvidia.yml rename docker-compose.dev.cpu.yml => docker-compose.dev.yml (100%) delete mode 100644 test/opencl_test.py diff --git a/.github/workflows/dev.opencl.yml b/.github/workflows/dev.opencl.yml deleted file mode 100644 index e49ce54..0000000 --- a/.github/workflows/dev.opencl.yml +++ /dev/null @@ -1,67 +0,0 @@ -name: OpenCL Dev CI/CD - -on: - push: - branches: - - "opencl" - - "dev" - - "cuda" - - "cpu" - - "beta" - -env: - REGISTRY: "ghcr.io" - REGISTRY_USER: ${{ github.actor }} - REGISTRY_SECRET: ${{ secrets.GITHUB_TOKEN }} - IMAGE_NAME: ${{ github.repository }} - -permissions: - contents: read - packages: write - -jobs: - build_and_publish: - runs-on: ubuntu-latest - strategy: - matrix: - include: - - docker_file: Dockerfile.opencl.nvidia - label: "dev-opencl-nvidia" - - docker_file: Dockerfile.opencl.amd.rusticl - label: "dev-opencl-amd-rusticl" - - docker_file: Dockerfile.opencl.amd.clover - label: "dev-opencl-amd-clover" - - steps: - - uses: actions/checkout@v4 - - - name: Meta - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - tags: | - type=ref,event=branch - type=ref,event=pr - type=ref,event=tag - type=sha,prefix=sha- - labels: | - type=raw,value=image-type=${{ matrix.label }} - - - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ env.REGISTRY_USER }} - password: ${{ env.REGISTRY_SECRET }} - - - name: Build and push - uses: docker/build-push-action@v5 - with: - context: . - file: ${{ matrix.docker_file }} - push: ${{ github.event_name != 'pull_request' }} - tags: | - ${{ steps.meta.outputs.tags }} - ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ matrix.label }} - labels: ${{ steps.meta.outputs.labels }} - platforms: linux/amd64 \ No newline at end of file diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml deleted file mode 100644 index 5aeb277..0000000 --- a/.github/workflows/dev.yml +++ /dev/null @@ -1,68 +0,0 @@ -name: CPU/CUDA Dev CI/CD - -on: - push: - branches: - - "opencl" - - "dev" - - "cuda" - - "cpu" - - "beta" - -env: - REGISTRY: "ghcr.io" - REGISTRY_USER: ${{ github.actor }} - REGISTRY_SECRET: ${{ secrets.GITHUB_TOKEN }} - IMAGE_NAME: ${{ github.repository }} - -permissions: - contents: read - packages: write - -jobs: - build_and_publish: - runs-on: ubuntu-latest - strategy: - matrix: - include: - - docker_file: Dockerfile - label: "dev-cpu" - - docker_file: Dockerfile.cuda - label: "dev-cuda" - - steps: - - uses: actions/checkout@v4 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Meta - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - tags: | - type=ref,event=branch - type=ref,event=pr - type=ref,event=tag - type=sha,prefix=sha- - labels: | - type=raw,value=image-type=${{ matrix.label }} - - - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ env.REGISTRY_USER }} - password: ${{ env.REGISTRY_SECRET }} - - - name: Build and push - uses: docker/build-push-action@v5 - with: - context: . - file: ${{ matrix.docker_file }} - push: ${{ github.event_name != 'pull_request' }} - tags: | - ${{ steps.meta.outputs.tags }} - ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ matrix.label }} - labels: ${{ steps.meta.outputs.labels }} - platforms: linux/amd64, linux/arm64 \ No newline at end of file diff --git a/.github/workflows/prod.opencl.yml b/.github/workflows/prod.opencl.yml deleted file mode 100644 index 557164f..0000000 --- a/.github/workflows/prod.opencl.yml +++ /dev/null @@ -1,65 +0,0 @@ -name: OpenCL Production CI/CD - -on: - push: - tags: - - "v*" - branches: - - "main" - -env: - REGISTRY: "ghcr.io" - REGISTRY_USER: ${{ github.actor }} - REGISTRY_SECRET: ${{ secrets.GITHUB_TOKEN }} - IMAGE_NAME: ${{ github.repository }} - -permissions: - contents: read - packages: write - -jobs: - build_and_publish: - runs-on: ubuntu-latest - strategy: - matrix: - include: - - docker_file: Dockerfile.opencl.nvidia - label: "latest-opencl-nvidia" - - docker_file: Dockerfile.opencl.amd.rusticl - label: "latest-opencl-amd-rusticl" - - docker_file: Dockerfile.opencl.amd.clover - label: "latest-opencl-amd-clover" - - steps: - - uses: actions/checkout@v4 - - - name: Meta - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - tags: | - type=ref,event=branch - type=ref,event=pr - type=ref,event=tag - type=sha,prefix=sha- - labels: | - type=raw,value=image-type=${{ matrix.label }} - - - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ env.REGISTRY_USER }} - password: ${{ env.REGISTRY_SECRET }} - - - name: Build and push - uses: docker/build-push-action@v5 - with: - context: . - file: ${{ matrix.docker_file }} - push: ${{ github.event_name != 'pull_request' }} - tags: | - ${{ steps.meta.outputs.tags }} - ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ matrix.label }} - labels: ${{ steps.meta.outputs.labels }} - platforms: linux/amd64 \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 8bf35a5..5729903 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,11 +1,9 @@ -name: Production CI/CD +name: ghcr.io CI/CD on: push: tags: - 'v*' - branches: - - "main" env: REGISTRY: "ghcr.io" @@ -27,9 +25,6 @@ jobs: label: "latest" - docker_file: Dockerfile.cuda label: "latest-cuda" - - docker_file: Dockerfile.opencl.nvidia - label: "latest-opencl-nvidia" - steps: - uses: actions/checkout@v4 @@ -63,6 +58,6 @@ jobs: push: ${{ github.event_name != 'pull_request' }} tags: | ${{ steps.meta.outputs.tags }} - ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ matrix.label }} - labels: ${{ steps.meta.outputs.labels }} + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest${{ matrix.label =='latest-cuda' && '-cuda' || '' }} + # labels: ${{ steps.meta.outputs.labels }} platforms: linux/amd64,linux/arm64 \ No newline at end of file diff --git a/Dockerfile.opencl.amd.clover b/Dockerfile.opencl.amd.clover deleted file mode 100644 index c5e4fe0..0000000 --- a/Dockerfile.opencl.amd.clover +++ /dev/null @@ -1,83 +0,0 @@ -FROM ubuntu:noble - -ARG DEBIAN_FRONTEND=noninteractive - -USER root - -ARG PYTORCH_OCL_VERSION=0.2.0 -ARG TORCH_VERSION=2.4 -ARG PYTHON_VERSION=cp312 -ARG PLATFORM=linux_x86_64 - -ENV WHL_FILE=pytorch_ocl-${PYTORCH_OCL_VERSION}+torch${TORCH_VERSION}-${PYTHON_VERSION}-none-${PLATFORM}.whl -ENV WHL_URL=https://github.com/artyom-beilis/pytorch_dlprim/releases/download/${PYTORCH_OCL_VERSION}/${WHL_FILE} - -WORKDIR /app -COPY . /app - -RUN apt-get update && \ - apt install software-properties-common -y && \ - add-apt-repository ppa:kisak/kisak-mesa -y && \ - apt-get update -y && \ - apt dist-upgrade -y && \ - apt-get install -y \ - wget \ - software-properties-common \ - apt-transport-https \ - ca-certificates \ - curl \ - gpg && \ - rm -rf /var/lib/apt/lists/* - -# Install OpenCL dependencies -RUN apt-get update && apt-get install -y \ - ocl-icd-opencl-dev \ - opencl-headers \ - ocl-icd-libopencl1 \ - clinfo \ - mesa-opencl-icd \ - && rm -rf /var/lib/apt/lists/* - -# Install Python 3.12 -RUN add-apt-repository ppa:deadsnakes/ppa -y && \ - apt-get update && \ - apt-get install -y \ - python3.12 \ - python3.12-venv \ - python3.12-dev \ - python3-pip \ - && rm -rf /var/lib/apt/lists/* - -# Set up Python virtual environment -RUN python3.12 -m venv /app/venv -ENV PATH="/app/venv/bin:$PATH" -RUN pip install --upgrade pip - -# Configure OpenCL vendors -RUN mkdir -p /etc/OpenCL/vendors && \ - echo "libMesaOpenCL.so.1" > /etc/OpenCL/vendors/mesa.icd && \ - chmod 755 /etc/OpenCL/vendors - -RUN groupadd -f render && groupadd -f video -RUN usermod -a -G render,video root - -RUN mkdir -p /dev/dri && \ - touch /dev/dri/renderD128 && \ - chmod 666 /dev/dri/renderD128 - -RUN chmod 666 /dev/dri/render* || true -RUN chmod 666 /dev/dri/card* || true - -# Set environment variables for OpenCL -ENV OCL_ICD_VENDORS="/etc/OpenCL/vendors" -ENV OPENCL_VENDOR_PATH="/etc/OpenCL/vendors" - -COPY requirements.txt /app/requirements.txt -RUN /app/venv/bin/pip install --no-cache-dir -r requirements.txt --extra-index-url https://download.pytorch.org/whl/cpu - -# Install OpenCL backend for PyTorch -RUN wget ${WHL_URL} && \ - /app/venv/bin/pip install ${WHL_FILE} && \ - rm ${WHL_FILE} - -CMD ["/app/venv/bin/python", "-m", "fastapi", "run", "main.py", "--proxy-headers", "--host", "0.0.0.0", "--port", "8000"] \ No newline at end of file diff --git a/Dockerfile.opencl.amd.rusticl b/Dockerfile.opencl.amd.rusticl deleted file mode 100644 index 0b178d5..0000000 --- a/Dockerfile.opencl.amd.rusticl +++ /dev/null @@ -1,92 +0,0 @@ -FROM ubuntu:noble - -ARG DEBIAN_FRONTEND=noninteractive - -USER root - -ARG PYTORCH_OCL_VERSION=0.2.0 -ARG TORCH_VERSION=2.4 -ARG PYTHON_VERSION=cp312 -ARG PLATFORM=linux_x86_64 - -ENV WHL_FILE=pytorch_ocl-${PYTORCH_OCL_VERSION}+torch${TORCH_VERSION}-${PYTHON_VERSION}-none-${PLATFORM}.whl -ENV WHL_URL=https://github.com/artyom-beilis/pytorch_dlprim/releases/download/${PYTORCH_OCL_VERSION}/${WHL_FILE} - -WORKDIR /app -COPY . /app - -RUN apt-get update && \ - apt install software-properties-common -y && \ - add-apt-repository ppa:kisak/kisak-mesa -y && \ - apt-get update -y && \ - apt dist-upgrade -y && \ - apt-get install -y \ - wget \ - software-properties-common \ - apt-transport-https \ - ca-certificates \ - curl \ - gpg && \ - rm -rf /var/lib/apt/lists/* - -# Install OpenCL dependencies -RUN apt-get update && apt-get install -y \ - ocl-icd-opencl-dev \ - opencl-headers \ - ocl-icd-libopencl1 \ - clinfo \ - mesa-opencl-icd \ - && rm -rf /var/lib/apt/lists/* - -# Install Python 3.12 -RUN add-apt-repository ppa:deadsnakes/ppa -y && \ - apt-get update && \ - apt-get install -y \ - python3.12 \ - python3.12-venv \ - python3.12-dev \ - python3-pip \ - && rm -rf /var/lib/apt/lists/* - -# Set up Python virtual environment -RUN python3.12 -m venv /app/venv -ENV PATH="/app/venv/bin:$PATH" -RUN pip install --upgrade pip - -# Install AMD GPU drivers -RUN apt update -y && \ - wget https://repo.radeon.com/amdgpu-install/6.2.3/ubuntu/noble/amdgpu-install_6.2.60203-1_all.deb && \ - apt install ./amdgpu-install_6.2.60203-1_all.deb -y && \ - rm -rf ./amdgpu-install_6.2.60203-1_all.deb - -# Configure OpenCL vendors -RUN mkdir -p /etc/OpenCL/vendors && \ - dpkg-divert --divert '/etc/OpenCL/vendors/mesa.icd.disabled' --rename '/etc/OpenCL/vendors/mesa.icd' && \ - echo "libamdocl64.so" > /etc/OpenCL/vendors/amdocl64.icd && \ - chmod 755 /etc/OpenCL/vendors - -RUN groupadd -f render && groupadd -f video -RUN usermod -a -G render,video root - -RUN mkdir -p /dev/dri && \ - touch /dev/dri/renderD128 && \ - chmod 666 /dev/dri/renderD128 - -RUN chmod 666 /dev/dri/render* || true -RUN chmod 666 /dev/dri/card* || true - -# Set environment variables for OpenCL -ENV OCL_ICD_VENDORS="/etc/OpenCL/vendors" -ENV OPENCL_VENDOR_PATH="/etc/OpenCL/vendors" -ENV RUSTICL_ENABLE=radeonsi -ENV RUSTICL_FEATURES="f16,f64" - -COPY requirements.txt /app/requirements.txt -RUN /app/venv/bin/pip install --no-cache-dir -r requirements.txt --extra-index-url https://download.pytorch.org/whl/cpu - -# Install OpenCL backend for PyTorch -RUN wget ${WHL_URL} && \ - /app/venv/bin/pip install ${WHL_FILE} && \ - rm ${WHL_FILE} - -CMD ["/app/venv/bin/python", "-m", "fastapi", "run", "main.py", "--proxy-headers", "--host", "0.0.0.0", "--port", "8000"] \ No newline at end of file diff --git a/Dockerfile.opencl.nvidia b/Dockerfile.opencl.nvidia deleted file mode 100644 index e0f1702..0000000 --- a/Dockerfile.opencl.nvidia +++ /dev/null @@ -1,36 +0,0 @@ -FROM python:3.12.7 - -ARG PYTORCH_OCL_VERSION=0.2.0 -ARG TORCH_VERSION=2.4 -ARG PYTHON_VERSION=cp312 -ARG PLATFORM=linux_x86_64 - -ENV WHL_FILE=pytorch_ocl-${PYTORCH_OCL_VERSION}+torch${TORCH_VERSION}-${PYTHON_VERSION}-none-${PLATFORM}.whl -ENV WHL_URL=https://github.com/artyom-beilis/pytorch_dlprim/releases/download/${PYTORCH_OCL_VERSION}/${WHL_FILE} - -ENV NVIDIA_VISIBLE_DEVICES all -ENV NVIDIA_DRIVER_CAPABILITIES compute,utility - -WORKDIR /app - -RUN apt update && \ - apt full-upgrade -y && \ - apt install python3 python3-full python3-pip python3-venv git wget ocl-icd-opencl-dev opencl-clhpp-headers opencl-c-headers opencl-headers ocl-icd-libopencl1 clinfo -y && \ - python3 -m venv /app/venv && \ - /app/venv/bin/pip install --upgrade pip - -# Configure OpenCL ICD loaders -RUN mkdir -p /etc/OpenCL/vendors && \ - echo "libnvidia-opencl.so.1" > /etc/OpenCL/vendors/nvidia.icd - -COPY requirements.txt /app/requirements.txt -RUN /app/venv/bin/pip install --no-cache-dir -r requirements.txt --extra-index-url https://download.pytorch.org/whl/cpu - -# Install OpenCL backend for PyTorch -RUN wget ${WHL_URL} && \ - /app/venv/bin/pip install ${WHL_FILE} && \ - rm ${WHL_FILE} - -COPY . /app - -CMD ["/app/venv/bin/python", "-m", "fastapi", "run", "main.py", "--proxy-headers", "--host", "0.0.0.0", "--port", "8000"] \ No newline at end of file diff --git a/README.md b/README.md index 8a510cb..6821155 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Vision Classification for NSFW and SFW media. +# Image & Video Classification for NSFW and SFW media. ## Stack: - [FastAPI](https://fastapi.tiangolo.com) @@ -9,8 +9,7 @@ - For ease of use it's recommended to use the provided [docker-compose.yml](https://github.com/doppeltilde/image_video_classification/blob/main/docker-compose.yml). -### **CPU Support (AMD64 & ARM64)** -Use the `latest` tag. +**CPU Support:** Use the `latest` tag. ```yml services: image_video_classification: @@ -18,7 +17,7 @@ services: ports: - "8000:8000" volumes: - - ./models:/root/.cache/huggingface/hub:rw + - models:/root/.cache/huggingface/hub:rw environment: - DEFAULT_MODEL_NAME - BATCH_SIZE @@ -27,13 +26,12 @@ services: - USE_API_KEYS - API_KEYS restart: unless-stopped -``` -### **NVIDIA GPU Support** -> [!IMPORTANT] -> Nvidia driver >=560 needs to be installed on the host machine. +volumes: + models: +``` -**CUDA (AMD64 & ARM64):** +**NVIDIA GPU Support:** Use the `latest-cuda` tag. ```yml services: image_video_classification_cuda: @@ -41,32 +39,7 @@ services: ports: - "8000:8000" volumes: - - ./models:/root/.cache/huggingface/hub:rw - environment: - - DEFAULT_MODEL_NAME - - BATCH_SIZE - - ACCESS_TOKEN - - DEFAULT_SCORE - - USE_API_KEYS - - API_KEYS - restart: unless-stopped - deploy: - resources: - reservations: - devices: - - driver: nvidia - count: all - capabilities: [ gpu ] -``` -**OpenCL (AMD64):** -```yml -services: - image_video_classification_opencl: - image: ghcr.io/doppeltilde/image_video_classification:latest-opencl-nvidia - ports: - - "8000:8000" - volumes: - - ./models:/root/.cache/huggingface/hub:rw + - models:/root/.cache/huggingface/hub:rw environment: - DEFAULT_MODEL_NAME - BATCH_SIZE @@ -82,71 +55,11 @@ services: - driver: nvidia count: all capabilities: [ gpu ] -``` - -### **AMD GPU Support** -> [!WARNING] -> Unless AMD starts to officially support older Cards again (e.g. gfx8), ROCm will not be available. -**OpenCL Rusticl (AMD64):** -> [!CAUTION] -> While Rusticl works on Polaris cards, there are significant differences in inference performance, with Polaris cards running Clover showing higher accuracy. - -```yml -services: - image_video_classification_cuda: - image: ghcr.io/doppeltilde/image_video_classification:latest-opencl-amd-rusticl - ports: - - "8000:8000" - volumes: - - ./models:/root/.cache/huggingface/hub:rw - - /tmp/.X11-unix:/tmp/.X11-unix - environment: - - DEFAULT_MODEL_NAME - - BATCH_SIZE - - ACCESS_TOKEN - - DEFAULT_SCORE - - USE_API_KEYS - - API_KEYS - restart: unless-stopped - devices: - - /dev/kfd - - /dev/dri - security_opt: - - seccomp:unconfined - group_add: - - "video" - - "render" -``` -**OpenCL Clover (AMD64):** -```yml -services: - image_video_classification_cuda: - image: ghcr.io/doppeltilde/image_video_classification:latest-opencl-amd-clover - ports: - - "8000:8000" - volumes: - - ./models:/root/.cache/huggingface/hub:rw - - /tmp/.X11-unix:/tmp/.X11-unix - environment: - - DEFAULT_MODEL_NAME - - BATCH_SIZE - - ACCESS_TOKEN - - DEFAULT_SCORE - - USE_API_KEYS - - API_KEYS - restart: unless-stopped - devices: - - /dev/kfd - - /dev/dri - security_opt: - - seccomp:unconfined - group_add: - - "video" - - "render" +volumes: + models: ``` -## Environment Variables - Create a `.env` file and set the preferred values. ```sh DEFAULT_MODEL_NAME=Falconsai/nsfw_image_detection @@ -162,28 +75,6 @@ USE_API_KEYS=False API_KEYS=abc,123,xyz ``` -## Tested Devices -Only tested with consumer grade hardware and only on Linux based systems. - -#### CPU -- AMD FX-6300 -- Intel Core i5-12400F -- AMD Ryzen 5 1600 -- AMD Ryzen 5 3600 -- AMD Ryzen 9 5950X - -#### NVIDIA GPU (CUDA & OpenCL) -- GTX 950 -- RTX 3060 Ti - -#### AMD GPU (OpenCL) -- RX 570 4GB -- RX 580 8GB -- RX 6600 XT - -#### Intel GPU (OpenCL NEO) -- None - ## Models Any model designed for image classification and compatible with huggingface transformers should work. @@ -277,8 +168,6 @@ curl -X 'POST' \ > [!TIP] > You can find code examples in the [`examples`](./examples/) folder. -> [!IMPORTANT] -> Many thanks to Artyom Beilis and company for providing the awesome [OpenCL backend for PyTorch](https://github.com/artyom-beilis/pytorch_dlprim)! --- _Notice:_ _This project was initally created to be used in-house, as such the diff --git a/docker-compose.dev.opencl.amd.yml b/docker-compose.dev.opencl.amd.yml deleted file mode 100644 index cf45520..0000000 --- a/docker-compose.dev.opencl.amd.yml +++ /dev/null @@ -1,27 +0,0 @@ -services: - opencl_amd_dev: - build: - context: . - dockerfile: ./Dockerfile.opencl.amd.rusticl - ports: - - "8200:8000" - environment: - - DEFAULT_MODEL_NAME - - BATCH_SIZE - - ACCESS_TOKEN - - DEFAULT_SCORE - - USE_API_KEYS - - API_KEYS - restart: unless-stopped - devices: - - /dev/kfd - - /dev/dri - security_opt: - - seccomp:unconfined - group_add: - - "video" - - "render" - volumes: - - ./models:/root/.cache/huggingface/hub:rw - - /tmp/.X11-unix:/tmp/.X11-unix - ipc: host diff --git a/docker-compose.dev.opencl.nvidia.yml b/docker-compose.dev.opencl.nvidia.yml deleted file mode 100644 index b045500..0000000 --- a/docker-compose.dev.opencl.nvidia.yml +++ /dev/null @@ -1,25 +0,0 @@ -services: - opencl_cuda_dev: - build: - context: . - dockerfile: ./Dockerfile.opencl.nvidia - ports: - - "8200:8000" - environment: - - DEFAULT_MODEL_NAME - - BATCH_SIZE - - ACCESS_TOKEN - - DEFAULT_SCORE - - USE_API_KEYS - - API_KEYS - restart: unless-stopped - deploy: - resources: - reservations: - devices: - - driver: nvidia - count: all - capabilities: [ gpu ] - volumes: - - ./models:/root/.cache/huggingface/hub:rw - ipc: host diff --git a/docker-compose.dev.cpu.yml b/docker-compose.dev.yml similarity index 100% rename from docker-compose.dev.cpu.yml rename to docker-compose.dev.yml diff --git a/docker-compose.yml b/docker-compose.yml index 4bef8ce..e4be069 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,3 +13,25 @@ services: - USE_API_KEYS - API_KEYS restart: unless-stopped + + cuda: + image: ghcr.io/doppeltilde/image_video_classification:latest-cuda + ports: + - "8000:8000" + volumes: + - ./models:/root/.cache/huggingface/hub:rw + environment: + - DEFAULT_MODEL_NAME + - BATCH_SIZE + - ACCESS_TOKEN + - DEFAULT_SCORE + - USE_API_KEYS + - API_KEYS + restart: unless-stopped + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: all + capabilities: [ gpu ] diff --git a/requirements.txt b/requirements.txt index 8f683a4..219e0f8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,8 @@ -fastapi[standard]==0.115.4 +fastapi[standard]==0.115.3 Pillow==11.0.0 -transformers==4.46.2 -torch==2.5.1 +transformers==4.46.0 +torch==2.5.0 python-dotenv==1.0.1 filetype==1.2.0 opencv-python-headless==4.10.0.84 -python-multipart==0.0.17 \ No newline at end of file +python-multipart==0.0.12 \ No newline at end of file diff --git a/src/routes/api/image_classification.py b/src/routes/api/image_classification.py index 7650301..a64b4b6 100644 --- a/src/routes/api/image_classification.py +++ b/src/routes/api/image_classification.py @@ -5,8 +5,9 @@ from typing import List from concurrent.futures import ThreadPoolExecutor import filetype -from src.shared.shared import check_model, clear_cache +from src.shared.shared import check_model from src.middleware.auth.auth import get_api_key +import torch router = APIRouter() @@ -57,7 +58,7 @@ async def image_classification( finally: img.close() del classifier - clear_cache() + torch.cuda.empty_cache() # Check Static Image else: @@ -78,7 +79,7 @@ async def image_classification( finally: img.close() del classifier - clear_cache() + torch.cuda.empty_cache() else: return HTTPException( status_code=400, detail="The uploaded file is not a valid image." @@ -91,7 +92,7 @@ async def image_classification( finally: img.close() - clear_cache() + torch.cuda.empty_cache() @router.post("/api/multi-image-classification", dependencies=[Depends(get_api_key)]) @@ -135,7 +136,7 @@ async def multi_image_classification( finally: img.close() del classifier - clear_cache() + torch.cuda.empty_cache() # Check Static Image else: @@ -153,7 +154,7 @@ async def multi_image_classification( finally: img.close() del classifier - clear_cache() + torch.cuda.empty_cache() else: img.close() @@ -167,6 +168,6 @@ async def multi_image_classification( finally: img.close() - clear_cache() + torch.cuda.empty_cache() return image_list diff --git a/src/routes/api/image_query_classification.py b/src/routes/api/image_query_classification.py index 4936bd4..adfc6c9 100644 --- a/src/routes/api/image_query_classification.py +++ b/src/routes/api/image_query_classification.py @@ -5,8 +5,9 @@ from typing import List import asyncio from concurrent.futures import ThreadPoolExecutor -from src.shared.shared import check_model, default_score, clear_cache +from src.shared.shared import check_model, default_score from src.middleware.auth.auth import get_api_key +import torch router = APIRouter() @@ -62,7 +63,7 @@ def process_image( finally: img.close() del result - clear_cache() + torch.cuda.empty_cache() @router.post("/api/image-query-classification", dependencies=[Depends(get_api_key)]) @@ -124,7 +125,7 @@ async def image_query_classification( finally: img.close() del classifier - clear_cache() + torch.cuda.empty_cache() # Check Static Image else: @@ -157,7 +158,7 @@ async def image_query_classification( finally: img.close() del classifier - clear_cache() + torch.cuda.empty_cache() except Exception as e: print("File is not a valid image.") @@ -165,7 +166,7 @@ async def image_query_classification( finally: img.close() - clear_cache() + torch.cuda.empty_cache() return totalResults @@ -238,7 +239,7 @@ async def multi_image_query_classification( finally: img.close() del classifier - clear_cache() + torch.cuda.empty_cache() # Check Static Image else: @@ -271,7 +272,7 @@ async def multi_image_query_classification( finally: img.close() del classifier - clear_cache() + torch.cuda.empty_cache() except Exception as e: print("File is not a valid image.") @@ -280,7 +281,7 @@ async def multi_image_query_classification( finally: img.close() - clear_cache() + torch.cuda.empty_cache() totalResults.append({index: image_list}) diff --git a/src/routes/api/video_classification.py b/src/routes/api/video_classification.py index 0ad8f3f..ece2119 100644 --- a/src/routes/api/video_classification.py +++ b/src/routes/api/video_classification.py @@ -7,8 +7,9 @@ from concurrent.futures import ThreadPoolExecutor import tempfile import filetype -from src.shared.shared import check_model, default_score, clear_cache +from src.shared.shared import check_model, default_score from src.middleware.auth.auth import get_api_key +import torch router = APIRouter() @@ -76,7 +77,7 @@ def process_video( finally: vc.release() del result - clear_cache() + torch.cuda.empty_cache() @router.post("/api/video-classification", dependencies=[Depends(get_api_key)]) @@ -125,7 +126,7 @@ async def video_classification( tf.close() os.remove(tf.name) del classifier - clear_cache() + torch.cuda.empty_cache() return totalResults diff --git a/src/shared/shared.py b/src/shared/shared.py index 4a4743a..94f4b14 100644 --- a/src/shared/shared.py +++ b/src/shared/shared.py @@ -1,6 +1,7 @@ from dotenv import load_dotenv import os from transformers import pipeline +import torch load_dotenv() @@ -8,6 +9,7 @@ default_model_name = os.getenv("DEFAULT_MODEL_NAME", "Falconsai/nsfw_image_detection") default_batch_size = os.getenv("BATCH_SIZE", 5) default_score = os.getenv("DEFAULT_SCORE", 0.7) +device = 0 if torch.cuda.is_available() else -1 # API KEY api_keys_str = os.getenv("API_KEYS", "") @@ -19,44 +21,16 @@ def check_model(model_name): try: _model_name = model_name or default_model_name - try: - import torch - import pytorch_ocl - - classifier = pipeline( - "image-classification", - model=_model_name, - token=access_token, - device="ocl:0", - batch_size=default_batch_size, - ) - except ModuleNotFoundError as err: - print(err) - import torch - - device = 0 if torch.cuda.is_available() else -1 - - classifier = pipeline( - "image-classification", - model=_model_name, - token=access_token, - device=device, - batch_size=default_batch_size, - ) + classifier = pipeline( + "image-classification", + model=_model_name, + token=access_token, + device=device, + batch_size=default_batch_size, + ) return classifier except Exception as e: print(e) return {"error": str(e)} - - -def clear_cache(): - try: - import torch - import pytorch_ocl - - torch.ocl.empty_cache() - except ModuleNotFoundError as err: - print(err) - torch.cuda.empty_cache() diff --git a/test/opencl_test.py b/test/opencl_test.py deleted file mode 100644 index 2dcc41c..0000000 --- a/test/opencl_test.py +++ /dev/null @@ -1,4 +0,0 @@ -import torch -import pytorch_ocl - -torch.randn(10, 10, device="ocl:0")