From 59c4f951ba08bff17abe3d613e063253425956c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pelayo=20Garc=C3=ADa=20B=C3=A1rcena?= <202404563@alu.comillas.edu> Date: Tue, 10 Mar 2026 19:46:12 +0100 Subject: [PATCH] feat: add AMD ROCm support for RX 5700 XT (gfx1010 / RDNA 1) - Dockerfile.rocm: new multi-stage image based on rocm/dev-ubuntu-24.04:6.3.1-complete * Sets PYTORCH_ROCM_VERSION=6.3 so uv installs ROCm-backed PyTorch wheels * Sets HSA_OVERRIDE_GFX_VERSION=10.3.0 to map RDNA1 (gfx1010) to RDNA2 kernels * Adds container user to 'video' and 'render' groups for /dev/kfd + /dev/dri access - docker-compose.rocm.yml: pre-built image compose file * Mounts /dev/kfd and /dev/dri (no NVIDIA plugin required) * group_add: video, render for GPU device node access * Documents per-generation HSA_OVERRIDE_GFX_VERSION values - docker-compose.build.rocm.yml: local build variant using Dockerfile.rocm - base_adapter.go: add GetPyTorchROCmVersion() and update GetPyTorchWheelURL() * PYTORCH_ROCM_VERSION env var selects ROCm wheel index (rocm6.3, etc.) * ROCm takes priority over CUDA; falls back to cu126 if neither is set * All existing adapters (WhisperX, PyAnnote, Voxtral, Parakeet, Canary) inherit ROCm wheel selection automatically via GetPyTorchWheelURL() --- Dockerfile.rocm | 142 ++++++++++++++++++ docker-compose.build.rocm.yml | 41 +++++ docker-compose.rocm.yml | 51 +++++++ .../transcription/adapters/base_adapter.go | 14 +- 4 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 Dockerfile.rocm create mode 100644 docker-compose.build.rocm.yml create mode 100644 docker-compose.rocm.yml diff --git a/Dockerfile.rocm b/Dockerfile.rocm new file mode 100644 index 00000000..8d0d7af8 --- /dev/null +++ b/Dockerfile.rocm @@ -0,0 +1,142 @@ +# Multi-stage build for Scriberr with AMD ROCm support +# Targets AMD RX 5700 XT (RDNA 1, gfx1010) and compatible GPUs. +# +# RX 5700 XT is not officially listed in AMD's ROCm support matrix, but works +# via HSA_OVERRIDE_GFX_VERSION=10.3.0 which maps it to gfx1030 (RDNA 2) kernels. +# +# For officially supported AMD hardware (Instinct MI series, Radeon Pro), remove +# or adjust HSA_OVERRIDE_GFX_VERSION accordingly. +# +# ROCm version: 6.3.x | PyTorch ROCm wheels: rocm6.3 + +######################## +# UI build stage +######################## +FROM node:20-alpine AS ui-builder +WORKDIR /web + +# Install deps and build web/frontend +COPY web/frontend/package*.json ./frontend/ +RUN cd frontend \ + && npm ci + +COPY web/frontend ./frontend +RUN cd frontend \ + && npm run build + + +######################## +# Go build stage +######################## +FROM golang:1.24-bookworm AS go-builder +WORKDIR /src + +# Pre-cache modules +COPY go.mod go.sum ./ +RUN go mod download + +# Copy source +COPY . . + +# Copy built UI into embed path +RUN rm -rf internal/web/dist && mkdir -p internal/web +COPY --from=ui-builder /web/frontend/dist internal/web/dist + +# Build binary (arch matches builder platform) +RUN CGO_ENABLED=0 \ + go build -o /out/scriberr cmd/server/main.go +# Build CLI binaries (cross-platform) +RUN mkdir -p /out/bin/cli \ + && GOOS=linux GOARCH=amd64 go build -o /out/bin/cli/scriberr-linux-amd64 ./cmd/scriberr-cli \ + && GOOS=darwin GOARCH=amd64 go build -o /out/bin/cli/scriberr-darwin-amd64 ./cmd/scriberr-cli \ + && GOOS=darwin GOARCH=arm64 go build -o /out/bin/cli/scriberr-darwin-arm64 ./cmd/scriberr-cli \ + && GOOS=windows GOARCH=amd64 go build -o /out/bin/cli/scriberr-windows-amd64.exe ./cmd/scriberr-cli + + +######################## +# ROCm Runtime stage +######################## +# rocm/dev-ubuntu-24.04:6.3.1-complete includes the full ROCm stack: +# hip-runtime-amd, rocblas, rocsolver, miopen-hip, rocfft, and related libs. +FROM rocm/dev-ubuntu-24.04:6.3.1-complete AS runtime + +ENV PYTHONUNBUFFERED=1 \ + HOST=0.0.0.0 \ + PORT=8080 \ + DATABASE_PATH=/app/data/scriberr.db \ + UPLOAD_DIR=/app/data/uploads \ + WHISPERX_ENV=/app/whisperx-env \ + APP_ENV=production \ + PUID=1000 \ + PGID=1000 \ + # AMD ROCm — PyTorch wheel version (maps to https://download.pytorch.org/whl/rocm6.3) + PYTORCH_ROCM_VERSION=6.3 \ + # HSA GFX override: makes RX 5700 XT (gfx1010 / RDNA 1) use gfx1030 (RDNA 2) kernels. + # This is required because AMD does not ship gfx1010 kernels in the ROCm distribution. + # Works reliably for inference workloads. Remove this line for officially supported hardware. + HSA_OVERRIDE_GFX_VERSION=10.3.0 \ + # Make the GPU visible inside the container + # ROCR_VISIBLE_DEVICES can be set to a specific GPU index (e.g. "0") at runtime + ROCR_VISIBLE_DEVICES=all + +WORKDIR /app + +# System deps: curl for uv install, ca-certs, ffmpeg for yt-dlp, git for git+ installs, gosu for user switching +# Ubuntu 24.04 comes with Python 3.12 which works fine with WhisperX +# Note: ROCm runtime libs are already present in the base image. +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + curl ca-certificates ffmpeg git gosu unzip \ + build-essential gcc g++ make python3-dev \ + python3 python3-venv python3-pip \ + && rm -rf /var/lib/apt/lists/* + +# Install uv (fast Python package manager) directly to system PATH +RUN curl -LsSf https://astral.sh/uv/install.sh | sh \ + && cp /root/.local/bin/uv /usr/local/bin/uv \ + && chmod 755 /usr/local/bin/uv \ + && uv --version + +# Install yt-dlp standalone binary +RUN curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o /usr/local/bin/yt-dlp \ + && chmod a+rx /usr/local/bin/yt-dlp \ + && yt-dlp --version + +# Install Deno (JavaScript runtime required for yt-dlp YouTube downloads) +# YouTube now requires JS execution for video cipher decryption +# See: https://github.com/yt-dlp/yt-dlp/issues/14404 +RUN curl -fsSL https://deno.land/install.sh | sh \ + && cp /root/.deno/bin/deno /usr/local/bin/deno \ + && chmod 755 /usr/local/bin/deno \ + && deno --version + +# Create default user. +# The user must belong to the 'video' and 'render' groups to access /dev/kfd and /dev/dri. +# Group IDs 44 (video) and 109 (render) are the standard IDs on Ubuntu hosts running ROCm. +# These are added to the container user so the process can open the GPU device nodes. +RUN groupadd -g 10001 appuser \ + && useradd -m -u 10001 -g 10001 appuser \ + && usermod -aG video,render appuser \ + && mkdir -p /app/data/uploads /app/data/transcripts \ + && chown -R appuser:appuser /app + +# Copy binary and entrypoint script +COPY --from=go-builder /out/scriberr /app/scriberr +COPY --from=go-builder /out/bin/cli /app/bin/cli +COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh + +# Make entrypoint script executable and set up basic permissions +RUN chmod +x /usr/local/bin/docker-entrypoint.sh \ + && chown appuser:appuser /app/scriberr + +# Expose port and declare volume for persistence +EXPOSE 8080 +VOLUME ["/app/data"] + +# Start as root to allow user ID changes, entrypoint script will switch users +# Verify uv is available +RUN uv --version + +# Use entrypoint script that handles user switching and permissions +ENTRYPOINT ["docker-entrypoint.sh"] +CMD ["/app/scriberr"] diff --git a/docker-compose.build.rocm.yml b/docker-compose.build.rocm.yml new file mode 100644 index 00000000..fb225d84 --- /dev/null +++ b/docker-compose.build.rocm.yml @@ -0,0 +1,41 @@ +# Docker Compose for building Scriberr locally with AMD ROCm support +# Builds from Dockerfile.rocm and tags the image as scriberr:local-rocm +# +# Usage: docker compose -f docker-compose.build.rocm.yml up --build +version: "3.9" +services: + scriberr: + build: + context: . + dockerfile: Dockerfile.rocm + image: scriberr:local-rocm + container_name: scriberr + ports: + - "8080:8080" + # AMD GPU access: expose the kernel fusion driver (/dev/kfd) and DRM render nodes (/dev/dri). + devices: + - /dev/kfd:/dev/kfd + - /dev/dri:/dev/dri + group_add: + - video + - render + environment: + - PUID=${PUID:-1000} + - PGID=${PGID:-1000} + - APP_ENV=production + # ROCm: PyTorch wheel version. Maps to https://download.pytorch.org/whl/rocm6.3 + - PYTORCH_ROCM_VERSION=6.3 + # RX 5700 XT (gfx1010 / RDNA 1) compatibility override. + # Instructs the ROCm runtime to use gfx1030 (RDNA 2) kernels. + # Remove or adjust for other AMD GPU generations (see docker-compose.rocm.yml). + - HSA_OVERRIDE_GFX_VERSION=10.3.0 + # Optionally restrict to a specific GPU index (default: all) + # - ROCR_VISIBLE_DEVICES=0 + volumes: + - ./scriberr_data:/app/data + - ./env-data:/app/whisperx-env + restart: unless-stopped + +volumes: + scriberr_data: + env-data: diff --git a/docker-compose.rocm.yml b/docker-compose.rocm.yml new file mode 100644 index 00000000..f86428fa --- /dev/null +++ b/docker-compose.rocm.yml @@ -0,0 +1,51 @@ +# Docker Compose for Scriberr with AMD ROCm GPU support +# Targets AMD RX 5700 XT (RDNA 1, gfx1010) and compatible AMD GPUs. +# +# Prerequisites on the host: +# 1. ROCm driver stack installed: https://rocm.docs.amd.com/en/latest/deploy/linux/quick_start.html +# 2. Your user must be in the 'video' and 'render' groups: +# sudo usermod -aG video,render $USER +# 3. Verify the GPU is visible: rocminfo | grep gfx +# +# Usage: docker compose -f docker-compose.rocm.yml up +version: "3.9" +services: + scriberr: + image: ghcr.io/rishikanthc/scriberr-rocm:latest + ports: + - "8080:8080" + volumes: + - scriberr_data:/app/data + - env_data:/app/whisperx-env + restart: unless-stopped + # AMD GPU access: expose the kernel fusion driver (/dev/kfd) and DRM render nodes (/dev/dri). + # No special Docker plugin is required — this works with plain Docker and Compose. + devices: + - /dev/kfd:/dev/kfd + - /dev/dri:/dev/dri + # The container user must belong to the 'video' and 'render' groups on the host. + group_add: + - video + - render + environment: + - PUID=${PUID:-1000} + - PGID=${PGID:-1000} + - APP_ENV=production + # ROCm: PyTorch wheel version. Maps to https://download.pytorch.org/whl/rocm6.3 + - PYTORCH_ROCM_VERSION=6.3 + # RX 5700 XT (gfx1010 / RDNA 1) compatibility override. + # Instructs the ROCm runtime to use gfx1030 (RDNA 2) kernels, which are included + # in the ROCm distribution and compatible with RDNA 1 silicon. + # Remove or change this for other AMD GPU generations: + # - RX 6000 series (RDNA 2, gfx1030): remove this line (officially supported) + # - RX 7000 series (RDNA 3, gfx1100): remove this line (officially supported) + # - Vega 56/64 (GCN 5, gfx900): HSA_OVERRIDE_GFX_VERSION=9.0.0 + - HSA_OVERRIDE_GFX_VERSION=10.3.0 + # Optionally restrict to a specific GPU index (default: all) + # - ROCR_VISIBLE_DEVICES=0 + # CORS: comma-separated list of allowed origins for production + # - ALLOWED_ORIGINS=https://your-domain.com + +volumes: + scriberr_data: {} + env_data: {} diff --git a/internal/transcription/adapters/base_adapter.go b/internal/transcription/adapters/base_adapter.go index b0f0347a..33cebfd5 100644 --- a/internal/transcription/adapters/base_adapter.go +++ b/internal/transcription/adapters/base_adapter.go @@ -38,8 +38,20 @@ func GetPyTorchCUDAVersion() string { return "cu126" // Default to CUDA 12.6 for legacy compatibility } -// GetPyTorchWheelURL returns the full PyTorch wheel URL for the configured CUDA version. +// GetPyTorchROCmVersion returns the AMD ROCm version for PyTorch wheels, if configured. +// Set PYTORCH_ROCM_VERSION (e.g. "6.3") to enable ROCm/HIP-backed PyTorch. +// When set, ROCm wheels take priority over CUDA wheels. +// Required for AMD GPUs such as RX 5700 XT (gfx1010 / RDNA 1). +func GetPyTorchROCmVersion() string { + return os.Getenv("PYTORCH_ROCM_VERSION") +} + +// GetPyTorchWheelURL returns the full PyTorch wheel index URL for the configured backend. +// Priority: ROCm (AMD) > CUDA (NVIDIA) > default CUDA 12.6. func GetPyTorchWheelURL() string { + if rocmVersion := GetPyTorchROCmVersion(); rocmVersion != "" { + return fmt.Sprintf("https://download.pytorch.org/whl/rocm%s", rocmVersion) + } return fmt.Sprintf("https://download.pytorch.org/whl/%s", GetPyTorchCUDAVersion()) }