Repository navigation
build(deps): CPU-only torch in the image — 9.50 GB → 2.95 GB (P2-5) - #408
Merged
Merged
Conversation
sentence-transformers pulled PyPI's CUDA torch, with fifteen nvidia-* packages, three cuda-* and triton, into an image whose app container never has a GPU (Ollama owns it). - requirements.in names the PyTorch CPU index. PEP 440 orders 2.13.0+cpu above 2.13.0, so the resolver prefers it without a torch pin; the Linux recompile changed nothing else. Image and CI install the same wheels. - pip-audit -r skips 2.13.0+cpu (PyPI does not list it) and still passes, so torch had silently left the scan. CI now audits the lock with the local tag stripped, as pinned, with --strict so an unauditable package fails. - docker-smoke asserts torch.version.cuda is None; test_lock_is_cpu_only fails if the lock regains a CUDA torch. Same-commit image sizes recorded in DEPLOYMENT.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # CHANGELOG.md
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The exact +cpu pin breaks the documented macOS host installation path.
Review effort: Balanced
Findings: None
What changed in this PR
Reduces the application image size by switching PyTorch to its CPU-only build and strengthening dependency auditing.
Changes:
- Uses the PyTorch CPU index and removes CUDA dependencies.
- Adds CI guards for CPU-only Torch and strict vulnerability auditing.
- Documents the resulting image-size reduction.
| File | Description |
|---|---|
requirements.in |
Configures the CPU wheel index. |
requirements.txt |
Locks CPU-only Torch and removes CUDA packages. |
requirements-dev.txt |
Propagates the CPU index. |
.github/workflows/tests.yml |
Strengthens auditing and image checks. |
tests/unit/test_lock_is_cpu_only.py |
Guards the CPU-only lock. |
docs/DEPLOYMENT.md |
Records operational impact. |
docs/ROADMAP.md |
Marks P2-5 complete. |
CHANGELOG.md |
Announces the dependency change. |
.claude/rules/file-map.md |
Registers the new test. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
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.



Independent of #403–#407: it touches the lock, CI and docs, none of which those PRs change. Merge order doesn't matter, apart from a likely trivial CHANGELOG/ROADMAP rebase.
What changes
sentence-transformerspulled PyPI's CUDA torch into theappimage, together with fifteennvidia-*packages, threecuda-*andtriton. Theappcontainer never has a GPU; Ollama owns it.requirements.innames the PyTorch CPU index (--extra-index-url https://download.pytorch.org/whl/cpu). PEP 440 orders2.13.0+cpuabove2.13.0, so the resolver picks the CPU build without a torch pin.torchbecame2.13.0+cpu, the 19 GPU packages left, and the dev lock gained only the index line.Measured
main, CUDA torchThe CPU image passes, by hand, every assertion
docker-smokemakes:torch 2.13.0+cpuandtorch.version.cuda is None;/api/healthreturns 200 with the database healthy.The cross-encoder reranker, the one torch consumer, loaded and completed its warm-up on the CPU build.
Caught before it shipped: torch had silently left the vulnerability scan
pip-audit -r requirements.txtskipstorch 2.13.0+cpu("Dependency not found on PyPI and could not be audited") and still passes. CI now does three things instead:+cpubuild is compiled from the public release's source and carries its advisories.--disable-pip --no-deps). The lock is the full closure, so nothing is lost, and resolving would pick the+cpuwheel again through the index line.--strict, so a package that can't be audited fails the step instead of disappearing from it.Verified locally: the strict audit passes on the stripped lock and fails on the raw one, and
pip-auditdoes report advisories for an old torch pinned the same way.Guards
docker-smokeassertstorch.version.cuda is Noneinside the image.tests/unit/test_lock_is_cpu_only.pyfails if the lock regains a CUDA torch or anynvidia-*,cuda-*ortritonpackage. This matters because a CPU index that lags a release would make the resolver fall back to CUDA silently. All three checks fail onmain's lock.Verification
ruff,mypy,bandit: clean. Fast suite: 3185 passed, 0 failed. The workflow YAML parses.Not verifiable before it happens
+cpupin on its next bump. It supportspip-compilewith index options, but local version labels are a known weak spot. The worst case is that torch bumps arrive ungrouped or need a manual recompile, not that the image regresses, because the lock test would catch a CUDA fallback.🤖 Generated with Claude Code