Skip to content

Commit 8f53754

Browse files
fxfitzrishikanthc
authored andcommitted
feat: add RTX 5090 Blackwell GPU support (sm_120)
Add support for NVIDIA RTX 50-series GPUs (Blackwell architecture) which require CUDA 12.8+ and PyTorch cu128 wheels due to the new sm_120 compute capability. Changes: - Add configurable PYTORCH_CUDA_VERSION environment variable to control PyTorch wheel version at runtime (cu126 for legacy, cu128 for Blackwell) - Update all model adapters to use dynamic CUDA version instead of hardcoded cu126 URLs - Update Dockerfile.cuda.12.9 for Blackwell with CUDA 12.9.1 base image, PYTORCH_CUDA_VERSION=cu128, and missing WHISPERX_ENV/yt-dlp - Update Dockerfile.cuda with explicit PYTORCH_CUDA_VERSION=cu126 - Add docker-compose.blackwell.yml for pre-built Blackwell image - Add docker-compose.build.blackwell.yml for local Blackwell builds - Add GPU compatibility documentation to README Fixes: #104
1 parent 718cb74 commit 8f53754

File tree

11 files changed

+146
-21
lines changed

11 files changed

+146
-21
lines changed

Dockerfile.cuda

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@ ENV PYTHONUNBUFFERED=1 \
5959
PUID=1000 \
6060
PGID=1000 \
6161
NVIDIA_VISIBLE_DEVICES=all \
62-
NVIDIA_DRIVER_CAPABILITIES=compute,utility
62+
NVIDIA_DRIVER_CAPABILITIES=compute,utility \
63+
# PyTorch CUDA wheel version: cu126 for legacy GPUs (GTX 10-series through RTX 40-series)
64+
PYTORCH_CUDA_VERSION=cu126
6365

6466
WORKDIR /app
6567

Dockerfile.cuda.12.9

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
# Multi-stage build for Scriberr with CUDA support
1+
# Multi-stage build for Scriberr with CUDA 12.9 support (Blackwell GPUs)
2+
# This Dockerfile targets NVIDIA RTX 50-series (Blackwell architecture, sm_120)
3+
# For legacy GPUs (GTX 10-series through RTX 40-series), use Dockerfile.cuda instead
24
# Builds React UI and Go server, then ships with NVIDIA CUDA runtime
35

46
########################
@@ -54,10 +56,14 @@ ENV PYTHONUNBUFFERED=1 \
5456
PORT=8080 \
5557
DATABASE_PATH=/app/data/scriberr.db \
5658
UPLOAD_DIR=/app/data/uploads \
59+
WHISPERX_ENV=/app/whisperx-env \
60+
APP_ENV=production \
5761
PUID=1000 \
5862
PGID=1000 \
5963
NVIDIA_VISIBLE_DEVICES=all \
60-
NVIDIA_DRIVER_CAPABILITIES=compute,utility
64+
NVIDIA_DRIVER_CAPABILITIES=compute,utility \
65+
# PyTorch CUDA wheel version: cu128 for Blackwell GPUs (RTX 50-series, sm_120)
66+
PYTORCH_CUDA_VERSION=cu128
6167

6268
WORKDIR /app
6369

@@ -76,6 +82,11 @@ RUN curl -LsSf https://astral.sh/uv/install.sh | sh \
7682
&& chmod 755 /usr/local/bin/uv \
7783
&& uv --version
7884

85+
# Install yt-dlp standalone binary (required by API handlers for YouTube URL processing)
86+
RUN curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o /usr/local/bin/yt-dlp \
87+
&& chmod a+rx /usr/local/bin/yt-dlp \
88+
&& yt-dlp --version
89+
7990
# Install Deno (JavaScript runtime required for yt-dlp YouTube downloads)
8091
# YouTube now requires JS execution for video cipher decryption
8192
# See: https://github.com/yt-dlp/yt-dlp/issues/14404

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,30 @@ volumes:
275275
docker compose -f docker-compose.cuda.yml up -d
276276
```
277277

278+
#### GPU Compatibility
279+
280+
Scriberr provides separate Docker images for different NVIDIA GPU generations due to CUDA/PyTorch compatibility requirements:
281+
282+
| GPU Generation | Compute Capability | Docker Image | Docker Compose File |
283+
|:---|:---|:---|:---|
284+
| GTX 10-series (Pascal) | sm_61 | `scriberr-cuda` | `docker-compose.cuda.yml` |
285+
| RTX 20-series (Turing) | sm_75 | `scriberr-cuda` | `docker-compose.cuda.yml` |
286+
| RTX 30-series (Ampere) | sm_86 | `scriberr-cuda` | `docker-compose.cuda.yml` |
287+
| RTX 40-series (Ada Lovelace) | sm_89 | `scriberr-cuda` | `docker-compose.cuda.yml` |
288+
| **RTX 50-series (Blackwell)** | sm_120 | `scriberr-cuda-blackwell` | `docker-compose.blackwell.yml` |
289+
290+
**RTX 50-series users (RTX 5080, 5090, etc.):** You must use the Blackwell-specific image. The standard CUDA image will not work due to PyTorch CUDA compatibility requirements. Use:
291+
292+
```bash
293+
docker compose -f docker-compose.blackwell.yml up -d
294+
```
295+
296+
Or for local builds:
297+
298+
```bash
299+
docker compose -f docker-compose.build.blackwell.yml up -d
300+
```
301+
278302
### App Startup
279303

280304
When you run Scriberr for the first time, it may take several minutes to start. This is normal!

docker-compose.blackwell.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Docker Compose for Scriberr with Blackwell GPU support (RTX 50-series)
2+
# Uses pre-built image from GitHub Container Registry
3+
# For legacy GPUs (GTX 10-series through RTX 40-series), use docker-compose.cuda.yml instead
4+
version: "3.9"
5+
services:
6+
scriberr:
7+
image: ghcr.io/rishikanthc/scriberr-cuda-blackwell:latest
8+
ports:
9+
- "8080:8080"
10+
volumes:
11+
- scriberr_data:/app/data
12+
- env_data:/app/whisperx-env
13+
restart: unless-stopped
14+
deploy:
15+
resources:
16+
reservations:
17+
devices:
18+
- driver: nvidia
19+
count: all
20+
capabilities:
21+
- gpu
22+
environment:
23+
- NVIDIA_VISIBLE_DEVICES=all
24+
- NVIDIA_DRIVER_CAPABILITIES=compute,utility
25+
- PUID=${PUID:-1000}
26+
- PGID=${PGID:-1000}
27+
# Security: already set in container, but can be overridden
28+
- APP_ENV=production
29+
# CORS: comma-separated list of allowed origins for production
30+
# - ALLOWED_ORIGINS=https://your-domain.com
31+
32+
volumes:
33+
scriberr_data: {}
34+
env_data: {}

docker-compose.build.blackwell.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Docker Compose for building Scriberr with Blackwell GPU support locally
2+
# Uses Dockerfile.cuda.12.9 for RTX 50-series (Blackwell architecture, sm_120)
3+
# For legacy GPUs (GTX 10-series through RTX 40-series), use docker-compose.build.cuda.yml instead
4+
services:
5+
scriberr:
6+
build:
7+
context: .
8+
dockerfile: Dockerfile.cuda.12.9
9+
image: scriberr:local-blackwell
10+
container_name: scriberr-blackwell
11+
ports:
12+
- "8080:8080"
13+
deploy:
14+
resources:
15+
reservations:
16+
devices:
17+
- driver: nvidia
18+
count: all
19+
capabilities:
20+
- gpu
21+
environment:
22+
- NVIDIA_VISIBLE_DEVICES=all
23+
- NVIDIA_DRIVER_CAPABILITIES=compute,utility
24+
- PUID=${PUID:-1000}
25+
- PGID=${PGID:-1000}
26+
# Security: already set in container, but can be overridden
27+
- APP_ENV=production
28+
# CORS: comma-separated list of allowed origins for production
29+
# - ALLOWED_ORIGINS=https://your-domain.com
30+
volumes:
31+
- ./scriberr_data:/app/data
32+
- ./env-data:/app/whisperx-env
33+
restart: unless-stopped
34+
35+
volumes:
36+
scriberr_data:
37+
env-data:

internal/transcription/adapters/base_adapter.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,22 @@ var (
2727
requestGroup singleflight.Group
2828
)
2929

30+
// GetPyTorchCUDAVersion returns the PyTorch CUDA wheel version to use.
31+
// This is configurable via the PYTORCH_CUDA_VERSION environment variable.
32+
// Defaults to "cu126" for CUDA 12.6 (legacy GPUs: GTX 10-series through RTX 40-series).
33+
// Set to "cu128" for CUDA 12.8 (Blackwell GPUs: RTX 50-series).
34+
func GetPyTorchCUDAVersion() string {
35+
if cudaVersion := os.Getenv("PYTORCH_CUDA_VERSION"); cudaVersion != "" {
36+
return cudaVersion
37+
}
38+
return "cu126" // Default to CUDA 12.6 for legacy compatibility
39+
}
40+
41+
// GetPyTorchWheelURL returns the full PyTorch wheel URL for the configured CUDA version.
42+
func GetPyTorchWheelURL() string {
43+
return fmt.Sprintf("https://download.pytorch.org/whl/%s", GetPyTorchCUDAVersion())
44+
}
45+
3046
// CheckEnvironmentReady checks if a UV environment is ready with caching and singleflight
3147
func CheckEnvironmentReady(envPath, importStatement string) bool {
3248
cacheKey := fmt.Sprintf("%s:%s", envPath, importStatement)

internal/transcription/adapters/canary_adapter.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,8 @@ func (c *CanaryAdapter) setupCanaryEnvironment() error {
207207
return nil
208208
}
209209

210-
// Create pyproject.toml (same as Parakeet since they share environment)
211-
pyprojectContent := `[project]
210+
// Create pyproject.toml with configurable PyTorch CUDA version
211+
pyprojectContent := fmt.Sprintf(`[project]
212212
name = "parakeet-transcription"
213213
version = "0.1.0"
214214
description = "Audio transcription using NVIDIA Parakeet models"
@@ -241,14 +241,14 @@ triton = [
241241
242242
[[tool.uv.index]]
243243
name = "pytorch"
244-
url = "https://download.pytorch.org/whl/cu126"
244+
url = "%s"
245245
explicit = true
246246
247247
[[tool.uv.index]]
248248
name = "pytorch-cpu"
249249
url = "https://download.pytorch.org/whl/cpu"
250250
explicit = true
251-
`
251+
`, GetPyTorchWheelURL())
252252
if err := os.WriteFile(pyprojectPath, []byte(pyprojectContent), 0644); err != nil {
253253
return fmt.Errorf("failed to write pyproject.toml: %w", err)
254254
}

internal/transcription/adapters/parakeet_adapter.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,8 @@ func (p *ParakeetAdapter) setupParakeetEnvironment() error {
179179
return fmt.Errorf("failed to create parakeet directory: %w", err)
180180
}
181181

182-
// Create pyproject.toml
183-
pyprojectContent := `[project]
182+
// Create pyproject.toml with configurable PyTorch CUDA version
183+
pyprojectContent := fmt.Sprintf(`[project]
184184
name = "parakeet-transcription"
185185
version = "0.1.0"
186186
description = "Audio transcription using NVIDIA Parakeet models"
@@ -213,14 +213,14 @@ triton = [
213213
214214
[[tool.uv.index]]
215215
name = "pytorch"
216-
url = "https://download.pytorch.org/whl/cu126"
216+
url = "%s"
217217
explicit = true
218218
219219
[[tool.uv.index]]
220220
name = "pytorch-cpu"
221221
url = "https://download.pytorch.org/whl/cpu"
222222
explicit = true
223-
`
223+
`, GetPyTorchWheelURL())
224224
pyprojectPath := filepath.Join(p.envPath, "pyproject.toml")
225225
if err := os.WriteFile(pyprojectPath, []byte(pyprojectContent), 0644); err != nil {
226226
return fmt.Errorf("failed to write pyproject.toml: %w", err)

internal/transcription/adapters/pyannote_adapter.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -216,10 +216,10 @@ func (p *PyAnnoteAdapter) setupPyAnnoteEnvironment() error {
216216
return fmt.Errorf("failed to create pyannote directory: %w", err)
217217
}
218218

219-
// Create pyproject.toml for PyAnnote
219+
// Create pyproject.toml with configurable PyTorch CUDA version
220220
// Note: We explicitly pin torch and torchaudio to 2.1.2 to ensure compatibility with pyannote.audio 3.1
221221
// Newer versions of torchaudio (2.2+) removed AudioMetaData which causes crashes
222-
pyprojectContent := `[project]
222+
pyprojectContent := fmt.Sprintf(`[project]
223223
name = "pyannote-diarization"
224224
version = "0.1.0"
225225
description = "Audio diarization using PyAnnote"
@@ -245,14 +245,14 @@ torchaudio = [
245245
246246
[[tool.uv.index]]
247247
name = "pytorch"
248-
url = "https://download.pytorch.org/whl/cu126"
248+
url = "%s"
249249
explicit = true
250250
251251
[[tool.uv.index]]
252252
name = "pytorch-cpu"
253253
url = "https://download.pytorch.org/whl/cpu"
254254
explicit = true
255-
`
255+
`, GetPyTorchWheelURL())
256256
pyprojectPath := filepath.Join(p.envPath, "pyproject.toml")
257257
if err := os.WriteFile(pyprojectPath, []byte(pyprojectContent), 0644); err != nil {
258258
return fmt.Errorf("failed to write pyproject.toml: %w", err)

internal/transcription/adapters/sortformer_adapter.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@ func (s *SortformerAdapter) setupSortformerEnvironment() error {
195195
return fmt.Errorf("failed to create sortformer directory: %w", err)
196196
}
197197

198-
// Create pyproject.toml (same as other NVIDIA models)
199-
pyprojectContent := `[project]
198+
// Create pyproject.toml with configurable PyTorch CUDA version
199+
pyprojectContent := fmt.Sprintf(`[project]
200200
name = "parakeet-transcription"
201201
version = "0.1.0"
202202
description = "Audio transcription using NVIDIA Parakeet models"
@@ -230,14 +230,14 @@ triton = [
230230
231231
[[tool.uv.index]]
232232
name = "pytorch"
233-
url = "https://download.pytorch.org/whl/cu126"
233+
url = "%s"
234234
explicit = true
235235
236236
[[tool.uv.index]]
237237
name = "pytorch-cpu"
238238
url = "https://download.pytorch.org/whl/cpu"
239239
explicit = true
240-
`
240+
`, GetPyTorchWheelURL())
241241
pyprojectPath := filepath.Join(s.envPath, "pyproject.toml")
242242
if err := os.WriteFile(pyprojectPath, []byte(pyprojectContent), 0644); err != nil {
243243
return fmt.Errorf("failed to write pyproject.toml: %w", err)

0 commit comments

Comments
 (0)