Pull requests / #634

#634 strata_pack.py build: refuse an output directory that already holds a pack, naming the file

closed · @Avicennasis · 0 Kommentare · Auf GitHub

Setup & installAMD / HIPModels & quantsLinux

Beschreibung

One fail-closed change on the packer, with a test that runs without a model or a GPU.

## `strata_pack.py build`: an occupied `--out` is refused before anything is written

`build()` did `out_dir.mkdir(parents=True, exist_ok=True)` (`tools/strata_pack.py:207`) and then wrote `experts.bin` (`:229`, through `pack_layer.build`, which opens it `"wb"`), `dense.bin`, `embd.bin` and `manifest.json` over whatever the directory held, with nothing said. A `--out` pointed at a finished pack - this tool's, or `iq_pack.py`'s, whose `dense.bin` and `experts.bin` share names with this tool's - was overwritten in place, and a build that stopped partway left the old `manifest.json` describing the new, half-written files.

Now a `manifest.json`, `index.txt` or `native_experts.txt` in `--out` stops `build` before it opens the GGUF or writes a byte, naming the directory and the file, and returns 1 like the other refusals in `build`:

```
$ python tools/strata_pack.py build --gguf /nonexistent/m-00001-of-00002.gguf --out /tmp/sr6-cli.9RfT/pack --skip-hash
/tmp/sr6-cli.9RfT/pack already holds a pack (manifest.json is there) - refusing to build; delete the directory or pass another --out
exit 1
```

Those three are the files the engine reads a pack's identity from (`src/core/expert_source.cpp:2289`, the fingerprint), so "holds a pack" means the same thing to the tool and to the engine. `experts.bin` on its own does not count: `build` writes `manifest.json` last, so `experts.bin` without it is a build that did not finish, and it is rebuilt as before. An empty or absent directory proceeds as today. There is no resume to keep - `pack_layer.build` has no sidecar and rewrites `experts.bin` from the start - so none was invented. (The same rule in Swiftlet #41 and Colibri `41b4544`: the manifest-equivalent is refused, and only an explicit install sidecar resumes.)

Where this meets setup: `setup.py:3503` re-runs `build` when `index.txt` or `experts.bin` is missing from the pack directory. An interrupted conversion (no `manifest.json` yet) is rebuilt as before. A directory with a finished pack and no `index.txt` (`pack_index.py` interrupted after `build` finished), or with `experts.bin` deleted by hand, now stops setup at this message instead of rewriting the directory; deleting it and running setup again is the way through, and is what the rewrite did to it anyway. `setup.py` is not touched.

Test: `tools/test_shards.py` (`python -m unittest tools.test_shards`), with the GGUF reader replaced by a sentinel so "went on into the build" is observable without the model's shards: each of the three markers is refused with the path and the file named and the directory's contents untouched; an empty and an absent directory go on into the build; `experts.bin` without `manifest.json` goes on too.

## What I ran, and where

Linux x86_64 (Ubuntu 24.04, AMD Ryzen 7 5800X - no AVX-512, no NVIDIA GPU), Python 3.12.3. Nothing under `src/` is touched, so nothing was built.

- `python -m unittest tools.test_shards`: 10 tests OK (the 7 from #92 plus 3). Against `main`'s `tools/strata_pack.py` with the same test file: 3 errors - every marker subtest, because the build goes on into the GGUF (the sentinel raises) instead of returning 1.
- `python -m unittest tools.test_calibrate`: 14 OK.
- `git diff --check` clean.

Branch is on `99f3dbd` (0.1.38); happy to rebase if it has moved by the time you look.

Mehr auf der Site

Links zu Install, Modellen, Releases.