Download src/export_to_rada.py from YSamchuk/Hetman-2b: direct link, hf CLI and curl.
- Browser
- Download file 33.2 kB
-
https://huggingface.co/YSamchuk/Hetman-2b/resolve/main/src/export_to_rada.py
- Command line
-
hf download hf://YSamchuk/Hetman-2b/src/export_to_rada.py
-
curl -L -o export_to_rada.py https://huggingface.co/YSamchuk/Hetman-2b/resolve/main/src/export_to_rada.py
33.2 kB
| """ | |
| Hetman-2-NCM 2.0B: Production Export Engine for Rada.cpp | |
| File: src/export_to_rada.py | |
| License: Apache License 2.0 | |
| Specification: RFC-RADA-NCM-2.0-EDGE-AUDIT / spec/09_EDGE_RUNTIME_RADA_CPP_AND_MEMORY_AUDIT.md | |
| Target Binary Format: .rada / .rncm Container v2 | |
| AUDIT-16 REVISIONS & OPTIMIZATIONS: | |
| 1. Strict 64-byte alignment using bitwise integer arithmetic ((x + 63) & ~63). | |
| 2. Two-tier hierarchical CRC32 checksums: | |
| - Header CRC32 (104B payload integrity) | |
| - Table CRC32 (all tensor descriptors integrity) | |
| - Per-tensor payload CRC32 (stored in descriptor.crc32) | |
| Enables instant zero-allocation mmap startup in Rada.cpp without reading full weights to RAM! | |
| 3. Robust backward-compatibility and safe 8-byte probing to prevent Segfaults on v1 (TH1) containers. | |
| 4. Direct zero-duplicate streaming tensor writer (payloads list in RAM completely removed). | |
| 5. Fully vectorized BitNet b1.58 2-bit packing without Python tolist() overhead. | |
| """ | |
| import argparse | |
| import os | |
| import struct | |
| import zlib | |
| from dataclasses import dataclass | |
| from typing import Any, Dict, List, Optional, Tuple, Union | |
| import numpy as np | |
| import torch | |
| import torch.nn as nn | |
| import sys | |
| from pathlib import Path | |
| _ROOT = str(Path(__file__).resolve().parent.parent) | |
| if _ROOT not in sys.path: | |
| sys.path.insert(0, _ROOT) | |
| from src.model import Hetman2Config, Hetman2ForCausalLM | |
| # ============================================================================== | |
| # 1. ARCHITECTURAL BINARY CONSTANTS | |
| # ============================================================================== | |
| RADA_NCM_MAGIC: int = 0x4D434E52 # "RNCM" in little-endian (b"RNCM"[::-1]) | |
| RADA_LEGACY_MAGIC: int = 0x41444152 # "RADA" in little-endian (legacy Hetman-1) | |
| RADA_VERSION: int = 2 | |
| CACHE_LINE_ALIGNMENT: int = 64 | |
| # Container feature flags | |
| RADA_FLAG_NONE: int = 0x00000000 | |
| RADA_FLAG_CRC32_ENABLED: int = 0x00000001 | |
| RADA_FLAG_TIED_LM_HEAD: int = 0x00000002 | |
| # Datatype identifiers for tensor descriptors | |
| DTYPE_TERNARY_2BIT: int = 1 | |
| DTYPE_BF16: int = 2 | |
| DTYPE_FP16: int = 3 | |
| DTYPE_FP32: int = 4 | |
| DTYPE_INT8: int = 5 | |
| DTYPE_UINT8: int = 6 | |
| # Header format: 18 uint32, 4 uint64, 3 uint32 (crcs + flags), 12 bytes pad = 128 bytes | |
| HEADER_STRUCT_FMT: str = "<18I4Q3I12s" | |
| HEADER_SIZE_BYTES: int = 128 | |
| # Tensor descriptor format: 64s name, uint32 dtype, uint32 n_dims, 4 uint64 dims, | |
| # uint64 offset, uint64 size_bytes, float32 scale_gamma, uint32 crc32 = 128 bytes | |
| TENSOR_DESC_FMT: str = "<64sII4QQQfI" | |
| TENSOR_DESC_SIZE_BYTES: int = 128 | |
| # ============================================================================== | |
| # 2. FILE HEADER & DESCRIPTOR STRUCTURES | |
| # ============================================================================== | |
| class RadaNcmFileHeader: | |
| """ | |
| Rada.cpp v2 Binary Container Header. | |
| Strictly aligns to 128 bytes (2 cache lines of 64 bytes). | |
| Integrates Hierarchical CRC32 metadata and container flags. | |
| """ | |
| magic: int = RADA_NCM_MAGIC | |
| version: int = RADA_VERSION | |
| vocab_size: int = 65536 | |
| hidden_size: int = 1536 | |
| intermediate_size: int = 6144 | |
| num_layers: int = 34 | |
| num_deltanet_layers: int = 28 | |
| num_global_layers: int = 6 | |
| deltanet_heads: int = 16 | |
| deltanet_head_dim: int = 64 | |
| global_heads_q: int = 12 | |
| global_heads_kv: int = 2 | |
| global_head_dim: int = 128 | |
| hopfield_groups: int = 16 | |
| hopfield_codebook_size: int = 1024 | |
| hopfield_val_dim: int = 32 | |
| tokens_per_block: int = 400 | |
| max_blocks: int = 8 | |
| tensor_table_offset: int = 128 | |
| tensor_data_offset: int = 0 | |
| bpe_vocab_offset: int = 0 | |
| bpe_vocab_size_bytes: int = 0 | |
| header_crc32: int = 0 | |
| table_crc32: int = 0 | |
| flags: int = RADA_FLAG_CRC32_ENABLED | |
| padding: bytes = b"\x00" * 12 | |
| def to_bytes(self) -> bytes: | |
| pad = self.padding[:12].ljust(12, b"\x00") | |
| packed = struct.pack( | |
| HEADER_STRUCT_FMT, | |
| self.magic, | |
| self.version, | |
| self.vocab_size, | |
| self.hidden_size, | |
| self.intermediate_size, | |
| self.num_layers, | |
| self.num_deltanet_layers, | |
| self.num_global_layers, | |
| self.deltanet_heads, | |
| self.deltanet_head_dim, | |
| self.global_heads_q, | |
| self.global_heads_kv, | |
| self.global_head_dim, | |
| self.hopfield_groups, | |
| self.hopfield_codebook_size, | |
| self.hopfield_val_dim, | |
| self.tokens_per_block, | |
| self.max_blocks, | |
| self.tensor_table_offset, | |
| self.tensor_data_offset, | |
| self.bpe_vocab_offset, | |
| self.bpe_vocab_size_bytes, | |
| self.header_crc32, | |
| self.table_crc32, | |
| self.flags, | |
| pad | |
| ) | |
| assert len(packed) == HEADER_SIZE_BYTES, f"Header size must be {HEADER_SIZE_BYTES} bytes!" | |
| return packed | |
| def from_bytes(cls, data: bytes) -> "RadaNcmFileHeader": | |
| if len(data) < HEADER_SIZE_BYTES: | |
| raise ValueError(f"Data buffer too small for header: {len(data)} < {HEADER_SIZE_BYTES}") | |
| fields = struct.unpack(HEADER_STRUCT_FMT, data[:HEADER_SIZE_BYTES]) | |
| return cls( | |
| magic=fields[0], | |
| version=fields[1], | |
| vocab_size=fields[2], | |
| hidden_size=fields[3], | |
| intermediate_size=fields[4], | |
| num_layers=fields[5], | |
| num_deltanet_layers=fields[6], | |
| num_global_layers=fields[7], | |
| deltanet_heads=fields[8], | |
| deltanet_head_dim=fields[9], | |
| global_heads_q=fields[10], | |
| global_heads_kv=fields[11], | |
| global_head_dim=fields[12], | |
| hopfield_groups=fields[13], | |
| hopfield_codebook_size=fields[14], | |
| hopfield_val_dim=fields[15], | |
| tokens_per_block=fields[16], | |
| max_blocks=fields[17], | |
| tensor_table_offset=fields[18], | |
| tensor_data_offset=fields[19], | |
| bpe_vocab_offset=fields[20], | |
| bpe_vocab_size_bytes=fields[21], | |
| header_crc32=fields[22], | |
| table_crc32=fields[23], | |
| flags=fields[24], | |
| padding=fields[25] | |
| ) | |
| class RadaTensorDescriptor: | |
| """ | |
| Rada.cpp Tensor Descriptor Struct (128 bytes). | |
| Contains full geometry, quantization metadata, cache-line aligned offset, | |
| and per-tensor CRC32 for zero-copy on-demand integrity verification. | |
| """ | |
| name: str | |
| dtype: int | |
| shape: Tuple[int, ...] | |
| offset: int | |
| size_bytes: int | |
| scale_gamma: float = 1.0 | |
| crc32: int = 0 | |
| def to_bytes(self) -> bytes: | |
| name_bytes = self.name.encode("utf-8")[:63].ljust(64, b"\x00") | |
| dims = list(self.shape) + [0] * (4 - len(self.shape)) | |
| packed = struct.pack( | |
| TENSOR_DESC_FMT, | |
| name_bytes, | |
| self.dtype, | |
| len(self.shape), | |
| dims[0], dims[1], dims[2], dims[3], | |
| self.offset, | |
| self.size_bytes, | |
| self.scale_gamma, | |
| self.crc32 | |
| ) | |
| assert len(packed) == TENSOR_DESC_SIZE_BYTES, f"Tensor descriptor size must be {TENSOR_DESC_SIZE_BYTES} bytes!" | |
| return packed | |
| def from_bytes(cls, data: bytes) -> "RadaTensorDescriptor": | |
| if len(data) < TENSOR_DESC_SIZE_BYTES: | |
| raise ValueError(f"Descriptor buffer too small: {len(data)} < {TENSOR_DESC_SIZE_BYTES}") | |
| fields = struct.unpack(TENSOR_DESC_FMT, data[:TENSOR_DESC_SIZE_BYTES]) | |
| raw_name = fields[0].split(b"\x00", 1)[0].decode("utf-8", errors="replace") | |
| n_dims = fields[2] | |
| dims = tuple(fields[3:3 + n_dims]) | |
| return cls( | |
| name=raw_name, | |
| dtype=fields[1], | |
| shape=dims, | |
| offset=fields[7], | |
| size_bytes=fields[8], | |
| scale_gamma=fields[9], | |
| crc32=fields[10] | |
| ) | |
| # ============================================================================== | |
| # 3. BITWISE ALIGNMENT & BITNET B1.58 TERNARY PACKING | |
| # ============================================================================== | |
| def align_to_boundary(value: int, alignment: int = CACHE_LINE_ALIGNMENT) -> int: | |
| """ | |
| Rounds up value to the nearest multiple of alignment. | |
| Strictly bitwise integer implementation without floating-point division. | |
| """ | |
| if alignment <= 0: | |
| return value | |
| if (alignment & (alignment - 1)) == 0: | |
| return (value + alignment - 1) & ~(alignment - 1) | |
| return ((value + alignment - 1) // alignment) * alignment | |
| def quantize_absmean_ternary(w: torch.Tensor, eps: float = 1e-6) -> Tuple[torch.Tensor, float]: | |
| """ | |
| Applies BitNet b1.58 Absmean quantization: | |
| gamma = max(mean(|W|), eps) | |
| W_tilde = clamp(round(W / gamma), -1, +1) | |
| """ | |
| w_float = w.detach().to(torch.float32) | |
| gamma = float(torch.mean(torch.abs(w_float)).item()) | |
| gamma = max(gamma, eps) | |
| scaled_w = w_float / gamma | |
| w_quant = torch.clamp(torch.round(scaled_w), -1.0, 1.0).to(torch.int8) | |
| return w_quant, gamma | |
| def pack_ternary_weights( | |
| weight: torch.Tensor, | |
| align_row_bytes: int = CACHE_LINE_ALIGNMENT | |
| ) -> Tuple[bytes, float, Tuple[int, ...]]: | |
| """ | |
| Packs ternary weights {-1, 0, +1} into 2-bit values (4 weights per byte): | |
| 00_2 -> 0 | |
| 01_2 -> +1 | |
| 10_2 -> -1 | |
| 11_2 -> 0 (reserved / padding) | |
| For 2D matrices [Rows, Cols], every row starts on an align_row_bytes boundary: | |
| Row_Stride_Bytes = align_to_boundary((Cols + 3) // 4, align_row_bytes) | |
| Vectorized implementation: zero Python tolist() overhead. | |
| """ | |
| orig_shape = tuple(weight.shape) | |
| w_quant, gamma = quantize_absmean_ternary(weight) | |
| if len(orig_shape) == 2: | |
| rows, cols = orig_shape | |
| row_unpadded_bytes = (cols + 3) // 4 | |
| row_stride = align_to_boundary(row_unpadded_bytes, align_row_bytes) | |
| # Vectorized bit-encoding | |
| codes = torch.zeros((rows, cols), dtype=torch.uint8, device=w_quant.device) | |
| codes[w_quant == 1] = 1 | |
| codes[w_quant == -1] = 2 | |
| pad_cols = (4 - (cols % 4)) % 4 | |
| if pad_cols > 0: | |
| codes = torch.nn.functional.pad(codes, (0, pad_cols), mode="constant", value=0) | |
| c = codes.view(rows, -1, 4) | |
| b = (c[:, :, 0] | (c[:, :, 1] << 2) | (c[:, :, 2] << 4) | (c[:, :, 3] << 6)).cpu().numpy() | |
| if row_stride == b.shape[1]: | |
| packed_bytes = b.tobytes() | |
| else: | |
| padded_mat = np.zeros((rows, row_stride), dtype=np.uint8) | |
| padded_mat[:, :b.shape[1]] = b | |
| packed_bytes = padded_mat.tobytes() | |
| return packed_bytes, gamma, orig_shape | |
| else: | |
| # 1D or higher dimension: flatten across non-trailing dims | |
| w_flat = w_quant.view(-1) | |
| total_elements = w_flat.numel() | |
| codes = torch.zeros(total_elements, dtype=torch.uint8, device=w_quant.device) | |
| codes[w_flat == 1] = 1 | |
| codes[w_flat == -1] = 2 | |
| pad_len = (4 - (total_elements % 4)) % 4 | |
| if pad_len > 0: | |
| codes = torch.nn.functional.pad(codes, (0, pad_len), mode="constant", value=0) | |
| c = codes.view(-1, 4) | |
| b = (c[:, 0] | (c[:, 1] << 2) | (c[:, 2] << 4) | (c[:, 3] << 6)).cpu().numpy() | |
| raw_bytes = b.tobytes() | |
| aligned_len = align_to_boundary(len(raw_bytes), align_row_bytes) | |
| padded_bytes = raw_bytes.ljust(aligned_len, b"\x00") | |
| return padded_bytes, gamma, orig_shape | |
| def unpack_ternary_weights( | |
| packed_bytes: bytes, | |
| shape: Tuple[int, ...], | |
| scale_gamma: float = 1.0, | |
| align_row_bytes: int = CACHE_LINE_ALIGNMENT | |
| ) -> torch.Tensor: | |
| """ | |
| Vectorized unpack of 2-bit packed bytes back into float32 ternary tensor. | |
| """ | |
| if len(shape) == 2: | |
| rows, cols = shape | |
| row_unpadded_bytes = (cols + 3) // 4 | |
| row_stride = align_to_boundary(row_unpadded_bytes, align_row_bytes) | |
| arr = np.frombuffer(packed_bytes, dtype=np.uint8).copy().reshape(rows, row_stride) | |
| arr_valid = np.ascontiguousarray(arr[:, :row_unpadded_bytes]) | |
| p = torch.from_numpy(arr_valid) | |
| c0 = p & 0x03 | |
| c1 = (p >> 2) & 0x03 | |
| c2 = (p >> 4) & 0x03 | |
| c3 = (p >> 6) & 0x03 | |
| u0 = torch.where(c0 == 1, 1.0, torch.where(c0 == 2, -1.0, 0.0)) | |
| u1 = torch.where(c1 == 1, 1.0, torch.where(c1 == 2, -1.0, 0.0)) | |
| u2 = torch.where(c2 == 1, 1.0, torch.where(c2 == 2, -1.0, 0.0)) | |
| u3 = torch.where(c3 == 1, 1.0, torch.where(c3 == 2, -1.0, 0.0)) | |
| u = torch.stack([u0, u1, u2, u3], dim=-1).view(rows, -1)[:, :cols] | |
| return (u * scale_gamma).to(torch.float32) | |
| else: | |
| total_elements = 1 | |
| for d in shape: | |
| total_elements *= d | |
| num_bytes = (total_elements + 3) // 4 | |
| p = torch.from_numpy(np.frombuffer(packed_bytes[:num_bytes], dtype=np.uint8).copy()) | |
| c0 = p & 0x03 | |
| c1 = (p >> 2) & 0x03 | |
| c2 = (p >> 4) & 0x03 | |
| c3 = (p >> 6) & 0x03 | |
| u0 = torch.where(c0 == 1, 1.0, torch.where(c0 == 2, -1.0, 0.0)) | |
| u1 = torch.where(c1 == 1, 1.0, torch.where(c1 == 2, -1.0, 0.0)) | |
| u2 = torch.where(c2 == 1, 1.0, torch.where(c2 == 2, -1.0, 0.0)) | |
| u3 = torch.where(c3 == 1, 1.0, torch.where(c3 == 2, -1.0, 0.0)) | |
| u = torch.stack([u0, u1, u2, u3], dim=-1).view(-1)[:total_elements] | |
| return (u * scale_gamma).view(shape).to(torch.float32) | |
| # ============================================================================== | |
| # 4. TENSOR QUANTIZATION & SERIALIZATION | |
| # ============================================================================== | |
| def is_ternary_candidate(name: str, tensor: torch.Tensor) -> bool: | |
| """ | |
| Identifies whether a parameter tensor belongs to the BitNet b1.58 ternary fabric. | |
| Linear projections, SwiGLU FFNs, Arbiter weights, and Stem projections are ternary. | |
| Embeddings, Hopfield codebooks, and LayerNorm/RMSNorm scales remain non-ternary. | |
| """ | |
| if tensor.ndim < 2: | |
| return False | |
| lower = name.lower() | |
| if "embed" in lower: | |
| return False | |
| if "codebook" in lower or "hopfield_c" in lower: | |
| return False | |
| if "norm" in lower or "bias" in lower: | |
| return False | |
| return True | |
| def serialize_tensor_payload( | |
| name: str, | |
| tensor: torch.Tensor, | |
| force_ternary: Optional[bool] = None | |
| ) -> Tuple[bytes, int, float, Tuple[int, ...]]: | |
| """ | |
| Serializes a single tensor into its 64-byte aligned payload buffer. | |
| Returns: | |
| (payload_bytes, dtype_enum, scale_gamma, original_shape) | |
| """ | |
| shape = tuple(tensor.shape) | |
| make_ternary = is_ternary_candidate(name, tensor) if force_ternary is None else force_ternary | |
| if make_ternary: | |
| packed_bytes, gamma, _ = pack_ternary_weights(tensor, align_row_bytes=CACHE_LINE_ALIGNMENT) | |
| aligned_size = align_to_boundary(len(packed_bytes), CACHE_LINE_ALIGNMENT) | |
| return packed_bytes.ljust(aligned_size, b"\x00"), DTYPE_TERNARY_2BIT, gamma, shape | |
| # Non-ternary branches | |
| lower = name.lower() | |
| if "embed" in lower: | |
| try: | |
| raw_data = tensor.detach().to(torch.bfloat16).contiguous().cpu().numpy().tobytes() | |
| dtype_code = DTYPE_BF16 | |
| except Exception: | |
| raw_data = tensor.detach().to(torch.float16).contiguous().cpu().numpy().tobytes() | |
| dtype_code = DTYPE_FP16 | |
| elif "codebook" in lower: | |
| raw_data = tensor.detach().to(torch.float16).contiguous().cpu().numpy().tobytes() | |
| dtype_code = DTYPE_FP16 | |
| else: | |
| raw_data = tensor.detach().to(torch.float32).contiguous().cpu().numpy().tobytes() | |
| dtype_code = DTYPE_FP32 | |
| aligned_size = align_to_boundary(len(raw_data), CACHE_LINE_ALIGNMENT) | |
| payload = raw_data.ljust(aligned_size, b"\x00") | |
| return payload, dtype_code, 1.0, shape | |
| # ============================================================================== | |
| # 5. STREAMING PRODUCTION EXPORT ENGINE (RADA EXPORTER) | |
| # ============================================================================== | |
| class RadaExporter: | |
| """ | |
| Production exporter for Hetman-2-NCM to Rada.cpp binary container format (.rada / .rncm). | |
| Features: | |
| - Zero intermediate payload accumulation (direct file streaming). | |
| - Strict 64-byte alignment across all container sections. | |
| - Two-tier hierarchical CRC32 generation for instant mmap verification. | |
| """ | |
| def __init__(self, config: Optional[Hetman2Config] = None): | |
| self.config = config or Hetman2Config() | |
| def create_header(self, num_tensors: int, tensor_table_offset: int) -> RadaNcmFileHeader: | |
| cfg = self.config | |
| return RadaNcmFileHeader( | |
| magic=RADA_NCM_MAGIC, | |
| version=RADA_VERSION, | |
| vocab_size=cfg.vocab_size, | |
| hidden_size=cfg.hidden_size, | |
| intermediate_size=cfg.intermediate_size, | |
| num_layers=cfg.num_layers, | |
| num_deltanet_layers=cfg.num_deltanet_layers, | |
| num_global_layers=cfg.num_global_layers, | |
| deltanet_heads=cfg.deltanet_heads, | |
| deltanet_head_dim=cfg.deltanet_head_dim, | |
| global_heads_q=cfg.global_heads_q, | |
| global_heads_kv=cfg.global_heads_kv, | |
| global_head_dim=cfg.global_head_dim, | |
| hopfield_groups=cfg.hopfield_groups, | |
| hopfield_codebook_size=cfg.hopfield_codebook_size, | |
| hopfield_val_dim=cfg.hopfield_val_dim, | |
| tokens_per_block=cfg.tokens_per_block, | |
| max_blocks=cfg.max_blocks, | |
| tensor_table_offset=tensor_table_offset, | |
| tensor_data_offset=0, | |
| bpe_vocab_offset=0, | |
| bpe_vocab_size_bytes=0, | |
| header_crc32=0, | |
| table_crc32=0, | |
| flags=RADA_FLAG_CRC32_ENABLED, | |
| padding=b"\x00" * 12 | |
| ) | |
| def export( | |
| self, | |
| model_or_state_dict: Union[nn.Module, Dict[str, torch.Tensor]], | |
| output_path: str, | |
| vocab_bytes: Optional[bytes] = None | |
| ) -> Dict[str, Any]: | |
| """ | |
| Exports state dict to .rada file with 64-byte alignment, CRC32, | |
| and ZERO memory duplication via streaming directly to disk. | |
| """ | |
| if isinstance(model_or_state_dict, nn.Module): | |
| state_dict = model_or_state_dict.state_dict() | |
| elif isinstance(model_or_state_dict, dict): | |
| state_dict = model_or_state_dict | |
| else: | |
| raise TypeError("model_or_state_dict must be nn.Module or dict") | |
| os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True) | |
| num_tensors = len(state_dict) | |
| tensor_table_offset = HEADER_SIZE_BYTES # 128 bytes (strictly 64B aligned) | |
| tensor_table_raw_size = 8 + num_tensors * TENSOR_DESC_SIZE_BYTES | |
| tensor_table_aligned_size = align_to_boundary(tensor_table_raw_size, CACHE_LINE_ALIGNMENT) | |
| tensor_data_offset = tensor_table_offset + tensor_table_aligned_size | |
| assert tensor_data_offset % CACHE_LINE_ALIGNMENT == 0, "tensor_data_offset must be 64-byte aligned!" | |
| descriptors: List[RadaTensorDescriptor] = [] | |
| total_ternary_weights = 0 | |
| total_ternary_bytes = 0 | |
| total_float_bytes = 0 | |
| # DIRECT STREAMING WRITE (Zero intermediate RAM overhead) | |
| with open(output_path, "wb") as f: | |
| # 1. Pre-seek to tensor_data_offset, reserving space for header & table | |
| f.seek(tensor_data_offset) | |
| sorted_names = sorted(state_dict.keys()) | |
| for name in sorted_names: | |
| tensor = state_dict[name] | |
| current_file_pos = f.tell() | |
| assert current_file_pos % CACHE_LINE_ALIGNMENT == 0, f"Offset for {name} unaligned: {current_file_pos}" | |
| payload, dtype_code, gamma, shape = serialize_tensor_payload(name, tensor) | |
| payload_len = len(payload) | |
| assert payload_len % CACHE_LINE_ALIGNMENT == 0, f"Payload for {name} must be 64B aligned!" | |
| # Calculate on-the-fly per-tensor CRC32 | |
| tensor_crc = zlib.crc32(payload) & 0xFFFFFFFF | |
| desc = RadaTensorDescriptor( | |
| name=name, | |
| dtype=dtype_code, | |
| shape=shape, | |
| offset=current_file_pos, | |
| size_bytes=payload_len, | |
| scale_gamma=gamma, | |
| crc32=tensor_crc | |
| ) | |
| descriptors.append(desc) | |
| # Write payload directly to disk stream | |
| f.write(payload) | |
| if dtype_code == DTYPE_TERNARY_2BIT: | |
| total_ternary_weights += tensor.numel() | |
| total_ternary_bytes += payload_len | |
| else: | |
| total_float_bytes += payload_len | |
| # Immediate release of buffer from RAM | |
| del payload | |
| # 2. Append BPE vocabulary at the end if provided | |
| bpe_vocab_offset = f.tell() | |
| bpe_vocab_size = 0 | |
| if vocab_bytes: | |
| bpe_vocab_size = len(vocab_bytes) | |
| aligned_vocab_size = align_to_boundary(bpe_vocab_size, CACHE_LINE_ALIGNMENT) | |
| f.write(vocab_bytes.ljust(aligned_vocab_size, b"\x00")) | |
| # 3. Finalize Tensor Table bytes and calculate Table CRC32 | |
| table_header = struct.pack("<II", num_tensors, 0) | |
| table_desc_bytes = b"".join(desc.to_bytes() for desc in descriptors) | |
| written_table_bytes = len(table_header) + len(table_desc_bytes) | |
| pad_table_len = tensor_table_aligned_size - written_table_bytes | |
| pad_table = b"\x00" * pad_table_len if pad_table_len > 0 else b"" | |
| table_crc = zlib.crc32(table_desc_bytes) & 0xFFFFFFFF | |
| # 4. Construct File Header with Tier 1 Checksums | |
| header = self.create_header(num_tensors=num_tensors, tensor_table_offset=tensor_table_offset) | |
| header.tensor_data_offset = tensor_data_offset | |
| header.bpe_vocab_offset = bpe_vocab_offset | |
| header.bpe_vocab_size_bytes = bpe_vocab_size | |
| header.table_crc32 = table_crc | |
| header.flags = RADA_FLAG_CRC32_ENABLED | |
| # Compute Header CRC32 (with header_crc32 field zeroed) | |
| header.header_crc32 = 0 | |
| raw_hdr = header.to_bytes() | |
| header.header_crc32 = zlib.crc32(raw_hdr[:104]) & 0xFFFFFFFF | |
| # 5. Rewind to beginning and flush finalized Header & Tensor Table | |
| f.seek(0) | |
| f.write(header.to_bytes()) | |
| f.write(table_header) | |
| f.write(table_desc_bytes) | |
| if pad_table: | |
| f.write(pad_table) | |
| assert f.tell() == tensor_data_offset, f"File pos {f.tell()} != expected data offset {tensor_data_offset}" | |
| total_file_size = os.path.getsize(output_path) | |
| return { | |
| "output_path": output_path, | |
| "total_file_size_bytes": total_file_size, | |
| "total_tensors": num_tensors, | |
| "total_ternary_weights": total_ternary_weights, | |
| "total_ternary_bytes": total_ternary_bytes, | |
| "total_float_bytes": total_float_bytes, | |
| "tensor_data_offset": tensor_data_offset, | |
| "header_crc32": f"0x{header.header_crc32:08X}", | |
| "table_crc32": f"0x{header.table_crc32:08X}", | |
| "header": header | |
| } | |
| def verify_container(container_path: str, verify_all_crcs: bool = True) -> Dict[str, Any]: | |
| """ | |
| Validates container integrity, header fields, 64-byte alignments, | |
| hierarchical CRC32 checksums, and unpacks ternary weights. | |
| """ | |
| if not os.path.isfile(container_path): | |
| raise FileNotFoundError(f"Container file not found: {container_path}") | |
| file_size = os.path.getsize(container_path) | |
| # 1. Safe 8-byte probing to prevent Segfault on legacy or truncated files | |
| if file_size < 8: | |
| raise ValueError(f"File too small to be a valid container: {file_size} bytes (minimum 8 bytes required)") | |
| with open(container_path, "rb") as f: | |
| magic, version = struct.unpack("<II", f.read(8)) | |
| if magic == RADA_LEGACY_MAGIC: | |
| if version == 1: | |
| raise ValueError( | |
| f"Legacy Hetman-1 container detected (magic=0x{magic:08X}, version=1). " | |
| f"Rada.cpp v2 requires Hetman-2-NCM format (magic=0x{RADA_NCM_MAGIC:08X}, version={RADA_VERSION})." | |
| ) | |
| raise ValueError(f"Unknown legacy format: magic=0x{magic:08X}, version={version}") | |
| if magic != RADA_NCM_MAGIC: | |
| raise ValueError( | |
| f"Invalid magic number: 0x{magic:08X} (expected RNCM=0x{RADA_NCM_MAGIC:08X})" | |
| ) | |
| if version != RADA_VERSION: | |
| raise ValueError(f"Unsupported container version: {version} (expected {RADA_VERSION})") | |
| if file_size < HEADER_SIZE_BYTES: | |
| raise ValueError(f"File truncated before end of header: {file_size} < {HEADER_SIZE_BYTES}") | |
| f.seek(0) | |
| header_bytes = f.read(HEADER_SIZE_BYTES) | |
| header = RadaNcmFileHeader.from_bytes(header_bytes) | |
| # 2. Verify Tier 1: Header CRC32 | |
| if header.flags & RADA_FLAG_CRC32_ENABLED: | |
| expected_hdr_crc = header.header_crc32 | |
| computed_hdr_crc = zlib.crc32(header_bytes[:104]) & 0xFFFFFFFF | |
| if expected_hdr_crc != computed_hdr_crc: | |
| raise ValueError( | |
| f"Header CRC32 mismatch! Stored: 0x{expected_hdr_crc:08X}, Computed: 0x{computed_hdr_crc:08X}" | |
| ) | |
| # 3. Cache-line alignment checks | |
| if header.tensor_table_offset % CACHE_LINE_ALIGNMENT != 0: | |
| raise ValueError(f"tensor_table_offset unaligned: {header.tensor_table_offset}") | |
| if header.tensor_data_offset % CACHE_LINE_ALIGNMENT != 0: | |
| raise ValueError(f"tensor_data_offset unaligned: {header.tensor_data_offset}") | |
| # 4. Read tensor table | |
| f.seek(header.tensor_table_offset) | |
| num_tensors, _ = struct.unpack("<II", f.read(8)) | |
| descriptors_raw = f.read(num_tensors * TENSOR_DESC_SIZE_BYTES) | |
| if len(descriptors_raw) < num_tensors * TENSOR_DESC_SIZE_BYTES: | |
| raise ValueError(f"Truncated descriptor table in file!") | |
| # Verify Tier 1: Table CRC32 | |
| if header.flags & RADA_FLAG_CRC32_ENABLED: | |
| expected_tbl_crc = header.table_crc32 | |
| computed_tbl_crc = zlib.crc32(descriptors_raw) & 0xFFFFFFFF | |
| if expected_tbl_crc != computed_tbl_crc: | |
| raise ValueError( | |
| f"Table CRC32 mismatch! Stored: 0x{expected_tbl_crc:08X}, Computed: 0x{computed_tbl_crc:08X}" | |
| ) | |
| descriptors: List[RadaTensorDescriptor] = [] | |
| for i in range(num_tensors): | |
| desc_bytes = descriptors_raw[i * TENSOR_DESC_SIZE_BYTES : (i + 1) * TENSOR_DESC_SIZE_BYTES] | |
| desc = RadaTensorDescriptor.from_bytes(desc_bytes) | |
| if desc.offset % CACHE_LINE_ALIGNMENT != 0: | |
| raise ValueError(f"Tensor {desc.name} offset unaligned: {desc.offset}") | |
| if desc.size_bytes % CACHE_LINE_ALIGNMENT != 0: | |
| raise ValueError(f"Tensor {desc.name} size unaligned: {desc.size_bytes}") | |
| descriptors.append(desc) | |
| # 5. Verify payload offsets, per-tensor CRC32, and ternary round-trip | |
| verified_crc_count = 0 | |
| verified_ternary_count = 0 | |
| for desc in descriptors: | |
| if desc.offset + desc.size_bytes > file_size: | |
| raise ValueError( | |
| f"Tensor {desc.name} exceeds file boundary: {desc.offset + desc.size_bytes} > {file_size}" | |
| ) | |
| # Check per-tensor CRC32 | |
| if (header.flags & RADA_FLAG_CRC32_ENABLED) and (verify_all_crcs or verified_crc_count < 10): | |
| f.seek(desc.offset) | |
| payload = f.read(desc.size_bytes) | |
| computed_tensor_crc = zlib.crc32(payload) & 0xFFFFFFFF | |
| if desc.crc32 != computed_tensor_crc: | |
| raise ValueError( | |
| f"Tensor '{desc.name}' CRC32 mismatch: " | |
| f"Stored 0x{desc.crc32:08X} != Computed 0x{computed_tensor_crc:08X}" | |
| ) | |
| verified_crc_count += 1 | |
| # Check numerical ternary round-trip on first 3 ternary matrices | |
| if desc.dtype == DTYPE_TERNARY_2BIT and verified_ternary_count < 3: | |
| f.seek(desc.offset) | |
| payload = f.read(desc.size_bytes) | |
| unpacked = unpack_ternary_weights( | |
| packed_bytes=payload, | |
| shape=desc.shape, | |
| scale_gamma=desc.scale_gamma, | |
| align_row_bytes=CACHE_LINE_ALIGNMENT | |
| ) | |
| assert unpacked.shape == desc.shape, f"Unpacked shape mismatch: {unpacked.shape} != {desc.shape}" | |
| verified_ternary_count += 1 | |
| return { | |
| "valid": True, | |
| "magic_hex": f"0x{header.magic:08X}", | |
| "version": header.version, | |
| "header_crc32": f"0x{header.header_crc32:08X}", | |
| "table_crc32": f"0x{header.table_crc32:08X}", | |
| "flags": header.flags, | |
| "vocab_size": header.vocab_size, | |
| "hidden_size": header.hidden_size, | |
| "intermediate_size": header.intermediate_size, | |
| "num_layers": header.num_layers, | |
| "num_deltanet_layers": header.num_deltanet_layers, | |
| "tokens_per_block": header.tokens_per_block, | |
| "max_blocks": header.max_blocks, | |
| "num_tensors": len(descriptors), | |
| "tensor_table_offset": header.tensor_table_offset, | |
| "tensor_data_offset": header.tensor_data_offset, | |
| "descriptors": descriptors | |
| } | |
| # ============================================================================== | |
| # 6. CONVENIENCE API FUNCTIONS | |
| # ============================================================================== | |
| def export_to_rada( | |
| model_or_state_dict: Union[nn.Module, Dict[str, torch.Tensor]], | |
| output_path: str, | |
| config: Optional[Hetman2Config] = None, | |
| vocab_bytes: Optional[bytes] = None | |
| ) -> Dict[str, Any]: | |
| """ | |
| High-level export function with streaming 64-byte alignment and BitNet b1.58 packing. | |
| """ | |
| exporter = RadaExporter(config=config) | |
| return exporter.export(model_or_state_dict, output_path, vocab_bytes=vocab_bytes) | |
| def verify_rada_file(path: str, verify_all_crcs: bool = True) -> Dict[str, Any]: | |
| """ | |
| Verifies binary validity and hierarchical CRC32 checksums of exported .rada container. | |
| """ | |
| return RadaExporter.verify_container(path, verify_all_crcs=verify_all_crcs) | |
| # ============================================================================== | |
| # 7. COMMAND-LINE INTERFACE | |
| # ============================================================================== | |
| def main(): | |
| parser = argparse.ArgumentParser(description="Hetman-2-NCM Rada.cpp Container Exporter (v2 Streaming)") | |
| parser.add_argument("--model_path", type=str, default="", help="Path to PyTorch checkpoint (.pt / .pth / .bin)") | |
| parser.add_argument("--output_path", type=str, required=True, help="Path for destination .rada binary container") | |
| parser.add_argument("--verify", action="store_true", help="Run verification checks after exporting") | |
| args = parser.parse_args() | |
| if args.model_path and os.path.exists(args.model_path): | |
| print(f"[*] Loading PyTorch checkpoint from: {args.model_path}") | |
| state_dict = torch.load(args.model_path, map_location="cpu") | |
| if "state_dict" in state_dict: | |
| state_dict = state_dict["state_dict"] | |
| else: | |
| print("[*] Creating synthetic mini-instance of Hetman2ForCausalLM for export...") | |
| config = Hetman2Config.create_mini() | |
| model = Hetman2ForCausalLM(config) | |
| state_dict = model.state_dict() | |
| print(f"[*] Exporting to: {args.output_path} (RADA_VERSION={RADA_VERSION}, 64B aligned, streaming)") | |
| result = export_to_rada(state_dict, args.output_path) | |
| print(f"[+] Export successful! Total container size: {result['total_file_size_bytes']} bytes") | |
| print(f" Tensors: {result['total_tensors']} | Ternary weights: {result['total_ternary_weights']}") | |
| print(f" Header CRC32: {result['header_crc32']} | Table CRC32: {result['table_crc32']}") | |
| if args.verify: | |
| print(f"[*] Verifying container integrity and hierarchical CRC32 checksums...") | |
| audit = verify_rada_file(args.output_path, verify_all_crcs=True) | |
| print(f"[+] Container 100% Valid! Magic: {audit['magic_hex']}, Version: {audit['version']}") | |
| print(f" All {audit['num_tensors']} tensor CRC32 checksums verified successfully!") | |
| if __name__ == "__main__": | |
| main() | |