"""Standalone loader for project-local mixed NVFP4/MXFP8 S2-Pro checkpoints.""" from __future__ import annotations import hashlib import json from pathlib import Path from typing import Any import torch from safetensors.torch import load_file from fish_speech.models.text2semantic.llama import ( BaseModelArgs, DualARTransformer, precompute_freqs_cis, ) from fish_speech.tokenizer import FishTokenizer from experimental.fp8 import MXFP8Linear from .modules import NVFP4Linear CHECKPOINT_FORMAT = "fish-s2-pro-project-local-nvfp4-mixed" def _sha256(path: Path) -> str: digest = hashlib.sha256() with path.open("rb") as handle: while chunk := handle.read(8 * 1024 * 1024): digest.update(chunk) return digest.hexdigest() def _install_empty_projection( model: DualARTransformer, record: dict[str, Any], *, w4a16_max_m: int, ) -> None: name = str(record["name"]) in_features = int(record["in_features"]) out_features = int(record["out_features"]) precision = str(record["precision"]) original = model.get_submodule(name) if not isinstance(original, torch.nn.Linear): raise TypeError(f"Expected an unmodified Linear at {name}, got {type(original)}") if (original.in_features, original.out_features) != (in_features, out_features): raise ValueError(f"Checkpoint shape metadata does not match config at {name}") if precision.startswith("nvfp4_w4a16_through_m"): unsupported = ( "low_rank_corrected", "sparse_channel_corrected", "hadamard", ) if any(marker in precision for marker in unsupported): raise ValueError( f"This standalone loader does not support corrected/rotated NVFP4: {name}" ) replacement: torch.nn.Module = NVFP4Linear( torch.empty( out_features, in_features // 2, dtype=torch.uint8, device="meta", ), torch.empty( out_features, in_features // 16, dtype=torch.float8_e4m3fn, device="meta", ), torch.empty((), dtype=torch.float32, device="meta"), in_features=in_features, out_features=out_features, w4a16_max_m=w4a16_max_m, ) elif precision == "mxfp8_w8a8": replacement = MXFP8Linear( torch.empty( out_features, in_features, dtype=torch.float8_e4m3fn, device="meta", ), torch.empty( in_features // 128, out_features, dtype=torch.int32, device="meta", ), in_features=in_features, out_features=out_features, ) else: raise ValueError(f"Unsupported precision record for {name}: {precision}") parent_name, attribute = name.rsplit(".", 1) setattr(model.get_submodule(parent_name), attribute, replacement) @torch.inference_mode() def load_mixed_nvfp4_checkpoint( path: str | Path, *, device: str | torch.device = "cuda:0", max_length: int = 3072, verify_checksums: bool = False, ) -> DualARTransformer: """Load a mixed checkpoint without materializing its BF16 source projections.""" path = Path(path) metadata = json.loads((path / "quantization.json").read_text()) if metadata.get("format") != CHECKPOINT_FORMAT: raise ValueError(f"Unsupported checkpoint format: {metadata.get('format')}") device = torch.device(device) if device.type != "cuda" or torch.cuda.get_device_capability(device)[0] != 12: raise RuntimeError("This mixed NVFP4/MXFP8 artifact currently requires sm_120") if verify_checksums: for filename, record in metadata["checksums"].items(): file_path = path / filename if file_path.stat().st_size != int(record["bytes"]): raise RuntimeError(f"Size mismatch for {filename}") if _sha256(file_path) != record["sha256"]: raise RuntimeError(f"SHA256 mismatch for {filename}") conversion = metadata["conversion"] records = conversion["records"] if len(records) != 180: raise ValueError(f"Expected 180 mixed projection records, found {len(records)}") if int(conversion["correction_parameters"]) != 0: raise ValueError("This loader intentionally rejects correction-bearing artifacts") config = BaseModelArgs.from_pretrained(str(path)) config.max_seq_len = max_length with torch.device("meta"): model = DualARTransformer(config) model.tokenizer = FishTokenizer.from_pretrained(path) for record in records: _install_empty_projection( model, record, w4a16_max_m=int(conversion["w4a16_max_m"]), ) index_path = path / "model.safetensors.index.json" if index_path.is_file(): index = json.loads(index_path.read_text()) shard_names = sorted(set(index["weight_map"].values())) else: shard_names = ["model.safetensors"] expected_keys = set(model.state_dict()) loaded_keys: set[str] = set() for shard_name in shard_names: shard = load_file(path / shard_name, device="cpu") unexpected = set(shard) - expected_keys if unexpected: raise RuntimeError( f"Unexpected checkpoint tensors in {shard_name}: {sorted(unexpected)[:5]}" ) model.load_state_dict(shard, strict=False, assign=True) loaded_keys.update(shard) missing = expected_keys - loaded_keys if missing: raise RuntimeError(f"Missing checkpoint tensors: {sorted(missing)[:5]}") # These buffers are non-persistent, so reconstruct them after the meta load. model.freqs_cis = precompute_freqs_cis( config.max_seq_len, config.head_dim, config.rope_base, ) model.causal_mask = torch.tril( torch.ones(config.max_seq_len, config.max_seq_len, dtype=torch.bool) ) model.fast_freqs_cis = precompute_freqs_cis( config.num_codebooks, config.fast_head_dim, config.rope_base, ) model = model.to(device=device).eval() sampling = metadata.get("qualified_sampling", {}) model.fixed_temperature = torch.tensor( sampling.get("temperature", 1.0), device=device, dtype=torch.float ) model.fixed_top_p = torch.tensor( sampling.get("top_p", 0.85), device=device, dtype=torch.float ) model.fixed_repetition_penalty = torch.tensor(1.5, device=device, dtype=torch.float) model._cache_setup_done = False nvfp4_count = sum(isinstance(module, NVFP4Linear) for module in model.modules()) mxfp8_count = sum(isinstance(module, MXFP8Linear) for module in model.modules()) if (nvfp4_count, mxfp8_count) != (60, 120): raise RuntimeError( f"Expected 60 NVFP4 and 120 MXFP8 modules, got {nvfp4_count}/{mxfp8_count}" ) meta_tensors = [ name for name, tensor in model.state_dict().items() if tensor.device.type == "meta" ] if meta_tensors: raise RuntimeError(f"Checkpoint left meta tensors: {meta_tensors[:5]}") return model