Pull requests / #92
#92 setup: name a missing or short shard with its numbers; verify reads back the manifest sha256
closed · merged 2026-09-29 · @Avicennasis · 0 comentarios · En GitHub
Setup & installServer & APIAMD / HIPNVIDIA / CUDAModels & quantsLinux
Descripción
Two fail-closed changes on the setup/verify seam, one per commit, each with a test that runs without a model or a GPU. (Companion PR: the GGUF reader refuses a duplicate tensor name.)
## `setup.py`: a missing or short shard is named with its numbers before anything reads it
Setup checked a shard by presence only (`missing <path>`), and a download by `Content-Length` only. A shard copied short into `--gguf-dir`, a `.part` renamed by hand, or a download an older setup finished without a `.done` mark passed as a model file; the failure came later, from the packer or the engine, at the first tensor past the end, naming neither the file nor the shortfall.
`check_shards()` reads each shard's header (the tensor directory, not the data - milliseconds on the 34 GB shard) and compares the file's length with what that directory needs, `data_start + max(offset + bytes)`:
```
[X] Qwen3.8-Flash-Next-GSQ-RCO-Q2_0-00001-of-00002.gguf is short: 1,234 of 1,274 bytes (40 missing)
delete it and run setup again (or copy the whole file into --gguf-dir)
```
A header that does not parse is refused by name (`... is not a whole GGUF shard (...)`); a missing file stays `missing <path>`. `download()`'s "could not finish" line now states the bytes on disk and the bytes the server announced instead of just the name. A tensor of a type the Python reader has no geometry for counts as 0 bytes, so the check can only under-estimate: it never refuses a whole file.
Test: `tools/test_shards.py` (`python -m unittest tools.test_shards`, unittest like `tools/test_calibrate.py`), over a minimal GGUF written by hand: whole shards pass; a missing, a short and a header-truncated shard each stop setup with the file named and, for the short one, both sizes and the difference.
## `strata_pack.py verify`: read back the source sha256 the manifest recorded
`build` writes `source.shard1_sha256` / `shard2_sha256` into `manifest.json` (unless `--skip-hash`, which is how setup builds), and nothing read them back - 0 readers in `src/`, `serve/`, `setup.py`, `tools/`. A pack verified against a different shard than it was built from reported tensor MISMATCHes, or passed under `--limit`.
A full `verify` (no `--limit`) now hashes the shard it is handed first and fails naming both digests when they differ:
```
<shard>: sha256 <got>, but the pack was built from <recorded>
tools/strata_pack.py verify FAIL
```
A manifest without the field (setup's packs) and a `--limit` run are unchanged, so the quick check stays quick. Shard 2's hash is recorded but not checked here: `verify` is not handed that file. Same test module: a matching hash passes, a wrong one fails naming both, an absent hash or `--limit` skips. On `main` the wrong-hash case returns 0.
Not in this PR, noted for later: the download itself still has no hash to check against - the manifest's hashes are computed from the downloaded file, so they cannot validate it. Hugging Face exposes the LFS object's sha256 on the resolve URL (`X-Linked-Etag`); hashing the stream as it is written would make that a free check, but resume needs the partial re-hashed and the HTTP path mocked in a test, so it is a separate change.
## What I ran, and where
Linux x86_64 (Ubuntu 24.04, AMD Ryzen 7 5800X - no AVX-512, no NVIDIA GPU), gcc 13.3.0, CMake 3.28.3, Python 3.12.3. The CUDA targets were not built (`STRATA_ENABLE_CUDA=OFF`); this is a claim about my machine, not yours.
- `python -m unittest tools.test_shards`: 7 tests OK. Against an export of `main` with the same test file: 1 failure (wrong-hash verify returns 0), 4 errors (`check_shards` does not exist).
- `python -m unittest tools.test_calibrate` 10 OK; `serve.test_server` 26 OK; `tools.test_iq_pack` 8 OK (with `STRATA_GGUF_PY` pointing at the pinned llama.cpp).
- `git diff --check` clean.
Branch is on `c1e9033` (0.1.20); happy to rebase if it has moved by the time you look.
En el sitio
Enlaces a install, modelos, releases.