Skip to content
This repository was archived by the owner on Jan 14, 2025. It is now read-only.

feat: OpenCL #13

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
64 changes: 64 additions & 0 deletions .github/workflows/prod.opencl.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
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-
type=raw,value=latest,enable=${{ matrix.label == 'latest' }}
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 }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64
9 changes: 4 additions & 5 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
matrix:
include:
- docker_file: Dockerfile
label: "latest"
label: "latest-cpu"
- docker_file: Dockerfile.cuda
label: "latest-cuda"
steps:
Expand All @@ -41,6 +41,7 @@ jobs:
type=ref,event=pr
type=ref,event=tag
type=sha,prefix=sha-
type=raw,value=latest,enable=${{ matrix.label == 'latest' }}
labels: |
type=raw,value=image-type=${{ matrix.label }}

Expand All @@ -56,8 +57,6 @@ jobs:
context: .
file: ${{ matrix.docker_file }}
push: ${{ github.event_name != 'pull_request' }}
tags: |
${{ steps.meta.outputs.tags }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest${{ matrix.label =='latest-cuda' && '-cuda' || '' }}
# labels: ${{ steps.meta.outputs.labels }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm64
94 changes: 94 additions & 0 deletions Dockerfile.opencl.amd.rusticl
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
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_CL_VERSION=2.1
ENV RUSTICL_FEATURES=fp16,fp64

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"]
133 changes: 123 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Image & Video Classification for NSFW and SFW media.
# Vision Classification for NSFW and SFW media.

## Stack:
- [FastAPI](https://fastapi.tiangolo.com)
Expand All @@ -9,15 +9,16 @@

- 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:** Use the `latest` tag.
### **CPU Support (AMD64 & ARM64)**
Use the `latest` tag.
```yml
services:
image_video_classification:
image: ghcr.io/doppeltilde/image_video_classification:latest
ports:
- "8000:8000"
volumes:
- models:/root/.cache/huggingface/hub:rw
- ./models:/root/.cache/huggingface/hub:rw
environment:
- DEFAULT_MODEL_NAME
- BATCH_SIZE
Expand All @@ -26,20 +27,46 @@ services:
- USE_API_KEYS
- API_KEYS
restart: unless-stopped

volumes:
models:
```

**NVIDIA GPU Support:** Use the `latest-cuda` tag.
### **NVIDIA GPU Support**
> [!IMPORTANT]
> Nvidia driver >=560 needs to be installed on the host machine.

**CUDA (AMD64 & ARM64):**
```yml
services:
image_video_classification_cuda:
image: ghcr.io/doppeltilde/image_video_classification:latest-cuda
ports:
- "8000:8000"
volumes:
- models:/root/.cache/huggingface/hub:rw
- ./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
environment:
- DEFAULT_MODEL_NAME
- BATCH_SIZE
Expand All @@ -55,11 +82,73 @@ 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.

volumes:
models:
**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):**
> [!CAUTION]
> Clover is only recommended for legacy cards (e.g. gfx8). If you're using gfx10 or newer, use Rusticl instead.
```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"
```

## Environment Variables
- Create a `.env` file and set the preferred values.
```sh
DEFAULT_MODEL_NAME=Falconsai/nsfw_image_detection
Expand All @@ -75,6 +164,28 @@ 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 Clover & Rusticl)
- 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.

Expand Down Expand Up @@ -168,6 +279,8 @@ 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
Expand Down