weftcodec 1.2.0__py3-none-any.whl
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.
- weftcodec/__init__.py +62 -0
- weftcodec/__main__.py +6 -0
- weftcodec/ai_modes.py +3360 -0
- weftcodec/cli.py +252 -0
- weftcodec/crc32c.py +33 -0
- weftcodec/dcp.py +2108 -0
- weftcodec/dependency.py +224 -0
- weftcodec/errors.py +119 -0
- weftcodec/frame.py +455 -0
- weftcodec/hashing.py +56 -0
- weftcodec/huffman.py +212 -0
- weftcodec/identity.py +141 -0
- weftcodec/limits.py +58 -0
- weftcodec/modes.py +718 -0
- weftcodec/orbax.py +1734 -0
- weftcodec/service.py +959 -0
- weftcodec/torch.py +94 -0
- weftcodec/varint.py +88 -0
- weftcodec/wcb.py +310 -0
- weftcodec-1.2.0.dist-info/METADATA +257 -0
- weftcodec-1.2.0.dist-info/RECORD +24 -0
- weftcodec-1.2.0.dist-info/WHEEL +5 -0
- weftcodec-1.2.0.dist-info/entry_points.txt +2 -0
- weftcodec-1.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: weftcodec
|
|
3
|
+
Version: 1.2.0
|
|
4
|
+
Summary: Independent Python reader for Weft WFT1 frames and canonical WCB, with a PyTorch-facing dataset over a WeftFS mount
|
|
5
|
+
Author: WeftFS contributors
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Project-URL: Source, https://github.com/infinityabundance/WeftFS
|
|
8
|
+
Keywords: weft,weftfs,codec,wft1,wcb,blake3,pytorch
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
12
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: System :: Filesystems
|
|
19
|
+
Requires-Python: >=3.9
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
Requires-Dist: blake3>=0.3.1
|
|
22
|
+
Requires-Dist: zstandard>=0.22
|
|
23
|
+
Provides-Extra: torch
|
|
24
|
+
Requires-Dist: torch; extra == "torch"
|
|
25
|
+
Provides-Extra: orbax
|
|
26
|
+
Requires-Dist: jax[cpu]>=0.4; extra == "orbax"
|
|
27
|
+
Requires-Dist: orbax-checkpoint>=0.5; extra == "orbax"
|
|
28
|
+
|
|
29
|
+
# weftcodec (Python)
|
|
30
|
+
|
|
31
|
+
An independent Python implementation of the WeftCodec v1 **reader**: WFT1 frame
|
|
32
|
+
parsing, canonical WCB decode/encode, domain-separated BLAKE3 content roots, and
|
|
33
|
+
a PyTorch-facing dataset over a mounted WeftFS directory.
|
|
34
|
+
|
|
35
|
+
There are **no Rust or Go extension modules**. This is a third implementation,
|
|
36
|
+
written from the normative specification and tested against Rust-generated
|
|
37
|
+
conformance vectors.
|
|
38
|
+
|
|
39
|
+
## Install
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
pip install dist/weftcodec-1.2.0-py3-none-any.whl
|
|
43
|
+
# with the optional dataset extra
|
|
44
|
+
pip install "dist/weftcodec-1.2.0-py3-none-any.whl[torch]"
|
|
45
|
+
# with the optional JAX/Orbax adapter extra
|
|
46
|
+
pip install "dist/weftcodec-1.2.0-py3-none-any.whl[orbax]"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Dependencies: `blake3`, `zstandard`. `torch`, `jax`, and `orbax-checkpoint`
|
|
50
|
+
are optional and are only imported by their adapter modules.
|
|
51
|
+
|
|
52
|
+
> **PyPI publication requires an API token we do not have.** The wheel is built
|
|
53
|
+
> in the Docker court and attached to the GitHub release; it is not published to
|
|
54
|
+
> PyPI.
|
|
55
|
+
|
|
56
|
+
## Usage
|
|
57
|
+
|
|
58
|
+
```sh
|
|
59
|
+
python -m weftcodec verify FRAME # validate structure + hashes
|
|
60
|
+
python -m weftcodec decode FRAME OUT # exact plaintext bytes
|
|
61
|
+
python -m weftcodec inspect FRAME # metadata as JSON
|
|
62
|
+
python -m weftcodec verify FRAME --deps DEPS_DIR # REFERENCE/DELTA/DICTIONARY
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Exit codes: `0` success, `1` codec or I/O failure, `2` usage error.
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from weftcodec import parse, content_root, verify_frame
|
|
69
|
+
from weftcodec.dependency import DirectoryResolver
|
|
70
|
+
from weftcodec.modes import decode_bytes
|
|
71
|
+
|
|
72
|
+
resolver = DirectoryResolver("deps") # files named by lowercase hex
|
|
73
|
+
frame_bytes = open("frame.wft1", "rb").read()
|
|
74
|
+
frame = parse(frame_bytes)
|
|
75
|
+
plaintext = decode_bytes(frame_bytes, resolver)
|
|
76
|
+
assert content_root(plaintext) == frame.header.content_hash
|
|
77
|
+
|
|
78
|
+
result = verify_frame("frame.wft1", resolver)
|
|
79
|
+
print(result.ok, result.mode, result.content_hash, result.computed_content_hash)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### WCB
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
from weftcodec import wcb
|
|
86
|
+
|
|
87
|
+
value = wcb.decode(bytes.fromhex("08030501610301050162050374776f05016300"))
|
|
88
|
+
assert wcb.encode(value) == bytes.fromhex("08030501610301050162050374776f05016300")
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Python/WCB mapping: `None`→null, `bool`, `U64`, `I64`, `str`, `bytes`,
|
|
92
|
+
`list`/`tuple`, `dict` (text keys), `Timestamp`. Map keys are sorted by their
|
|
93
|
+
full encoded bytes; duplicates are rejected.
|
|
94
|
+
|
|
95
|
+
### PyTorch dataset
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
from weftcodec.torch import WeftMapDataset
|
|
99
|
+
|
|
100
|
+
dataset = WeftMapDataset("/mnt/weft/dataset")
|
|
101
|
+
path, raw = dataset[0] # (relative path, bytes)
|
|
102
|
+
|
|
103
|
+
import torch
|
|
104
|
+
tensors = WeftMapDataset("/mnt/weft/dataset", dtype=torch.uint8)
|
|
105
|
+
path, tensor = tensors[0] # torch.frombuffer view
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Entries are sorted by POSIX-relative path, so ordering is deterministic across
|
|
109
|
+
processes.
|
|
110
|
+
|
|
111
|
+
### PyTorch Distributed Checkpoint adapter
|
|
112
|
+
|
|
113
|
+
`weftcodec.dcp` implements the shape of
|
|
114
|
+
`torch.distributed.checkpoint.StorageWriter` / `StorageReader` over a WeftFS
|
|
115
|
+
store. The training process does not need a FUSE mount: every durable byte goes
|
|
116
|
+
through the Rust `weftfs` CLI (`checkpoint write` / `checkpoint restore`).
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
import torch
|
|
120
|
+
import torch.distributed.checkpoint as dcp
|
|
121
|
+
from weftcodec.dcp import WeftStorageWriter, WeftStorageReader, init_store
|
|
122
|
+
|
|
123
|
+
init_store("/data/weft-store")
|
|
124
|
+
|
|
125
|
+
model = MyModel()
|
|
126
|
+
dcp.save(
|
|
127
|
+
model.state_dict(),
|
|
128
|
+
storage_writer=WeftStorageWriter(
|
|
129
|
+
"run-0001", # single WeftFS checkpoint name
|
|
130
|
+
store_root="/data/weft-store",
|
|
131
|
+
topology=8, # store every tensor split 8 ways on axis 0
|
|
132
|
+
shard_strategy="zstd", # exact; tensor-sharded is the mode-10 option
|
|
133
|
+
),
|
|
134
|
+
no_dist=True,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
fresh = MyModel()
|
|
138
|
+
dcp.load(
|
|
139
|
+
fresh.state_dict(),
|
|
140
|
+
storage_reader=WeftStorageReader("run-0001", store_root="/data/weft-store"),
|
|
141
|
+
no_dist=True,
|
|
142
|
+
)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Async save (the encode/store work runs on a `ThreadPoolExecutor` worker, with a
|
|
146
|
+
hard per-tensor staging bound; tensors are still copied through host memory):
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
from weftcodec.dcp import save_checkpoint_async
|
|
150
|
+
|
|
151
|
+
handle = save_checkpoint_async(
|
|
152
|
+
model.state_dict(),
|
|
153
|
+
checkpoint_id="run-0002",
|
|
154
|
+
store_root="/data/weft-store",
|
|
155
|
+
topology=8,
|
|
156
|
+
staging_bytes=256 * 1024 * 1024, # 256 MiB bound on one resolved tensor copy
|
|
157
|
+
)
|
|
158
|
+
metadata = handle.result() # raises the save error on this thread
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Every checkpoint is a canonical `weft.checkpoint.v1` manifest plus mode-10 or
|
|
162
|
+
exact codec shards; the DCP metadata is canonical WCB at
|
|
163
|
+
`/checkpoints/<name>/dcp.metadata`. The adapter verifies each tensor's BLAKE3
|
|
164
|
+
content root against the Rust manifest before/after every transfer. Verify with:
|
|
165
|
+
|
|
166
|
+
```sh
|
|
167
|
+
weftfs --store /data/weft-store checkpoint verify --name run-0001 --json
|
|
168
|
+
weftfs --store /data/weft-store verify --full --json
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
A checkpoint written by the Rust CLI alone (plain safetensors tensor names) is
|
|
172
|
+
readable too: the adapter synthesises DCP metadata from the manifest and reports
|
|
173
|
+
`reader.metadata_source == "manifest"`. Supported tensor dtypes are exactly the
|
|
174
|
+
WEFT-TENSOR v1 set (`f16`, `bf16`, `f32`, `f64`, `i8`, `u8`, `i16`, `i32`,
|
|
175
|
+
`i64`); everything else is rejected, never coerced. ShardedTensor, DTensor and
|
|
176
|
+
custom `planner_data` are not persisted. See `docs/PYTORCH-DCP.md` for the full
|
|
177
|
+
contract and non-claims.
|
|
178
|
+
|
|
179
|
+
### JAX / Orbax adapter
|
|
180
|
+
|
|
181
|
+
`weftcodec.orbax` is an Orbax `AsyncCheckpointHandler` that stores a JAX PyTree
|
|
182
|
+
as one canonical `weft.checkpoint.v1` checkpoint through the same Rust CLI and
|
|
183
|
+
the same adapter plumbing as the DCP path. Each flattened leaf is recorded in a
|
|
184
|
+
canonical WCB `weft.orbax.v1` record with its path, dtype, shape, BLAKE3 content
|
|
185
|
+
root and logical root; the Orbax directory only carries a small canonical
|
|
186
|
+
locator pointing at the store.
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
import jax
|
|
190
|
+
from weftcodec.orbax import WeftOrbaxHandler, WeftSaveArgs, WeftRestoreArgs
|
|
191
|
+
|
|
192
|
+
handler = WeftOrbaxHandler(staging_bytes=256 * 1024 * 1024)
|
|
193
|
+
target = jax.tree_util.tree_map(
|
|
194
|
+
lambda a: jax.ShapeDtypeStruct(a.shape, a.dtype, sharding=a.sharding), params
|
|
195
|
+
)
|
|
196
|
+
# Drive it with orbax.checkpoint.Checkpointer, AsyncCheckpointer, or
|
|
197
|
+
# CheckpointManager:
|
|
198
|
+
# save(directory, args=WeftSaveArgs(
|
|
199
|
+
# item=params, store_root="/data/weft-store", checkpoint_id="run-0001"))
|
|
200
|
+
# restore(directory, args=WeftRestoreArgs(item=target))
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Supported leaf dtypes are the same exact WEFT-TENSOR v1 set. A target PyTree
|
|
204
|
+
with a missing, extra, differently typed, or differently shaped leaf fails
|
|
205
|
+
closed; different JAX sharding topologies are accepted because the stored
|
|
206
|
+
logical tensor is topology independent. `staging_bytes` bounds the staging
|
|
207
|
+
container and the restored bytes. See `docs/JAX-ORBAX.md` for the full contract,
|
|
208
|
+
measured comparison against Orbax's own OCDBT checkpoint, and non-claims (CPU
|
|
209
|
+
only, single process, no TPU/GPU, no multi-host JAX).
|
|
210
|
+
|
|
211
|
+
## Supported modes
|
|
212
|
+
|
|
213
|
+
| Mode | Value | Python reader |
|
|
214
|
+
|---|---:|---|
|
|
215
|
+
| `RAW` | 0 | implemented |
|
|
216
|
+
| `ZSTD` | 1 | implemented (`zstandard`) |
|
|
217
|
+
| `REFERENCE` | 2 | implemented |
|
|
218
|
+
| `DELTA` | 3 | implemented |
|
|
219
|
+
| `DICTIONARY` | 4 | implemented (raw-content zstd dictionary) |
|
|
220
|
+
| `STRUCTURED` | 5 | implemented (canonical WCB validation) |
|
|
221
|
+
| `TENSOR` | 6 | implemented (descriptor validation) |
|
|
222
|
+
| `TOKEN_SEQUENCE` | 7 | implemented (descriptor + varint payload) |
|
|
223
|
+
| `QUANTIZED_TENSOR` | 8 | implemented (descriptor validation) |
|
|
224
|
+
| `FLOAT_TENSOR` | 9 | implemented (all five dtypes, `huffman-canonical-v1` exponent plane) |
|
|
225
|
+
| `TENSOR_SHARDED` | 10 | implemented (q4_0/q8_0 shards, plane verification, shard-set root) |
|
|
226
|
+
| `WEIGHT_DELTA` | 11 | implemented (base resolution, modular word subtraction, `delta_root`) |
|
|
227
|
+
| `KV_CACHE` | 12 | implemented (one page per frame, byte-plane decode) |
|
|
228
|
+
| `ACTIVATION_STREAM` | 13 | implemented (one chunk per frame, `digest_root`, stream root) |
|
|
229
|
+
| `SEMANTIC_DELTA` | 14 | implemented (policy verification against the resolved base) |
|
|
230
|
+
| `TENSOR_TILED` | 15 | implemented (per-tile roots and whole-tensor logical root) |
|
|
231
|
+
| `SPARSE_DELTA` | 16 | implemented (`zero-run-v1`, `delta_root`) |
|
|
232
|
+
|
|
233
|
+
Every allocated mode 0–18 is implemented. There is no approximate or lossy
|
|
234
|
+
decode path. Reserved mode values 17–127 and experimental values 128–255 are
|
|
235
|
+
rejected by `weftcodec.frame` with `UnsupportedMode`.
|
|
236
|
+
|
|
237
|
+
The reader is deliberately a decoder, not a WEFT-TENSOR container reader: it
|
|
238
|
+
does not claim WeftQL selectors, Context Roots, capability envelopes,
|
|
239
|
+
`weft.checkpoint.v1` manifests, WFA1 archives, or `weft.tensor.layout.v1` /
|
|
240
|
+
`weft.tensor.shard.v1` records. `TENSOR_TILED` supports full decode; the
|
|
241
|
+
region reader is not implemented in Python.
|
|
242
|
+
|
|
243
|
+
## Tests
|
|
244
|
+
|
|
245
|
+
```sh
|
|
246
|
+
pytest -q
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
The suite consumes `../WeftCodec/conformance/v1/**` (Rust-generated vectors) and
|
|
250
|
+
runs the Rust CLI for cross-language encode/decode checks when
|
|
251
|
+
`/work/.docker-cache/target-rust/release/weftcodec` is available. The PyTorch test
|
|
252
|
+
uses `pytest.importorskip("torch")`.
|
|
253
|
+
|
|
254
|
+
`test_ai_modes.py` decodes every valid AI-mode vector to its recorded bytes and
|
|
255
|
+
recomputes every recorded root; `test_random_differential.py` generates at least
|
|
256
|
+
2,000 frames per mode 9–16 from a deterministic PRNG and compares the Python
|
|
257
|
+
reader against the Rust CLI on every frame, plus 1,600 body mutants.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
weftcodec/__init__.py,sha256=pkcW0yS2JTZo5xqW1MYzb46n36PJDGKv8mE2m3NpdyY,1689
|
|
2
|
+
weftcodec/__main__.py,sha256=mzx10AUUv_v_CRVT_rZYwihgTQuhWFpjc3neblSFbTM,123
|
|
3
|
+
weftcodec/ai_modes.py,sha256=J5flGXVySMe9woYg1U1nWeVcgqoMd95YDKc3_ZAFJVw,118711
|
|
4
|
+
weftcodec/cli.py,sha256=vmVXoGRqsVA_LPaxj4rlfhcIC7bnl4DDGuA2A9WAlbw,8074
|
|
5
|
+
weftcodec/crc32c.py,sha256=XlXKr39OzLzBuERM27r8i9ldqA1T0C1jlInVBu3SDek,735
|
|
6
|
+
weftcodec/dcp.py,sha256=ee4SHPFk4B_y3kgQGoz9auCUH7ibsWDfDtItiazSxEU,75950
|
|
7
|
+
weftcodec/dependency.py,sha256=5vpnDJN2krq_YAc1pJWkhYr80nlbdvA1qYPHW8tnjS8,8441
|
|
8
|
+
weftcodec/errors.py,sha256=Fd4uzlkTFjr6e8IKOcAH4GDmLyBY00_xLFD-epmyWeU,2608
|
|
9
|
+
weftcodec/frame.py,sha256=mKkF0IL4XnX128tEae-lFG2MSkxkZ4ESfBct1jRDOp4,15535
|
|
10
|
+
weftcodec/hashing.py,sha256=kgvV1ZGXbmepIaEcau3Djp3KZ6J-ykwHQ0mvUov8PDA,1859
|
|
11
|
+
weftcodec/huffman.py,sha256=ChTmtRi_DfmJ8_cvFvQYRCTwpXax-NPtfQqCru2DQ1c,7356
|
|
12
|
+
weftcodec/identity.py,sha256=d679KgOzMI5MKVkDvdR_K1q3LNOktXTihLeKupj8bVs,4015
|
|
13
|
+
weftcodec/limits.py,sha256=NBZC_Qo4w-dsefxwNMRQ49gomMePKTWUv5ca1Bgt6_g,2232
|
|
14
|
+
weftcodec/modes.py,sha256=2pn9OJFiUrWnkfJI6qzvyGrg9nrKAybDPC6anuP908A,25017
|
|
15
|
+
weftcodec/orbax.py,sha256=m3af69jU-mLx0Eny-vShwIL4wRsBD0ows3F_lipKBBs,61818
|
|
16
|
+
weftcodec/service.py,sha256=zzUdyXgfGZ7GtR2BntCUiEpwoXzXYAnaAtnW7Hi6tzY,31611
|
|
17
|
+
weftcodec/torch.py,sha256=PZIJQBNRgo8xbagcGxI5MSjD6iYhQQeqPKjJ5KTsMDA,3211
|
|
18
|
+
weftcodec/varint.py,sha256=6srhBLYJZEGGAWsDiW7fyUVL9p5FBwR_wiS9oCAes2E,2504
|
|
19
|
+
weftcodec/wcb.py,sha256=HBjh_gbO2eBZWthCqU8f4z57kG3nlBhj8Zq4LcXdIuw,10861
|
|
20
|
+
weftcodec-1.2.0.dist-info/METADATA,sha256=1GmGSeLMiZD87izNVBOTAnwAfetg2HNiXjoWJMhEQwM,10304
|
|
21
|
+
weftcodec-1.2.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
|
|
22
|
+
weftcodec-1.2.0.dist-info/entry_points.txt,sha256=IsOuP8jWz37d7NvWT9r9ACBpGPtvYsj8F9WTY1-kgMg,52
|
|
23
|
+
weftcodec-1.2.0.dist-info/top_level.txt,sha256=HO5-vBHWV3GGFKc540HJ5FFH_e-HVSTdMDgK1DGSua4,10
|
|
24
|
+
weftcodec-1.2.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
weftcodec
|