Compare commits

...
3 changed files with 644 additions and 594 deletions
+55 -16
View File
@@ -341,7 +341,10 @@ citing that these instructions have been present in over 99.7% of CPUs since 200
NumPy is a dependency of the document classifier (via scikit-learn), so any CPU that NumPy is a dependency of the document classifier (via scikit-learn), so any CPU that
predates SSE4.2 support will crash with `SIGILL` (illegal instruction) when the classifier predates SSE4.2 support will crash with `SIGILL` (illegal instruction) when the classifier
is loaded or trained, regardless of whether AI features are enabled. is loaded or trained, regardless of whether AI features are enabled. NumPy is also pulled in
transitively by `ocrmypdf`'s default page-finalization step (via the `fpdf2` package), which
runs during normal OCR/archive generation - so affected hardware can crash during ordinary
document consumption as well, not only during classifier training.
This differs from NumPy's optional SIMD dispatch (e.g. AVX2, AVX512), which is detected and This differs from NumPy's optional SIMD dispatch (e.g. AVX2, AVX512), which is detected and
selected safely at runtime - the `x86-64-v2` requirement above is a hard floor baked into the selected safely at runtime - the `x86-64-v2` requirement above is a hard floor baked into the
@@ -365,28 +368,64 @@ If this prints nothing, your CPU is affected.
The Celery worker (and potentially the web server) repeatedly crashes and restarts with a The Celery worker (and potentially the web server) repeatedly crashes and restarts with a
`SIGILL` error, typically visible in `dmesg`/`journalctl` as a `trap invalid opcode` inside `SIGILL` error, typically visible in `dmesg`/`journalctl` as a `trap invalid opcode` inside
`_multiarray_umath...so`. Because the classifier is trained on a periodic schedule `_multiarray_umath...so`. This can surface either as an intermittent crash when the
(hourly, by default), affected instances see intermittent, hard-to-reproduce document classifier's periodic training task runs (hourly, by default), or as a `RuntimeError: NumPy
consumption failures whenever that scheduled task runs and takes down the worker process was built with baseline optimizations... but your machine doesn't support` raised from
mid-task. `documents.parsers.ParseError` during OCR of a document being consumed, since `ocrmypdf`
imports NumPy indirectly through `fpdf2` while finalizing pages.
### Action Required (for affected hardware only) ### Current mitigation: NumPy is pinned below 2.4
There is no way to make the classifier itself work on such CPUs - it requires an unofficial Because so much affected hardware is still in active use, Paperless-ngx pins NumPy to
NumPy build with `cpu-baseline=none`, which is not something we can ship. The practical `<2.4` (currently resolving to the 2.3.x series) rather than requiring affected users to
path forward is to stop the classifier from ever loading or training, which avoids work around the problem themselves. This is a **temporary accommodation, not a permanent
importing NumPy at all: fix** - we don't control NumPy's wheel baseline, and this pin holds back a transitive
dependency indefinitely.
**Check whether your hardware will keep being supported.** Use the SSE4.2 check under
[Affected hardware](#affected-hardware) above. If your CPU has SSE4.2, this issue never
applies to you, now or later - the pin doesn't change anything for you. If your CPU lacks
SSE4.2, the pin is the only reason Paperless-ngx works for you today, and that protection is
not indefinite - see below.
**This pin has an expiration date.** NumPy 2.3.x is only
[supported upstream until 2027-06-08](https://endoflife.date/numpy) under the
[SPEC 0](https://scientific-python.org/specs/spec-0000/) policy (roughly 24 months from its
June 2025 release). After that date, 2.3.x stops receiving security fixes, and we will need
to either drop the pin (reintroducing this crash on affected hardware) or find another way
forward. If your CPU lacks SSE4.2, plan around that date rather than assuming indefinite
support - watch the
[paperless-ngx release notes](https://github.com/paperless-ngx/paperless-ngx/releases) as
it approaches, since we'll announce there if/when the pin is lifted.
If you build your own image or otherwise manage dependencies independently of our lockfile,
make sure your own NumPy pin matches (`numpy<2.4`) - nothing stops your build tooling from
picking up 2.4+ on its own.
### If you're stuck on NumPy 2.4+ (custom builds, or after the pin is eventually dropped)
There is no way to make NumPy 2.4+ itself work on affected CPUs on the official images - it
requires an unofficial build with `cpu-baseline=none`, which is not something we can ship.
Setting
```bash ```bash
PAPERLESS_TRAIN_TASK_CRON=disable PAPERLESS_TRAIN_TASK_CRON=disable
``` ```
This disables the periodic classifier training task (see disables the periodic classifier training task (see
[`PAPERLESS_TRAIN_TASK_CRON`](configuration.md#PAPERLESS_TRAIN_TASK_CRON)). Automatic [`PAPERLESS_TRAIN_TASK_CRON`](configuration.md#PAPERLESS_TRAIN_TASK_CRON)) and stops the
matching based on the classifier (suggested correspondents, document types, tags, and classifier itself from ever loading or training. Automatic matching based on the classifier
storage paths from trained rules) will no longer be available, but rule-based matching is (suggested correspondents, document types, tags, and storage paths from trained rules) will
unaffected, and document consumption itself will no longer be at risk of crashing the no longer be available, but rule-based matching is unaffected.
worker.
**This setting alone does not fully resolve the issue**, because `ocrmypdf` also imports
NumPy indirectly (via `fpdf2`) as part of its normal page-finalization step, independent of
the classifier. On affected hardware, OCR of documents can therefore still crash the worker
even with the classifier disabled. Advanced users may be able to work around this by building
a custom image that installs an alternate NumPy build compiled without the `x86-64-v2`
baseline (e.g. from source with `-Dcpu-baseline=none`), but this is unsupported and not
something the project can provide guidance for.
## Database Migrations ## Database Migrations
+6
View File
@@ -149,6 +149,12 @@ typing = [
[tool.uv] [tool.uv]
required-version = ">=0.9.0" required-version = ">=0.9.0"
# TEMPORARY: numpy>=2.4 raises the manylinux x86_64 wheel's CPU baseline to
# x86-64-v2 (SSE4.2+), which crashes on older/embedded CPUs. Pinning below
# 2.4 keeps that hardware working. numpy 2.3.x is supported upstream until
# 2027-06-08 (https://endoflife.date/numpy); revisit this pin before then.
# See docs/migration-v3.md#minimum-cpu-requirements-numpy-baseline
constraint-dependencies = [ "numpy<2.4" ]
environments = [ environments = [
"sys_platform == 'darwin'", "sys_platform == 'darwin'",
"sys_platform == 'linux'", "sys_platform == 'linux'",
Generated
+583 -578
View File
File diff suppressed because it is too large Load Diff