Store inference weights as safetensors with a strict direct loader
Browse files- LICENSING.md +3 -3
- NOTICE +3 -1
- README.md +18 -4
- SHA256SUMS +8 -6
- inference_engine.py +5 -5
- v3.pth → model.safetensors +2 -2
- model_config.json +9 -0
- model_loader.py +70 -0
- requirements.txt +1 -0
LICENSING.md
CHANGED
|
@@ -2,8 +2,8 @@
|
|
| 2 |
|
| 3 |
| Artifact | License |
|
| 4 |
| --- | --- |
|
| 5 |
-
| `
|
| 6 |
-
| `predict.py` and `
|
| 7 |
| Release documentation | Apache-2.0, except third-party notices and license texts, which retain their terms. |
|
| 8 |
| Public dataset material | Not redistributed. Uploader-listed CC BY 4.0; credits/modification notes are retained in README and NOTICE, with license text in `LICENSE-CC-BY-4.0.txt`. |
|
| 9 |
| Separately installed dependencies | Their own licenses and notices. No dependency binaries or environments are bundled. |
|
|
@@ -22,7 +22,7 @@ AGPL permits commercial activity when its terms are met. A proprietary integrati
|
|
| 22 |
|
| 23 |
## Source and installation
|
| 24 |
|
| 25 |
-
|
| 26 |
|
| 27 |
Unmodified dependencies are obtained from their publishers. Exact releases include [PyMuPDF 2.0](https://pypi.org/project/PyMuPDF/2.0/#files) ([source](https://github.com/pymupdf/PyMuPDF), [MuPDF](https://mupdf.com/releases)) and [RF-DETR 1.11.2](https://pypi.org/project/rfdetr/1.11.2/#files) ([source](https://github.com/roboflow/rf-detr)). Preserve matching source/notices when conveying dependencies. This repository is not a binary-distribution compliance bundle.
|
| 28 |
|
|
|
|
| 2 |
|
| 3 |
| Artifact | License |
|
| 4 |
| --- | --- |
|
| 5 |
+
| `model.safetensors` model weights | Apache-2.0; full text in `LICENSE`, with upstream attribution in `NOTICE`. |
|
| 6 |
+
| `predict.py`, `inference_engine.py`, and `model_loader.py` | AGPL-3.0-only; full text in `LICENSE-CODE-AGPL-3.0.txt`. These files are the complete release program source. |
|
| 7 |
| Release documentation | Apache-2.0, except third-party notices and license texts, which retain their terms. |
|
| 8 |
| Public dataset material | Not redistributed. Uploader-listed CC BY 4.0; credits/modification notes are retained in README and NOTICE, with license text in `LICENSE-CC-BY-4.0.txt`. |
|
| 9 |
| Separately installed dependencies | Their own licenses and notices. No dependency binaries or environments are bundled. |
|
|
|
|
| 22 |
|
| 23 |
## Source and installation
|
| 24 |
|
| 25 |
+
All three Python source files, pinned requirements, full license texts and installation/inference commands are included in this package. `requirements-lock-macos-py313.txt` records the tested dependency resolution. No private local module, training records or drawings are needed to run the CLI. `SHA256SUMS` verifies the package files.
|
| 26 |
|
| 27 |
Unmodified dependencies are obtained from their publishers. Exact releases include [PyMuPDF 2.0](https://pypi.org/project/PyMuPDF/2.0/#files) ([source](https://github.com/pymupdf/PyMuPDF), [MuPDF](https://mupdf.com/releases)) and [RF-DETR 1.11.2](https://pypi.org/project/rfdetr/1.11.2/#files) ([source](https://github.com/roboflow/rf-detr)). Preserve matching source/notices when conveying dependencies. This repository is not a binary-distribution compliance bundle.
|
| 28 |
|
NOTICE
CHANGED
|
@@ -10,7 +10,9 @@ https://storage.googleapis.com/rfdetr/small_coco/checkpoint_best_regular.pth
|
|
| 10 |
https://roboflow.com/licensing
|
| 11 |
|
| 12 |
Changes: the native base was fine-tuned for door openings. The release checkpoint
|
| 13 |
-
retains inference
|
|
|
|
|
|
|
| 14 |
The release CLI adapts the existing inference implementation for portable use.
|
| 15 |
RF-DETR acknowledges LW-DETR, DINOv2 and Deformable DETR in its distribution.
|
| 16 |
No standalone upstream NOTICE was present in the installed RF-DETR distribution;
|
|
|
|
| 10 |
https://roboflow.com/licensing
|
| 11 |
|
| 12 |
Changes: the native base was fine-tuned for door openings. The release checkpoint
|
| 13 |
+
retains inference tensor names, shapes, dtypes and values in safetensors while
|
| 14 |
+
omitting training records/identifying metadata. Packaging conversion does not
|
| 15 |
+
retrain the model or change its inference preprocessing.
|
| 16 |
The release CLI adapts the existing inference implementation for portable use.
|
| 17 |
RF-DETR acknowledges LW-DETR, DINOv2 and Deformable DETR in its distribution.
|
| 18 |
No standalone upstream NOTICE was present in the installed RF-DETR distribution;
|
README.md
CHANGED
|
@@ -21,7 +21,7 @@ Fine-tuned using public floor-plan datasets and additional architectural drawing
|
|
| 21 |
|
| 22 |
One opening counts as one item; double doors should count as one opening. The single foreground class is `door` (ID 0). Windows and cabinets are outside the intended class. Predictions require human review, including areas where no box was proposed. Counts are preliminary and do not automatically identify unique physical openings across repeated drawings.
|
| 23 |
|
| 24 |
-
**License scope:** `
|
| 25 |
|
| 26 |
## Install
|
| 27 |
|
|
@@ -34,7 +34,7 @@ python -m pip install -r requirements.txt
|
|
| 34 |
python -m pip check
|
| 35 |
```
|
| 36 |
|
| 37 |
-
`requirements-lock-macos-py313.txt` provides the complete tested dependency resolution for that platform. Training and web-server extras are not required.
|
| 38 |
|
| 39 |
## Predict
|
| 40 |
|
|
@@ -51,7 +51,7 @@ python predict.py --input plan.pdf --pages 1 --output results-pdf --device cpu
|
|
| 51 |
python predict.py --input plan.pdf --pages 2,4-6 --output results-selected --device cpu
|
| 52 |
```
|
| 53 |
|
| 54 |
-
Each output directory must be new. `
|
| 55 |
|
| 56 |
Optional drawing-area crop and render preview:
|
| 57 |
|
|
@@ -63,7 +63,21 @@ python predict.py --help
|
|
| 63 |
|
| 64 |
ROI bounds are left/top/right/bottom percentages. Image loading applies EXIF orientation, composites transparency onto white, and converts to RGB. PDFs are rendered in RGB at **150 DPI** by default, with a 40-million-pixel page limit.
|
| 65 |
|
| 66 |
-
Inference uses **768×768** white-padded tiles with **384-pixel stride**, model resolution **512×512**, confidence threshold **0.3**, tile-boundary rechecks, and final greedy NMS with IoU **0.5**. The
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
|
| 68 |
## Outputs and limitations
|
| 69 |
|
|
|
|
| 21 |
|
| 22 |
One opening counts as one item; double doors should count as one opening. The single foreground class is `door` (ID 0). Windows and cabinets are outside the intended class. Predictions require human review, including areas where no box was proposed. Counts are preliminary and do not automatically identify unique physical openings across repeated drawings.
|
| 23 |
|
| 24 |
+
**License scope:** `model.safetensors` model weights are Apache-2.0. The supplied Python runner, including PDF functionality, is AGPL-3.0-only. See [LICENSING.md](LICENSING.md) and [NOTICE](NOTICE).
|
| 25 |
|
| 26 |
## Install
|
| 27 |
|
|
|
|
| 34 |
python -m pip check
|
| 35 |
```
|
| 36 |
|
| 37 |
+
`requirements-lock-macos-py313.txt` provides the complete tested dependency resolution for that platform. Training and web-server extras are not required. The weights are stored in safetensors and loaded directly by `model_loader.py` with the pinned `rfdetr==1.11.2` implementation. No `.pth` file, pickle loading, conversion back to pickle, or base-weight download is required at runtime. This package does not implement or claim Transformers `pipeline()` / `from_pretrained()` compatibility.
|
| 38 |
|
| 39 |
## Predict
|
| 40 |
|
|
|
|
| 51 |
python predict.py --input plan.pdf --pages 2,4-6 --output results-selected --device cpu
|
| 52 |
```
|
| 53 |
|
| 54 |
+
Each output directory must be new. `model.safetensors` is selected relative to the script by default. Apple Silicon users can use `--device mps`. `--device cuda` requires a compatible PyTorch/CUDA installation; CUDA and other operating systems have not been validated for this release.
|
| 55 |
|
| 56 |
Optional drawing-area crop and render preview:
|
| 57 |
|
|
|
|
| 63 |
|
| 64 |
ROI bounds are left/top/right/bottom percentages. Image loading applies EXIF orientation, composites transparency onto white, and converts to RGB. PDFs are rendered in RGB at **150 DPI** by default, with a 40-million-pixel page limit.
|
| 65 |
|
| 66 |
+
Inference uses **768×768** white-padded tiles with **384-pixel stride**, model resolution **512×512**, confidence threshold **0.3**, tile-boundary rechecks, and final greedy NMS with IoU **0.5**. The direct loader constructs `RFDETRSmall(pretrain_weights=None, num_classes=1, resolution=512, device=...)`, strictly loads the included safetensors state, restores class names, and uses the existing RF-DETR prediction facade. The existing box/score handling is preserved without adding a class filter. Override settings with `--dpi`, `--threshold`, `--nms-iou`, `--checkpoint` (a safetensors file), or `--model-config` (defaults beside weights); changing settings can change predictions.
|
| 67 |
+
|
| 68 |
+
## Direct loader
|
| 69 |
+
|
| 70 |
+
`model_loader.py` reads `model_config.json` and `model.safetensors` directly. The minimal config contains only the pinned RF-DETR version, Small variant, resolution, foreground class count and class mapping. Architecture defaults are fixed by `rfdetr==1.11.2`: a windowed DINOv2 Small encoder, three decoder layers, patch size 16, positional grid 32 and 300 queries / 13 groups. The loader rejects unsupported config/version, missing or unexpected weight keys, and incompatible shapes or dtypes. It uses strict state loading and confirms the loaded tensors match the file. The model runs without optimization, quantization, or precision conversion.
|
| 71 |
+
|
| 72 |
+
The image commands above use this loader together with the unchanged image preprocessing, tiling, boundary rechecks and NMS in `inference_engine.py`. A minimal Python loading example is:
|
| 73 |
+
|
| 74 |
+
```python
|
| 75 |
+
from model_loader import load_model
|
| 76 |
+
|
| 77 |
+
model = load_model(device="cpu") # model.safetensors + model_config.json beside loader
|
| 78 |
+
```
|
| 79 |
+
|
| 80 |
+
Use `predict.py` for image/PDF prediction with the complete preprocessing shown above. Initializing the model without pretrained weights creates its architecture locally; every required state tensor is then supplied by the strict safetensors load. The file preserves the original tensor names, shapes, dtypes and values, including its empty boolean buffer. No keys are dropped to deduplicate shared storage.
|
| 81 |
|
| 82 |
## Outputs and limitations
|
| 83 |
|
SHA256SUMS
CHANGED
|
@@ -1,11 +1,13 @@
|
|
| 1 |
8cabf52c61130fc97a7e5da5e3685ccf44841c0c53d6f881189369b136603cca LICENSE
|
| 2 |
9ba9550ad48438d0836ddab3da480b3b69ffa0aac7b7878b5a0039e7ab429411 LICENSE-CC-BY-4.0.txt
|
| 3 |
57c8ff33c9c0cfc3ef00e650a1cc910d7ee479a8bc509f6c9209a7c2a11399d6 LICENSE-CODE-AGPL-3.0.txt
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
|
|
|
|
|
|
|
|
|
| 8 |
e904d946b83504016bf6b83a452b8959212e07245c58424b5fccdeac7daffafb predict.py
|
| 9 |
6828f00d1c7922c5f3b7af01708e65b19581f38a0929b27d7e521b9ff66ab77b requirements-lock-macos-py313.txt
|
| 10 |
-
|
| 11 |
-
518e463dfc63c4ebcac82b7719f82a105c2e8c2e3461326933996cbc8becd0b3 v3.pth
|
|
|
|
| 1 |
8cabf52c61130fc97a7e5da5e3685ccf44841c0c53d6f881189369b136603cca LICENSE
|
| 2 |
9ba9550ad48438d0836ddab3da480b3b69ffa0aac7b7878b5a0039e7ab429411 LICENSE-CC-BY-4.0.txt
|
| 3 |
57c8ff33c9c0cfc3ef00e650a1cc910d7ee479a8bc509f6c9209a7c2a11399d6 LICENSE-CODE-AGPL-3.0.txt
|
| 4 |
+
39c8f97aa86f61a2d47d13cd1aac0667333fff03339421fefede6bb437be739a LICENSING.md
|
| 5 |
+
e254f895fbdbe26efea3aa2a9d07f0c19d2e6c0fd4b5ec09367cd52816ee88fe NOTICE
|
| 6 |
+
3457211166e298fbdbd7f790727a292786d7741c60776f9373ce7836264727cb README.md
|
| 7 |
+
01a1c9a923de14a8af1b36078121328182db7208ae76e9664f742b6f0a22725c inference_engine.py
|
| 8 |
+
aca8b59ff9c6f144a1ca284f689683e9ed7cd951555832cfc09c10e5ae93bd0d model.safetensors
|
| 9 |
+
4b143322ca27af276eb497a959009b14729accf70d2bfaee98e751a8073b9443 model_config.json
|
| 10 |
+
ec26695f9ba3bc72d4b9bd48414183af3ef5ccc6f03c473c26f12844cc25b308 model_loader.py
|
| 11 |
e904d946b83504016bf6b83a452b8959212e07245c58424b5fccdeac7daffafb predict.py
|
| 12 |
6828f00d1c7922c5f3b7af01708e65b19581f38a0929b27d7e521b9ff66ab77b requirements-lock-macos-py313.txt
|
| 13 |
+
5f29cba77ad563b6fe076b2364afc921894bad2bad0617529c9f85e71746cd26 requirements.txt
|
|
|
inference_engine.py
CHANGED
|
@@ -198,7 +198,8 @@ def main():
|
|
| 198 |
parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
| 199 |
parser.add_argument('--input', required=True, type=Path, help='PDF or one PNG/JPEG image.')
|
| 200 |
parser.add_argument('--pages', help='Required for PDFs: 1-based page numbers, e.g. 5 or 5,7-9.')
|
| 201 |
-
parser.add_argument('--checkpoint', type=Path, default=Path(__file__).resolve().parent / '
|
|
|
|
| 202 |
parser.add_argument('--output', type=Path, help='New output folder; defaults to a timestamped outputs/ folder.')
|
| 203 |
parser.add_argument('--dpi', type=int, default=150, help='PDF rendering DPI. Default: 150, matching training preparation.')
|
| 204 |
parser.add_argument('--threshold', type=float, default=.3)
|
|
@@ -257,14 +258,13 @@ def main():
|
|
| 257 |
if installed != '1.11.2':
|
| 258 |
parser.error(f'This script requires RF-DETR 1.11.2; found {installed}.')
|
| 259 |
import torch
|
| 260 |
-
from
|
| 261 |
if args.device == 'mps' and not torch.backends.mps.is_available():
|
| 262 |
parser.error('MPS unavailable; use the Mac environment or pass --device cpu.')
|
| 263 |
if args.device == 'cuda' and not torch.cuda.is_available():
|
| 264 |
parser.error('CUDA unavailable.')
|
| 265 |
-
print('Loading
|
| 266 |
-
model =
|
| 267 |
-
resolution=512, device=args.device)
|
| 268 |
output.mkdir(parents=True)
|
| 269 |
report = dict(input=args.input.name, checkpoint=None if args.preview_only else args.checkpoint.name,
|
| 270 |
status='running', preview_only=args.preview_only, threshold=args.threshold, nms_iou=args.nms_iou,
|
|
|
|
| 198 |
parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
| 199 |
parser.add_argument('--input', required=True, type=Path, help='PDF or one PNG/JPEG image.')
|
| 200 |
parser.add_argument('--pages', help='Required for PDFs: 1-based page numbers, e.g. 5 or 5,7-9.')
|
| 201 |
+
parser.add_argument('--checkpoint', type=Path, default=Path(__file__).resolve().parent / 'model.safetensors')
|
| 202 |
+
parser.add_argument('--model-config', type=Path, help='Architecture JSON; defaults beside weights.')
|
| 203 |
parser.add_argument('--output', type=Path, help='New output folder; defaults to a timestamped outputs/ folder.')
|
| 204 |
parser.add_argument('--dpi', type=int, default=150, help='PDF rendering DPI. Default: 150, matching training preparation.')
|
| 205 |
parser.add_argument('--threshold', type=float, default=.3)
|
|
|
|
| 258 |
if installed != '1.11.2':
|
| 259 |
parser.error(f'This script requires RF-DETR 1.11.2; found {installed}.')
|
| 260 |
import torch
|
| 261 |
+
from model_loader import load_model
|
| 262 |
if args.device == 'mps' and not torch.backends.mps.is_available():
|
| 263 |
parser.error('MPS unavailable; use the Mac environment or pass --device cpu.')
|
| 264 |
if args.device == 'cuda' and not torch.cuda.is_available():
|
| 265 |
parser.error('CUDA unavailable.')
|
| 266 |
+
print('Loading safetensors door weights...', flush=True)
|
| 267 |
+
model = load_model(args.checkpoint, args.model_config, device=args.device)
|
|
|
|
| 268 |
output.mkdir(parents=True)
|
| 269 |
report = dict(input=args.input.name, checkpoint=None if args.preview_only else args.checkpoint.name,
|
| 270 |
status='running', preview_only=args.preview_only, threshold=args.threshold, nms_iou=args.nms_iou,
|
v3.pth → model.safetensors
RENAMED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:aca8b59ff9c6f144a1ca284f689683e9ed7cd951555832cfc09c10e5ae93bd0d
|
| 3 |
+
size 127223664
|
model_config.json
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"variant": "RFDETRSmall",
|
| 3 |
+
"rfdetr_version": "1.11.2",
|
| 4 |
+
"resolution": 512,
|
| 5 |
+
"num_classes": 1,
|
| 6 |
+
"id2label": {
|
| 7 |
+
"0": "door"
|
| 8 |
+
}
|
| 9 |
+
}
|
model_loader.py
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# SPDX-License-Identifier: AGPL-3.0-only
|
| 2 |
+
# Safetensors loading added 2026-10-28; inference preprocessing is unchanged.
|
| 3 |
+
"""Strict, direct safetensors loader for this pinned RF-DETR Small release."""
|
| 4 |
+
from importlib.metadata import version
|
| 5 |
+
import json
|
| 6 |
+
from pathlib import Path
|
| 7 |
+
import warnings
|
| 8 |
+
|
| 9 |
+
import torch
|
| 10 |
+
from safetensors.torch import load_file
|
| 11 |
+
|
| 12 |
+
HERE = Path(__file__).resolve().parent
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def load_model(weights_path=None, config_path=None, device='cpu'):
|
| 16 |
+
"""Rebuild Small, load every tensor strictly, and return its RF-DETR facade.
|
| 17 |
+
|
| 18 |
+
No checkpoint deserialization, temporary pickle, pretrained download, dtype
|
| 19 |
+
conversion, or inference optimization is used. The CLI supplies the existing
|
| 20 |
+
RGB preparation, tiling, boundary rechecks and NMS via inference_engine.py.
|
| 21 |
+
"""
|
| 22 |
+
weights_path = Path(weights_path) if weights_path is not None else HERE / 'model.safetensors'
|
| 23 |
+
config_path = Path(config_path) if config_path is not None else weights_path.parent / 'model_config.json'
|
| 24 |
+
if weights_path.suffix != '.safetensors':
|
| 25 |
+
raise ValueError('Use a .safetensors weights file.')
|
| 26 |
+
config = json.loads(config_path.read_text())
|
| 27 |
+
expected_config = {
|
| 28 |
+
'variant': 'RFDETRSmall', 'rfdetr_version': '1.11.2',
|
| 29 |
+
'resolution': 512, 'num_classes': 1, 'id2label': {'0': 'door'},
|
| 30 |
+
}
|
| 31 |
+
if config != expected_config:
|
| 32 |
+
raise ValueError('model_config.json does not describe this RF-DETR Small release.')
|
| 33 |
+
if version('rfdetr') != config['rfdetr_version']:
|
| 34 |
+
raise RuntimeError('Install the pinned rfdetr==1.11.2 inference dependencies.')
|
| 35 |
+
if device not in ('cpu', 'mps', 'cuda'):
|
| 36 |
+
raise ValueError('Choose cpu, mps or cuda.')
|
| 37 |
+
if device == 'mps' and not torch.backends.mps.is_available():
|
| 38 |
+
raise RuntimeError('MPS unavailable; use --device cpu.')
|
| 39 |
+
if device == 'cuda' and not torch.cuda.is_available():
|
| 40 |
+
raise RuntimeError('CUDA unavailable; use --device cpu.')
|
| 41 |
+
|
| 42 |
+
from rfdetr import RFDETRSmall
|
| 43 |
+
from rfdetr.config import PretrainWeightsCompatibilityWarning
|
| 44 |
+
|
| 45 |
+
# The pinned Small constructor uses bundled backbone configuration. Patch 16
|
| 46 |
+
# and positional grid 32 create the backbone locally, without DINOv2 weights.
|
| 47 |
+
# Its expected "initialised from scratch" warning is superseded by the strict
|
| 48 |
+
# complete-state load below; no randomly initialized weights remain in use.
|
| 49 |
+
with warnings.catch_warnings():
|
| 50 |
+
warnings.simplefilter('ignore', PretrainWeightsCompatibilityWarning)
|
| 51 |
+
model = RFDETRSmall(pretrain_weights=None, num_classes=config['num_classes'],
|
| 52 |
+
resolution=config['resolution'], device=device)
|
| 53 |
+
module = model.model.model
|
| 54 |
+
state = load_file(str(weights_path), device='cpu')
|
| 55 |
+
expected = module.state_dict()
|
| 56 |
+
missing = sorted(expected.keys() - state.keys())
|
| 57 |
+
unexpected = sorted(state.keys() - expected.keys())
|
| 58 |
+
if missing or unexpected:
|
| 59 |
+
raise RuntimeError(f'Weight key mismatch: missing={missing}, unexpected={unexpected}')
|
| 60 |
+
for name, tensor in state.items():
|
| 61 |
+
if tensor.shape != expected[name].shape or tensor.dtype != expected[name].dtype:
|
| 62 |
+
raise RuntimeError(f'Weight shape/dtype mismatch: {name}')
|
| 63 |
+
module.load_state_dict(state, strict=True)
|
| 64 |
+
loaded_state = module.state_dict()
|
| 65 |
+
if not all(torch.equal(tensor, loaded_state[name]) for name, tensor in state.items()):
|
| 66 |
+
raise RuntimeError('Loaded model tensors do not exactly match the safetensors file.')
|
| 67 |
+
module.eval()
|
| 68 |
+
model.model.class_names = [config['id2label'][str(i)] for i in range(config['num_classes'])]
|
| 69 |
+
model.model.args.class_names = model.model.class_names
|
| 70 |
+
return model
|
requirements.txt
CHANGED
|
@@ -8,3 +8,4 @@ pymupdf==2.0
|
|
| 8 |
supervision==0.30.8
|
| 9 |
transformers==5.19.0
|
| 10 |
huggingface_hub==1.33.0
|
|
|
|
|
|
| 8 |
supervision==0.30.8
|
| 9 |
transformers==5.19.0
|
| 10 |
huggingface_hub==1.33.0
|
| 11 |
+
safetensors==0.8.0
|