Skip to content

AI Upscale Image

AI Upscale Image #182

Workflow file for this run

name: AI Upscale Image
on:
workflow_dispatch: # Manual trigger
push:
branches: [main]
paths:
- "Dockerfile.ai_upscale"
- "entrypoint-ai_upscale.sh"
- ".github/workflows/ai-upscale.yml"
workflow_run:
# Also trigger after ffmpeg-base completes to pick up new ffmpeg image
workflows: ["FFmpeg Base Image"]
types: [completed]
branches: [main]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}-ai-upscale
jobs:
build:
runs-on: ubuntu-latest
# Skip if triggered by failed ffmpeg workflow
if: ${{ github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' }}
permissions:
contents: read
packages: write
strategy:
matrix:
include:
- nvidia: 'cuda:12.4'
base_image: 'ubuntu:22.04'
- nvidia: 'cuda:12.6'
base_image: 'ubuntu:24.04'
- nvidia: 'cuda:12.8'
base_image: 'ubuntu:24.04'
- nvidia: 'cuda:13.0'
base_image: 'ubuntu:24.04'
latest: true
steps:
- name: Free disk space
run: |
# Remove large unnecessary packages to free up space for torch/tensorrt
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache
sudo apt-get clean
df -h
- uses: actions/checkout@v4
with:
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Parse CUDA version
id: cuda
run: |
# Extract "12.4" from "cuda:12.4"
CUDA_VER="${{ matrix.nvidia }}"
CUDA_VER="${CUDA_VER#cuda:}"
echo "version=$CUDA_VER" >> $GITHUB_OUTPUT
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=cuda${{ steps.cuda.outputs.version }}
type=raw,value=latest,enable=${{ matrix.latest == true }}
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile.ai_upscale
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
FFMPEG_IMAGE=ghcr.io/${{ github.repository }}-ffmpeg:cuda${{ steps.cuda.outputs.version }}
NVIDIA=${{ matrix.nvidia }}
BASE_IMAGE=${{ matrix.base_image }}
no-cache: true
- name: Verify image
run: |
# Free space: BuildKit uses separate storage, prune it before pulling
docker buildx prune -af || true
docker system prune -af || true
df -h
docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:cuda${{ steps.cuda.outputs.version }}
# Verify everything that should be enabled is actually linked
# Note: --entrypoint bypasses the default entrypoint which tries to build TensorRT engines (requires GPU)
docker run --rm --entrypoint sh ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:cuda${{ steps.cuda.outputs.version }} -c "
echo '=== Verifying AI Upscale build ==='
LDD_OUTPUT=\$(ldd /usr/local/bin/ffmpeg)
# Verify ffmpeg binaries exist
for bin in ffmpeg ffprobe ffplay; do
test -x /usr/local/bin/\$bin || { echo \"ERROR: \$bin not found\"; exit 1; }
echo \"OK: \$bin exists\"
done
# Verify non-NVIDIA dependencies are satisfied
# Note: All NVIDIA libraries (libnvinfer, libcuda, libcudart) are loaded via dlopen,
# so ffmpeg works even without NVIDIA GPU/drivers installed
MISSING=\$(echo \"\$LDD_OUTPUT\" | grep 'not found' | grep -v -E 'libnvinfer|libnvonnxparser|libcudart|libcuda' || true)
if [ -n \"\$MISSING\" ]; then
echo 'ERROR: Missing non-NVIDIA libraries:'
echo \"\$MISSING\"
exit 1
fi
echo 'OK: All non-NVIDIA dependencies satisfied'
# Verify ffmpeg has NO hard CUDA dependency (all CUDA/TensorRT loaded via dlopen)
if echo \"\$LDD_OUTPUT\" | grep -q 'libcudart'; then
echo 'ERROR: libcudart linked at compile time (should use dlopen)'
exit 1
fi
echo 'OK: No libcudart dependency (CUDA Driver API via dlopen)'
echo 'OK: libnvinfer loaded via dlopen (not in ldd output)'
# Verify Python AI packages installed (use pip show, not import - import needs CUDA runtime)
echo '=== Verifying Python packages ==='
pip3 show torch >/dev/null 2>&1 || { echo 'ERROR: torch not installed'; exit 1; }
echo 'OK: torch installed'
pip3 show onnx >/dev/null 2>&1 || { echo 'ERROR: onnx not installed'; exit 1; }
echo 'OK: onnx installed'
pip3 show tensorrt >/dev/null 2>&1 || { echo 'ERROR: tensorrt not installed'; exit 1; }
echo 'OK: tensorrt installed'
# Verify AI upscale scripts exist
echo '=== Verifying AI upscale scripts ==='
test -x /app/tools/install-ai_upscale.sh || { echo 'ERROR: install-ai_upscale.sh not found'; exit 1; }
echo 'OK: install-ai_upscale.sh exists'
test -f /app/tools/export-tensorrt.py || { echo 'ERROR: export-tensorrt.py not found'; exit 1; }
echo 'OK: export-tensorrt.py exists'
echo ''
echo '=== All verifications passed ==='
"