File size: 11,355 Bytes
16f5171
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
#!/usr/bin/env python3
"""Validate the self-contained Fish S2-Pro NVFP4/MXFP8 V1 release."""

from __future__ import annotations

import hashlib
import json
import struct
from pathlib import Path, PurePosixPath


ROOT = Path(__file__).resolve().parent
DTYPE_BYTES = {
    "BF16": 2,
    "F32": 4,
    "F8_E4M3": 1,
    "I32": 4,
    "U8": 1,
}


def fail(message: str) -> None:
    raise RuntimeError(message)


def sha256(path: Path) -> str:
    digest = hashlib.sha256()
    with path.open("rb") as handle:
        for chunk in iter(lambda: handle.read(8 * 1024 * 1024), b""):
            digest.update(chunk)
    return digest.hexdigest()


def load_json(relative: str) -> dict:
    path = ROOT / relative
    if not path.is_file():
        fail(f"missing required JSON file: {relative}")
    try:
        return json.loads(path.read_text(encoding="utf-8"))
    except (OSError, json.JSONDecodeError) as error:
        fail(f"invalid JSON in {relative}: {error}")


def safetensors_header(path: Path) -> dict:
    with path.open("rb") as handle:
        raw_length = handle.read(8)
        if len(raw_length) != 8:
            fail(f"truncated safetensors length: {path.name}")
        header_length = struct.unpack("<Q", raw_length)[0]
        if header_length <= 2 or header_length > path.stat().st_size - 8:
            fail(f"invalid safetensors header length: {path.name}")
        try:
            return json.loads(handle.read(header_length))
        except json.JSONDecodeError as error:
            fail(f"invalid safetensors header in {path.name}: {error}")


def validate_metadata() -> dict:
    config = load_json("config.json")
    policy = config.get("fish_s2_quantization")
    if not isinstance(policy, dict):
        fail("config.json has no fish_s2_quantization dictionary")
    expected = {
        "format": "mixed_nvfp4_mxfp8",
        "profile": "balanced",
        "release": "v1",
        "policy": "w4a16_gate_up_middle30_mxfp8_rest",
        "nvfp4_modules": 60,
        "mxfp8_modules": 120,
        "runtime": "bundled",
        "hardware_family": "sm_120",
    }
    if policy != expected:
        fail(f"unexpected config quantization policy: {policy}")

    quantization = load_json("quantization.json")
    if quantization.get("format") != "fish-s2-pro-project-local-nvfp4-mixed":
        fail("unexpected quantization format")
    if quantization.get("policy") != "w4a16_gate_up_middle30_mxfp8_rest":
        fail("unexpected quantization policy")
    release = quantization.get("release", {})
    if release.get("version") != "1.0" or release.get("xpo3_release") is not False:
        fail("release must identify V1 and explicitly remain outside XPO3")
    if release.get("repository_name") != "ajh-code/Fish-Audio-S2-Pro-NVFP4-Balanced":
        fail("release metadata has the wrong Hugging Face repository name")
    if release.get("self_contained_weights") is not True:
        fail("release does not declare self-contained weights")
    fresh_load = quantization.get("fresh_load_verification", {})
    if fresh_load.get("status") != "passed":
        fail("checkpoint lacks passed fresh-load verification")
    conversion = quantization.get("conversion", {})
    if len(conversion.get("records", [])) != 180:
        fail("quantization metadata must contain 180 projection records")
    if conversion.get("correction_parameters") != 0:
        fail("V1 loader does not accept correction-bearing checkpoints")
    if conversion.get("w4a16_max_m") != 1:
        fail("V1 must use the qualified M=1 W4A16 decode boundary")

    source = (ROOT / ".source").read_text(encoding="utf-8")
    for revision in (
        "1de9996b6be38b745688de084d87a5633f714e4e",
        "e5e292632cb11e7a27b2b7487f58f612bc101e13",
        "a04c1b63b1a7a670840fb3e97a82c0dbe2a35ded",
        "7a03467b90d6feff6bd196928dfe156bd173f36e",
    ):
        if revision not in source:
            fail(f".source is missing pinned revision {revision}")

    license_text = (ROOT / "LICENSE.md").read_text(encoding="utf-8")
    if "FISH AUDIO RESEARCH LICENSE AGREEMENT" not in license_text:
        fail("LICENSE.md is not the Fish Audio Research License")
    notice = (ROOT / "Notice").read_text(encoding="utf-8")
    if "This model is licensed under the Fish Audio Research License" not in notice:
        fail("Notice lacks the required Fish Audio attribution")
    if "Built with Fish Audio" not in notice:
        fail("Notice lacks the required Built with Fish Audio statement")
    readme = (ROOT / "README.md").read_text(encoding="utf-8")
    for required in (
        "Built with Fish Audio",
        "This is not yet an XPO3 release",
        "Commercial use requires a separate",
    ):
        if required not in readme:
            fail(f"README.md lacks required release statement: {required}")
    return quantization


def validate_checkpoint(quantization: dict) -> tuple[int, int, int]:
    index = load_json("model.safetensors.index.json")
    weight_map = index.get("weight_map")
    if not isinstance(weight_map, dict) or not weight_map:
        fail("checkpoint index has no weight map")
    shard_names = sorted(set(weight_map.values()))
    if shard_names != [
        "model-00001-of-00003.safetensors",
        "model-00002-of-00003.safetensors",
        "model-00003-of-00003.safetensors",
    ]:
        fail(f"unexpected checkpoint shards: {shard_names}")

    discovered: dict[str, str] = {}
    logical_bytes = 0
    for shard_name in shard_names:
        shard_path = ROOT / shard_name
        if not shard_path.is_file():
            fail(f"missing checkpoint shard: {shard_name}")
        header = safetensors_header(shard_path)
        for name, record in header.items():
            if name == "__metadata__":
                continue
            if name in discovered:
                fail(f"duplicate tensor across shards: {name}")
            dtype = record.get("dtype")
            shape = record.get("shape")
            offsets = record.get("data_offsets")
            if dtype not in DTYPE_BYTES or not isinstance(shape, list):
                fail(f"unsupported tensor metadata for {name}")
            if (
                not isinstance(offsets, list)
                or len(offsets) != 2
                or not all(isinstance(value, int) for value in offsets)
                or offsets[0] < 0
                or offsets[1] < offsets[0]
            ):
                fail(f"invalid data offsets for {name}")
            elements = 1
            for dimension in shape:
                if not isinstance(dimension, int) or dimension < 0:
                    fail(f"invalid shape for {name}")
                elements *= dimension
            tensor_bytes = elements * DTYPE_BYTES[dtype]
            if offsets[1] - offsets[0] != tensor_bytes:
                fail(f"tensor byte range mismatch for {name}")
            logical_bytes += tensor_bytes
            discovered[name] = shard_name

    if discovered != weight_map:
        missing = sorted(set(weight_map) - set(discovered))
        extra = sorted(set(discovered) - set(weight_map))
        fail(f"checkpoint index mismatch; missing={missing[:3]} extra={extra[:3]}")
    expected_size = int(index.get("metadata", {}).get("total_size", -1))
    if logical_bytes != expected_size:
        fail(f"logical checkpoint size mismatch: {logical_bytes} != {expected_size}")
    if logical_bytes != quantization.get("state_payload_bytes"):
        fail("quantization state_payload_bytes does not match the checkpoint")

    counts = {
        "qdata": sum(name.endswith(".qdata") for name in weight_map),
        "weight_block_scale": sum(
            name.endswith(".weight_block_scale") for name in weight_map
        ),
        "weight_scale": sum(name.endswith(".weight_scale") for name in weight_map),
        "weight_fp8": sum(name.endswith(".weight_fp8") for name in weight_map),
        "weight_scale_storage": sum(
            name.endswith(".weight_scale_storage") for name in weight_map
        ),
    }
    if counts != {
        "qdata": 60,
        "weight_block_scale": 60,
        "weight_scale": 60,
        "weight_fp8": 120,
        "weight_scale_storage": 120,
    }:
        fail(f"unexpected packed tensor counts: {counts}")
    if counts != quantization.get("packed_tensor_counts"):
        fail("packed tensor counts disagree with quantization.json")
    return len(weight_map), len(shard_names), logical_bytes


def validate_runtime() -> None:
    required = (
        "codec.pth",
        "client.py",
        "launch.sh",
        "install.sh",
        "Dockerfile",
        "compose.yaml",
        "runtime/server.py",
        "runtime/web/index.html",
        "runtime/experimental/codec.py",
        "runtime/experimental/nvfp4/checkpoint.py",
        "runtime/experimental/nvfp4/modules.py",
        "runtime/experimental/fp8/modules.py",
        "runtime/native/smallm_gemv/smallm_gemv.cpp",
        "runtime/native/smallm_gemv/smallm_gemv.cu",
        "runtime/native/smallm_gemv/smallm_gemv.h",
        "runtime/native/LICENSE",
        "vendor/fish-speech/.project-root",
        "vendor/fish-speech/LICENSE",
        "vendor/fish-speech/pyproject.toml",
        "vendor/fish-speech/fish_speech/configs/modded_dac_vq.yaml",
        "vendor/fish-speech/tools/api_server.py",
    )
    for relative in required:
        if not (ROOT / relative).is_file():
            fail(f"missing required release file: {relative}")


def validate_manifest() -> int:
    manifest = load_json("MANIFEST.json")
    records = manifest.get("files")
    if not isinstance(records, list) or not records:
        fail("MANIFEST.json has no file records")
    seen: set[str] = set()
    for record in records:
        relative = record.get("path")
        if not isinstance(relative, str):
            fail("manifest record has no path")
        pure = PurePosixPath(relative)
        if pure.is_absolute() or ".." in pure.parts or relative == "MANIFEST.json":
            fail(f"unsafe or recursive manifest path: {relative}")
        if relative in seen:
            fail(f"duplicate manifest path: {relative}")
        seen.add(relative)
        path = ROOT.joinpath(*pure.parts)
        if not path.is_file():
            fail(f"manifest file is missing: {relative}")
        if path.stat().st_size != record.get("size"):
            fail(f"manifest size mismatch: {relative}")
        if sha256(path) != record.get("sha256"):
            fail(f"manifest hash mismatch: {relative}")
    return len(records)


def main() -> None:
    quantization = validate_metadata()
    checkpoint_tensors, checkpoint_shards, logical_bytes = validate_checkpoint(
        quantization
    )
    validate_runtime()
    manifest_files = validate_manifest()
    print(
        json.dumps(
            {
                "status": "pass",
                "release": "v1",
                "xpo3_release": False,
                "checkpoint_tensors": checkpoint_tensors,
                "checkpoint_shards": checkpoint_shards,
                "checkpoint_logical_bytes": logical_bytes,
                "nvfp4_projections": 60,
                "mxfp8_projections": 120,
                "manifest_files": manifest_files,
                "self_contained_weights": True,
            },
            indent=2,
        )
    )


if __name__ == "__main__":
    main()