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
weftcodec/cli.py
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
"""Command-line reader for WFT1 frames."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import json
|
|
7
|
+
import sys
|
|
8
|
+
|
|
9
|
+
from . import modes
|
|
10
|
+
from .dependency import DirectoryFrameSourceResolver, DirectoryResolver
|
|
11
|
+
from .errors import WeftError
|
|
12
|
+
from .frame import parse
|
|
13
|
+
from .identity import verify_frame
|
|
14
|
+
from .limits import Limits
|
|
15
|
+
|
|
16
|
+
EXIT_OK = 0
|
|
17
|
+
EXIT_FAILURE = 1
|
|
18
|
+
EXIT_USAGE = 2
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _resolver(args):
|
|
22
|
+
if getattr(args, "resolve", False):
|
|
23
|
+
source = getattr(args, "frame_source", None)
|
|
24
|
+
if not source:
|
|
25
|
+
raise SystemExit("--resolve requires --frame-source")
|
|
26
|
+
return DirectoryFrameSourceResolver(source, Limits())
|
|
27
|
+
if getattr(args, "deps", None):
|
|
28
|
+
return DirectoryResolver(args.deps)
|
|
29
|
+
return None
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _base_frame(args):
|
|
33
|
+
path = getattr(args, "base", None)
|
|
34
|
+
if not path:
|
|
35
|
+
return None
|
|
36
|
+
with open(path, "rb") as handle:
|
|
37
|
+
return handle.read()
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _print_error(exc: WeftError) -> None:
|
|
41
|
+
print("%s: %s" % (exc.error_class, exc.message), file=sys.stderr)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _verify(args) -> int:
|
|
45
|
+
result = verify_frame(
|
|
46
|
+
args.file, _resolver(args), Limits(), _base_frame(args)
|
|
47
|
+
)
|
|
48
|
+
if result.ok:
|
|
49
|
+
if args.json:
|
|
50
|
+
print(json.dumps(result.to_dict(), sort_keys=True))
|
|
51
|
+
else:
|
|
52
|
+
print(
|
|
53
|
+
"OK mode=%s decoded_len=%d content_hash=%s chunks=%d dependencies=%d"
|
|
54
|
+
% (
|
|
55
|
+
result.mode,
|
|
56
|
+
result.decoded_len,
|
|
57
|
+
result.content_hash,
|
|
58
|
+
result.chunk_count,
|
|
59
|
+
result.dependency_count,
|
|
60
|
+
)
|
|
61
|
+
)
|
|
62
|
+
return EXIT_OK
|
|
63
|
+
if args.json:
|
|
64
|
+
print(json.dumps(result.to_dict(), sort_keys=True))
|
|
65
|
+
else:
|
|
66
|
+
print("%s: %s" % (result.error_class, result.error), file=sys.stderr)
|
|
67
|
+
return EXIT_FAILURE
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _decode(args) -> int:
|
|
71
|
+
try:
|
|
72
|
+
with open(args.file, "rb") as handle:
|
|
73
|
+
data = handle.read()
|
|
74
|
+
except OSError as exc:
|
|
75
|
+
print("Io: %s" % exc, file=sys.stderr)
|
|
76
|
+
return EXIT_FAILURE
|
|
77
|
+
try:
|
|
78
|
+
plaintext = modes.decode_bytes(
|
|
79
|
+
data, _resolver(args), Limits(), _base_frame(args)
|
|
80
|
+
)
|
|
81
|
+
except WeftError as exc:
|
|
82
|
+
_print_error(exc)
|
|
83
|
+
return EXIT_FAILURE
|
|
84
|
+
if args.output == "-":
|
|
85
|
+
sys.stdout.buffer.write(plaintext)
|
|
86
|
+
sys.stdout.buffer.flush()
|
|
87
|
+
return EXIT_OK
|
|
88
|
+
try:
|
|
89
|
+
with open(args.output, "wb") as handle:
|
|
90
|
+
handle.write(plaintext)
|
|
91
|
+
except OSError as exc:
|
|
92
|
+
print("Io: %s" % exc, file=sys.stderr)
|
|
93
|
+
return EXIT_FAILURE
|
|
94
|
+
return EXIT_OK
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _inspect_record(frame) -> dict:
|
|
98
|
+
header = frame.header
|
|
99
|
+
record = {
|
|
100
|
+
"ok": True,
|
|
101
|
+
"mode": header.mode_name,
|
|
102
|
+
"mode_value": header.mode,
|
|
103
|
+
"format_major": header.format_major,
|
|
104
|
+
"format_minor": header.format_minor,
|
|
105
|
+
"domain": header.domain,
|
|
106
|
+
"domain_name": "payload" if header.domain == 0 else "structured",
|
|
107
|
+
"flags": header.flag_names(),
|
|
108
|
+
"flags_value": header.flags,
|
|
109
|
+
"features": header.feature_names(),
|
|
110
|
+
"features_value": header.features,
|
|
111
|
+
"level": header.level,
|
|
112
|
+
"decoded_len": header.decoded_len,
|
|
113
|
+
"body_len": header.body_len,
|
|
114
|
+
"table_len": header.table_len,
|
|
115
|
+
"frame_len": len(frame.raw),
|
|
116
|
+
"chunk_count": header.chunk_count,
|
|
117
|
+
"dep_count": header.dep_count,
|
|
118
|
+
"dependency_count": header.dep_count,
|
|
119
|
+
"content_hash": header.content_hash.hex(),
|
|
120
|
+
"dependencies": [
|
|
121
|
+
{
|
|
122
|
+
"hash": dep.hash.hex(),
|
|
123
|
+
"decoded_len": dep.decoded_len,
|
|
124
|
+
"dep_domain": dep.dep_domain,
|
|
125
|
+
"dep_flags": dep.dep_flags,
|
|
126
|
+
"codec_hint": dep.codec_hint,
|
|
127
|
+
}
|
|
128
|
+
for dep in frame.dependencies
|
|
129
|
+
],
|
|
130
|
+
"chunks": [
|
|
131
|
+
{
|
|
132
|
+
"encoded_off": chunk.encoded_off,
|
|
133
|
+
"encoded_len": chunk.encoded_len,
|
|
134
|
+
"decoded_len": chunk.decoded_len,
|
|
135
|
+
"hash": chunk.hash.hex(),
|
|
136
|
+
}
|
|
137
|
+
for chunk in frame.chunks
|
|
138
|
+
],
|
|
139
|
+
}
|
|
140
|
+
limits = Limits()
|
|
141
|
+
try:
|
|
142
|
+
if header.mode == 6:
|
|
143
|
+
record["tensor"] = modes.tensor_metadata(frame, limits)
|
|
144
|
+
elif header.mode == 7:
|
|
145
|
+
record["tokens"] = modes.token_metadata(frame, limits)
|
|
146
|
+
elif header.mode == 8:
|
|
147
|
+
record["quantized_tensor"] = modes.quantized_tensor_metadata(frame, limits)
|
|
148
|
+
elif header.mode == 5:
|
|
149
|
+
from . import wcb
|
|
150
|
+
|
|
151
|
+
record["structured"] = _jsonable(wcb.decode(frame.body, limits))
|
|
152
|
+
except WeftError as exc:
|
|
153
|
+
record["descriptor_error"] = {
|
|
154
|
+
"error_class": exc.error_class,
|
|
155
|
+
"error": exc.message,
|
|
156
|
+
}
|
|
157
|
+
return record
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def _jsonable(value):
|
|
161
|
+
from . import wcb
|
|
162
|
+
|
|
163
|
+
if value is None or isinstance(value, (bool, str, int, float)):
|
|
164
|
+
return value
|
|
165
|
+
if isinstance(value, (bytes, bytearray)):
|
|
166
|
+
return {"bytes_hex": bytes(value).hex()}
|
|
167
|
+
if isinstance(value, wcb.U64):
|
|
168
|
+
return {"u64": value.value}
|
|
169
|
+
if isinstance(value, wcb.I64):
|
|
170
|
+
return {"i64": value.value}
|
|
171
|
+
if isinstance(value, wcb.Timestamp):
|
|
172
|
+
return {"timestamp_nanos": value.nanos}
|
|
173
|
+
if isinstance(value, list):
|
|
174
|
+
return [_jsonable(item) for item in value]
|
|
175
|
+
if isinstance(value, dict):
|
|
176
|
+
return {key: _jsonable(item) for key, item in value.items()}
|
|
177
|
+
return repr(value)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def _inspect(args) -> int:
|
|
181
|
+
try:
|
|
182
|
+
with open(args.file, "rb") as handle:
|
|
183
|
+
data = handle.read()
|
|
184
|
+
except OSError as exc:
|
|
185
|
+
print(json.dumps({"ok": False, "error_class": "Io", "error": str(exc)}))
|
|
186
|
+
return EXIT_FAILURE
|
|
187
|
+
try:
|
|
188
|
+
frame = parse(data, Limits())
|
|
189
|
+
except WeftError as exc:
|
|
190
|
+
print(
|
|
191
|
+
json.dumps(
|
|
192
|
+
{"ok": False, "error_class": exc.error_class, "error": exc.message},
|
|
193
|
+
sort_keys=True,
|
|
194
|
+
)
|
|
195
|
+
)
|
|
196
|
+
return EXIT_FAILURE
|
|
197
|
+
print(json.dumps(_inspect_record(frame), sort_keys=True))
|
|
198
|
+
return EXIT_OK
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
202
|
+
parser = argparse.ArgumentParser(
|
|
203
|
+
prog="python -m weftcodec",
|
|
204
|
+
description="Independent Python reader for Weft WFT1 frames and WCB.",
|
|
205
|
+
)
|
|
206
|
+
sub = parser.add_subparsers(dest="command", required=True)
|
|
207
|
+
|
|
208
|
+
verify = sub.add_parser("verify", help="validate a frame and every hash")
|
|
209
|
+
verify.add_argument("file")
|
|
210
|
+
verify.add_argument("--deps", help="directory of dependency files named by hex")
|
|
211
|
+
verify.add_argument(
|
|
212
|
+
"--base", help="base frame for WEIGHT_DELTA/SEMANTIC_DELTA/SPARSE_DELTA"
|
|
213
|
+
)
|
|
214
|
+
verify.add_argument(
|
|
215
|
+
"--resolve", action="store_true", help="resolve dependencies as frames"
|
|
216
|
+
)
|
|
217
|
+
verify.add_argument(
|
|
218
|
+
"--frame-source", dest="frame_source", help="directory of frames named by hex"
|
|
219
|
+
)
|
|
220
|
+
verify.add_argument("--json", action="store_true", help="emit a JSON result")
|
|
221
|
+
verify.set_defaults(func=_verify)
|
|
222
|
+
|
|
223
|
+
decode = sub.add_parser("decode", help="decode a frame to plaintext")
|
|
224
|
+
decode.add_argument("file")
|
|
225
|
+
decode.add_argument("output", help="output path, or - for stdout")
|
|
226
|
+
decode.add_argument("--deps", help="directory of dependency files named by hex")
|
|
227
|
+
decode.add_argument(
|
|
228
|
+
"--base", help="base frame for WEIGHT_DELTA/SEMANTIC_DELTA/SPARSE_DELTA"
|
|
229
|
+
)
|
|
230
|
+
decode.add_argument(
|
|
231
|
+
"--resolve", action="store_true", help="resolve dependencies as frames"
|
|
232
|
+
)
|
|
233
|
+
decode.add_argument(
|
|
234
|
+
"--frame-source", dest="frame_source", help="directory of frames named by hex"
|
|
235
|
+
)
|
|
236
|
+
decode.set_defaults(func=_decode)
|
|
237
|
+
|
|
238
|
+
inspect = sub.add_parser("inspect", help="emit frame metadata as JSON")
|
|
239
|
+
inspect.add_argument("file")
|
|
240
|
+
inspect.add_argument("--json", action="store_true", help=argparse.SUPPRESS)
|
|
241
|
+
inspect.set_defaults(func=_inspect)
|
|
242
|
+
return parser
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
def main(argv=None) -> int:
|
|
246
|
+
parser = build_parser()
|
|
247
|
+
args = parser.parse_args(argv)
|
|
248
|
+
return args.func(args)
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
if __name__ == "__main__": # pragma: no cover
|
|
252
|
+
raise SystemExit(main())
|
weftcodec/crc32c.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""CRC-32C (Castagnoli), WEFTCODEC-FORMAT §1.
|
|
2
|
+
|
|
3
|
+
Polynomial 0x1EDC6F41, reflected input/output, init 0xFFFFFFFF, final XOR
|
|
4
|
+
0xFFFFFFFF. Implemented locally so the reader has no extra dependency.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
_POLY = 0x82F63B78
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _make_table() -> "list[int]":
|
|
13
|
+
table = []
|
|
14
|
+
for index in range(256):
|
|
15
|
+
crc = index
|
|
16
|
+
for _ in range(8):
|
|
17
|
+
if crc & 1:
|
|
18
|
+
crc = (crc >> 1) ^ _POLY
|
|
19
|
+
else:
|
|
20
|
+
crc >>= 1
|
|
21
|
+
table.append(crc)
|
|
22
|
+
return table
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
_TABLE = _make_table()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def crc32c(data: bytes) -> int:
|
|
29
|
+
crc = 0xFFFFFFFF
|
|
30
|
+
table = _TABLE
|
|
31
|
+
for byte in data:
|
|
32
|
+
crc = table[(crc ^ byte) & 0xFF] ^ (crc >> 8)
|
|
33
|
+
return crc ^ 0xFFFFFFFF
|