From 4466921313cd22eb77f16ed4c115fbe4a17b9f0f Mon Sep 17 00:00:00 2001 From: chsbusch-dot Date: Thu, 2 Jul 2026 11:51:46 -0700 Subject: [PATCH 1/2] Enable PaddlePaddle GPU (CUDA 12) for ALPR on Linux x86_64 CodeProject.AI's ALPR runs PaddleOCR on CPU on CUDA-12 Linux hosts due to three issues; this fixes all three so the module uses the GPU: - requirements.linux.cuda12.txt had a bare `paddlepaddle-gpu`, but PyPI only ships CUDA<=11.7 builds, so a non-CUDA-12 build (or none) was installed. Pin 2.6.2.post120 and add Paddle's cu120 package index so the real CUDA-12 wheel is used. (Works on CUDA 12.0-12.7 drivers via forward compat.) - modulesettings.linux.json hardcoded "InstallGPU": false (stale "GPU only installs easily on Windows" assumption). Flip to true so the adapter's enable_GPU isn't forced off. - install.sh: Paddle dlopens the unversioned libcudnn.so, but Ubuntu ships only libcudnn.so.8. Symlink it during install so cuDNN loads. Verified on an RTX A5000 (CUDA 12.4/12.7 driver, cuDNN 8.9) container: ALPR now reports inferenceDevice=GPU. Co-Authored-By: Claude Opus 4.8 --- install.sh | 11 +++++++++++ modulesettings.linux.json | 2 +- requirements.linux.cuda12.txt | 10 +++++++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/install.sh b/install.sh index 43ccd2d..c2c89ab 100644 --- a/install.sh +++ b/install.sh @@ -146,6 +146,17 @@ if [ "${moduleInstallErrors}" = "" ] && [ "$os" = "linux" ] && [ "$architecture" fi fi +# PaddlePaddle (CUDA) dlopens the UNVERSIONED libcudnn.so, but Ubuntu's cuDNN package +# only ships libcudnn.so.8. Without this link Paddle fails at import with +# "PreconditionNotMetError: Cannot load cudnn shared library". Create it if missing. +if [ "$os" = "linux" ] && [ "$architecture" == "x86_64" ]; then + if [ -f /usr/lib/x86_64-linux-gnu/libcudnn.so.8 ] && [ ! -e /usr/lib/x86_64-linux-gnu/libcudnn.so ]; then + write "Linking libcudnn.so -> libcudnn.so.8 for PaddlePaddle..." $color_info + sudo ln -sf /usr/lib/x86_64-linux-gnu/libcudnn.so.8 /usr/lib/x86_64-linux-gnu/libcudnn.so >/dev/null 2>/dev/null + writeLine "Done" $color_success + fi +fi + if [ "$os" = "macos" ]; then # The Numpy Debacle, 2024 diff --git a/modulesettings.linux.json b/modulesettings.linux.json index 7fa052e..715caf8 100644 --- a/modulesettings.linux.json +++ b/modulesettings.linux.json @@ -3,7 +3,7 @@ "ALPR": { "GpuOptions" : { - "InstallGPU": false + "InstallGPU": true } } } diff --git a/requirements.linux.cuda12.txt b/requirements.linux.cuda12.txt index 005afb2..c3ffa54 100644 --- a/requirements.linux.cuda12.txt +++ b/requirements.linux.cuda12.txt @@ -2,7 +2,15 @@ numpy==1.23.3 # Installing NumPy, a package for scientific computing -paddlepaddle-gpu # Installing PaddlePaddle, Parallel Distributed Deep Learning +# PaddlePaddle GPU build for CUDA 12.x (runs on CUDA 12.0-12.7 drivers via minor-version +# forward compatibility). PyPI's paddlepaddle-gpu only ships CUDA<=11.7 builds, so the +# bare requirement silently gets a non-CUDA-12 build (or nothing) and ALPR falls back to +# CPU. The CUDA-12 (.post120) wheel lives only on Paddle's own package index, added below. +# NOTE: paddlepaddle.org.cn / bcebos are China-hosted; on networks that cannot reach them, +# fetch the wheel elsewhere and `pip install` the local .whl (see README GPU notes). +# Do NOT jump to Paddle 3.x here: it drops Python 3.8 and breaks PaddleOCR 2.7.0.3. +--extra-index-url https://www.paddlepaddle.org.cn/packages/stable/cu120/ +paddlepaddle-gpu==2.6.2.post120 # PaddlePaddle GPU (CUDA 12), Parallel Distributed Deep Learning paddleocr==2.7.0.3 # Installing PaddleOCR, the OCR toolkit based on PaddlePaddle imutils # Installing imutils, the image utilities library From ed67a81105c751896cebff3e95240ae61ab55ce7 Mon Sep 17 00:00:00 2001 From: chsbusch-dot Date: Thu, 2 Jul 2026 12:13:29 -0700 Subject: [PATCH 2/2] Add offline local-wheel fallback for the CUDA-12 PaddlePaddle GPU install MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The CUDA-12 wheel is served only from Paddle's China-hosted index, which many networks/VMs cannot reach — so the requirements install silently gets no CUDA build and ALPR runs on CPU. install.sh now falls back to a wheel placed in the module's wheels/ folder when paddlepaddle isn't already installed. Adds wheels/README.md documenting where to get the wheel. Co-Authored-By: Claude Opus 4.8 --- install.sh | 15 +++++++++++++++ wheels/README.md | 26 ++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 wheels/README.md diff --git a/install.sh b/install.sh index c2c89ab..bb4d5da 100644 --- a/install.sh +++ b/install.sh @@ -157,6 +157,21 @@ if [ "$os" = "linux" ] && [ "$architecture" == "x86_64" ]; then fi fi +# Offline / restricted-network fallback for the CUDA-12 PaddlePaddle GPU wheel. +# requirements.linux.cuda12.txt installs paddlepaddle-gpu from Paddle's (China-hosted) +# index; where that host is unreachable the install gets no CUDA build and ALPR runs +# on CPU. As a fallback, drop the matching wheel in this module's `wheels/` folder and +# it is installed from there. See wheels/README.md. +if [ "$os" = "linux" ] && [ "$architecture" == "x86_64" ]; then + if ! "$venvPythonCmdPath" -m pip show paddlepaddle-gpu >/dev/null 2>&1 && \ + ! "$venvPythonCmdPath" -m pip show paddlepaddle >/dev/null 2>&1; then + localWheel=$(ls "${moduleDirPath}/wheels/"paddlepaddle*.whl 2>/dev/null | head -1) + if [ -n "$localWheel" ]; then + installPythonPackagesByName "$localWheel" "PaddlePaddle GPU (local wheel, offline)" + fi + fi +fi + if [ "$os" = "macos" ]; then # The Numpy Debacle, 2024 diff --git a/wheels/README.md b/wheels/README.md new file mode 100644 index 0000000..8ef15bb --- /dev/null +++ b/wheels/README.md @@ -0,0 +1,26 @@ +# Offline PaddlePaddle GPU wheel + +`requirements.linux.cuda12.txt` installs the CUDA-12 PaddlePaddle GPU build +(`paddlepaddle-gpu==2.6.2.post120`) from Paddle's own package index, which is +China-hosted (`paddlepaddle.org.cn` / `bcebos.com`). Some networks — and many +datacenter / VM environments — cannot reach it, so that install silently gets no +CUDA build and ALPR falls back to CPU. + +**If that's your situation:** download the wheel matching your module venv's Python +from a machine that *can* reach the host, and drop it in **this folder**. `install.sh` +installs it automatically when the indexed download isn't available. + +Wheel (Python 3.8 shown — pick the `cp##` tag matching your venv): + +``` +paddlepaddle_gpu-2.6.2.post120-cp38-cp38-linux_x86_64.whl +``` + +Direct URL (when reachable): + +``` +https://paddle-whl.bj.bcebos.com/stable/cu120/paddlepaddle-gpu/paddlepaddle_gpu-2.6.2.post120-cp38-cp38-linux_x86_64.whl +``` + +Only the `paddlepaddle-gpu` wheel is needed here; everything else installs from PyPI. +Do **not** switch to PaddlePaddle 3.x — it drops Python 3.8 and breaks PaddleOCR 2.7.0.3.