Files
SnapOtter/docker/download_models.py
T
Siddharth Kumar Sah b4b59a7500 fix: force CPU mode in download_models.py for build-time compatibility
paddlepaddle-gpu tries to load libcuda.so.1 on import, but no GPU
driver exists during Docker build. Set PADDLE_DEVICE=cpu, FLAGS_use_cuda=0,
and CUDA_VISIBLE_DEVICES="" before any ML imports to force CPU mode.
2026-04-10 11:22:56 +08:00

143 lines
4.7 KiB
Python

"""Pre-download and verify all ML models for the Docker image.
This script runs at Docker build time. Any failure exits non-zero,
failing the build. No silent fallbacks.
"""
import os
import sys
import urllib.request
# Force CPU mode during build - no GPU driver available at build time.
# Must be set before any ML library import.
os.environ["PADDLE_DEVICE"] = "cpu"
os.environ["FLAGS_use_cuda"] = "0"
os.environ["CUDA_VISIBLE_DEVICES"] = ""
REALESRGAN_MODEL_DIR = "/opt/models/realesrgan"
REALESRGAN_MODEL_URL = (
"https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth"
)
REALESRGAN_MODEL_PATH = os.path.join(REALESRGAN_MODEL_DIR, "RealESRGAN_x4plus.pth")
REALESRGAN_MIN_SIZE = 60_000_000 # ~67 MB
REMBG_MODELS = [
"u2net",
"isnet-general-use",
"bria-rmbg",
"birefnet-general-lite",
"birefnet-portrait",
"birefnet-general",
]
# PaddleOCR language codes (not ISO). German/French/Spanish use "latin" model.
# Valid keys: ch, en, korean, japan, chinese_cht, ta, te, ka, latin, arabic, cyrillic, devanagari
PADDLEOCR_LANGUAGES = ["en", "ch", "japan", "korean", "latin"]
def download_rembg_models():
"""Download all rembg ONNX models."""
print("=== Downloading rembg models ===")
from rembg import new_session
for model in REMBG_MODELS:
print(f" Downloading {model}...")
new_session(model)
print(f" {model} ready")
print(f"All {len(REMBG_MODELS)} rembg models downloaded.\n")
def download_realesrgan_model():
"""Download RealESRGAN_x4plus.pth pretrained weights."""
print("=== Downloading RealESRGAN model ===")
os.makedirs(REALESRGAN_MODEL_DIR, exist_ok=True)
print(f" Downloading from {REALESRGAN_MODEL_URL}...")
urllib.request.urlretrieve(REALESRGAN_MODEL_URL, REALESRGAN_MODEL_PATH)
size = os.path.getsize(REALESRGAN_MODEL_PATH)
assert size > REALESRGAN_MIN_SIZE, (
f"RealESRGAN model too small: {size} bytes (expected > {REALESRGAN_MIN_SIZE})"
)
print(f" RealESRGAN_x4plus.pth downloaded ({size / 1_000_000:.1f} MB)\n")
def download_paddleocr_models():
"""Pre-download PaddleOCR models for all supported languages."""
print("=== Downloading PaddleOCR models ===")
os.environ["PADDLE_PDX_DISABLE_MODEL_SOURCE_CHECK"] = "True"
# Force CPU mode during build - no GPU driver available at build time
os.environ["PADDLE_DEVICE"] = "cpu"
os.environ["FLAGS_use_cuda"] = "0"
from paddleocr import PaddleOCR
for lang in PADDLEOCR_LANGUAGES:
print(f" Downloading models for lang={lang}...")
PaddleOCR(lang=lang, use_gpu=False, show_log=False)
print(f" {lang} ready")
print(f"All {len(PADDLEOCR_LANGUAGES)} PaddleOCR languages downloaded.\n")
def verify_mediapipe():
"""Verify MediaPipe face detection models are bundled in the wheel."""
print("=== Verifying MediaPipe models ===")
import mediapipe as mp
for selection in [0, 1]:
label = "short-range" if selection == 0 else "full-range"
print(f" Verifying {label} model (selection={selection})...")
detector = mp.solutions.face_detection.FaceDetection(
model_selection=selection, min_detection_confidence=0.5
)
detector.close()
print(f" {label} model OK")
print("MediaPipe models verified.\n")
def smoke_test():
"""Final verification that all ML libraries and models are loadable."""
import platform
print("=== Running smoke test ===")
is_amd64 = platform.machine() in ("x86_64", "amd64")
from rembg import new_session
from paddleocr import PaddleOCR
import mediapipe as mp
import cv2
import numpy
from PIL import Image
import seam_carving
print(" Core imports OK")
# RealESRGAN/basicsr has a known torchvision compat issue on arm64.
# On amd64 we verify the full import chain; on arm64 we just check the model file.
if is_amd64:
from realesrgan import RealESRGANer
from basicsr.archs.rrdbnet_arch import RRDBNet
print(" RealESRGAN imports OK (amd64)")
else:
print(" RealESRGAN import skipped (arm64 - Lanczos fallback used)")
assert os.path.exists(REALESRGAN_MODEL_PATH), (
f"RealESRGAN model missing: {REALESRGAN_MODEL_PATH}"
)
assert os.path.getsize(REALESRGAN_MODEL_PATH) > REALESRGAN_MIN_SIZE, (
"RealESRGAN model file is too small"
)
print(" RealESRGAN model file verified")
print("Smoke test passed.\n")
def main():
print("Pre-downloading all ML models...\n")
download_rembg_models()
download_realesrgan_model()
download_paddleocr_models()
verify_mediapipe()
smoke_test()
print("All models downloaded and verified.")
if __name__ == "__main__":
main()