sciwrite-lint 0.2.0__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/PKG-INFO +90 -29
- sciwrite_lint-0.2.0/sciwrite_lint.egg-info/PKG-INFO → sciwrite_lint-0.2.2/README.md +63 -54
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/pyproject.toml +27 -20
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/__init__.py +1 -1
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/__main__.py +30 -15
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/checks/cross_section_consistency.py +3 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/checks/full_paper_consistency.py +26 -34
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/checks/ref_internal_checks.py +16 -49
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/cli/check.py +22 -21
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/cli/fetch.py +6 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/cli/misc.py +382 -75
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/cli/verify.py +36 -14
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/config.py +17 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/eval_claims.py +152 -77
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/fulltext.py +13 -1
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/llm_utils.py +99 -70
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/pipeline.py +542 -134
- sciwrite_lint-0.2.2/sciwrite_lint/py.typed +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/references/embedding_store.py +23 -14
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/references/reference_store.py +9 -23
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/references/workspace_db.py +220 -102
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/schemas.py +2 -2
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/usage.py +18 -42
- sciwrite_lint-0.2.2/sciwrite_lint/vision/cache.py +234 -0
- sciwrite_lint-0.2.2/sciwrite_lint/vision/describe.py +632 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/vision/image_extraction.py +31 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/vision/pipeline.py +23 -3
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/vllm/vllm_server.py +90 -11
- sciwrite_lint-0.2.0/README.md → sciwrite_lint-0.2.2/sciwrite_lint.egg-info/PKG-INFO +115 -9
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint.egg-info/SOURCES.txt +1 -0
- sciwrite_lint-0.2.2/sciwrite_lint.egg-info/requires.txt +27 -0
- sciwrite_lint-0.2.0/sciwrite_lint/vision/cache.py +0 -140
- sciwrite_lint-0.2.0/sciwrite_lint/vision/describe.py +0 -311
- sciwrite_lint-0.2.0/sciwrite_lint.egg-info/requires.txt +0 -27
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/LICENSE +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/_network.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/api.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/checks/__init__.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/checks/_section_utils.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/checks/cite_purpose.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/checks/claim_support.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/checks/dangling_cite.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/checks/dangling_ref.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/checks/reference_accuracy.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/checks/reference_exists.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/checks/reference_unreliable.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/checks/registry.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/checks/retracted_cite.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/checks/structure_promises.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/checks/unreferenced_figure.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/claims.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/claude_backend.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/claude_cli.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/cli/__init__.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/cli/config.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/cli/rank.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/cross_paper.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/local_pdfs.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/manuscript_store.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/models.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/pdf/__init__.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/pdf/grobid.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/pdf/pdf_download.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/prompt_safety.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/rate_limiter.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/references/__init__.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/references/citations.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/references/crossref.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/references/matching.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/references/metadata.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/references/retraction_watch.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/report.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/scoring/__init__.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/scoring/chain.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/scoring/contribution.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/scoring/scilint_score.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/tex_parser.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/vision/__init__.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/vllm/__init__.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/vllm/metrics.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/web.py +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint.egg-info/dependency_links.txt +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint.egg-info/entry_points.txt +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint.egg-info/top_level.txt +0 -0
- {sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/setup.cfg +0 -0
|
@@ -1,43 +1,50 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sciwrite-lint
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: A linter for scientific manuscripts — reference verification, consistency checking, and structural validation.
|
|
5
5
|
Author: Sergey Samsonau
|
|
6
|
+
Maintainer-email: Authentic Research Partners LLC <info@arpconnect.com>
|
|
6
7
|
License-Expression: MIT
|
|
7
|
-
Project-URL: Homepage, https://
|
|
8
|
+
Project-URL: Homepage, https://arpconnect.com
|
|
8
9
|
Project-URL: Repository, https://github.com/authentic-research-partners/sciwrite-lint
|
|
10
|
+
Project-URL: Documentation, https://github.com/authentic-research-partners/sciwrite-lint#readme
|
|
9
11
|
Project-URL: Issues, https://github.com/authentic-research-partners/sciwrite-lint/issues
|
|
10
|
-
|
|
12
|
+
Project-URL: Paper, https://arxiv.org/abs/2604.08501
|
|
13
|
+
Keywords: linter,latex,bibtex,pdf,scientific-writing,academic-writing,citation-checker,reference-verification,claim-verification,manuscript,peer-review,arxiv,vllm,qwen
|
|
11
14
|
Classifier: Development Status :: 3 - Alpha
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
12
16
|
Classifier: Intended Audience :: Science/Research
|
|
13
|
-
Classifier: Topic ::
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering
|
|
18
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
20
|
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Typing :: Typed
|
|
15
22
|
Requires-Python: <3.14,>=3.13
|
|
16
23
|
Description-Content-Type: text/markdown
|
|
17
24
|
License-File: LICENSE
|
|
18
|
-
Requires-Dist: httpx>=0.
|
|
19
|
-
Requires-Dist: tenacity>=
|
|
20
|
-
Requires-Dist: trafilatura>=
|
|
21
|
-
Requires-Dist: aiosqlite>=0.
|
|
25
|
+
Requires-Dist: httpx>=0.28
|
|
26
|
+
Requires-Dist: tenacity>=9.0
|
|
27
|
+
Requires-Dist: trafilatura>=2.0
|
|
28
|
+
Requires-Dist: aiosqlite>=0.22
|
|
22
29
|
Requires-Dist: loguru>=0.7
|
|
23
30
|
Requires-Dist: anyascii>=0.3
|
|
24
|
-
Requires-Dist: rich>=
|
|
31
|
+
Requires-Dist: rich>=14.0
|
|
25
32
|
Requires-Dist: defusedxml>=0.7
|
|
26
|
-
Requires-Dist: pydantic>=2.
|
|
33
|
+
Requires-Dist: pydantic>=2.10
|
|
27
34
|
Requires-Dist: rapidfuzz>=3.0
|
|
28
35
|
Requires-Dist: bibtexparser>=1.4
|
|
29
|
-
Requires-Dist: pdfplumber>=0.
|
|
30
|
-
Requires-Dist: openai>=
|
|
36
|
+
Requires-Dist: pdfplumber>=0.11
|
|
37
|
+
Requires-Dist: openai>=2.0
|
|
31
38
|
Requires-Dist: grobid-tei-xml>=0.1
|
|
32
|
-
Requires-Dist: sentence-transformers>=
|
|
33
|
-
Requires-Dist: numpy>=
|
|
39
|
+
Requires-Dist: sentence-transformers>=5.0
|
|
40
|
+
Requires-Dist: numpy>=2.0
|
|
34
41
|
Requires-Dist: sqlite-vec>=0.1.6
|
|
35
|
-
Requires-Dist: torch>=2.
|
|
36
|
-
Requires-Dist: transformers>=4.
|
|
37
|
-
Requires-Dist: Pillow>=
|
|
38
|
-
Requires-Dist: pypdf>=
|
|
39
|
-
Requires-Dist: pypdfium2>=
|
|
40
|
-
Requires-Dist: pdf2image>=1.
|
|
42
|
+
Requires-Dist: torch>=2.5
|
|
43
|
+
Requires-Dist: transformers>=4.50
|
|
44
|
+
Requires-Dist: Pillow>=12.0
|
|
45
|
+
Requires-Dist: pypdf>=6.0
|
|
46
|
+
Requires-Dist: pypdfium2>=5.0
|
|
47
|
+
Requires-Dist: pdf2image>=1.17
|
|
41
48
|
Provides-Extra: dev
|
|
42
49
|
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
43
50
|
Requires-Dist: pytest-xdist>=3.0; extra == "dev"
|
|
@@ -45,6 +52,8 @@ Dynamic: license-file
|
|
|
45
52
|
|
|
46
53
|
# sciwrite-lint
|
|
47
54
|
|
|
55
|
+
[](https://arxiv.org/abs/2604.08501)
|
|
56
|
+
|
|
48
57
|
A linter for scientific manuscripts. Checks that your references exist, your metadata is accurate, your citations support the claims you make, and your cited papers' own bibliographies are real. Works on LaTeX and PDF. Runs entirely on your machine. Produces a **SciLint Score**.
|
|
49
58
|
|
|
50
59
|
The only open-source tool that combines reference verification, claim checking, manuscript consistency, figure analysis, and bibliography verification in one pipeline — powered entirely by a local LLM on your own GPU.
|
|
@@ -123,7 +132,7 @@ sciwrite-lint contributions paper.pdf --format json
|
|
|
123
132
|
|
|
124
133
|
### Optimizations
|
|
125
134
|
|
|
126
|
-
Three models — a vision model (Qwen3-VL-2B), an embedding model (Arctic Embed), and an 8B reasoning LLM (Qwen3 via vLLM) — share a single consumer GPU. Models run in separate pipeline stages; on WSL2, CUDA memory virtualization pages idle allocations to system RAM, letting all three share physical VRAM. FP8 weights and KV cache (Ada Lovelace+) and per-paper SQLite caching with hash-based invalidation are baseline. On top of that:
|
|
135
|
+
Three models — a vision model (Qwen3-VL-2B default, or 8B FP8 via `--vision-backend vllm` for +15% accuracy), an embedding model (Arctic Embed), and an 8B reasoning LLM (Qwen3 via vLLM) — share a single consumer GPU. Models run in separate pipeline stages; on WSL2, CUDA memory virtualization pages idle allocations to system RAM, letting all three share physical VRAM. FP8 weights and KV cache (Ada Lovelace+) and per-paper SQLite caching with hash-based invalidation are baseline. On top of that:
|
|
127
136
|
|
|
128
137
|
- **Semantic section filtering** — embedding-based KNN retrieval sends only the ~5 most relevant sections per claim to the LLM, reducing LLM calls ~4x
|
|
129
138
|
- **Prefix-first prompt structure** — shared context placed before variable content in all prompts, maximizing vLLM's automatic prefix caching
|
|
@@ -134,11 +143,11 @@ Three models — a vision model (Qwen3-VL-2B), an embedding model (Arctic Embed)
|
|
|
134
143
|
- **8-source full-text cascade** — early exit on first successful download across arXiv, Semantic Scholar, OpenAlex, PubMed Central, Europe PMC, Unpaywall, bioRxiv, CORE
|
|
135
144
|
- **Live monitoring** *(advanced)* — `sciwrite-lint containers monitor` shows service health, VRAM usage, and KV cache utilization in a terminal dashboard
|
|
136
145
|
|
|
137
|
-
Full pipeline on a 50-reference paper: ~30 minutes initial (dominated by downloads and claim verification), minutes on cached reruns. On native Linux,
|
|
146
|
+
Full pipeline on a 50-reference paper: ~30 minutes initial (dominated by downloads and claim verification), minutes on cached reruns. On native Linux, the pipeline automatically swaps vLLM containers to free GPU for embedding and vision stages (~50x faster than CPU). *(Native Linux GPU swap is preliminary — tested on WSL2 only; expected to work, may need minor fixes.)*
|
|
138
147
|
|
|
139
148
|
## Install
|
|
140
149
|
|
|
141
|
-
**Assumed setup:** A workstation with an NVIDIA GPU (16+ GB VRAM). Developed and tested on Windows (WSL2). Native Linux is likely to work with GPU memory allocation tuning (see [docs/services.md](docs/services.md#embedding-device)). Not tested on macOS.
|
|
150
|
+
**Assumed setup:** A workstation with an NVIDIA GPU (16+ GB VRAM). Developed and tested on Windows (WSL2). Native Linux is likely to work with GPU memory allocation tuning (see [docs/services.md](https://github.com/authentic-research-partners/sciwrite-lint/blob/main/docs/services.md#embedding-device)). Not tested on macOS.
|
|
142
151
|
|
|
143
152
|
Requires [uv](https://docs.astral.sh/uv/getting-started/installation/), a container runtime (podman or docker), CUDA drivers, and [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html).
|
|
144
153
|
|
|
@@ -148,6 +157,32 @@ uv tool install sciwrite-lint --python 3.13
|
|
|
148
157
|
|
|
149
158
|
uv downloads Python 3.13 automatically (does not affect any Python you may already have) and installs sciwrite-lint as a globally available command.
|
|
150
159
|
|
|
160
|
+
### Reproducible environment (optional)
|
|
161
|
+
|
|
162
|
+
`pyproject.toml` declares lower bounds for dependencies, so `uv tool install` / `pip install` may resolve newer versions as upstream releases ship. If you want the exact versions the maintainer develops and tests against — for reproducing benchmarks, debugging version-drift issues, or CI — install from [`requirements-pinned.txt`](requirements-pinned.txt) instead.
|
|
163
|
+
|
|
164
|
+
**What's in it:** top-level packages declared in `pyproject.toml` pinned to `==` versions. Transitive dependencies are not pinned — pip resolves them within each top-level package's own constraints. This is a deliberate middle ground: it locks the packages sciwrite-lint actually imports and tests against, without over-constraining the dep tree.
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# Clone the public repo (required — uv tool install can't read a local file)
|
|
168
|
+
git clone https://github.com/authentic-research-partners/sciwrite-lint.git
|
|
169
|
+
cd sciwrite-lint
|
|
170
|
+
|
|
171
|
+
# With uv (recommended — fast, isolated, manages Python itself)
|
|
172
|
+
uv venv --python 3.13 .venv
|
|
173
|
+
source .venv/bin/activate
|
|
174
|
+
uv pip install -r requirements-pinned.txt
|
|
175
|
+
uv pip install -e . --no-deps # install sciwrite-lint source; deps already pinned
|
|
176
|
+
|
|
177
|
+
# Or with plain pip
|
|
178
|
+
python3.13 -m venv .venv
|
|
179
|
+
source .venv/bin/activate
|
|
180
|
+
pip install -r requirements-pinned.txt
|
|
181
|
+
pip install -e . --no-deps
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Activate the venv in each new terminal with `source .venv/bin/activate`. For most users, the plain `uv tool install sciwrite-lint` above is simpler — use the pinned file only when you need exact version reproduction.
|
|
185
|
+
|
|
151
186
|
## Setup
|
|
152
187
|
|
|
153
188
|
```bash
|
|
@@ -157,11 +192,22 @@ sciwrite-lint containers start # start GROBID + vLLM (needs GPU for vLLM
|
|
|
157
192
|
sciwrite-lint containers monitor # live dashboard: service health, VRAM, KV cache
|
|
158
193
|
```
|
|
159
194
|
|
|
160
|
-

|
|
195
|
+

|
|
161
196
|
|
|
162
197
|
`init` detects `.tex` files and their `.bib` references and generates a `.sciwrite-lint.toml` config. Review to confirm the right files were detected.
|
|
163
198
|
|
|
164
|
-
**
|
|
199
|
+
**Providing PDFs manually (`local_pdfs/`):** Drop any reference PDF into the `local_pdfs/` directory to skip the download step entirely. This is useful when you already have the file, when the paper is paywalled, or when the publisher blocks automated downloads (Cell, Springer, some PMC pages). Name files by the reference title:
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
local_pdfs/
|
|
203
|
+
├── States of Curiosity Modulate Hippocampus-Dependent Learning.pdf
|
|
204
|
+
├── Mind in Society.pdf
|
|
205
|
+
└── The System of Professions.pdf
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
The tool fuzzy-matches filenames against your `.bib` titles (threshold 0.80) and copies matches to the workspace. On the next run, matched references upgrade from T2 to T1 and go through GROBID parsing and claim verification like any other full-text reference.
|
|
209
|
+
|
|
210
|
+
**Finding what to download:** `sciwrite-lint verify` lists T2 references that are confirmed open access with direct URLs — open in your browser and save to `local_pdfs/`. For paywalled papers, use your institution's library access.
|
|
165
211
|
|
|
166
212
|
**Optional API keys** increase rate limits for Semantic Scholar, NCBI, and CORE:
|
|
167
213
|
|
|
@@ -170,7 +216,7 @@ sciwrite-lint config show # see what's configured
|
|
|
170
216
|
sciwrite-lint config set-key semantic-scholar YOUR_KEY # dedicated rate limit
|
|
171
217
|
```
|
|
172
218
|
|
|
173
|
-
See [docs/services.md](docs/services.md) for GPU requirements, all external APIs, and API key details.
|
|
219
|
+
See [docs/services.md](https://github.com/authentic-research-partners/sciwrite-lint/blob/main/docs/services.md) for GPU requirements, all external APIs, and API key details.
|
|
174
220
|
|
|
175
221
|
## Usage
|
|
176
222
|
|
|
@@ -256,12 +302,27 @@ Output formats: terminal (default) or `--format json`.
|
|
|
256
302
|
|
|
257
303
|
- `sciwrite-lint checks` — list all checks
|
|
258
304
|
- `sciwrite-lint <command> --help` — detailed usage for any command
|
|
259
|
-
- [docs/services.md](docs/services.md) — GROBID, vLLM, external APIs, configuration
|
|
305
|
+
- [docs/services.md](https://github.com/authentic-research-partners/sciwrite-lint/blob/main/docs/services.md) — GROBID, vLLM, external APIs, configuration
|
|
260
306
|
|
|
261
307
|
For contributors and advanced users:
|
|
262
308
|
|
|
263
|
-
- [docs/evals.md](docs/evals.md) — detection evaluation framework, adding test cases
|
|
264
|
-
- [docs/calibration.md](docs/calibration.md) — SciLint Score calibration against ground-truth papers
|
|
309
|
+
- [docs/evals.md](https://github.com/authentic-research-partners/sciwrite-lint/blob/main/docs/evals.md) — detection evaluation framework, adding test cases
|
|
310
|
+
- [docs/calibration.md](https://github.com/authentic-research-partners/sciwrite-lint/blob/main/docs/calibration.md) — SciLint Score calibration against ground-truth papers
|
|
311
|
+
|
|
312
|
+
## Citation
|
|
313
|
+
|
|
314
|
+
If you use sciwrite-lint in your research, please cite the accompanying paper ([arXiv:2604.08501](https://arxiv.org/abs/2604.08501)):
|
|
315
|
+
|
|
316
|
+
```bibtex
|
|
317
|
+
@article{samsonau2026sciwritelint,
|
|
318
|
+
title = {sciwrite-lint: Verification Infrastructure for the Age of Science Vibe-Writing},
|
|
319
|
+
author = {Samsonau, Sergey V.},
|
|
320
|
+
journal = {arXiv preprint arXiv:2604.08501},
|
|
321
|
+
year = {2026},
|
|
322
|
+
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
GitHub's "Cite this repository" button (powered by [`CITATION.cff`](CITATION.cff)) will also generate this for you.
|
|
265
326
|
|
|
266
327
|
## License
|
|
267
328
|
|
|
@@ -1,50 +1,7 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: sciwrite-lint
|
|
3
|
-
Version: 0.2.0
|
|
4
|
-
Summary: A linter for scientific manuscripts — reference verification, consistency checking, and structural validation.
|
|
5
|
-
Author: Sergey Samsonau
|
|
6
|
-
License-Expression: MIT
|
|
7
|
-
Project-URL: Homepage, https://github.com/authentic-research-partners/sciwrite-lint
|
|
8
|
-
Project-URL: Repository, https://github.com/authentic-research-partners/sciwrite-lint
|
|
9
|
-
Project-URL: Issues, https://github.com/authentic-research-partners/sciwrite-lint/issues
|
|
10
|
-
Keywords: linter,scientific-writing,citation-verification,latex
|
|
11
|
-
Classifier: Development Status :: 3 - Alpha
|
|
12
|
-
Classifier: Intended Audience :: Science/Research
|
|
13
|
-
Classifier: Topic :: Text Processing :: Markup :: LaTeX
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
-
Requires-Python: <3.14,>=3.13
|
|
16
|
-
Description-Content-Type: text/markdown
|
|
17
|
-
License-File: LICENSE
|
|
18
|
-
Requires-Dist: httpx>=0.27
|
|
19
|
-
Requires-Dist: tenacity>=8.0
|
|
20
|
-
Requires-Dist: trafilatura>=1.8
|
|
21
|
-
Requires-Dist: aiosqlite>=0.20
|
|
22
|
-
Requires-Dist: loguru>=0.7
|
|
23
|
-
Requires-Dist: anyascii>=0.3
|
|
24
|
-
Requires-Dist: rich>=13.0
|
|
25
|
-
Requires-Dist: defusedxml>=0.7
|
|
26
|
-
Requires-Dist: pydantic>=2.0
|
|
27
|
-
Requires-Dist: rapidfuzz>=3.0
|
|
28
|
-
Requires-Dist: bibtexparser>=1.4
|
|
29
|
-
Requires-Dist: pdfplumber>=0.10
|
|
30
|
-
Requires-Dist: openai>=1.0
|
|
31
|
-
Requires-Dist: grobid-tei-xml>=0.1
|
|
32
|
-
Requires-Dist: sentence-transformers>=3.0
|
|
33
|
-
Requires-Dist: numpy>=1.24
|
|
34
|
-
Requires-Dist: sqlite-vec>=0.1.6
|
|
35
|
-
Requires-Dist: torch>=2.0
|
|
36
|
-
Requires-Dist: transformers>=4.45
|
|
37
|
-
Requires-Dist: Pillow>=10.0
|
|
38
|
-
Requires-Dist: pypdf>=4.0
|
|
39
|
-
Requires-Dist: pypdfium2>=4.0
|
|
40
|
-
Requires-Dist: pdf2image>=1.16
|
|
41
|
-
Provides-Extra: dev
|
|
42
|
-
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
43
|
-
Requires-Dist: pytest-xdist>=3.0; extra == "dev"
|
|
44
|
-
Dynamic: license-file
|
|
45
|
-
|
|
46
1
|
# sciwrite-lint
|
|
47
2
|
|
|
3
|
+
[](https://arxiv.org/abs/2604.08501)
|
|
4
|
+
|
|
48
5
|
A linter for scientific manuscripts. Checks that your references exist, your metadata is accurate, your citations support the claims you make, and your cited papers' own bibliographies are real. Works on LaTeX and PDF. Runs entirely on your machine. Produces a **SciLint Score**.
|
|
49
6
|
|
|
50
7
|
The only open-source tool that combines reference verification, claim checking, manuscript consistency, figure analysis, and bibliography verification in one pipeline — powered entirely by a local LLM on your own GPU.
|
|
@@ -123,7 +80,7 @@ sciwrite-lint contributions paper.pdf --format json
|
|
|
123
80
|
|
|
124
81
|
### Optimizations
|
|
125
82
|
|
|
126
|
-
Three models — a vision model (Qwen3-VL-2B), an embedding model (Arctic Embed), and an 8B reasoning LLM (Qwen3 via vLLM) — share a single consumer GPU. Models run in separate pipeline stages; on WSL2, CUDA memory virtualization pages idle allocations to system RAM, letting all three share physical VRAM. FP8 weights and KV cache (Ada Lovelace+) and per-paper SQLite caching with hash-based invalidation are baseline. On top of that:
|
|
83
|
+
Three models — a vision model (Qwen3-VL-2B default, or 8B FP8 via `--vision-backend vllm` for +15% accuracy), an embedding model (Arctic Embed), and an 8B reasoning LLM (Qwen3 via vLLM) — share a single consumer GPU. Models run in separate pipeline stages; on WSL2, CUDA memory virtualization pages idle allocations to system RAM, letting all three share physical VRAM. FP8 weights and KV cache (Ada Lovelace+) and per-paper SQLite caching with hash-based invalidation are baseline. On top of that:
|
|
127
84
|
|
|
128
85
|
- **Semantic section filtering** — embedding-based KNN retrieval sends only the ~5 most relevant sections per claim to the LLM, reducing LLM calls ~4x
|
|
129
86
|
- **Prefix-first prompt structure** — shared context placed before variable content in all prompts, maximizing vLLM's automatic prefix caching
|
|
@@ -134,11 +91,11 @@ Three models — a vision model (Qwen3-VL-2B), an embedding model (Arctic Embed)
|
|
|
134
91
|
- **8-source full-text cascade** — early exit on first successful download across arXiv, Semantic Scholar, OpenAlex, PubMed Central, Europe PMC, Unpaywall, bioRxiv, CORE
|
|
135
92
|
- **Live monitoring** *(advanced)* — `sciwrite-lint containers monitor` shows service health, VRAM usage, and KV cache utilization in a terminal dashboard
|
|
136
93
|
|
|
137
|
-
Full pipeline on a 50-reference paper: ~30 minutes initial (dominated by downloads and claim verification), minutes on cached reruns. On native Linux,
|
|
94
|
+
Full pipeline on a 50-reference paper: ~30 minutes initial (dominated by downloads and claim verification), minutes on cached reruns. On native Linux, the pipeline automatically swaps vLLM containers to free GPU for embedding and vision stages (~50x faster than CPU). *(Native Linux GPU swap is preliminary — tested on WSL2 only; expected to work, may need minor fixes.)*
|
|
138
95
|
|
|
139
96
|
## Install
|
|
140
97
|
|
|
141
|
-
**Assumed setup:** A workstation with an NVIDIA GPU (16+ GB VRAM). Developed and tested on Windows (WSL2). Native Linux is likely to work with GPU memory allocation tuning (see [docs/services.md](docs/services.md#embedding-device)). Not tested on macOS.
|
|
98
|
+
**Assumed setup:** A workstation with an NVIDIA GPU (16+ GB VRAM). Developed and tested on Windows (WSL2). Native Linux is likely to work with GPU memory allocation tuning (see [docs/services.md](https://github.com/authentic-research-partners/sciwrite-lint/blob/main/docs/services.md#embedding-device)). Not tested on macOS.
|
|
142
99
|
|
|
143
100
|
Requires [uv](https://docs.astral.sh/uv/getting-started/installation/), a container runtime (podman or docker), CUDA drivers, and [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html).
|
|
144
101
|
|
|
@@ -148,6 +105,32 @@ uv tool install sciwrite-lint --python 3.13
|
|
|
148
105
|
|
|
149
106
|
uv downloads Python 3.13 automatically (does not affect any Python you may already have) and installs sciwrite-lint as a globally available command.
|
|
150
107
|
|
|
108
|
+
### Reproducible environment (optional)
|
|
109
|
+
|
|
110
|
+
`pyproject.toml` declares lower bounds for dependencies, so `uv tool install` / `pip install` may resolve newer versions as upstream releases ship. If you want the exact versions the maintainer develops and tests against — for reproducing benchmarks, debugging version-drift issues, or CI — install from [`requirements-pinned.txt`](requirements-pinned.txt) instead.
|
|
111
|
+
|
|
112
|
+
**What's in it:** top-level packages declared in `pyproject.toml` pinned to `==` versions. Transitive dependencies are not pinned — pip resolves them within each top-level package's own constraints. This is a deliberate middle ground: it locks the packages sciwrite-lint actually imports and tests against, without over-constraining the dep tree.
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
# Clone the public repo (required — uv tool install can't read a local file)
|
|
116
|
+
git clone https://github.com/authentic-research-partners/sciwrite-lint.git
|
|
117
|
+
cd sciwrite-lint
|
|
118
|
+
|
|
119
|
+
# With uv (recommended — fast, isolated, manages Python itself)
|
|
120
|
+
uv venv --python 3.13 .venv
|
|
121
|
+
source .venv/bin/activate
|
|
122
|
+
uv pip install -r requirements-pinned.txt
|
|
123
|
+
uv pip install -e . --no-deps # install sciwrite-lint source; deps already pinned
|
|
124
|
+
|
|
125
|
+
# Or with plain pip
|
|
126
|
+
python3.13 -m venv .venv
|
|
127
|
+
source .venv/bin/activate
|
|
128
|
+
pip install -r requirements-pinned.txt
|
|
129
|
+
pip install -e . --no-deps
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Activate the venv in each new terminal with `source .venv/bin/activate`. For most users, the plain `uv tool install sciwrite-lint` above is simpler — use the pinned file only when you need exact version reproduction.
|
|
133
|
+
|
|
151
134
|
## Setup
|
|
152
135
|
|
|
153
136
|
```bash
|
|
@@ -157,11 +140,22 @@ sciwrite-lint containers start # start GROBID + vLLM (needs GPU for vLLM
|
|
|
157
140
|
sciwrite-lint containers monitor # live dashboard: service health, VRAM, KV cache
|
|
158
141
|
```
|
|
159
142
|
|
|
160
|
-

|
|
143
|
+

|
|
161
144
|
|
|
162
145
|
`init` detects `.tex` files and their `.bib` references and generates a `.sciwrite-lint.toml` config. Review to confirm the right files were detected.
|
|
163
146
|
|
|
164
|
-
**
|
|
147
|
+
**Providing PDFs manually (`local_pdfs/`):** Drop any reference PDF into the `local_pdfs/` directory to skip the download step entirely. This is useful when you already have the file, when the paper is paywalled, or when the publisher blocks automated downloads (Cell, Springer, some PMC pages). Name files by the reference title:
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
local_pdfs/
|
|
151
|
+
├── States of Curiosity Modulate Hippocampus-Dependent Learning.pdf
|
|
152
|
+
├── Mind in Society.pdf
|
|
153
|
+
└── The System of Professions.pdf
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
The tool fuzzy-matches filenames against your `.bib` titles (threshold 0.80) and copies matches to the workspace. On the next run, matched references upgrade from T2 to T1 and go through GROBID parsing and claim verification like any other full-text reference.
|
|
157
|
+
|
|
158
|
+
**Finding what to download:** `sciwrite-lint verify` lists T2 references that are confirmed open access with direct URLs — open in your browser and save to `local_pdfs/`. For paywalled papers, use your institution's library access.
|
|
165
159
|
|
|
166
160
|
**Optional API keys** increase rate limits for Semantic Scholar, NCBI, and CORE:
|
|
167
161
|
|
|
@@ -170,7 +164,7 @@ sciwrite-lint config show # see what's configured
|
|
|
170
164
|
sciwrite-lint config set-key semantic-scholar YOUR_KEY # dedicated rate limit
|
|
171
165
|
```
|
|
172
166
|
|
|
173
|
-
See [docs/services.md](docs/services.md) for GPU requirements, all external APIs, and API key details.
|
|
167
|
+
See [docs/services.md](https://github.com/authentic-research-partners/sciwrite-lint/blob/main/docs/services.md) for GPU requirements, all external APIs, and API key details.
|
|
174
168
|
|
|
175
169
|
## Usage
|
|
176
170
|
|
|
@@ -256,12 +250,27 @@ Output formats: terminal (default) or `--format json`.
|
|
|
256
250
|
|
|
257
251
|
- `sciwrite-lint checks` — list all checks
|
|
258
252
|
- `sciwrite-lint <command> --help` — detailed usage for any command
|
|
259
|
-
- [docs/services.md](docs/services.md) — GROBID, vLLM, external APIs, configuration
|
|
253
|
+
- [docs/services.md](https://github.com/authentic-research-partners/sciwrite-lint/blob/main/docs/services.md) — GROBID, vLLM, external APIs, configuration
|
|
260
254
|
|
|
261
255
|
For contributors and advanced users:
|
|
262
256
|
|
|
263
|
-
- [docs/evals.md](docs/evals.md) — detection evaluation framework, adding test cases
|
|
264
|
-
- [docs/calibration.md](docs/calibration.md) — SciLint Score calibration against ground-truth papers
|
|
257
|
+
- [docs/evals.md](https://github.com/authentic-research-partners/sciwrite-lint/blob/main/docs/evals.md) — detection evaluation framework, adding test cases
|
|
258
|
+
- [docs/calibration.md](https://github.com/authentic-research-partners/sciwrite-lint/blob/main/docs/calibration.md) — SciLint Score calibration against ground-truth papers
|
|
259
|
+
|
|
260
|
+
## Citation
|
|
261
|
+
|
|
262
|
+
If you use sciwrite-lint in your research, please cite the accompanying paper ([arXiv:2604.08501](https://arxiv.org/abs/2604.08501)):
|
|
263
|
+
|
|
264
|
+
```bibtex
|
|
265
|
+
@article{samsonau2026sciwritelint,
|
|
266
|
+
title = {sciwrite-lint: Verification Infrastructure for the Age of Science Vibe-Writing},
|
|
267
|
+
author = {Samsonau, Sergey V.},
|
|
268
|
+
journal = {arXiv preprint arXiv:2604.08501},
|
|
269
|
+
year = {2026},
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
GitHub's "Cite this repository" button (powered by [`CITATION.cff`](CITATION.cff)) will also generate this for you.
|
|
265
274
|
|
|
266
275
|
## License
|
|
267
276
|
|
|
@@ -4,49 +4,56 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "sciwrite-lint"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.2"
|
|
8
8
|
description = "A linter for scientific manuscripts — reference verification, consistency checking, and structural validation."
|
|
9
9
|
requires-python = ">=3.13,<3.14"
|
|
10
10
|
license = "MIT"
|
|
11
11
|
authors = [{ name = "Sergey Samsonau" }]
|
|
12
|
+
maintainers = [{ name = "Authentic Research Partners LLC", email = "info@arpconnect.com" }]
|
|
12
13
|
readme = "README.md"
|
|
13
|
-
keywords = ["linter", "scientific-writing", "citation-verification", "
|
|
14
|
+
keywords = ["linter", "latex", "bibtex", "pdf", "scientific-writing", "academic-writing", "citation-checker", "reference-verification", "claim-verification", "manuscript", "peer-review", "arxiv", "vllm", "qwen"]
|
|
14
15
|
classifiers = [
|
|
15
16
|
"Development Status :: 3 - Alpha",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
16
18
|
"Intended Audience :: Science/Research",
|
|
17
|
-
"Topic ::
|
|
19
|
+
"Topic :: Scientific/Engineering",
|
|
20
|
+
"Topic :: Software Development :: Quality Assurance",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
18
22
|
"Programming Language :: Python :: 3.13",
|
|
23
|
+
"Typing :: Typed",
|
|
19
24
|
]
|
|
20
25
|
dependencies = [
|
|
21
|
-
"httpx>=0.
|
|
22
|
-
"tenacity>=
|
|
23
|
-
"trafilatura>=
|
|
24
|
-
"aiosqlite>=0.
|
|
26
|
+
"httpx>=0.28",
|
|
27
|
+
"tenacity>=9.0",
|
|
28
|
+
"trafilatura>=2.0",
|
|
29
|
+
"aiosqlite>=0.22",
|
|
25
30
|
"loguru>=0.7",
|
|
26
31
|
"anyascii>=0.3",
|
|
27
|
-
"rich>=
|
|
32
|
+
"rich>=14.0",
|
|
28
33
|
"defusedxml>=0.7",
|
|
29
|
-
"pydantic>=2.
|
|
34
|
+
"pydantic>=2.10",
|
|
30
35
|
"rapidfuzz>=3.0",
|
|
31
36
|
"bibtexparser>=1.4",
|
|
32
|
-
"pdfplumber>=0.
|
|
33
|
-
"openai>=
|
|
37
|
+
"pdfplumber>=0.11",
|
|
38
|
+
"openai>=2.0",
|
|
34
39
|
"grobid-tei-xml>=0.1",
|
|
35
|
-
"sentence-transformers>=
|
|
36
|
-
"numpy>=
|
|
40
|
+
"sentence-transformers>=5.0",
|
|
41
|
+
"numpy>=2.0",
|
|
37
42
|
"sqlite-vec>=0.1.6",
|
|
38
|
-
"torch>=2.
|
|
39
|
-
"transformers>=4.
|
|
40
|
-
"Pillow>=
|
|
41
|
-
"pypdf>=
|
|
42
|
-
"pypdfium2>=
|
|
43
|
-
"pdf2image>=1.
|
|
43
|
+
"torch>=2.5",
|
|
44
|
+
"transformers>=4.50",
|
|
45
|
+
"Pillow>=12.0",
|
|
46
|
+
"pypdf>=6.0",
|
|
47
|
+
"pypdfium2>=5.0",
|
|
48
|
+
"pdf2image>=1.17",
|
|
44
49
|
]
|
|
45
50
|
|
|
46
51
|
[project.urls]
|
|
47
|
-
Homepage = "https://
|
|
52
|
+
Homepage = "https://arpconnect.com"
|
|
48
53
|
Repository = "https://github.com/authentic-research-partners/sciwrite-lint"
|
|
54
|
+
Documentation = "https://github.com/authentic-research-partners/sciwrite-lint#readme"
|
|
49
55
|
Issues = "https://github.com/authentic-research-partners/sciwrite-lint/issues"
|
|
56
|
+
Paper = "https://arxiv.org/abs/2604.08501"
|
|
50
57
|
|
|
51
58
|
[project.optional-dependencies]
|
|
52
59
|
dev = [
|
|
@@ -18,6 +18,10 @@ from loguru import logger
|
|
|
18
18
|
|
|
19
19
|
from sciwrite_lint import __version__
|
|
20
20
|
from sciwrite_lint.config import LintConfig, PaperConfig, load_config
|
|
21
|
+
from sciwrite_lint.vllm.vllm_server import MODELS as _VLLM_MODELS
|
|
22
|
+
|
|
23
|
+
_ALL_MODELS = sorted(_VLLM_MODELS.keys())
|
|
24
|
+
_TEXT_MODELS = [k for k, v in _VLLM_MODELS.items() if v["kind"] == "text"]
|
|
21
25
|
|
|
22
26
|
|
|
23
27
|
# ---------------------------------------------------------------------------
|
|
@@ -179,6 +183,12 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
179
183
|
"limit. Above 4, the live monitor may fail to track progress and "
|
|
180
184
|
"vLLM/API throughput plateaus.",
|
|
181
185
|
)
|
|
186
|
+
p_check.add_argument(
|
|
187
|
+
"--vision-backend",
|
|
188
|
+
choices=["transformers", "vllm"],
|
|
189
|
+
default=None,
|
|
190
|
+
help="Vision backend: transformers (2B, default) or vllm (8B FP8 on port 5002)",
|
|
191
|
+
)
|
|
182
192
|
p_check.set_defaults(func=run_check)
|
|
183
193
|
|
|
184
194
|
# --- checks ---
|
|
@@ -296,7 +306,7 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
296
306
|
)
|
|
297
307
|
p_vc.add_argument(
|
|
298
308
|
"--model",
|
|
299
|
-
choices=
|
|
309
|
+
choices=_TEXT_MODELS,
|
|
300
310
|
default="",
|
|
301
311
|
help="vLLM model preset (default: qwen3)",
|
|
302
312
|
)
|
|
@@ -381,14 +391,20 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
381
391
|
# --- vision ---
|
|
382
392
|
p_vision = sub.add_parser(
|
|
383
393
|
"vision",
|
|
384
|
-
help="Extract and describe manuscript figures
|
|
394
|
+
help="Extract and describe manuscript figures (transformers 2B or vLLM 8B FP8).",
|
|
385
395
|
)
|
|
386
396
|
p_vision.add_argument("--paper", required=True, help="Paper name from [[papers]]")
|
|
387
397
|
p_vision.add_argument(
|
|
388
398
|
"--device",
|
|
389
399
|
choices=["auto", "cpu", "cuda"],
|
|
390
|
-
default=
|
|
391
|
-
help="Device for VL inference (default: auto — CUDA if available)",
|
|
400
|
+
default=None,
|
|
401
|
+
help="Device for VL inference (default: auto — CUDA if available, transformers only)",
|
|
402
|
+
)
|
|
403
|
+
p_vision.add_argument(
|
|
404
|
+
"--backend",
|
|
405
|
+
choices=["transformers", "vllm"],
|
|
406
|
+
default=None,
|
|
407
|
+
help="Vision backend: transformers (2B, default) or vllm (8B FP8 on port 5002)",
|
|
392
408
|
)
|
|
393
409
|
p_vision.add_argument(
|
|
394
410
|
"--fresh",
|
|
@@ -407,9 +423,7 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
407
423
|
choices=["start", "stop", "restart", "status", "monitor"],
|
|
408
424
|
help="start/stop/restart/status/monitor of all containers",
|
|
409
425
|
)
|
|
410
|
-
p_containers.add_argument(
|
|
411
|
-
"--model", choices=["qwen3", "gemma3"], help="vLLM model to use"
|
|
412
|
-
)
|
|
426
|
+
p_containers.add_argument("--model", choices=_ALL_MODELS, help="vLLM model to use")
|
|
413
427
|
p_containers.add_argument(
|
|
414
428
|
"--update",
|
|
415
429
|
action="store_true",
|
|
@@ -427,6 +441,11 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
427
441
|
action="store_true",
|
|
428
442
|
help="Remove and recreate containers (applies config changes like memory limits)",
|
|
429
443
|
)
|
|
444
|
+
p_containers.add_argument(
|
|
445
|
+
"--vision",
|
|
446
|
+
action="store_true",
|
|
447
|
+
help="Also start vision vLLM (qwen3-vl-8b-fp8 on port 5002)",
|
|
448
|
+
)
|
|
430
449
|
p_containers.add_argument("--config", help="Path to .sciwrite-lint.toml")
|
|
431
450
|
p_containers.set_defaults(func=run_containers)
|
|
432
451
|
|
|
@@ -452,9 +471,7 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
452
471
|
p_vllm_status.set_defaults(func=run_vllm)
|
|
453
472
|
|
|
454
473
|
p_vllm_start = vllm_sub.add_parser("start", help="Start vLLM server")
|
|
455
|
-
p_vllm_start.add_argument(
|
|
456
|
-
"--model", choices=["qwen3", "gemma3"], help="Model to serve"
|
|
457
|
-
)
|
|
474
|
+
p_vllm_start.add_argument("--model", choices=_ALL_MODELS, help="Model to serve")
|
|
458
475
|
p_vllm_start.add_argument(
|
|
459
476
|
"--update",
|
|
460
477
|
action="store_true",
|
|
@@ -464,13 +481,11 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
464
481
|
p_vllm_start.set_defaults(func=run_vllm)
|
|
465
482
|
|
|
466
483
|
p_vllm_stop = vllm_sub.add_parser("stop", help="Stop vLLM server")
|
|
467
|
-
p_vllm_stop.add_argument(
|
|
468
|
-
"--model", choices=["qwen3", "gemma3"], help="Model to stop"
|
|
469
|
-
)
|
|
484
|
+
p_vllm_stop.add_argument("--model", choices=_ALL_MODELS, help="Model to stop")
|
|
470
485
|
p_vllm_stop.set_defaults(func=run_vllm)
|
|
471
486
|
|
|
472
487
|
p_vllm_logs = vllm_sub.add_parser("logs", help="Show vLLM container logs")
|
|
473
|
-
p_vllm_logs.add_argument("--model", choices=
|
|
488
|
+
p_vllm_logs.add_argument("--model", choices=_ALL_MODELS)
|
|
474
489
|
p_vllm_logs.add_argument(
|
|
475
490
|
"-f", "--follow", action="store_true", help="Follow log output"
|
|
476
491
|
)
|
|
@@ -478,7 +493,7 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
478
493
|
p_vllm_logs.set_defaults(func=run_vllm)
|
|
479
494
|
|
|
480
495
|
p_vllm_rm = vllm_sub.add_parser("rm", help="Remove vLLM container")
|
|
481
|
-
p_vllm_rm.add_argument("--model", choices=
|
|
496
|
+
p_vllm_rm.add_argument("--model", choices=_ALL_MODELS)
|
|
482
497
|
p_vllm_rm.add_argument(
|
|
483
498
|
"--force", action="store_true", help="Force remove even if running"
|
|
484
499
|
)
|
{sciwrite_lint-0.2.0 → sciwrite_lint-0.2.2}/sciwrite_lint/checks/cross_section_consistency.py
RENAMED
|
@@ -44,6 +44,9 @@ For each item, set is_genuine to true ONLY if the values or claims \
|
|
|
44
44
|
CONFLICT. Set is_genuine to false if the passages agree or discuss \
|
|
45
45
|
different topics.
|
|
46
46
|
|
|
47
|
+
Report at most 4 contradictions. If you find more, return only the 4 \
|
|
48
|
+
most clear-cut cases.
|
|
49
|
+
|
|
47
50
|
Reply with JSON: {"contradictions": [\
|
|
48
51
|
{"type": "number|claim|framing", "section_a_says": "...", \
|
|
49
52
|
"section_b_says": "...", "explanation": "...", "is_genuine": true/false}]}
|