docs: warn that .half() corrupts CRNN recognition output on GPU + note .cuda() is required for GPU#2111
Open
moduvoice wants to merge 1 commit into
Open
docs: warn that .half() corrupts CRNN recognition output on GPU + note .cuda() is required for GPU#2111moduvoice wants to merge 1 commit into
moduvoice wants to merge 1 commit into
Conversation
- README Quick Tour: note that ocr_predictor() stays on CPU with no warning unless .cuda()/.to(device) is called explicitly (measured 17.16x speedup on T4 when enabled), linking to the existing GPU docs. - README Developer mode: note that the unpinned torch version range can silently resolve to a CUDA build newer than the local driver supports, making torch.cuda.is_available() return False with no error. - docs/using_model_export.rst: add a warning that .half() (fp16) on the default crnn_vgg16_bn recognizer silently corrupts recognition output on a T4 (deterministic, no error/warning), while transformer-based recognizers (master, parseq) are unaffected under the same test. - Add AGENTS.md summarizing these findings for future contributors and coding agents. No code changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
While benchmarking docTR's default OCR pipeline (
db_resnet50+crnn_vgg16_bn) on an NVIDIA T4 (Turing, 16GB, driver 550.163.01 / CUDA 12.4, torch 2.6.0+cu124, doctr 1.0.2a0 @1a1018c), I found two documentation gaps worth flagging, one of which is safety-relevant rather than just a performance nit:Silent CPU fallback. The README "Quick Tour" never calls
.cuda()/.to(device), so on a machine with a CUDA GPU available,ocr_predictor(...)still runs 100% on CPU with zero warning (peak_vram_mb: 0.0). The GPU section already exists indocs/using_doctr/using_models.rst, it's just not linked from the Quick Tour, so it's easy to miss. Adding the single.cuda()call measured a 17.16x speedup (2.657s → 0.155s/image) on this box..half()(fp16) silently corrupts recognition output for the default recognizer — CRITICAL. This is the important one. The officially documented half-precision path (docs/using_model_export.rst,.cuda().half()) works fine for transformer-based recognizers, but applied to the README's own default combo,crnn_vgg16_bn(annn.LSTM-based decoder), it silently mangles the recognized text. No exception, no warning — the run completes normally and even looks faster (which it is). Example, same image, same detector, only dtype changed:This was 100% reproducible across 2 independent runs (deterministic, not a flaky numerics thing). To isolate the root cause, I fixed the detector and swapped only the recognizer:
masterandparseq(transformer-based recognizers, self-contained attention, nonn.LSTM) produced output identical to fp32 under the exact same.half()call. So this looks specific to the CRNN's LSTM decoder under fp16, not to half-precision inference in docTR generally. I searched existing issues (e.g. [Bug] SARNet half-precision error. #1441, a crash on a different architecture,sar_resnet31) and didn't find this silent-corruption pattern reported forcrnn_vgg16_bnbefore.Since I couldn't find prior coverage of this specific case, and a silently wrong OCR result is a lot more dangerous than a slow one, I think it deserves a clearly flagged warning in the docs even though the actual fix (why the LSTM decoder is fp16-sensitive) is a code-level question I'm not proposing to touch here — see "Out of scope" below.
While looking into this I also checked whether the "PyTorch vs TensorFlow default backend" question (mentioned in some older docs/issues) still applies — it doesn't. As of this commit, TF has been fully removed (README tagline already says "powered by PyTorch",
pyproject.tomlhas zero tensorflow dependencies). No doc change needed there; just confirming it's already accurate.Changes (doc-only, no code/behavior changes)
README.mdocr_predictor(...)example that the predictor stays on CPU by default with no warning, how to move it to GPU, and the measured T4 speedup, linking to the existingusing_models.rstGPU section.torchversion range can silently resolve to a CUDA build newer than the local driver supports (torch.cuda.is_available()returnsFalse, no error), with the fix (pin the CUDA index).docs/source/using_doctr/using_model_export.rst.. warning::right after the existing.half()example, describing the CRNN + fp16 corruption with the concrete before/after word list, and noting thatmaster/parseqwere unaffected in the same test.AGENTS.md(new)No production code was changed — only prose additions to existing docs and a new contributor-notes file.
Out of scope (flagging as a possible follow-up issue, not fixing here)
The root cause of the CRNN + fp16 corruption (likely fp16 precision loss accumulating through the
nn.LSTMgates indoctr/models/recognition/crnn/pytorch.py) is a code-level question — possibly worth anautocast-style guard around the LSTM decoder, or at minimum a runtime warning when.half()is combined with a CRNN recognizer. I'm not proposing a code fix in this PR (this account only submits doc/text changes), but I'm happy to open a separate issue with the reproduction script if that's useful — let me know and I will.Testing / reproduction
Environment: Tesla T4 16GB, driver 550.163.01 (CUDA 12.4), Python 3.11.15, torch 2.6.0+cu124, torchvision 0.21.0+cu124, python-doctr 1.0.2a0 (editable install @ commit
1a1018c).masterandparseqrecognizers (same detector/image) to isolate the corruption to the CRNN decoder specifically..cuda()speedup and VRAM numbers viatorch.cuda.max_memory_allocated()and wall-clock timing (3 runs each), CPU vs GPU-fp32 vs GPU-fp16.Disclosure: I used an AI agent (Claude) to help investigate and benchmark this, with GPU access on a real Tesla T4, and to draft this PR. All findings above were verified by direct, reproducible execution rather than inferred.