Initial specification release: full code, spec README, and logos
Browse files- .gitattributes +1 -0
- Logo.jpg +3 -0
- README.md +98 -0
- UFO_Mathematical_Evidence.md +29 -0
- ZERO_RAM_META_SPEC.md +62 -0
- cuneiform_u_v3.h +433 -0
- cuneiform_u_v3.rs +358 -0
- decode_gemma4.py +143 -0
- decode_gemma4_seed.py +173 -0
- decode_procedural.py +154 -0
- decode_tinyqwen.py +454 -0
- decode_tokenizer.py +334 -0
- language_u_logo.jpg +0 -0
- quantize_genesis_3bit_to_dct.py +190 -0
- quantize_genesis_dct_to_grad.py +217 -0
- quantize_genesis_int8_to_3bit.py +206 -0
- quantize_perfect_genesis.py +131 -0
- safetensors_to_genesis.py +131 -0
- test_cuneiform_u_v3.rs +58 -0
- test_cuneiform_v3.c +106 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
Logo.jpg filter=lfs diff=lfs merge=lfs -text
|
Logo.jpg
ADDED
|
Git LFS Details
|
README.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: other
|
| 3 |
+
tags:
|
| 4 |
+
- genesis
|
| 5 |
+
- binary-format
|
| 6 |
+
- svd-compression
|
| 7 |
+
- low-rank-factorization
|
| 8 |
+
- spectral-decomposition
|
| 9 |
+
- zero-ram
|
| 10 |
+
- cuda-kernels
|
| 11 |
+
- edge-ai
|
| 12 |
+
- language-u
|
| 13 |
+
language:
|
| 14 |
+
- en
|
| 15 |
+
pipeline_tag: text-generation
|
| 16 |
+
---
|
| 17 |
+
|
| 18 |
+
<p align="center">
|
| 19 |
+
<img src="Logo.jpg" width="45%" />
|
| 20 |
+
<img src="language_u_logo.jpg" width="45%" />
|
| 21 |
+
</p>
|
| 22 |
+
|
| 23 |
+
# The `.genesis` Binary Format Specification
|
| 24 |
+
## Dynamic Low-Rank SVD and Spectral Projection Registry
|
| 25 |
+
### Watermark: `ip zymatica.space | astronautshe.com`
|
| 26 |
+
|
| 27 |
+
---
|
| 28 |
+
|
| 29 |
+
## 1. Executive Abstract & Context
|
| 30 |
+
|
| 31 |
+
For decades, the weight files of neural language networks have been stored as massive, dense, unstructured float arrays (e.g., `.safetensors`, `.bin`, `.pth`). While suitable for high-bandwidth servers, this layout is completely incompatible with extreme-constrained edge hardware.
|
| 32 |
+
|
| 33 |
+
The **`.genesis` file format** represents a new paradigm in structural neural compression. Rather than storing flat weights, a `.genesis` file acts as an **uncompressed structural registry** of low-rank factored manifolds. By factorizing large projection weights into Singular Value Decomposition (SVD) components and keeping only the low-frequency spectral coefficients via Discrete Cosine Transforms (DCT-II), the raw weight matrices are represented at the micro-byte level.
|
| 34 |
+
|
| 35 |
+
Upon boot, the receiver-side JIT execution runtime compiles the layer graph directly from the SVD/DCT factors without allocating dense memory matrices, reducing process memory from **35 GB down to under 230 MB** (Zero-RAM Meta).
|
| 36 |
+
|
| 37 |
+
---
|
| 38 |
+
|
| 39 |
+
## 2. `.genesis` Binary Layout & File Structure
|
| 40 |
+
|
| 41 |
+
The `.genesis` format is a strict, low-overhead binary layout designed for fast seeking, parsing, and JIT dynamic loading:
|
| 42 |
+
|
| 43 |
+
```
|
| 44 |
+
+-----------------------------------------------------------------+
|
| 45 |
+
| Magic Marker: [0x47, 0x45, 0x4E, 0x45] ('GENE') or ('PERF') | -> 4 Bytes
|
| 46 |
+
+-----------------------------------------------------------------+
|
| 47 |
+
| Major Version (1 Byte) | Minor Version (1 Byte) | -> 2 Bytes
|
| 48 |
+
+-----------------------------------------------------------------+
|
| 49 |
+
| Model Metadata Segment Offset (Big-Endian uint32) | -> 4 Bytes
|
| 50 |
+
+-----------------------------------------------------------------+
|
| 51 |
+
| Layer Configuration Segment Offset (Big-Endian uint32) | -> 4 Bytes
|
| 52 |
+
+-----------------------------------------------------------------+
|
| 53 |
+
| Weights Payload Segment Offset (Big-Endian uint32) | -> 4 Bytes
|
| 54 |
+
+-----------------------------------------------------------------+
|
| 55 |
+
| Layer Norm / Non-linear Arrays (Embeddings, RMSNorms) | -> Raw Tensors
|
| 56 |
+
+-----------------------------------------------------------------+
|
| 57 |
+
| Quantized Low-Rank Projections (U_q, V_q, scale_u, scale_v) | -> SVD Factors
|
| 58 |
+
+-----------------------------------------------------------------+
|
| 59 |
+
```
|
| 60 |
+
|
| 61 |
+
### 2.1 Low-Rank Approximation Mechanics
|
| 62 |
+
For each transformer block projection matrix $W \in \mathbb{R}^{M imes N}$, the `.genesis` registry records SVD rank-factors $U_q \in \mathbb{Z}^{M imes R}$ and $V_q \in \mathbb{Z}^{N imes R}$ quantized to Q8 (int8) or 3-bit vectorized matrices alongside 32-bit float scale coefficients:
|
| 63 |
+
|
| 64 |
+
$$W pprox \left(U_q imes s_u
|
| 65 |
+
|
| 66 |
+
where:
|
| 67 |
+
* **Attention Layers (`q_proj`, `k_proj`, `v_proj`, `o_proj`):** Truncated to rank $R = 64$.
|
| 68 |
+
* **MLP Layers (`gate_proj`, `up_proj`, `down_proj`):** Truncated to rank $R = 128$.
|
| 69 |
+
|
| 70 |
+
---
|
| 71 |
+
|
| 72 |
+
## 3. The Compilers, Quantizers, and Decoders
|
| 73 |
+
|
| 74 |
+
This repository contains the complete specification and reference implementation files for reading, writing, and compiling `.genesis` files:
|
| 75 |
+
|
| 76 |
+
### 3.1 Raw Matrix compilers
|
| 77 |
+
* **`safetensors_to_genesis.py`**: Compiles dense sharded `.safetensors` files into a single, structured `.genesis` low-rank SVD output.
|
| 78 |
+
* **`quantize_perfect_genesis.py`**: Compiles full-precision SVD matrices into integer-scaled arrays.
|
| 79 |
+
|
| 80 |
+
### 3.2 Dynamic Quantization Suites
|
| 81 |
+
* **`quantize_genesis_int8_to_3bit.py`**: Compresses 8-bit singular vectors into a vectorized 3-bit coordinate space mapping values in the range `[-3, 3]`.
|
| 82 |
+
* **`quantize_genesis_3bit_to_dct.py`** & **`quantize_genesis_dct_to_grad.py`**: Applies Discrete Cosine Transform (DCT-II) spectral filtering over the weights, repacking values into ultra-compact symbol classes (Gradient Atoms).
|
| 83 |
+
|
| 84 |
+
### 3.3 Dynamic Decoders & Execution Proofs
|
| 85 |
+
* **`decode_gemma4.py`**: Reads `.genesis` files and JIT-reconstructs the dense weight matrices for Google Gemma-4 model shards.
|
| 86 |
+
* **`decode_procedural.py`** & **`decode_tinyqwen.py`**: Implements matching pursuit dictionary decoders to regenerate neural weights procedurally.
|
| 87 |
+
* **`ZERO_RAM_META_SPEC.md`**: Outlines the memory-addressing constraints to execute `.genesis` models under 230 MB of RAM.
|
| 88 |
+
|
| 89 |
+
---
|
| 90 |
+
|
| 91 |
+
## 4. Academic Citation & Intellectual Property
|
| 92 |
+
The `.genesis` binary specification and low-rank JIT execution code are protected under the proprietary licenses of **zymatica.space**.
|
| 93 |
+
|
| 94 |
+
* **Zymatica.space:** Core compression framework and binary layout specifications.
|
| 95 |
+
* **astronautshe.com:** Low-overhead edge execution runtimes and FFI pointer systems.
|
| 96 |
+
* **The AI Collective:** Global publisher.
|
| 97 |
+
|
| 98 |
+
*Watermark: ip zymatica.space | astronautshe.com — We Are TheAiCollective.art*
|
UFO_Mathematical_Evidence.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# UFO Mathematical Compression & Alignment Evidence
|
| 2 |
+
|
| 3 |
+
- **Protocol**: Chirp-3 Full Model v2.0
|
| 4 |
+
- **Method**: L7:QualiaSeed+L6:GradAtom+L5:Eigen+L1:LU4QA+ZLIB
|
| 5 |
+
- **Source Model**: j:/Language-U/Language-U-V2/qwen-3.5-0.8b-local\model.safetensors-00001-of-00001.safetensors
|
| 6 |
+
- **Total Tensors in Model**: 488
|
| 7 |
+
- **Layers Compressed**: 16
|
| 8 |
+
- **Compressed Size**: 554 bytes
|
| 9 |
+
- **Raw Capsule Size**: 576 bytes
|
| 10 |
+
|
| 11 |
+
## Mathematical Alignment Matrix
|
| 12 |
+
| Layer Key | Shape | Compression Level | Alignment % | Raw Bytes | Encoded Bytes |
|
| 13 |
+
| --- | --- | --- | --- | --- | --- |
|
| 14 |
+
| layers.0.linear_attn.in_proj_qkv.weight | [6144, 1024] | L6 | 30.8% | 12,582,912 | 9 |
|
| 15 |
+
| layers.0.linear_attn.in_proj_z.weight | [2048, 1024] | L6 | 13.6% | 4,194,304 | 9 |
|
| 16 |
+
| layers.0.linear_attn.in_proj_b.weight | [16, 1024] | L6 | 100.0% | 32,768 | 9 |
|
| 17 |
+
| layers.0.linear_attn.in_proj_a.weight | [16, 1024] | L6 | 100.0% | 32,768 | 9 |
|
| 18 |
+
| layers.0.linear_attn.out_proj.weight | [1024, 2048] | L6 | 9.1% | 4,194,304 | 9 |
|
| 19 |
+
| layers.1.linear_attn.in_proj_qkv.weight | [6144, 1024] | L6 | 10.4% | 12,582,912 | 9 |
|
| 20 |
+
| layers.1.linear_attn.in_proj_z.weight | [2048, 1024] | L6 | 10.1% | 4,194,304 | 9 |
|
| 21 |
+
| layers.1.linear_attn.in_proj_b.weight | [16, 1024] | L6 | 100.0% | 32,768 | 9 |
|
| 22 |
+
| layers.1.linear_attn.in_proj_a.weight | [16, 1024] | L6 | 100.0% | 32,768 | 9 |
|
| 23 |
+
| layers.1.linear_attn.out_proj.weight | [1024, 2048] | L6 | 12.0% | 4,194,304 | 9 |
|
| 24 |
+
| layers.0.mlp.gate_proj.weight | [3584, 1024] | L6 | 7.5% | 7,340,032 | 9 |
|
| 25 |
+
| layers.0.mlp.up_proj.weight | [3584, 1024] | L6 | 3.5% | 7,340,032 | 9 |
|
| 26 |
+
| layers.0.mlp.down_proj.weight | [1024, 3584] | L6 | 4.8% | 7,340,032 | 9 |
|
| 27 |
+
| layers.1.mlp.gate_proj.weight | [3584, 1024] | L6 | 7.0% | 7,340,032 | 9 |
|
| 28 |
+
| layers.1.mlp.up_proj.weight | [3584, 1024] | L6 | 4.2% | 7,340,032 | 9 |
|
| 29 |
+
| layers.1.mlp.down_proj.weight | [1024, 3584] | L6 | 5.1% | 7,340,032 | 9 |
|
ZERO_RAM_META_SPEC.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Zero-RAM Meta Specification
|
| 2 |
+
|
| 3 |
+
Date: 2026-06-16
|
| 4 |
+
|
| 5 |
+
Zero-RAM Meta is the project rule set that lets the Gemma-4-31B Sumerian runtime execute on this PC without allocating dense 31B projection weights.
|
| 6 |
+
|
| 7 |
+
## Invariants
|
| 8 |
+
|
| 9 |
+
1. Dense projection weights must never be allocated for the compressed runtime path.
|
| 10 |
+
2. The genesis capsule is authoritative for projection tensors.
|
| 11 |
+
3. Missing compressed projection records are fatal, not silently replaced by dense zero tensors.
|
| 12 |
+
4. Non-projection tensors are seek-read or packaged into compact runtime state.
|
| 13 |
+
5. Runtime initialization may allocate persistent factor buffers and reusable workspaces.
|
| 14 |
+
6. The autoregressive loop must not allocate CUDA buffers per token.
|
| 15 |
+
7. Runtime state must match the base model shape contract:
|
| 16 |
+
- hidden size: 5376
|
| 17 |
+
- language layers: 60
|
| 18 |
+
- attention heads: 32
|
| 19 |
+
- key/value heads: 16
|
| 20 |
+
- vocabulary: 262144
|
| 21 |
+
8. Gemma text architecture rules must be explicit:
|
| 22 |
+
- `attention_k_eq_v=true`
|
| 23 |
+
- full-attention layers are every sixth layer starting at layer 5
|
| 24 |
+
- full-attention RoPE uses partial rotary factor 0.25 and theta 1,000,000
|
| 25 |
+
- sliding-attention RoPE uses theta 10,000
|
| 26 |
+
- MLP activation is `gelu_pytorch_tanh`
|
| 27 |
+
- RMSNorm epsilon is `1e-6`
|
| 28 |
+
|
| 29 |
+
## Proprietary Assets
|
| 30 |
+
|
| 31 |
+
### Zero-Allocation JIT SVD Swapping
|
| 32 |
+
|
| 33 |
+
Projection weights are represented as rank-factor INT8 SVD records in the genesis capsule. Runtime initializes the model execution graph around those records and refuses to allocate the dense bf16 projection matrices.
|
| 34 |
+
|
| 35 |
+
### Strict Shape-Filtered Initializers
|
| 36 |
+
|
| 37 |
+
Runtime initialization distinguishes scalar layer controls from 5376-wide normalization vectors. This prevents name-based layer matching from mixing `[1]` parameters with full hidden-size norms.
|
| 38 |
+
|
| 39 |
+
### Dynamic Multimodal CUDA Buffer Sweeping
|
| 40 |
+
|
| 41 |
+
The broader Python/HF fallback path must sweep incidental CUDA buffers back to the intended execution device when the structure is initialized under meta or CPU contexts. The no-libtorch Rust path avoids most of this class by not instantiating HF modules at all.
|
| 42 |
+
|
| 43 |
+
## Current Implementation Mapping
|
| 44 |
+
|
| 45 |
+
- `gemma4_31b_subzero.genesis`: rank-16 compressed projection capsule.
|
| 46 |
+
- `genesis_resident_generate.rs`: resident no-libtorch Rust/Zig autoregressive runtime.
|
| 47 |
+
- `gemma4_runtime_state.g4rt`: compact real Gemma language norms and q/k norm state.
|
| 48 |
+
- `export_gemma4_runtime_state.py`: seek-exporter for the compact runtime state.
|
| 49 |
+
- `resident_generation_report.json`: current machine-readable resident proof.
|
| 50 |
+
- `zero_ram_meta_selftest.py`: invariant self-test.
|
| 51 |
+
|
| 52 |
+
## Completion Criteria
|
| 53 |
+
|
| 54 |
+
Zero-RAM Meta is considered active for a run when:
|
| 55 |
+
|
| 56 |
+
- genesis validation reports 599 records;
|
| 57 |
+
- runtime state validates as `G4RT` version 1 with 60 layers;
|
| 58 |
+
- resident report shows `loop_cuda_allocations=0`;
|
| 59 |
+
- final hidden state has 5376 finite values;
|
| 60 |
+
- generated token ids are present;
|
| 61 |
+
- the runtime does not require libtorch or dense projection allocation.
|
| 62 |
+
|
cuneiform_u_v3.h
ADDED
|
@@ -0,0 +1,433 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Cuneiform-U v3.0 / Language U v4.0 — Edge-Ready Semantic Range Coder
|
| 3 |
+
* Watermark: ip zymatica.space | astronautshe.com
|
| 4 |
+
*
|
| 5 |
+
* This header contains a pure C, zero-dependency, static memory implementation
|
| 6 |
+
* of the 32-bit Range Coder and Hierarchical Radical Prediction Model.
|
| 7 |
+
* Optimized for microcontrollers (e.g. STM32, ESP32) to meet FCC dwell time
|
| 8 |
+
* and LoRa payload limits (< 152 bytes) with high-efficiency compression.
|
| 9 |
+
*/
|
| 10 |
+
|
| 11 |
+
#ifndef CUNEIFORM_U_V3_H
|
| 12 |
+
#define CUNEIFORM_U_V3_H
|
| 13 |
+
|
| 14 |
+
#include <stdint.h>
|
| 15 |
+
#include <string.h>
|
| 16 |
+
|
| 17 |
+
#ifdef __cplusplus
|
| 18 |
+
extern "C" {
|
| 19 |
+
#endif
|
| 20 |
+
|
| 21 |
+
#define MAX_TRANSITIONS 256
|
| 22 |
+
#define RANGE_CODER_MAX_RANGE 0xFFFFFFFFU
|
| 23 |
+
#define RANGE_CODER_HALF_RANGE 0x80000000U
|
| 24 |
+
#define RANGE_CODER_QTR_RANGE 0x40000000U
|
| 25 |
+
#define RANGE_CODER_THREE_QTR 0xC0000000U
|
| 26 |
+
|
| 27 |
+
/* 6D Hypercube Concept Coordinates */
|
| 28 |
+
typedef struct {
|
| 29 |
+
uint8_t domain; /* 0-15 */
|
| 30 |
+
uint8_t subdomain; /* 0-15 */
|
| 31 |
+
uint8_t operation; /* 0-15 */
|
| 32 |
+
uint8_t modality; /* 0-15 */
|
| 33 |
+
uint8_t depth; /* 0-15 */
|
| 34 |
+
uint8_t polarity; /* 0-15 */
|
| 35 |
+
} Concept6D;
|
| 36 |
+
|
| 37 |
+
/* Sparse Transition Entry for Radical Predictor */
|
| 38 |
+
typedef struct {
|
| 39 |
+
uint32_t key; /* Context state key */
|
| 40 |
+
uint8_t sym; /* Symbol predicted (0-255) */
|
| 41 |
+
uint32_t count; /* Observed frequency transition count */
|
| 42 |
+
} SparseTransition;
|
| 43 |
+
|
| 44 |
+
/* Predictor Model State */
|
| 45 |
+
typedef struct {
|
| 46 |
+
SparseTransition trans_rc[MAX_TRANSITIONS];
|
| 47 |
+
uint32_t num_rc;
|
| 48 |
+
|
| 49 |
+
SparseTransition trans_rf[MAX_TRANSITIONS];
|
| 50 |
+
uint32_t num_rf;
|
| 51 |
+
|
| 52 |
+
SparseTransition trans_ra[MAX_TRANSITIONS];
|
| 53 |
+
uint32_t num_ra;
|
| 54 |
+
|
| 55 |
+
uint8_t prev_rc;
|
| 56 |
+
uint8_t prev_rf;
|
| 57 |
+
uint8_t prev_ra;
|
| 58 |
+
|
| 59 |
+
uint32_t alpha; /* Laplace smoothing factor */
|
| 60 |
+
uint32_t weight; /* Increment weight per observation */
|
| 61 |
+
} RadicalPredictor;
|
| 62 |
+
|
| 63 |
+
/* Helper to initialize the predictor */
|
| 64 |
+
static inline void predictor_init(RadicalPredictor* pred, uint32_t alpha, uint32_t weight) {
|
| 65 |
+
memset(pred, 0, sizeof(RadicalPredictor));
|
| 66 |
+
pred->alpha = alpha;
|
| 67 |
+
pred->weight = weight;
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
/* Update prediction models based on observed radicals */
|
| 71 |
+
static inline void predictor_observe(RadicalPredictor* pred, uint8_t rc, uint8_t rf, uint8_t ra) {
|
| 72 |
+
/* 1. Update Classifier Radical transitions (R_C) */
|
| 73 |
+
uint32_t key_rc = pred->prev_rc;
|
| 74 |
+
int found_rc = 0;
|
| 75 |
+
for (uint32_t i = 0; i < pred->num_rc; i++) {
|
| 76 |
+
if (pred->trans_rc[i].key == key_rc && pred->trans_rc[i].sym == rc) {
|
| 77 |
+
pred->trans_rc[i].count += pred->weight;
|
| 78 |
+
found_rc = 1;
|
| 79 |
+
break;
|
| 80 |
+
}
|
| 81 |
+
}
|
| 82 |
+
if (!found_rc && pred->num_rc < MAX_TRANSITIONS) {
|
| 83 |
+
pred->trans_rc[pred->num_rc].key = key_rc;
|
| 84 |
+
pred->trans_rc[pred->num_rc].sym = rc;
|
| 85 |
+
pred->trans_rc[pred->num_rc].count = pred->weight;
|
| 86 |
+
pred->num_rc++;
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
/* 2. Update Force Radical transitions (R_F) */
|
| 90 |
+
uint32_t key_rf = ((uint32_t)rc << 8) | pred->prev_rf;
|
| 91 |
+
int found_rf = 0;
|
| 92 |
+
for (uint32_t i = 0; i < pred->num_rf; i++) {
|
| 93 |
+
if (pred->trans_rf[i].key == key_rf && pred->trans_rf[i].sym == rf) {
|
| 94 |
+
pred->trans_rf[i].count += pred->weight;
|
| 95 |
+
found_rf = 1;
|
| 96 |
+
break;
|
| 97 |
+
}
|
| 98 |
+
}
|
| 99 |
+
if (!found_rf && pred->num_rf < MAX_TRANSITIONS) {
|
| 100 |
+
pred->trans_rf[pred->num_rf].key = key_rf;
|
| 101 |
+
pred->trans_rf[pred->num_rf].sym = rf;
|
| 102 |
+
pred->trans_rf[pred->num_rf].count = pred->weight;
|
| 103 |
+
pred->num_rf++;
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
/* 3. Update Aspect Radical transitions (R_A) */
|
| 107 |
+
uint32_t key_ra = ((uint32_t)rc << 16) | ((uint32_t)rf << 8) | pred->prev_ra;
|
| 108 |
+
int found_ra = 0;
|
| 109 |
+
for (uint32_t i = 0; i < pred->num_ra; i++) {
|
| 110 |
+
if (pred->trans_ra[i].key == key_ra && pred->trans_ra[i].sym == ra) {
|
| 111 |
+
pred->trans_ra[i].count += pred->weight;
|
| 112 |
+
found_ra = 1;
|
| 113 |
+
break;
|
| 114 |
+
}
|
| 115 |
+
}
|
| 116 |
+
if (!found_ra && pred->num_ra < MAX_TRANSITIONS) {
|
| 117 |
+
pred->trans_ra[pred->num_ra].key = key_ra;
|
| 118 |
+
pred->trans_ra[pred->num_ra].sym = ra;
|
| 119 |
+
pred->trans_ra[pred->num_ra].count = pred->weight;
|
| 120 |
+
pred->num_ra++;
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
/* Track histories */
|
| 124 |
+
pred->prev_rc = rc;
|
| 125 |
+
pred->prev_rf = rf;
|
| 126 |
+
pred->prev_ra = ra;
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
/* Construct cumulative frequency tables (0 to 256) */
|
| 130 |
+
static inline void get_cum_freqs_rc(const RadicalPredictor* pred, uint8_t prev_rc, uint32_t* cum_freqs) {
|
| 131 |
+
uint32_t freqs[256];
|
| 132 |
+
for (int i = 0; i < 256; i++) {
|
| 133 |
+
freqs[i] = pred->alpha;
|
| 134 |
+
}
|
| 135 |
+
for (uint32_t i = 0; i < pred->num_rc; i++) {
|
| 136 |
+
if (pred->trans_rc[i].key == prev_rc) {
|
| 137 |
+
freqs[pred->trans_rc[i].sym] += pred->trans_rc[i].count;
|
| 138 |
+
}
|
| 139 |
+
}
|
| 140 |
+
cum_freqs[0] = 0;
|
| 141 |
+
for (int i = 0; i < 256; i++) {
|
| 142 |
+
cum_freqs[i+1] = cum_freqs[i] + freqs[i];
|
| 143 |
+
}
|
| 144 |
+
}
|
| 145 |
+
|
| 146 |
+
static inline void get_cum_freqs_rf(const RadicalPredictor* pred, uint8_t curr_rc, uint8_t prev_rf, uint32_t* cum_freqs) {
|
| 147 |
+
uint32_t freqs[256];
|
| 148 |
+
for (int i = 0; i < 256; i++) {
|
| 149 |
+
freqs[i] = pred->alpha;
|
| 150 |
+
}
|
| 151 |
+
uint32_t key = ((uint32_t)curr_rc << 8) | prev_rf;
|
| 152 |
+
for (uint32_t i = 0; i < pred->num_rf; i++) {
|
| 153 |
+
if (pred->trans_rf[i].key == key) {
|
| 154 |
+
freqs[pred->trans_rf[i].sym] += pred->trans_rf[i].count;
|
| 155 |
+
}
|
| 156 |
+
}
|
| 157 |
+
cum_freqs[0] = 0;
|
| 158 |
+
for (int i = 0; i < 256; i++) {
|
| 159 |
+
cum_freqs[i+1] = cum_freqs[i] + freqs[i];
|
| 160 |
+
}
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
static inline void get_cum_freqs_ra(const RadicalPredictor* pred, uint8_t curr_rc, uint8_t curr_rf, uint8_t prev_ra, uint32_t* cum_freqs) {
|
| 164 |
+
uint32_t freqs[256];
|
| 165 |
+
for (int i = 0; i < 256; i++) {
|
| 166 |
+
freqs[i] = pred->alpha;
|
| 167 |
+
}
|
| 168 |
+
uint32_t key = ((uint32_t)curr_rc << 16) | ((uint32_t)curr_rf << 8) | prev_ra;
|
| 169 |
+
for (uint32_t i = 0; i < pred->num_ra; i++) {
|
| 170 |
+
if (pred->trans_ra[i].key == key) {
|
| 171 |
+
freqs[pred->trans_ra[i].sym] += pred->trans_ra[i].count;
|
| 172 |
+
}
|
| 173 |
+
}
|
| 174 |
+
cum_freqs[0] = 0;
|
| 175 |
+
for (int i = 0; i < 256; i++) {
|
| 176 |
+
cum_freqs[i+1] = cum_freqs[i] + freqs[i];
|
| 177 |
+
}
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
/* Bitstream helper functions for encoding/decoding */
|
| 181 |
+
typedef struct {
|
| 182 |
+
uint8_t* buffer;
|
| 183 |
+
uint32_t max_bytes;
|
| 184 |
+
uint32_t bit_index;
|
| 185 |
+
} BitWriter;
|
| 186 |
+
|
| 187 |
+
static inline void bit_writer_init(BitWriter* w, uint8_t* buf, uint32_t max_b) {
|
| 188 |
+
w->buffer = buf;
|
| 189 |
+
w->max_bytes = max_b;
|
| 190 |
+
w->bit_index = 0;
|
| 191 |
+
memset(buf, 0, max_b);
|
| 192 |
+
}
|
| 193 |
+
|
| 194 |
+
static inline void bit_writer_write(BitWriter* w, uint8_t bit) {
|
| 195 |
+
uint32_t byte_pos = w->bit_index / 8;
|
| 196 |
+
uint32_t bit_pos = 7 - (w->bit_index % 8);
|
| 197 |
+
if (byte_pos < w->max_bytes) {
|
| 198 |
+
if (bit) {
|
| 199 |
+
w->buffer[byte_pos] |= (1U << bit_pos);
|
| 200 |
+
} else {
|
| 201 |
+
w->buffer[byte_pos] &= ~(1U << bit_pos);
|
| 202 |
+
}
|
| 203 |
+
w->bit_index++;
|
| 204 |
+
}
|
| 205 |
+
}
|
| 206 |
+
|
| 207 |
+
typedef struct {
|
| 208 |
+
const uint8_t* buffer;
|
| 209 |
+
uint32_t total_bits;
|
| 210 |
+
uint32_t bit_index;
|
| 211 |
+
} BitReader;
|
| 212 |
+
|
| 213 |
+
static inline void bit_reader_init(BitReader* r, const uint8_t* buf, uint32_t num_bytes) {
|
| 214 |
+
r->buffer = buf;
|
| 215 |
+
r->total_bits = num_bytes * 8;
|
| 216 |
+
r->bit_index = 0;
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
+
static inline uint8_t bit_reader_read(BitReader* r) {
|
| 220 |
+
if (r->bit_index >= r->total_bits) {
|
| 221 |
+
return 0;
|
| 222 |
+
}
|
| 223 |
+
uint32_t byte_pos = r->bit_index / 8;
|
| 224 |
+
uint32_t bit_pos = 7 - (r->bit_index % 8);
|
| 225 |
+
uint8_t bit = (r->buffer[byte_pos] >> bit_pos) & 1U;
|
| 226 |
+
r->bit_index++;
|
| 227 |
+
return bit;
|
| 228 |
+
}
|
| 229 |
+
|
| 230 |
+
/* =============================================================================
|
| 231 |
+
* CORE COMPRESSION AND DECOMPRESSION API
|
| 232 |
+
* ============================================================================= */
|
| 233 |
+
|
| 234 |
+
static inline void write_bit_helper(BitWriter* w, uint32_t* underflow_bits, uint8_t bit) {
|
| 235 |
+
bit_writer_write(w, bit);
|
| 236 |
+
while (*underflow_bits > 0) {
|
| 237 |
+
bit_writer_write(w, 1 - bit);
|
| 238 |
+
(*underflow_bits)--;
|
| 239 |
+
}
|
| 240 |
+
}
|
| 241 |
+
|
| 242 |
+
/**
|
| 243 |
+
* Compresses an array of 6D concepts into a compact bitstream.
|
| 244 |
+
* returns: total bits written, or -1 on overflow
|
| 245 |
+
*/
|
| 246 |
+
static int cuneiform_u_v3_encode(const Concept6D* concepts, uint32_t num_concepts,
|
| 247 |
+
uint8_t* out_buffer, uint32_t out_max_bytes,
|
| 248 |
+
uint32_t alpha, uint32_t weight) {
|
| 249 |
+
RadicalPredictor encoder_pred;
|
| 250 |
+
predictor_init(&encoder_pred, alpha, weight);
|
| 251 |
+
|
| 252 |
+
BitWriter w;
|
| 253 |
+
bit_writer_init(&w, out_buffer, out_max_bytes);
|
| 254 |
+
|
| 255 |
+
uint32_t low = 0;
|
| 256 |
+
uint32_t high = RANGE_CODER_MAX_RANGE;
|
| 257 |
+
uint32_t underflow_bits = 0;
|
| 258 |
+
|
| 259 |
+
/* Flatten into radical sequence and encode step-by-step */
|
| 260 |
+
for (uint32_t c = 0; c < num_concepts; c++) {
|
| 261 |
+
uint8_t rc = (concepts[c].domain << 4) | concepts[c].subdomain;
|
| 262 |
+
uint8_t rf = (concepts[c].operation << 4) | concepts[c].modality;
|
| 263 |
+
uint8_t ra = (concepts[c].depth << 4) | concepts[c].polarity;
|
| 264 |
+
|
| 265 |
+
uint8_t symbols[3] = {rc, rf, ra};
|
| 266 |
+
|
| 267 |
+
/* For dynamically tracking state history during the single concept */
|
| 268 |
+
uint8_t prev_rc = encoder_pred.prev_rc;
|
| 269 |
+
uint8_t prev_rf = encoder_pred.prev_rf;
|
| 270 |
+
uint8_t prev_ra = encoder_pred.prev_ra;
|
| 271 |
+
|
| 272 |
+
for (int step = 0; step < 3; step++) {
|
| 273 |
+
uint32_t cum_freqs[257];
|
| 274 |
+
if (step == 0) {
|
| 275 |
+
get_cum_freqs_rc(&encoder_pred, prev_rc, cum_freqs);
|
| 276 |
+
} else if (step == 1) {
|
| 277 |
+
get_cum_freqs_rf(&encoder_pred, symbols[0], prev_rf, cum_freqs);
|
| 278 |
+
} else {
|
| 279 |
+
get_cum_freqs_ra(&encoder_pred, symbols[0], symbols[1], prev_ra, cum_freqs);
|
| 280 |
+
}
|
| 281 |
+
|
| 282 |
+
uint8_t sym = symbols[step];
|
| 283 |
+
uint32_t total = cum_freqs[256];
|
| 284 |
+
uint32_t cum_low = cum_freqs[sym];
|
| 285 |
+
uint32_t cum_high = cum_freqs[sym + 1];
|
| 286 |
+
|
| 287 |
+
uint64_t range_width = (uint64_t)high - low + 1;
|
| 288 |
+
high = low + (uint32_t)((range_width * cum_high) / total) - 1;
|
| 289 |
+
low = low + (uint32_t)((range_width * cum_low) / total);
|
| 290 |
+
|
| 291 |
+
/* Renormalize */
|
| 292 |
+
while (1) {
|
| 293 |
+
if (high < RANGE_CODER_HALF_RANGE) {
|
| 294 |
+
write_bit_helper(&w, &underflow_bits, 0);
|
| 295 |
+
low <<= 1;
|
| 296 |
+
high = (high << 1) | 1U;
|
| 297 |
+
} else if (low >= RANGE_CODER_HALF_RANGE) {
|
| 298 |
+
write_bit_helper(&w, &underflow_bits, 1);
|
| 299 |
+
low = (low - RANGE_CODER_HALF_RANGE) << 1;
|
| 300 |
+
high = ((high - RANGE_CODER_HALF_RANGE) << 1) | 1U;
|
| 301 |
+
} else if (low >= RANGE_CODER_QTR_RANGE && high < RANGE_CODER_THREE_QTR) {
|
| 302 |
+
underflow_bits++;
|
| 303 |
+
low = (low - RANGE_CODER_QTR_RANGE) << 1;
|
| 304 |
+
high = ((high - RANGE_CODER_QTR_RANGE) << 1) | 1U;
|
| 305 |
+
} else {
|
| 306 |
+
break;
|
| 307 |
+
}
|
| 308 |
+
}
|
| 309 |
+
}
|
| 310 |
+
|
| 311 |
+
/* Update predictor with the verified concept */
|
| 312 |
+
predictor_observe(&encoder_pred, rc, rf, ra);
|
| 313 |
+
}
|
| 314 |
+
|
| 315 |
+
/* Final bit flush */
|
| 316 |
+
underflow_bits++;
|
| 317 |
+
if (low < RANGE_CODER_QTR_RANGE) {
|
| 318 |
+
write_bit_helper(&w, &underflow_bits, 0);
|
| 319 |
+
} else {
|
| 320 |
+
write_bit_helper(&w, &underflow_bits, 1);
|
| 321 |
+
}
|
| 322 |
+
|
| 323 |
+
return w.bit_index;
|
| 324 |
+
}
|
| 325 |
+
|
| 326 |
+
/**
|
| 327 |
+
* Decompresses a bitstream back into 6D concepts.
|
| 328 |
+
* returns: 1 on success, 0 on failure
|
| 329 |
+
*/
|
| 330 |
+
static int cuneiform_u_v3_decode(const uint8_t* in_buffer, uint32_t in_bytes,
|
| 331 |
+
Concept6D* out_concepts, uint32_t num_concepts,
|
| 332 |
+
uint32_t alpha, uint32_t weight) {
|
| 333 |
+
RadicalPredictor decoder_pred;
|
| 334 |
+
predictor_init(&decoder_pred, alpha, weight);
|
| 335 |
+
|
| 336 |
+
BitReader r;
|
| 337 |
+
bit_reader_init(&r, in_buffer, in_bytes);
|
| 338 |
+
|
| 339 |
+
/* Initialize value */
|
| 340 |
+
uint32_t value = 0;
|
| 341 |
+
for (int i = 0; i < 32; i++) {
|
| 342 |
+
value = (value << 1) | bit_reader_read(&r);
|
| 343 |
+
}
|
| 344 |
+
|
| 345 |
+
uint32_t low = 0;
|
| 346 |
+
uint32_t high = RANGE_CODER_MAX_RANGE;
|
| 347 |
+
|
| 348 |
+
for (uint32_t c = 0; c < num_concepts; c++) {
|
| 349 |
+
uint8_t prev_rc = decoder_pred.prev_rc;
|
| 350 |
+
uint8_t prev_rf = decoder_pred.prev_rf;
|
| 351 |
+
uint8_t prev_ra = decoder_pred.prev_ra;
|
| 352 |
+
|
| 353 |
+
uint8_t symbols[3] = {0, 0, 0};
|
| 354 |
+
|
| 355 |
+
for (int step = 0; step < 3; step++) {
|
| 356 |
+
uint32_t cum_freqs[257];
|
| 357 |
+
if (step == 0) {
|
| 358 |
+
get_cum_freqs_rc(&decoder_pred, prev_rc, cum_freqs);
|
| 359 |
+
} else if (step == 1) {
|
| 360 |
+
get_cum_freqs_rf(&decoder_pred, symbols[0], prev_rf, cum_freqs);
|
| 361 |
+
} else {
|
| 362 |
+
get_cum_freqs_ra(&decoder_pred, symbols[0], symbols[1], prev_ra, cum_freqs);
|
| 363 |
+
}
|
| 364 |
+
|
| 365 |
+
uint32_t total = cum_freqs[256];
|
| 366 |
+
uint64_t range_width = (uint64_t)high - low + 1;
|
| 367 |
+
|
| 368 |
+
/* Compute scaled value */
|
| 369 |
+
uint64_t scaled_val = (((uint64_t)(value - low) + 1) * total - 1) / range_width;
|
| 370 |
+
|
| 371 |
+
/* Find symbol using binary search */
|
| 372 |
+
uint8_t sym = 0;
|
| 373 |
+
int l = 0, rr = 255;
|
| 374 |
+
while (l <= rr) {
|
| 375 |
+
int mid = (l + rr) / 2;
|
| 376 |
+
if (cum_freqs[mid] <= scaled_val && scaled_val < cum_freqs[mid + 1]) {
|
| 377 |
+
sym = (uint8_t)mid;
|
| 378 |
+
break;
|
| 379 |
+
} else if (scaled_val >= cum_freqs[mid + 1]) {
|
| 380 |
+
l = mid + 1;
|
| 381 |
+
} else {
|
| 382 |
+
rr = mid - 1;
|
| 383 |
+
}
|
| 384 |
+
}
|
| 385 |
+
|
| 386 |
+
symbols[step] = sym;
|
| 387 |
+
|
| 388 |
+
uint32_t cum_low = cum_freqs[sym];
|
| 389 |
+
uint32_t cum_high = cum_freqs[sym + 1];
|
| 390 |
+
|
| 391 |
+
high = low + (uint32_t)((range_width * cum_high) / total) - 1;
|
| 392 |
+
low = low + (uint32_t)((range_width * cum_low) / total);
|
| 393 |
+
|
| 394 |
+
/* Renormalize */
|
| 395 |
+
while (1) {
|
| 396 |
+
if (high < RANGE_CODER_HALF_RANGE) {
|
| 397 |
+
low <<= 1;
|
| 398 |
+
high = (high << 1) | 1U;
|
| 399 |
+
value = (value << 1) | bit_reader_read(&r);
|
| 400 |
+
} else if (low >= RANGE_CODER_HALF_RANGE) {
|
| 401 |
+
low = (low - RANGE_CODER_HALF_RANGE) << 1;
|
| 402 |
+
high = ((high - RANGE_CODER_HALF_RANGE) << 1) | 1U;
|
| 403 |
+
value = ((value - RANGE_CODER_HALF_RANGE) << 1) | bit_reader_read(&r);
|
| 404 |
+
} else if (low >= RANGE_CODER_QTR_RANGE && high < RANGE_CODER_THREE_QTR) {
|
| 405 |
+
low = (low - RANGE_CODER_QTR_RANGE) << 1;
|
| 406 |
+
high = ((high - RANGE_CODER_QTR_RANGE) << 1) | 1U;
|
| 407 |
+
value = ((value - RANGE_CODER_QTR_RANGE) << 1) | bit_reader_read(&r);
|
| 408 |
+
} else {
|
| 409 |
+
break;
|
| 410 |
+
}
|
| 411 |
+
}
|
| 412 |
+
}
|
| 413 |
+
|
| 414 |
+
/* Save decoded coordinates */
|
| 415 |
+
out_concepts[c].domain = (symbols[0] >> 4) & 0xF;
|
| 416 |
+
out_concepts[c].subdomain = symbols[0] & 0xF;
|
| 417 |
+
out_concepts[c].operation = (symbols[1] >> 4) & 0xF;
|
| 418 |
+
out_concepts[c].modality = symbols[1] & 0xF;
|
| 419 |
+
out_concepts[c].depth = (symbols[2] >> 4) & 0xF;
|
| 420 |
+
out_concepts[c].polarity = symbols[2] & 0xF;
|
| 421 |
+
|
| 422 |
+
/* Keep decoder state predictor synchronized */
|
| 423 |
+
predictor_observe(&decoder_pred, symbols[0], symbols[1], symbols[2]);
|
| 424 |
+
}
|
| 425 |
+
|
| 426 |
+
return 1;
|
| 427 |
+
}
|
| 428 |
+
|
| 429 |
+
#ifdef __cplusplus
|
| 430 |
+
}
|
| 431 |
+
#endif
|
| 432 |
+
|
| 433 |
+
#endif /* CUNEIFORM_U_V3_H */
|
cuneiform_u_v3.rs
ADDED
|
@@ -0,0 +1,358 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Watermark: ip zymatica.space | astronautshe.com
|
| 2 |
+
// Copyright (c) 2026 Zymatica. All rights reserved.
|
| 3 |
+
|
| 4 |
+
use std::collections::HashMap;
|
| 5 |
+
|
| 6 |
+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
| 7 |
+
pub struct Concept6D {
|
| 8 |
+
pub domain: u8,
|
| 9 |
+
pub subdomain: u8,
|
| 10 |
+
pub operation: u8,
|
| 11 |
+
pub modality: u8,
|
| 12 |
+
pub depth: u8,
|
| 13 |
+
pub polarity: u8,
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
pub struct RadicalPredictor {
|
| 17 |
+
pub alpha: u32,
|
| 18 |
+
pub weight: u32,
|
| 19 |
+
pub trans_rc: HashMap<u8, HashMap<u8, u32>>,
|
| 20 |
+
pub trans_rf: HashMap<u16, HashMap<u8, u32>>,
|
| 21 |
+
pub trans_ra: HashMap<u32, HashMap<u8, u32>>,
|
| 22 |
+
pub prev_rc: u8,
|
| 23 |
+
pub prev_rf: u8,
|
| 24 |
+
pub prev_ra: u8,
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
impl RadicalPredictor {
|
| 28 |
+
pub fn new(alpha: u32, weight: u32) -> Self {
|
| 29 |
+
Self {
|
| 30 |
+
alpha,
|
| 31 |
+
weight,
|
| 32 |
+
trans_rc: HashMap::new(),
|
| 33 |
+
trans_rf: HashMap::new(),
|
| 34 |
+
trans_ra: HashMap::new(),
|
| 35 |
+
prev_rc: 0,
|
| 36 |
+
prev_rf: 0,
|
| 37 |
+
prev_ra: 0,
|
| 38 |
+
}
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
pub fn observe(&mut self, rc: u8, rf: u8, ra: u8) {
|
| 42 |
+
let w = self.weight;
|
| 43 |
+
let key_rc = self.prev_rc;
|
| 44 |
+
self.trans_rc
|
| 45 |
+
.entry(key_rc)
|
| 46 |
+
.or_insert_with(HashMap::new)
|
| 47 |
+
.entry(rc)
|
| 48 |
+
.and_modify(|c| *c += w)
|
| 49 |
+
.or_insert(w);
|
| 50 |
+
|
| 51 |
+
let key_rf = ((rc as u16) << 8) | (self.prev_rf as u16);
|
| 52 |
+
self.trans_rf
|
| 53 |
+
.entry(key_rf)
|
| 54 |
+
.or_insert_with(HashMap::new)
|
| 55 |
+
.entry(rf)
|
| 56 |
+
.and_modify(|c| *c += w)
|
| 57 |
+
.or_insert(w);
|
| 58 |
+
|
| 59 |
+
let key_ra = ((rc as u32) << 16) | ((rf as u32) << 8) | (self.prev_ra as u32);
|
| 60 |
+
self.trans_ra
|
| 61 |
+
.entry(key_ra)
|
| 62 |
+
.or_insert_with(HashMap::new)
|
| 63 |
+
.entry(ra)
|
| 64 |
+
.and_modify(|c| *c += w)
|
| 65 |
+
.or_insert(w);
|
| 66 |
+
|
| 67 |
+
self.prev_rc = rc;
|
| 68 |
+
self.prev_rf = rf;
|
| 69 |
+
self.prev_ra = ra;
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
pub fn get_cum_freqs_rc(&self, prev_rc: u8) -> Vec<u32> {
|
| 73 |
+
let mut freqs = vec![self.alpha; 256];
|
| 74 |
+
if let Some(map) = self.trans_rc.get(&prev_rc) {
|
| 75 |
+
for (&sym, &count) in map {
|
| 76 |
+
freqs[sym as usize] += count;
|
| 77 |
+
}
|
| 78 |
+
}
|
| 79 |
+
let mut cum_freqs = vec![0; 257];
|
| 80 |
+
for i in 0..256 {
|
| 81 |
+
cum_freqs[i + 1] = cum_freqs[i] + freqs[i];
|
| 82 |
+
}
|
| 83 |
+
cum_freqs
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
pub fn get_cum_freqs_rf(&self, curr_rc: u8, prev_rf: u8) -> Vec<u32> {
|
| 87 |
+
let mut freqs = vec![self.alpha; 256];
|
| 88 |
+
let key = ((curr_rc as u16) << 8) | (prev_rf as u16);
|
| 89 |
+
if let Some(map) = self.trans_rf.get(&key) {
|
| 90 |
+
for (&sym, &count) in map {
|
| 91 |
+
freqs[sym as usize] += count;
|
| 92 |
+
}
|
| 93 |
+
}
|
| 94 |
+
let mut cum_freqs = vec![0; 257];
|
| 95 |
+
for i in 0..256 {
|
| 96 |
+
cum_freqs[i + 1] = cum_freqs[i] + freqs[i];
|
| 97 |
+
}
|
| 98 |
+
cum_freqs
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
pub fn get_cum_freqs_ra(&self, curr_rc: u8, curr_rf: u8, prev_ra: u8) -> Vec<u32> {
|
| 102 |
+
let mut freqs = vec![self.alpha; 256];
|
| 103 |
+
let key = ((curr_rc as u32) << 16) | ((curr_rf as u32) << 8) | (prev_ra as u32);
|
| 104 |
+
if let Some(map) = self.trans_ra.get(&key) {
|
| 105 |
+
for (&sym, &count) in map {
|
| 106 |
+
freqs[sym as usize] += count;
|
| 107 |
+
}
|
| 108 |
+
}
|
| 109 |
+
let mut cum_freqs = vec![0; 257];
|
| 110 |
+
for i in 0..256 {
|
| 111 |
+
cum_freqs[i + 1] = cum_freqs[i] + freqs[i];
|
| 112 |
+
}
|
| 113 |
+
cum_freqs
|
| 114 |
+
}
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
pub struct BitWriter {
|
| 118 |
+
pub buffer: Vec<u8>,
|
| 119 |
+
pub current_byte: u8,
|
| 120 |
+
pub bit_count: usize,
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
impl BitWriter {
|
| 124 |
+
pub fn new() -> Self {
|
| 125 |
+
Self {
|
| 126 |
+
buffer: Vec::new(),
|
| 127 |
+
current_byte: 0,
|
| 128 |
+
bit_count: 0,
|
| 129 |
+
}
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
pub fn write_bit(&mut self, bit: u8) {
|
| 133 |
+
self.current_byte = (self.current_byte << 1) | (bit & 1);
|
| 134 |
+
self.bit_count += 1;
|
| 135 |
+
if self.bit_count % 8 == 0 {
|
| 136 |
+
self.buffer.push(self.current_byte);
|
| 137 |
+
self.current_byte = 0;
|
| 138 |
+
}
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
pub fn write_bit_helper(&mut self, underflow_bits: &mut u32, bit: u8) {
|
| 142 |
+
self.write_bit(bit);
|
| 143 |
+
while *underflow_bits > 0 {
|
| 144 |
+
self.write_bit(1 - bit);
|
| 145 |
+
*underflow_bits -= 1;
|
| 146 |
+
}
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
pub fn flush(&mut self) -> Vec<u8> {
|
| 150 |
+
if self.bit_count % 8 != 0 {
|
| 151 |
+
let padding_bits = 8 - (self.bit_count % 8);
|
| 152 |
+
self.current_byte <<= padding_bits;
|
| 153 |
+
self.buffer.push(self.current_byte);
|
| 154 |
+
self.current_byte = 0;
|
| 155 |
+
self.bit_count += padding_bits;
|
| 156 |
+
}
|
| 157 |
+
self.buffer.clone()
|
| 158 |
+
}
|
| 159 |
+
}
|
| 160 |
+
|
| 161 |
+
pub struct BitReader {
|
| 162 |
+
pub data: Vec<u8>,
|
| 163 |
+
pub byte_index: usize,
|
| 164 |
+
pub bit_index: usize,
|
| 165 |
+
pub total_bits: usize,
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
impl BitReader {
|
| 169 |
+
pub fn new(data: Vec<u8>) -> Self {
|
| 170 |
+
let total_bits = data.len() * 8;
|
| 171 |
+
Self {
|
| 172 |
+
data,
|
| 173 |
+
byte_index: 0,
|
| 174 |
+
bit_index: 0,
|
| 175 |
+
total_bits,
|
| 176 |
+
}
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
pub fn read_bit(&mut self) -> u8 {
|
| 180 |
+
if self.byte_index >= self.data.len() {
|
| 181 |
+
return 0;
|
| 182 |
+
}
|
| 183 |
+
let bit = (self.data[self.byte_index] >> (7 - self.bit_index)) & 1;
|
| 184 |
+
self.bit_index += 1;
|
| 185 |
+
if self.bit_index == 8 {
|
| 186 |
+
self.bit_index = 0;
|
| 187 |
+
self.byte_index += 1;
|
| 188 |
+
}
|
| 189 |
+
bit
|
| 190 |
+
}
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
pub fn cuneiform_u_v3_encode(
|
| 194 |
+
concepts: &[Concept6D],
|
| 195 |
+
alpha: u32,
|
| 196 |
+
weight: u32,
|
| 197 |
+
) -> Vec<u8> {
|
| 198 |
+
let mut pred = RadicalPredictor::new(alpha, weight);
|
| 199 |
+
let mut w = BitWriter::new();
|
| 200 |
+
|
| 201 |
+
let mut low: u32 = 0;
|
| 202 |
+
let mut high: u32 = 0xFFFFFFFF;
|
| 203 |
+
let mut underflow_bits: u32 = 0;
|
| 204 |
+
|
| 205 |
+
for c in concepts {
|
| 206 |
+
let rc = (c.domain << 4) | c.subdomain;
|
| 207 |
+
let rf = (c.operation << 4) | c.modality;
|
| 208 |
+
let ra = (c.depth << 4) | c.polarity;
|
| 209 |
+
|
| 210 |
+
let symbols = [rc, rf, ra];
|
| 211 |
+
let prev_rc = pred.prev_rc;
|
| 212 |
+
let prev_rf = pred.prev_rf;
|
| 213 |
+
let prev_ra = pred.prev_ra;
|
| 214 |
+
|
| 215 |
+
for step in 0..3 {
|
| 216 |
+
let cum_freqs = match step {
|
| 217 |
+
0 => pred.get_cum_freqs_rc(prev_rc),
|
| 218 |
+
1 => pred.get_cum_freqs_rf(symbols[0], prev_rf),
|
| 219 |
+
_ => pred.get_cum_freqs_ra(symbols[0], symbols[1], prev_ra),
|
| 220 |
+
};
|
| 221 |
+
|
| 222 |
+
let sym = symbols[step] as usize;
|
| 223 |
+
let total = cum_freqs[256];
|
| 224 |
+
let cum_low = cum_freqs[sym];
|
| 225 |
+
let cum_high = cum_freqs[sym + 1];
|
| 226 |
+
|
| 227 |
+
let range_width = (high as u64) - (low as u64) + 1;
|
| 228 |
+
high = low + ((range_width * cum_high as u64) / total as u64) as u32 - 1;
|
| 229 |
+
low = low + ((range_width * cum_low as u64) / total as u64) as u32;
|
| 230 |
+
|
| 231 |
+
// Renormalize
|
| 232 |
+
loop {
|
| 233 |
+
if high < 0x80000000 {
|
| 234 |
+
w.write_bit_helper(&mut underflow_bits, 0);
|
| 235 |
+
low <<= 1;
|
| 236 |
+
high = (high << 1) | 1;
|
| 237 |
+
} else if low >= 0x80000000 {
|
| 238 |
+
w.write_bit_helper(&mut underflow_bits, 1);
|
| 239 |
+
low = (low - 0x80000000) << 1;
|
| 240 |
+
high = ((high - 0x80000000) << 1) | 1;
|
| 241 |
+
} else if low >= 0x40000000 && high < 0xC0000000 {
|
| 242 |
+
underflow_bits += 1;
|
| 243 |
+
low = (low - 0x40000000) << 1;
|
| 244 |
+
high = ((high - 0x40000000) << 1) | 1;
|
| 245 |
+
} else {
|
| 246 |
+
break;
|
| 247 |
+
}
|
| 248 |
+
}
|
| 249 |
+
}
|
| 250 |
+
pred.observe(rc, rf, ra);
|
| 251 |
+
}
|
| 252 |
+
|
| 253 |
+
underflow_bits += 1;
|
| 254 |
+
if low < 0x40000000 {
|
| 255 |
+
w.write_bit_helper(&mut underflow_bits, 0);
|
| 256 |
+
} else {
|
| 257 |
+
w.write_bit_helper(&mut underflow_bits, 1);
|
| 258 |
+
}
|
| 259 |
+
|
| 260 |
+
w.flush()
|
| 261 |
+
}
|
| 262 |
+
|
| 263 |
+
pub fn cuneiform_u_v3_decode(
|
| 264 |
+
encoded_bytes: Vec<u8>,
|
| 265 |
+
num_concepts: usize,
|
| 266 |
+
alpha: u32,
|
| 267 |
+
weight: u32,
|
| 268 |
+
) -> Vec<Concept6D> {
|
| 269 |
+
let mut pred = RadicalPredictor::new(alpha, weight);
|
| 270 |
+
let mut r = BitReader::new(encoded_bytes);
|
| 271 |
+
|
| 272 |
+
let mut value: u32 = 0;
|
| 273 |
+
for _ in 0..32 {
|
| 274 |
+
value = (value << 1) | (r.read_bit() as u32);
|
| 275 |
+
}
|
| 276 |
+
|
| 277 |
+
let mut low: u32 = 0;
|
| 278 |
+
let mut high: u32 = 0xFFFFFFFF;
|
| 279 |
+
let mut decoded = Vec::with_capacity(num_concepts);
|
| 280 |
+
|
| 281 |
+
for _ in 0..num_concepts {
|
| 282 |
+
let prev_rc = pred.prev_rc;
|
| 283 |
+
let prev_rf = pred.prev_rf;
|
| 284 |
+
let prev_ra = pred.prev_ra;
|
| 285 |
+
|
| 286 |
+
let mut symbols = [0u8; 3];
|
| 287 |
+
|
| 288 |
+
for step in 0..3 {
|
| 289 |
+
let cum_freqs = match step {
|
| 290 |
+
0 => pred.get_cum_freqs_rc(prev_rc),
|
| 291 |
+
1 => pred.get_cum_freqs_rf(symbols[0], prev_rf),
|
| 292 |
+
_ => pred.get_cum_freqs_ra(symbols[0], symbols[1], prev_ra),
|
| 293 |
+
};
|
| 294 |
+
|
| 295 |
+
let total = cum_freqs[256] as u64;
|
| 296 |
+
let range_width = (high as u64) - (low as u64) + 1;
|
| 297 |
+
let scaled_val = (((value as u64 - low as u64) + 1) * total - 1) / range_width;
|
| 298 |
+
|
| 299 |
+
// Binary search
|
| 300 |
+
let mut sym = 0u8;
|
| 301 |
+
let mut l = 0i32;
|
| 302 |
+
let mut rr = 255i32;
|
| 303 |
+
while l <= rr {
|
| 304 |
+
let mid = (l + rr) / 2;
|
| 305 |
+
let cum_mid = cum_freqs[mid as usize] as u64;
|
| 306 |
+
let cum_mid_next = cum_freqs[(mid + 1) as usize] as u64;
|
| 307 |
+
if cum_mid <= scaled_val && scaled_val < cum_mid_next {
|
| 308 |
+
sym = mid as u8;
|
| 309 |
+
break;
|
| 310 |
+
} else if scaled_val >= cum_mid_next {
|
| 311 |
+
l = mid + 1;
|
| 312 |
+
} else {
|
| 313 |
+
rr = mid - 1;
|
| 314 |
+
}
|
| 315 |
+
}
|
| 316 |
+
|
| 317 |
+
symbols[step] = sym;
|
| 318 |
+
|
| 319 |
+
let cum_low = cum_freqs[sym as usize];
|
| 320 |
+
let cum_high = cum_freqs[(sym + 1) as usize];
|
| 321 |
+
|
| 322 |
+
high = low + ((range_width * cum_high as u64) / total) as u32 - 1;
|
| 323 |
+
low = low + ((range_width * cum_low as u64) / total) as u32;
|
| 324 |
+
|
| 325 |
+
// Renormalize
|
| 326 |
+
loop {
|
| 327 |
+
if high < 0x80000000 {
|
| 328 |
+
low <<= 1;
|
| 329 |
+
high = (high << 1) | 1;
|
| 330 |
+
value = (value << 1) | (r.read_bit() as u32);
|
| 331 |
+
} else if low >= 0x80000000 {
|
| 332 |
+
low = (low - 0x80000000) << 1;
|
| 333 |
+
high = ((high - 0x80000000) << 1) | 1;
|
| 334 |
+
value = ((value - 0x80000000) << 1) | (r.read_bit() as u32);
|
| 335 |
+
} else if low >= 0x40000000 && high < 0xC0000000 {
|
| 336 |
+
low = (low - 0x40000000) << 1;
|
| 337 |
+
high = ((high - 0x40000000) << 1) | 1;
|
| 338 |
+
value = ((value - 0x40000000) << 1) | (r.read_bit() as u32);
|
| 339 |
+
} else {
|
| 340 |
+
break;
|
| 341 |
+
}
|
| 342 |
+
}
|
| 343 |
+
}
|
| 344 |
+
|
| 345 |
+
decoded.push(Concept6D {
|
| 346 |
+
domain: symbols[0] >> 4,
|
| 347 |
+
subdomain: symbols[0] & 0x0F,
|
| 348 |
+
operation: symbols[1] >> 4,
|
| 349 |
+
modality: symbols[1] & 0x0F,
|
| 350 |
+
depth: symbols[2] >> 4,
|
| 351 |
+
polarity: symbols[2] & 0x0F,
|
| 352 |
+
});
|
| 353 |
+
|
| 354 |
+
pred.observe(symbols[0], symbols[1], symbols[2]);
|
| 355 |
+
}
|
| 356 |
+
|
| 357 |
+
decoded
|
| 358 |
+
}
|
decode_gemma4.py
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Standalone weight decoder/reconstructor for Gemma-4-31B-it SubZero
|
| 2 |
+
# Watermark: ip zymatica.space | astronautshe.com
|
| 3 |
+
|
| 4 |
+
import os
|
| 5 |
+
import sys
|
| 6 |
+
import json
|
| 7 |
+
import struct
|
| 8 |
+
import time
|
| 9 |
+
import torch
|
| 10 |
+
from safetensors.torch import save_file
|
| 11 |
+
|
| 12 |
+
def main():
|
| 13 |
+
print("=" * 80)
|
| 14 |
+
print(" GEMMA-4-31B-IT SUBZERO WEIGHT DECODER / RECONSTRUCTOR")
|
| 15 |
+
print(" Watermark: ip zymatica.space | astronautshe.com")
|
| 16 |
+
print("=" * 80)
|
| 17 |
+
|
| 18 |
+
genesis_path = "J:/gemma-4-31B-it-local/working/gemma4_31b_subzero.genesis"
|
| 19 |
+
output_dir = "J:/gemma-4-31B-it-local/working/reconstructed_gemma4"
|
| 20 |
+
os.makedirs(output_dir, exist_ok=True)
|
| 21 |
+
|
| 22 |
+
if not os.path.exists(genesis_path):
|
| 23 |
+
print(f"[-] Error: Could not find genesis file at {genesis_path}")
|
| 24 |
+
print(" Please download/place 'gemma4_31b_subzero.genesis' in the current folder.")
|
| 25 |
+
sys.exit(1)
|
| 26 |
+
|
| 27 |
+
GENESIS_MAGIC = 0x47454E45 # "GENE"
|
| 28 |
+
GENESIS_VERSION = 4 # INT8 version
|
| 29 |
+
PERFECT_MAGIC = 0x50455246 # "PERF"
|
| 30 |
+
|
| 31 |
+
print(f"[*] Reading and parsing genesis file: {genesis_path}...")
|
| 32 |
+
start_time = time.time()
|
| 33 |
+
|
| 34 |
+
layer_map = {}
|
| 35 |
+
|
| 36 |
+
with open(genesis_path, "rb") as f:
|
| 37 |
+
magic = struct.unpack('>I', f.read(4))[0]
|
| 38 |
+
assert magic == GENESIS_MAGIC, "Invalid genesis magic header"
|
| 39 |
+
version = struct.unpack('>H', f.read(2))[0]
|
| 40 |
+
assert version == GENESIS_VERSION, f"Unsupported version: {version}"
|
| 41 |
+
watermark = f.read(32).decode('utf-8', errors='ignore').strip()
|
| 42 |
+
perf_magic = struct.unpack('>I', f.read(4))[0]
|
| 43 |
+
assert perf_magic == PERFECT_MAGIC, "Invalid perfect magic header"
|
| 44 |
+
|
| 45 |
+
hidden_dim, num_heads, kv_heads, ffn_dim, num_blocks, vocab_size = struct.unpack('>IIIIII', f.read(24))
|
| 46 |
+
f.read(16) # Skip scales/energy targets
|
| 47 |
+
num_layers = struct.unpack('>I', f.read(4))[0]
|
| 48 |
+
|
| 49 |
+
print(f" Watermark: {watermark}")
|
| 50 |
+
print(f" Layers: {num_layers} | blocks: {num_blocks} | hidden: {hidden_dim} | ffn: {ffn_dim}")
|
| 51 |
+
|
| 52 |
+
for idx in range(num_layers):
|
| 53 |
+
name_len = struct.unpack('>H', f.read(2))[0]
|
| 54 |
+
name = f.read(name_len).decode('utf-8')
|
| 55 |
+
m, n, rank = struct.unpack('>III', f.read(12))
|
| 56 |
+
scale_u, scale_v = struct.unpack('>ff', f.read(8))
|
| 57 |
+
|
| 58 |
+
# Read int8 SVD vectors
|
| 59 |
+
u_bytes = f.read(m * rank)
|
| 60 |
+
v_bytes = f.read(n * rank)
|
| 61 |
+
|
| 62 |
+
U_q = torch.frombuffer(bytearray(u_bytes), dtype=torch.int8).reshape(m, rank).float()
|
| 63 |
+
V_q = torch.frombuffer(bytearray(v_bytes), dtype=torch.int8).reshape(n, rank).float()
|
| 64 |
+
|
| 65 |
+
has_residual = struct.unpack('>?', f.read(1))[0]
|
| 66 |
+
if has_residual:
|
| 67 |
+
# residual block (if any, skipped in default run)
|
| 68 |
+
res_rank = struct.unpack('>I', f.read(4))[0]
|
| 69 |
+
su_r, sv_r = struct.unpack('>ff', f.read(8))
|
| 70 |
+
U_res = torch.frombuffer(bytearray(f.read(m * res_rank)), dtype=torch.int8).reshape(m, res_rank).float() * su_r
|
| 71 |
+
V_res = torch.frombuffer(bytearray(f.read(n * res_rank)), dtype=torch.int8).reshape(n, res_rank).float() * sv_r
|
| 72 |
+
|
| 73 |
+
# Reconstruct weight matrix: W = (U * su) @ (V * sv).T
|
| 74 |
+
U = U_q * scale_u
|
| 75 |
+
V = V_q * scale_v
|
| 76 |
+
W_rec = U @ V.t()
|
| 77 |
+
|
| 78 |
+
if has_residual:
|
| 79 |
+
W_rec = W_rec + (U_res @ V_res.t())
|
| 80 |
+
|
| 81 |
+
# Convert back to bfloat16
|
| 82 |
+
layer_map[name] = W_rec.to(torch.bfloat16)
|
| 83 |
+
|
| 84 |
+
if (idx + 1) % 50 == 0 or idx + 1 == num_layers:
|
| 85 |
+
print(f" [{idx+1:3d}/{num_layers}] Reconstructed: {name[-50:]} ({m}x{n} rank {rank})")
|
| 86 |
+
|
| 87 |
+
# Save the reconstructed model weights into two shards mirroring the original model
|
| 88 |
+
print("\n[*] Sharding and saving reconstructed weights as safetensors...")
|
| 89 |
+
|
| 90 |
+
# We split tensors based on the original shard mapping:
|
| 91 |
+
# Shard 1 contains layers 0 to 47. Shard 2 contains layers 48 to 59.
|
| 92 |
+
shard_1_tensors = {}
|
| 93 |
+
shard_2_tensors = {}
|
| 94 |
+
|
| 95 |
+
for name, tensor in layer_map.items():
|
| 96 |
+
is_shard_2 = False
|
| 97 |
+
for i in range(48, 60):
|
| 98 |
+
if f"layers.{i}." in name:
|
| 99 |
+
is_shard_2 = True
|
| 100 |
+
break
|
| 101 |
+
if is_shard_2:
|
| 102 |
+
shard_2_tensors[name] = tensor
|
| 103 |
+
else:
|
| 104 |
+
shard_1_tensors[name] = tensor
|
| 105 |
+
|
| 106 |
+
# Add zero-initialized non-SVD layers (layernorms, embed_tokens, etc.) to complete weights dictionary
|
| 107 |
+
# The receiver SFT healing loop will restore the values of norms/embeddings.
|
| 108 |
+
print(" - Injecting placeholder non-SVD layers (layernorms, embed_tokens)...")
|
| 109 |
+
|
| 110 |
+
# Embed tokens shape: [vocab_size, hidden_dim]
|
| 111 |
+
embed_shape = (vocab_size, hidden_dim)
|
| 112 |
+
shard_1_tensors["model.language_model.embed_tokens.weight"] = torch.zeros(embed_shape, dtype=torch.bfloat16)
|
| 113 |
+
|
| 114 |
+
# Layernorm and position embeddings
|
| 115 |
+
for name in ["model.embed_vision.embedding_projection.bias", "model.language_model.final_layernorm.weight"]:
|
| 116 |
+
shard_2_tensors[name] = torch.zeros((hidden_dim,), dtype=torch.bfloat16)
|
| 117 |
+
|
| 118 |
+
for i in range(num_blocks):
|
| 119 |
+
target_shard = shard_2_tensors if i >= 48 else shard_1_tensors
|
| 120 |
+
target_shard[f"model.language_model.layers.{i}.input_layernorm.weight"] = torch.zeros((hidden_dim,), dtype=torch.bfloat16)
|
| 121 |
+
target_shard[f"model.language_model.layers.{i}.post_attention_layernorm.weight"] = torch.zeros((hidden_dim,), dtype=torch.bfloat16)
|
| 122 |
+
target_shard[f"model.language_model.layers.{i}.pre_feedforward_layernorm.weight"] = torch.zeros((hidden_dim,), dtype=torch.bfloat16)
|
| 123 |
+
target_shard[f"model.language_model.layers.{i}.post_feedforward_layernorm.weight"] = torch.zeros((hidden_dim,), dtype=torch.bfloat16)
|
| 124 |
+
target_shard[f"model.language_model.layers.{i}.layer_scalar"] = torch.zeros((1,), dtype=torch.bfloat16)
|
| 125 |
+
|
| 126 |
+
# Save files
|
| 127 |
+
s1_path = os.path.join(output_dir, "model-00001-of-00002.safetensors")
|
| 128 |
+
s2_path = os.path.join(output_dir, "model-00002-of-00002.safetensors")
|
| 129 |
+
|
| 130 |
+
print(f" - Saving shard 1 ({len(shard_1_tensors)} tensors) to {s1_path}...")
|
| 131 |
+
save_file(shard_1_tensors, s1_path)
|
| 132 |
+
|
| 133 |
+
print(f" - Saving shard 2 ({len(shard_2_tensors)} tensors) to {s2_path}...")
|
| 134 |
+
save_file(shard_2_tensors, s2_path)
|
| 135 |
+
|
| 136 |
+
elapsed = time.time() - start_time
|
| 137 |
+
print(f"\n[+] Standalone weights reconstruction successfully completed in {elapsed:.1f}s!")
|
| 138 |
+
print(f" Reconstructed model directory: {output_dir}")
|
| 139 |
+
print(" (Note: run local LoRA SFT healing next to restore full coherence)")
|
| 140 |
+
print("=" * 80)
|
| 141 |
+
|
| 142 |
+
if __name__ == "__main__":
|
| 143 |
+
main()
|
decode_gemma4_seed.py
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Gemma-4 Standalone Reconstructor
|
| 2 |
+
# WARNING: This decoder produces a LOSSY APPROXIMATION. The rank-3 seed captures only
|
| 3 |
+
# the top-3 dictionary pursuit projections per weight matrix. Embedding and layernorm
|
| 4 |
+
# parameters are initialized to defaults (zeros/ones), NOT reconstructed from the seed.
|
| 5 |
+
# Watermark: ip zymatica.space | astronautshe.com
|
| 6 |
+
import os, sys, struct, zlib, json, gc
|
| 7 |
+
import numpy as np, torch
|
| 8 |
+
from safetensors.torch import save_file
|
| 9 |
+
|
| 10 |
+
MS, DS, GM, PM = 42, 256, 0x47454E45, 0x50455246
|
| 11 |
+
|
| 12 |
+
def get_dict(dim, ds, seed):
|
| 13 |
+
rng = np.random.RandomState(seed)
|
| 14 |
+
m = rng.standard_normal((dim, ds)).astype(np.float32)
|
| 15 |
+
return m / (np.linalg.norm(m, axis=0, keepdims=True) + 1e-9)
|
| 16 |
+
|
| 17 |
+
def get_si(name):
|
| 18 |
+
if "embed_vision" in name:
|
| 19 |
+
return 5, [5376, 1152], "zeros"
|
| 20 |
+
elif "embed_tokens" in name:
|
| 21 |
+
return 5, [262144, 5376], "embed"
|
| 22 |
+
elif "language_model.norm" in name:
|
| 23 |
+
return 5, [5376], "ones"
|
| 24 |
+
elif "patch_embedder.input_proj" in name:
|
| 25 |
+
return 5, [1152, 768], "zeros"
|
| 26 |
+
elif "position_embedding_table" in name:
|
| 27 |
+
return 5, [2, 10240, 1152], "embed"
|
| 28 |
+
elif "std_bias" in name:
|
| 29 |
+
return 5, [1152], "zeros"
|
| 30 |
+
elif "std_scale" in name:
|
| 31 |
+
return 5, [1152], "ones"
|
| 32 |
+
|
| 33 |
+
if "language_model.layers." in name:
|
| 34 |
+
b = int(name.split('.')[3])
|
| 35 |
+
s_idx = min(5, b // 12 + 1)
|
| 36 |
+
if any(x in name for x in ["layernorm", "layer_scalar"]):
|
| 37 |
+
return s_idx, ([1] if "layer" in name else [5376]), "ones"
|
| 38 |
+
elif "k_norm" in name or "q_norm" in name:
|
| 39 |
+
return s_idx, ([512] if (b % 6 == 5) else [256]), "ones"
|
| 40 |
+
|
| 41 |
+
is_sp = (b % 6 == 5)
|
| 42 |
+
if "self_attn.q_proj" in name:
|
| 43 |
+
return s_idx, ([16384, 5376] if is_sp else [8192, 5376]), "svd"
|
| 44 |
+
elif "self_attn.k_proj" in name:
|
| 45 |
+
return s_idx, ([2048, 5376] if is_sp else [4096, 5376]), "svd"
|
| 46 |
+
elif "self_attn.v_proj" in name:
|
| 47 |
+
return s_idx, [4096, 5376], "svd"
|
| 48 |
+
elif "self_attn.o_proj" in name:
|
| 49 |
+
return s_idx, ([5376, 16384] if is_sp else [5376, 8192]), "svd"
|
| 50 |
+
elif "mlp.gate" in name or "mlp.up" in name:
|
| 51 |
+
return s_idx, [21504, 5376], "svd"
|
| 52 |
+
elif "mlp.down" in name:
|
| 53 |
+
return s_idx, [5376, 21504], "svd"
|
| 54 |
+
|
| 55 |
+
if "vision_tower.encoder.layers." in name:
|
| 56 |
+
if any(x in name for x in ["layernorm"]):
|
| 57 |
+
return 5, [1152], "ones"
|
| 58 |
+
elif "k_norm" in name or "q_norm" in name:
|
| 59 |
+
return 5, [72], "ones"
|
| 60 |
+
elif "self_attn" in name:
|
| 61 |
+
return 5, [1152, 1152], "svd"
|
| 62 |
+
elif "mlp.gate" in name or "mlp.up" in name:
|
| 63 |
+
return 5, [4304, 1152], "svd"
|
| 64 |
+
elif "mlp.down" in name:
|
| 65 |
+
return 5, [1152, 4304], "svd"
|
| 66 |
+
return None, None, None
|
| 67 |
+
|
| 68 |
+
def gen_keys():
|
| 69 |
+
keys = [
|
| 70 |
+
"model.embed_vision.embedding_projection.weight", "model.language_model.embed_tokens.weight",
|
| 71 |
+
"model.language_model.norm.weight", "model.vision_tower.patch_embedder.input_proj.weight",
|
| 72 |
+
"model.vision_tower.patch_embedder.position_embedding_table", "model.vision_tower.std_bias", "model.vision_tower.std_scale"
|
| 73 |
+
]
|
| 74 |
+
for i in range(60):
|
| 75 |
+
pre = f"model.language_model.layers.{i}"
|
| 76 |
+
keys.extend([
|
| 77 |
+
f"{pre}.input_layernorm.weight", f"{pre}.post_attention_layernorm.weight",
|
| 78 |
+
f"{pre}.pre_feedforward_layernorm.weight", f"{pre}.post_feedforward_layernorm.weight",
|
| 79 |
+
f"{pre}.layer_scalar", f"{pre}.self_attn.k_norm.weight",
|
| 80 |
+
f"{pre}.self_attn.q_norm.weight", f"{pre}.self_attn.q_proj.weight",
|
| 81 |
+
f"{pre}.self_attn.k_proj.weight"
|
| 82 |
+
])
|
| 83 |
+
if i % 6 != 5:
|
| 84 |
+
keys.append(f"{pre}.self_attn.v_proj.weight")
|
| 85 |
+
keys.extend([
|
| 86 |
+
f"{pre}.self_attn.o_proj.weight", f"{pre}.mlp.gate_proj.weight",
|
| 87 |
+
f"{pre}.mlp.up_proj.weight", f"{pre}.mlp.down_proj.weight"
|
| 88 |
+
])
|
| 89 |
+
for i in range(27):
|
| 90 |
+
pre = f"model.vision_tower.encoder.layers.{i}"
|
| 91 |
+
keys.extend([
|
| 92 |
+
f"{pre}.input_layernorm.weight", f"{pre}.post_attention_layernorm.weight",
|
| 93 |
+
f"{pre}.pre_feedforward_layernorm.weight", f"{pre}.post_feedforward_layernorm.weight",
|
| 94 |
+
f"{pre}.self_attn.k_norm.weight", f"{pre}.self_attn.q_norm.weight",
|
| 95 |
+
f"{pre}.self_attn.q_proj.linear.weight", f"{pre}.self_attn.k_proj.linear.weight",
|
| 96 |
+
f"{pre}.self_attn.v_proj.linear.weight", f"{pre}.self_attn.o_proj.linear.weight",
|
| 97 |
+
f"{pre}.mlp.gate_proj.linear.weight", f"{pre}.mlp.up_proj.linear.weight",
|
| 98 |
+
f"{pre}.mlp.down_proj.linear.weight"
|
| 99 |
+
])
|
| 100 |
+
return keys
|
| 101 |
+
|
| 102 |
+
def reconstruct(seed_path, output_dir):
|
| 103 |
+
with open(seed_path, "rb") as f_in:
|
| 104 |
+
raw = zlib.decompress(f_in.read())
|
| 105 |
+
pos = 0
|
| 106 |
+
magic = struct.unpack_from('>I', raw, pos)[0]; pos += 4
|
| 107 |
+
assert magic == GM
|
| 108 |
+
version = struct.unpack_from('>H', raw, pos)[0]; pos += 2
|
| 109 |
+
assert version == 12
|
| 110 |
+
pos += 32 + 4
|
| 111 |
+
hidden, heads, kv_heads, ffn_dim, blocks, vocab = struct.unpack_from('>IIIIII', raw, pos); pos += 24
|
| 112 |
+
pos += 16
|
| 113 |
+
num_layers = struct.unpack_from('>I', raw, pos)[0]; pos += 4
|
| 114 |
+
|
| 115 |
+
svd = {}
|
| 116 |
+
for idx in range(num_layers):
|
| 117 |
+
nl = struct.unpack_from('>H', raw, pos)[0]; pos += 2
|
| 118 |
+
name = raw[pos : pos + nl].decode('utf-8'); pos += nl
|
| 119 |
+
m, n, r = struct.unpack_from('>III', raw, pos); pos += 12
|
| 120 |
+
svd[name] = {"idx": idx, "m": m, "n": n, "r": r, "pos": pos}
|
| 121 |
+
pos += r * 4
|
| 122 |
+
|
| 123 |
+
all_keys = gen_keys()
|
| 124 |
+
idx_json = {"metadata": {"total_size": 0}, "weight_map": {}}
|
| 125 |
+
os.makedirs(output_dir, exist_ok=True)
|
| 126 |
+
|
| 127 |
+
for sh in range(1, 6):
|
| 128 |
+
fn = f"model-0000{sh}-of-00005.safetensors"
|
| 129 |
+
print(f"Reconstructing Shard {sh}/5...")
|
| 130 |
+
tensors = {}
|
| 131 |
+
for key in all_keys:
|
| 132 |
+
target_sh, shape, init = get_si(key)
|
| 133 |
+
if target_sh == sh:
|
| 134 |
+
if init == "ones":
|
| 135 |
+
t = torch.ones(shape, dtype=torch.bfloat16)
|
| 136 |
+
elif init == "embed":
|
| 137 |
+
# Embeddings are NOT stored in the seed — initialize to zeros
|
| 138 |
+
# (not random, since we cannot recover the original embedding values)
|
| 139 |
+
t = torch.zeros(shape, dtype=torch.bfloat16)
|
| 140 |
+
else:
|
| 141 |
+
t = torch.zeros(shape, dtype=torch.bfloat16)
|
| 142 |
+
|
| 143 |
+
if key in svd:
|
| 144 |
+
meta = svd[key]
|
| 145 |
+
idx_val, m, n, r, p_pos = meta["idx"], meta["m"], meta["n"], meta["r"], meta["pos"]
|
| 146 |
+
U = get_dict(m, DS, MS + idx_val * 1000)
|
| 147 |
+
V = get_dict(n, DS, MS + idx_val * 1000 + 500)
|
| 148 |
+
iu, iv, cs = [], [], []
|
| 149 |
+
temp = p_pos
|
| 150 |
+
for _ in range(r):
|
| 151 |
+
iu.append(raw[temp])
|
| 152 |
+
iv.append(raw[temp+1])
|
| 153 |
+
c = struct.unpack_from('>e', raw, temp+2)[0]
|
| 154 |
+
cs.append(c)
|
| 155 |
+
temp += 4
|
| 156 |
+
t = torch.from_numpy((U[:, iu] * np.array(cs, dtype=np.float32)) @ V[:, iv].T).to(torch.bfloat16)
|
| 157 |
+
tensors[key] = t
|
| 158 |
+
idx_json["weight_map"][key] = fn
|
| 159 |
+
save_file(tensors, os.path.join(output_dir, fn))
|
| 160 |
+
del tensors
|
| 161 |
+
gc.collect()
|
| 162 |
+
|
| 163 |
+
with open(os.path.join(output_dir, "model.safetensors.index.json"), "w") as f:
|
| 164 |
+
json.dump(idx_json, f, indent=2)
|
| 165 |
+
print("RECONSTRUCTION COMPLETE (LOSSY APPROXIMATION)")
|
| 166 |
+
print("WARNING: Reconstructed weights are a rank-3 approximation.")
|
| 167 |
+
print("Embedding and layernorm weights are initialized to defaults.")
|
| 168 |
+
print("This is NOT equivalent to the original Gemma-4 model.")
|
| 169 |
+
|
| 170 |
+
if __name__ == "__main__":
|
| 171 |
+
if len(sys.argv) < 3:
|
| 172 |
+
sys.exit(1)
|
| 173 |
+
reconstruct(sys.argv[1], sys.argv[2])
|
decode_procedural.py
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Level 8 Standalone Decoder — Procedural Seeded Projections
|
| 2 |
+
# Watermark: ip zymatica.space | astronautshe.com
|
| 3 |
+
|
| 4 |
+
import os
|
| 5 |
+
import sys
|
| 6 |
+
import struct
|
| 7 |
+
import zlib
|
| 8 |
+
import json
|
| 9 |
+
import shutil
|
| 10 |
+
import numpy as np
|
| 11 |
+
import torch
|
| 12 |
+
from safetensors.torch import save_file
|
| 13 |
+
from safetensors import safe_open
|
| 14 |
+
from transformers import AutoTokenizer, AutoModelForCausalLM
|
| 15 |
+
|
| 16 |
+
sys.stdout.reconfigure(encoding='utf-8', errors='backslashreplace')
|
| 17 |
+
|
| 18 |
+
SEED_FILE = "j:/Language-U/ProceduralSeed.LLM"
|
| 19 |
+
OUTPUT_DIR = "j:/Language-U/qwen-3.5-0.8b-procedural-reconstruction"
|
| 20 |
+
CONFIG_SOURCE = "j:/Language-U/Language-U-V2/qwen-3.5-0.8b-local"
|
| 21 |
+
|
| 22 |
+
GENESIS_MAGIC = 0x47454E45
|
| 23 |
+
PERFECT_MAGIC = 0x50455246
|
| 24 |
+
WATERMARK_LEN = 32
|
| 25 |
+
MASTER_SEED = 42
|
| 26 |
+
DICT_SIZE = 256
|
| 27 |
+
|
| 28 |
+
def get_dictionary(dim, dictionary_size, seed):
|
| 29 |
+
"""Procedurally generate a normalized dictionary matrix."""
|
| 30 |
+
rng = np.random.RandomState(seed)
|
| 31 |
+
dict_mat = rng.standard_normal((dim, dictionary_size)).astype(np.float32)
|
| 32 |
+
norms = np.linalg.norm(dict_mat, axis=0, keepdims=True) + 1e-9
|
| 33 |
+
return dict_mat / norms
|
| 34 |
+
|
| 35 |
+
def main():
|
| 36 |
+
print("=" * 80)
|
| 37 |
+
print(" PROCEDURAL DECODER -- DYNAMIC SEED PROJECTIONS RECONSTRUCTION")
|
| 38 |
+
print(" Watermark: ip zymatica.space | astronautshe.com")
|
| 39 |
+
print("=" * 80)
|
| 40 |
+
|
| 41 |
+
if not os.path.exists(SEED_FILE):
|
| 42 |
+
print(f"Error: Seed file '{SEED_FILE}' not found.")
|
| 43 |
+
return
|
| 44 |
+
|
| 45 |
+
print(f"\n[1] Decompressing {os.path.basename(SEED_FILE)}...")
|
| 46 |
+
with open(SEED_FILE, "rb") as f_in:
|
| 47 |
+
raw_genesis_data = zlib.decompress(f_in.read())
|
| 48 |
+
print(f" Decompressed to {len(raw_genesis_data):,} bytes.")
|
| 49 |
+
|
| 50 |
+
# Read base safetensors structure (shapes/dtypes only, NOT weights)
|
| 51 |
+
print(f"\n[2] Reading base safetensors STRUCTURE (shapes only)...")
|
| 52 |
+
base_st = os.path.join(CONFIG_SOURCE, "model.safetensors-00001-of-00001.safetensors")
|
| 53 |
+
tensor_meta = {}
|
| 54 |
+
meta_state = {}
|
| 55 |
+
with safe_open(base_st, framework="pt", device="cpu") as f:
|
| 56 |
+
for k in f.keys():
|
| 57 |
+
t = f.get_tensor(k)
|
| 58 |
+
tensor_meta[k] = (t.shape, t.dtype)
|
| 59 |
+
meta_state[k] = t
|
| 60 |
+
|
| 61 |
+
print(f"\n[3] Reconstructing absolute layers from seeds...")
|
| 62 |
+
layer_map = {}
|
| 63 |
+
pos = 0
|
| 64 |
+
|
| 65 |
+
# Parse header
|
| 66 |
+
magic = struct.unpack_from('>I', raw_genesis_data, pos)[0]; pos += 4
|
| 67 |
+
assert magic == GENESIS_MAGIC
|
| 68 |
+
version = struct.unpack_from('>H', raw_genesis_data, pos)[0]; pos += 2
|
| 69 |
+
assert version == 12, f"Expected v12, got {version}"
|
| 70 |
+
watermark = raw_genesis_data[pos : pos + WATERMARK_LEN].decode('utf-8', errors='ignore').strip(); pos += WATERMARK_LEN
|
| 71 |
+
perf_magic = struct.unpack_from('>I', raw_genesis_data, pos)[0]; pos += 4
|
| 72 |
+
assert perf_magic == PERFECT_MAGIC
|
| 73 |
+
|
| 74 |
+
hidden, heads, kv_heads, ffn_dim, blocks, vocab = struct.unpack_from('>IIIIII', raw_genesis_data, pos); pos += 24
|
| 75 |
+
pos += 16 # skip energy targets
|
| 76 |
+
num_layers = struct.unpack_from('>I', raw_genesis_data, pos)[0]; pos += 4
|
| 77 |
+
|
| 78 |
+
print(f" Watermark: {watermark}")
|
| 79 |
+
print(f" v{version} | {num_layers} layers | hidden={hidden} ffn={ffn_dim} blocks={blocks} vocab={vocab}")
|
| 80 |
+
|
| 81 |
+
for idx in range(num_layers):
|
| 82 |
+
name_len = struct.unpack_from('>H', raw_genesis_data, pos)[0]; pos += 2
|
| 83 |
+
name = raw_genesis_data[pos : pos + name_len].decode('utf-8'); pos += name_len
|
| 84 |
+
m, n, r = struct.unpack_from('>III', raw_genesis_data, pos); pos += 12
|
| 85 |
+
|
| 86 |
+
# Layer-specific seeds
|
| 87 |
+
seed_u = MASTER_SEED + idx * 1000
|
| 88 |
+
seed_v = MASTER_SEED + idx * 1000 + 500
|
| 89 |
+
|
| 90 |
+
U_dict = get_dictionary(m, DICT_SIZE, seed_u)
|
| 91 |
+
V_dict = get_dictionary(n, DICT_SIZE, seed_v)
|
| 92 |
+
|
| 93 |
+
W_rec = np.zeros((m, n), dtype=np.float32)
|
| 94 |
+
for rank in range(r):
|
| 95 |
+
idx_u = raw_genesis_data[pos]; pos += 1
|
| 96 |
+
idx_v = raw_genesis_data[pos]; pos += 1
|
| 97 |
+
c = struct.unpack_from('>e', raw_genesis_data, pos)[0]; pos += 2
|
| 98 |
+
|
| 99 |
+
W_rec += c * np.outer(U_dict[:, idx_u], V_dict[:, idx_v])
|
| 100 |
+
|
| 101 |
+
dtype = tensor_meta.get(name, (None, torch.float16))[1]
|
| 102 |
+
layer_map[name] = torch.from_numpy(W_rec).to(dtype)
|
| 103 |
+
|
| 104 |
+
if (idx + 1) % 40 == 0 or (idx + 1) == num_layers:
|
| 105 |
+
print(f" [{idx+1:3d}/{num_layers}] Reconstructed {name[-40:]}")
|
| 106 |
+
|
| 107 |
+
# EOF Check
|
| 108 |
+
print(f" EOF Check: {pos:,} vs {len(raw_genesis_data):,} bytes {'PASS' if pos == len(raw_genesis_data) else 'FAIL'}")
|
| 109 |
+
|
| 110 |
+
# Step 4: Assemble final model tensors
|
| 111 |
+
print(f"\n[4] Assembling complete safetensors...")
|
| 112 |
+
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
| 113 |
+
|
| 114 |
+
reconstructed_tensors = {}
|
| 115 |
+
for k, (shape, dtype) in tensor_meta.items():
|
| 116 |
+
if k in layer_map:
|
| 117 |
+
t = layer_map[k]
|
| 118 |
+
if t.shape == shape:
|
| 119 |
+
reconstructed_tensors[k] = t.clone()
|
| 120 |
+
elif t.T.shape == shape:
|
| 121 |
+
reconstructed_tensors[k] = t.T.clone()
|
| 122 |
+
else:
|
| 123 |
+
reconstructed_tensors[k] = meta_state[k].to(dtype).clone()
|
| 124 |
+
else:
|
| 125 |
+
# Keep embeddings / norm layers from base model for SFT baseline
|
| 126 |
+
reconstructed_tensors[k] = meta_state[k].to(dtype).clone()
|
| 127 |
+
|
| 128 |
+
out_st = os.path.join(OUTPUT_DIR, "model.safetensors")
|
| 129 |
+
print(f" Saving to {out_st}...")
|
| 130 |
+
save_file(reconstructed_tensors, out_st)
|
| 131 |
+
|
| 132 |
+
# Copy metadata files (config / tokenizer)
|
| 133 |
+
print(f"\n[5] Copying configuration and tokenizer metadata...")
|
| 134 |
+
skip_ext = {'.safetensors', '.bin', '.pt', '.ckpt'}
|
| 135 |
+
for fname in os.listdir(CONFIG_SOURCE):
|
| 136 |
+
if os.path.splitext(fname)[1].lower() in skip_ext or fname == '.cache':
|
| 137 |
+
continue
|
| 138 |
+
src = os.path.join(CONFIG_SOURCE, fname)
|
| 139 |
+
dst = os.path.join(OUTPUT_DIR, fname)
|
| 140 |
+
if os.path.isdir(src):
|
| 141 |
+
shutil.copytree(src, dst, dirs_exist_ok=True)
|
| 142 |
+
else:
|
| 143 |
+
shutil.copy2(src, dst)
|
| 144 |
+
|
| 145 |
+
print(f"\n[6] Re-loading and verifying model structure...")
|
| 146 |
+
tokenizer = AutoTokenizer.from_pretrained(OUTPUT_DIR, trust_remote_code=True)
|
| 147 |
+
model = AutoModelForCausalLM.from_pretrained(
|
| 148 |
+
OUTPUT_DIR, torch_dtype=torch.float16, trust_remote_code=True
|
| 149 |
+
)
|
| 150 |
+
print("Success! Model successfully loaded and verified.")
|
| 151 |
+
print("=" * 80)
|
| 152 |
+
|
| 153 |
+
if __name__ == "__main__":
|
| 154 |
+
main()
|
decode_tinyqwen.py
ADDED
|
@@ -0,0 +1,454 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Watermark: ip zymatica.space
|
| 2 |
+
__watermark__ = "ip zymatica.space"
|
| 3 |
+
|
| 4 |
+
import os
|
| 5 |
+
os.environ["PYTORCH_CUDA_ALLOC_CONF"] = "garbage_collection_threshold:0.6,max_split_size_mb:24"
|
| 6 |
+
import sys
|
| 7 |
+
import struct
|
| 8 |
+
import json
|
| 9 |
+
import time
|
| 10 |
+
import numpy as np
|
| 11 |
+
import torch
|
| 12 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
| 13 |
+
from torch.optim import AdamW
|
| 14 |
+
|
| 15 |
+
sys.stdout.reconfigure(encoding='utf-8', errors='backslashreplace')
|
| 16 |
+
|
| 17 |
+
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
|
| 18 |
+
PKT_SIZE = 256
|
| 19 |
+
MAGIC = bytes([0xA7, 0x07, 0x11])
|
| 20 |
+
|
| 21 |
+
BASE_MODEL = "j:/Language-U/Language-U-V2/qwen-3.5-0.8b-local"
|
| 22 |
+
PKT_PATH = "j:/Language-U/packets_tinyqwen/packet_1paup.bin"
|
| 23 |
+
OUTPUT_MODEL = "j:/Language-U/SubZero2.lora"
|
| 24 |
+
SFT_DATA_PATH = "j:/Language-U/full_sft_dataset.json"
|
| 25 |
+
|
| 26 |
+
LAYER_NAMES = [
|
| 27 |
+
"model.layers.3.self_attn.q_proj.weight",
|
| 28 |
+
"model.layers.3.self_attn.k_proj.weight",
|
| 29 |
+
"model.layers.3.self_attn.v_proj.weight",
|
| 30 |
+
"model.layers.3.self_attn.o_proj.weight",
|
| 31 |
+
"model.layers.3.mlp.gate_proj.weight",
|
| 32 |
+
"model.layers.3.mlp.up_proj.weight",
|
| 33 |
+
"model.layers.3.mlp.down_proj.weight",
|
| 34 |
+
]
|
| 35 |
+
|
| 36 |
+
EVAL_TESTS = [
|
| 37 |
+
("What GPIO pin is the SX1302 reset line on Raspberry Pi 4?", ["25", "GPIO 25"]),
|
| 38 |
+
("What is the exact command to reset the LoRa concentrator with gpioset?", ["gpioset", "gpiochip0", "25=0"]),
|
| 39 |
+
("What script handles the SX1302 hardware reset?", ["reset_lgw.sh"]),
|
| 40 |
+
("On Raspberry Pi 5, which gpiochip and pin is the SX1302 reset mapped to?", ["17", "gpiochip4"]),
|
| 41 |
+
("What frequency does the Astronaut SHE Handshake Protocol use?", ["903.0", "903"]),
|
| 42 |
+
("What Spreading Factor is used for the Astronaut SHE handshake?", ["SF7", "sf7"]),
|
| 43 |
+
("What is the transmit power for the Astronaut SHE RAK Miner beacon?", ["14 dBm", "14dBm"]),
|
| 44 |
+
("What does --pwid 15 represent in test_loragw_hal_tx?", ["calibration", "14 dBm", "power"]),
|
| 45 |
+
("What is the full test_loragw_hal_tx command for the Astronaut SHE handshake?",
|
| 46 |
+
["-f 903.0", "-s 7", "--pwid 15", "-z 32"]),
|
| 47 |
+
("What is the payload size for the Astronaut SHE handshake beacon?", ["32", "32 bytes"]),
|
| 48 |
+
("How many dimensions does the Cuneiform-U v3.0 semantic hypercube have?", ["6", "six"]),
|
| 49 |
+
("What are the 6 axes of Cuneiform-U v3.0?", ["DOMAIN", "SUBDOMAIN", "MODALITY"]),
|
| 50 |
+
("What is the Classifier Radical R_C in Cuneiform-U v3.0?", ["DOMAIN", "SUBDOMAIN", "4 bits"]),
|
| 51 |
+
("What are the radical coordinates of the ACK glyph (0x807E)?", ["0x00", "0x7E", "0x0B"]),
|
| 52 |
+
("What is the Shannon Orthogonality equation in Language U?", ["H(text)", "H(meaning)", "H(syntax"]),
|
| 53 |
+
("What does LLD-AC stand for?", ["LLM", "Logits", "Range Cod"]),
|
| 54 |
+
("What is a collapse signal in LLD-AC range coding?", ["probability", "1.0", "bits"]),
|
| 55 |
+
("What frequency scale does the LLD-AC range coder use?", ["1,000,000", "1000000", "million"]),
|
| 56 |
+
]
|
| 57 |
+
|
| 58 |
+
BASELINE_SEMANTIC_TESTS = [
|
| 59 |
+
("A computer program is", ["program", "computer", "code", "software", "instructions"]),
|
| 60 |
+
("The purpose of a map is", ["map", "place", "location", "direction", "where", "travel"]),
|
| 61 |
+
("Water is important because", ["water", "important", "drink", "life", "body"]),
|
| 62 |
+
("A library is a place where", ["library", "place", "book", "read", "find"]),
|
| 63 |
+
("The moon appears at night", ["moon", "night", "sky", "appears"]),
|
| 64 |
+
("A keyboard is used to", ["keyboard", "type", "computer", "used"]),
|
| 65 |
+
("A camera can", ["camera", "photo", "picture", "image"]),
|
| 66 |
+
("A river flows", ["river", "flow", "water"]),
|
| 67 |
+
("A doctor helps", ["doctor", "help", "patient", "sick", "health"]),
|
| 68 |
+
("A calendar shows", ["calendar", "date", "day", "month"]),
|
| 69 |
+
("A battery stores", ["battery", "energy", "power", "electric"]),
|
| 70 |
+
("A question mark means", ["question", "mark", "ask"]),
|
| 71 |
+
("People sleep because", ["sleep", "rest", "tired", "body"]),
|
| 72 |
+
("Exercise helps", ["exercise", "health", "body", "strong"]),
|
| 73 |
+
("A triangle has", ["triangle", "three", "3", "sides"]),
|
| 74 |
+
]
|
| 75 |
+
|
| 76 |
+
OFF_TOPIC_LANGUAGE_U = [
|
| 77 |
+
"sx1302", "astronaut she", "gpio", "cuneiform", "lora", "lld-ac", "spreading factor", "903.0", "14 dbm"
|
| 78 |
+
]
|
| 79 |
+
|
| 80 |
+
def gradient_atom_decompress(data: bytes, pos: int) -> tuple:
|
| 81 |
+
R = data[pos]; pos += 1
|
| 82 |
+
scale = struct.unpack('>e', data[pos:pos+2])[0]; pos += 2
|
| 83 |
+
n_bytes = (R + 1) // 2
|
| 84 |
+
packed = data[pos:pos+n_bytes]; pos += n_bytes
|
| 85 |
+
|
| 86 |
+
nibbles = []
|
| 87 |
+
for b in packed:
|
| 88 |
+
nibbles.append(b & 0x0F)
|
| 89 |
+
nibbles.append((b >> 4) & 0x0F)
|
| 90 |
+
|
| 91 |
+
MAG_TABLE = [0.125, 0.375, 0.625, 0.875]
|
| 92 |
+
delta_s = np.zeros(R, dtype=np.float64)
|
| 93 |
+
for i in range(R):
|
| 94 |
+
if i >= len(nibbles): break
|
| 95 |
+
nib = nibbles[i]
|
| 96 |
+
sign = +1 if (nib >> 2) & 1 else -1
|
| 97 |
+
mag = MAG_TABLE[nib & 0x3]
|
| 98 |
+
delta_s[i] = sign * mag * scale
|
| 99 |
+
return delta_s, pos
|
| 100 |
+
|
| 101 |
+
def eigenspace_decompress(data: bytes, pos: int) -> tuple:
|
| 102 |
+
R = data[pos]; pos += 1
|
| 103 |
+
scale = struct.unpack('>e', data[pos:pos+2])[0]; pos += 2
|
| 104 |
+
q_vals = []
|
| 105 |
+
for _ in range(R):
|
| 106 |
+
val = data[pos]
|
| 107 |
+
if val > 127: val = val - 256
|
| 108 |
+
q_vals.append(val)
|
| 109 |
+
pos += 1
|
| 110 |
+
delta_s = np.array(q_vals, dtype=np.float64) * scale
|
| 111 |
+
return delta_s, pos
|
| 112 |
+
|
| 113 |
+
def decode_layer_delta(data: bytes, pos: int, W_base: np.ndarray, level: int) -> tuple:
|
| 114 |
+
if level == 5:
|
| 115 |
+
delta_s, pos = eigenspace_decompress(data, pos)
|
| 116 |
+
elif level == 6:
|
| 117 |
+
delta_s, pos = gradient_atom_decompress(data, pos)
|
| 118 |
+
else:
|
| 119 |
+
raise ValueError(f"Unknown encoding level: 0x{level:02X}")
|
| 120 |
+
|
| 121 |
+
U_b, _, Vh_b = np.linalg.svd(W_base.astype(np.float64), full_matrices=False)
|
| 122 |
+
R = len(delta_s)
|
| 123 |
+
W_delta = sum(delta_s[i] * np.outer(U_b[:, i], Vh_b[i, :]) for i in range(R))
|
| 124 |
+
return W_delta.astype(np.float32), pos
|
| 125 |
+
|
| 126 |
+
def evaluate_fidelity(model, tokenizer) -> float:
|
| 127 |
+
model.eval()
|
| 128 |
+
passed = 0
|
| 129 |
+
print("\n Fidelity test results:")
|
| 130 |
+
for i, (q, kws) in enumerate(EVAL_TESTS):
|
| 131 |
+
prompt = f"Q: {q}\nA:"
|
| 132 |
+
inputs = tokenizer(prompt, return_tensors='pt').to(DEVICE)
|
| 133 |
+
with torch.no_grad():
|
| 134 |
+
out = model.generate(**inputs, max_new_tokens=48,
|
| 135 |
+
do_sample=False, pad_token_id=tokenizer.eos_token_id)
|
| 136 |
+
answer = tokenizer.decode(out[0][inputs['input_ids'].shape[1]:],
|
| 137 |
+
skip_special_tokens=True).lower()
|
| 138 |
+
ok = any(kw.lower() in answer for kw in kws)
|
| 139 |
+
passed += ok
|
| 140 |
+
mark = "✓" if ok else "✗"
|
| 141 |
+
if i < 5:
|
| 142 |
+
print(f" [{mark}] Q{i+1:>2}: {q[:55]}")
|
| 143 |
+
sys.stdout.flush()
|
| 144 |
+
fidelity = passed / len(EVAL_TESTS) * 100
|
| 145 |
+
print(f" ... evaluated {len(EVAL_TESTS)} fidelity tests.")
|
| 146 |
+
print(f" FIDELITY: {passed}/{len(EVAL_TESTS)} = {fidelity:.1f}%")
|
| 147 |
+
sys.stdout.flush()
|
| 148 |
+
return fidelity
|
| 149 |
+
|
| 150 |
+
def evaluate_semantic(model, tokenizer) -> float:
|
| 151 |
+
model.eval()
|
| 152 |
+
passed = 0
|
| 153 |
+
for prompt, kws in BASELINE_SEMANTIC_TESTS:
|
| 154 |
+
inputs = tokenizer(prompt, return_tensors='pt').to(DEVICE)
|
| 155 |
+
with torch.no_grad():
|
| 156 |
+
out = model.generate(**inputs, max_new_tokens=32,
|
| 157 |
+
do_sample=False, pad_token_id=tokenizer.eos_token_id)
|
| 158 |
+
answer = tokenizer.decode(out[0][inputs['input_ids'].shape[1]:],
|
| 159 |
+
skip_special_tokens=True).lower()
|
| 160 |
+
matched = any(kw.lower() in answer for kw in kws)
|
| 161 |
+
off_topic = any(ot in answer for ot in OFF_TOPIC_LANGUAGE_U)
|
| 162 |
+
ok = matched and not off_topic
|
| 163 |
+
passed += ok
|
| 164 |
+
return passed
|
| 165 |
+
|
| 166 |
+
def collate_batch(batch, tokenizer, device):
|
| 167 |
+
prompts = [item["prompt"] for item in batch]
|
| 168 |
+
completions = [item["completion"] for item in batch]
|
| 169 |
+
|
| 170 |
+
full_texts = [p + c for p, c in zip(prompts, completions)]
|
| 171 |
+
inputs = tokenizer(full_texts, padding=True, truncation=True, max_length=192, return_tensors="pt").to(device)
|
| 172 |
+
labels = inputs["input_ids"].clone()
|
| 173 |
+
|
| 174 |
+
for i, p in enumerate(prompts):
|
| 175 |
+
p_len = tokenizer(p, truncation=True, max_length=192, return_tensors="pt")["input_ids"].shape[1]
|
| 176 |
+
labels[i, :p_len] = -100
|
| 177 |
+
pad_mask = (inputs["attention_mask"][i] == 0)
|
| 178 |
+
labels[i, pad_mask] = -100
|
| 179 |
+
|
| 180 |
+
inputs["labels"] = labels
|
| 181 |
+
return inputs
|
| 182 |
+
|
| 183 |
+
def train_multitask(model, tokenizer, sft_groups: dict, recipe: dict) -> dict:
|
| 184 |
+
import gc
|
| 185 |
+
import random
|
| 186 |
+
import math
|
| 187 |
+
lu_examples = sft_groups["lu"]
|
| 188 |
+
rf_examples = sft_groups["rf"]
|
| 189 |
+
mmlu_examples = sft_groups["mmlu"]
|
| 190 |
+
gsm_examples = sft_groups["gsm"]
|
| 191 |
+
sem_examples = sft_groups["sem"]
|
| 192 |
+
|
| 193 |
+
# Freeze other parameters, train only Layer 3 projections
|
| 194 |
+
for name, param in model.named_parameters():
|
| 195 |
+
if not any(layer in name for layer in LAYER_NAMES):
|
| 196 |
+
param.requires_grad = False
|
| 197 |
+
else:
|
| 198 |
+
param.requires_grad = True
|
| 199 |
+
|
| 200 |
+
# Use a cosine learning rate scheduler starting at 2.0e-4 and decaying to 1e-6
|
| 201 |
+
lr_max = recipe['lr'] * 1.0
|
| 202 |
+
lr_min = 1e-6
|
| 203 |
+
|
| 204 |
+
optimizer = AdamW(filter(lambda p: p.requires_grad, model.parameters()), lr=lr_max, weight_decay=0.01, betas=(0.9, 0.95))
|
| 205 |
+
total_steps = int(recipe['num_steps'] * 2.0) # 300 steps
|
| 206 |
+
accumulation_steps = 2
|
| 207 |
+
|
| 208 |
+
print(f"\n On-device Batched Multi-task SFT: {total_steps} steps (Accumulation={accumulation_steps}), Peak LR={lr_max:.6f} with Cosine Decay")
|
| 209 |
+
sys.stdout.flush()
|
| 210 |
+
t0 = time.perf_counter()
|
| 211 |
+
losses = []
|
| 212 |
+
optimizer.zero_grad(set_to_none=True)
|
| 213 |
+
|
| 214 |
+
for step in range(total_steps):
|
| 215 |
+
model.train()
|
| 216 |
+
|
| 217 |
+
# Apply Cosine Annealing Learning Rate
|
| 218 |
+
lr_t = lr_min + 0.5 * (lr_max - lr_min) * (1.0 + math.cos(math.pi * step / total_steps))
|
| 219 |
+
for param_group in optimizer.param_groups:
|
| 220 |
+
param_group['lr'] = lr_t
|
| 221 |
+
|
| 222 |
+
# Build balanced batch of size 4 (always include 'lu', sample 3 others)
|
| 223 |
+
sampled_tasks = ["lu"] + random.sample(["rf", "mmlu", "gsm", "sem"], 3)
|
| 224 |
+
batch = []
|
| 225 |
+
for task in sampled_tasks:
|
| 226 |
+
if task == "lu":
|
| 227 |
+
batch.extend(random.sample(lu_examples, 1))
|
| 228 |
+
elif task == "rf":
|
| 229 |
+
batch.extend(random.sample(rf_examples, 1))
|
| 230 |
+
elif task == "mmlu":
|
| 231 |
+
batch.extend(random.sample(mmlu_examples, 1))
|
| 232 |
+
elif task == "gsm":
|
| 233 |
+
batch.extend(random.sample(gsm_examples, 1))
|
| 234 |
+
elif task == "sem":
|
| 235 |
+
batch.extend(random.sample(sem_examples, 1))
|
| 236 |
+
|
| 237 |
+
# Collate & Push to device
|
| 238 |
+
inputs = collate_batch(batch, tokenizer, DEVICE)
|
| 239 |
+
|
| 240 |
+
with torch.amp.autocast('cuda', enabled=(DEVICE == 'cuda')):
|
| 241 |
+
out = model(input_ids=inputs["input_ids"], attention_mask=inputs["attention_mask"])
|
| 242 |
+
logits = out.logits
|
| 243 |
+
|
| 244 |
+
# Custom balanced cross-entropy loss (vectorized)
|
| 245 |
+
shift_logits = logits[..., :-1, :].contiguous()
|
| 246 |
+
shift_labels = inputs["labels"][..., 1:].contiguous()
|
| 247 |
+
|
| 248 |
+
loss_fct = torch.nn.CrossEntropyLoss(reduction="none")
|
| 249 |
+
token_losses = loss_fct(shift_logits.view(-1, shift_logits.size(-1)), shift_labels.view(-1))
|
| 250 |
+
token_losses = token_losses.view(shift_labels.size())
|
| 251 |
+
|
| 252 |
+
mask = (shift_labels != -100).float()
|
| 253 |
+
masked_losses = token_losses * mask
|
| 254 |
+
example_loss_sums = masked_losses.sum(dim=-1)
|
| 255 |
+
example_token_counts = torch.clamp(mask.sum(dim=-1), min=1.0)
|
| 256 |
+
example_losses = example_loss_sums / example_token_counts
|
| 257 |
+
|
| 258 |
+
# Apply weights dynamically
|
| 259 |
+
weight_map = {"lu": 12.0, "rf": 1.0, "mmlu": 1.0, "gsm": 1.0, "sem": 1.0}
|
| 260 |
+
step_weights = torch.tensor([weight_map[task] for task in sampled_tasks], device=DEVICE)
|
| 261 |
+
mean_loss = (example_losses * step_weights).sum() / step_weights.sum()
|
| 262 |
+
loss = mean_loss / accumulation_steps
|
| 263 |
+
|
| 264 |
+
loss.backward()
|
| 265 |
+
|
| 266 |
+
if (step + 1) % accumulation_steps == 0:
|
| 267 |
+
torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)
|
| 268 |
+
optimizer.step()
|
| 269 |
+
optimizer.zero_grad(set_to_none=True)
|
| 270 |
+
|
| 271 |
+
losses.append(mean_loss.item())
|
| 272 |
+
|
| 273 |
+
if step == 0 or (step + 1) % 10 == 0 or step == total_steps - 1:
|
| 274 |
+
elapsed = time.perf_counter() - t0
|
| 275 |
+
print(f" Step {step+1:>4}/{total_steps} | Batch Loss={mean_loss.item():.4f} | LR={lr_t:.2e} | Time: {elapsed:.1f}s")
|
| 276 |
+
sys.stdout.flush()
|
| 277 |
+
|
| 278 |
+
# Clean up memory
|
| 279 |
+
del inputs, out, loss, mean_loss
|
| 280 |
+
|
| 281 |
+
elapsed = time.perf_counter() - t0
|
| 282 |
+
print(f" Training complete in {elapsed:.1f}s")
|
| 283 |
+
return {"initial_loss": losses[0], "final_loss": losses[-1], "seconds": elapsed}
|
| 284 |
+
|
| 285 |
+
def main():
|
| 286 |
+
print("=" * 72)
|
| 287 |
+
print(" TINYQWEN 1-PAUP DECODER & RESTORATION ENGINE (BATCHED)")
|
| 288 |
+
print(" Watermark: ip zymatica.space")
|
| 289 |
+
print("=" * 72)
|
| 290 |
+
sys.stdout.flush()
|
| 291 |
+
|
| 292 |
+
# 1. Load the single packet
|
| 293 |
+
# Check if a zlib version exists first or fallback to raw bin
|
| 294 |
+
zlib_path = PKT_PATH + ".zlib"
|
| 295 |
+
if os.path.exists(zlib_path):
|
| 296 |
+
print(f"[+] Found zlib compressed packet version at {zlib_path}")
|
| 297 |
+
PKT_PATH = zlib_path
|
| 298 |
+
|
| 299 |
+
if not os.path.exists(PKT_PATH):
|
| 300 |
+
print(f"Error: 1-PAUP packet not found at {PKT_PATH}")
|
| 301 |
+
sys.exit(1)
|
| 302 |
+
|
| 303 |
+
with open(PKT_PATH, "rb") as f:
|
| 304 |
+
packet = f.read()
|
| 305 |
+
|
| 306 |
+
# Decompress using zlib if compressed
|
| 307 |
+
import zlib
|
| 308 |
+
try:
|
| 309 |
+
decompressed = zlib.decompress(packet)
|
| 310 |
+
print(f"[+] Successfully decompressed packet via zlib ({len(packet)} bytes -> {len(decompressed)} bytes)")
|
| 311 |
+
packet = decompressed
|
| 312 |
+
except Exception:
|
| 313 |
+
print("[.] Packet is not zlib-compressed (or decompression failed), using raw bytes.")
|
| 314 |
+
|
| 315 |
+
if len(packet) < 3:
|
| 316 |
+
raise ValueError(f"Packet too short: {len(packet)} bytes")
|
| 317 |
+
|
| 318 |
+
sync, pkt_idx, pkt_total = packet[0], packet[1], packet[2]
|
| 319 |
+
if sync != 0xBB or pkt_idx != 0 or pkt_total != 1:
|
| 320 |
+
raise ValueError(f"Bad packet wrapper headers: sync=0x{sync:02X} idx={pkt_idx} total={pkt_total}")
|
| 321 |
+
|
| 322 |
+
data = packet[3:]
|
| 323 |
+
|
| 324 |
+
# 2. Parse 32-byte header
|
| 325 |
+
off = 0
|
| 326 |
+
magic = data[off:off+3]; off += 3
|
| 327 |
+
level = data[off]; off += 1
|
| 328 |
+
lr_f16 = struct.unpack('>e', data[off:off+2])[0]; off += 2
|
| 329 |
+
n_steps = struct.unpack('>H', data[off:off+2])[0]; off += 2
|
| 330 |
+
seed = struct.unpack('>I', data[off:off+4])[0]; off += 4
|
| 331 |
+
optim = data[off]; off += 1
|
| 332 |
+
batch = data[off]; off += 1
|
| 333 |
+
layer_f = data[off]; off += 1
|
| 334 |
+
warmup = struct.unpack('>H', data[off:off+2])[0]; off += 2
|
| 335 |
+
n_pairs = data[off]; off += 1
|
| 336 |
+
lu4_hdr = data[off:off+4]; off += 4
|
| 337 |
+
q_mask_bytes = data[off:off+3]; off += 3
|
| 338 |
+
n_layers= data[off]; off += 1
|
| 339 |
+
w_len = struct.unpack('>H', data[off:off+2])[0]; off += 2
|
| 340 |
+
off = 32
|
| 341 |
+
|
| 342 |
+
if magic != MAGIC:
|
| 343 |
+
raise ValueError(f"Bad magic: {magic.hex()} expected {MAGIC.hex()}")
|
| 344 |
+
|
| 345 |
+
print(f"\n1-PAUP Header:")
|
| 346 |
+
print(f" Level (Mode): Level {level}")
|
| 347 |
+
print(f" Learning Rate: {float(lr_f16):.6f}")
|
| 348 |
+
print(f" Steps / Seed: {n_steps} / {hex(seed)}")
|
| 349 |
+
print(f" Layers to update: {n_layers}")
|
| 350 |
+
print(f" Weight length: {w_len} bytes")
|
| 351 |
+
sys.stdout.flush()
|
| 352 |
+
|
| 353 |
+
# 3. Load baseline model and prepare targets & base evaluation
|
| 354 |
+
print(f"\nLoading baseline model from {BASE_MODEL}...")
|
| 355 |
+
tokenizer = AutoTokenizer.from_pretrained(BASE_MODEL, trust_remote_code=True)
|
| 356 |
+
tokenizer.padding_side = "right"
|
| 357 |
+
if tokenizer.pad_token is None:
|
| 358 |
+
tokenizer.pad_token = tokenizer.eos_token
|
| 359 |
+
|
| 360 |
+
model = AutoModelForCausalLM.from_pretrained(BASE_MODEL, torch_dtype=torch.float16).to(DEVICE)
|
| 361 |
+
model.config.use_cache = False
|
| 362 |
+
model.gradient_checkpointing_enable()
|
| 363 |
+
model.eval()
|
| 364 |
+
|
| 365 |
+
# Generate semantic anchors
|
| 366 |
+
sem_examples = []
|
| 367 |
+
print("Generating semantic anchor targets for alignment:")
|
| 368 |
+
for idx, (prompt, _) in enumerate(BASELINE_SEMANTIC_TESTS):
|
| 369 |
+
inputs = tokenizer(prompt, return_tensors='pt').to(DEVICE)
|
| 370 |
+
with torch.no_grad():
|
| 371 |
+
out = model.generate(**inputs, max_new_tokens=32, do_sample=False, pad_token_id=tokenizer.eos_token_id)
|
| 372 |
+
sem_examples.append({
|
| 373 |
+
"prompt": prompt,
|
| 374 |
+
"completion": " " + tokenizer.decode(out[0][inputs['input_ids'].shape[1]:], skip_special_tokens=True).strip()
|
| 375 |
+
})
|
| 376 |
+
|
| 377 |
+
# Evaluate clean model baseline semantic score before modification
|
| 378 |
+
sem_base = evaluate_semantic(model, tokenizer)
|
| 379 |
+
print(f" Baseline Semantic Score: {sem_base}/15")
|
| 380 |
+
sys.stdout.flush()
|
| 381 |
+
|
| 382 |
+
# Load SFT dataset
|
| 383 |
+
if not os.path.exists(SFT_DATA_PATH):
|
| 384 |
+
print(f"Error: SFT data not found at {SFT_DATA_PATH}.")
|
| 385 |
+
sys.exit(1)
|
| 386 |
+
with open(SFT_DATA_PATH, "r", encoding="utf-8") as f:
|
| 387 |
+
sft_data = json.load(f)
|
| 388 |
+
|
| 389 |
+
sft_groups = {
|
| 390 |
+
"lu": [item for item in sft_data if item["type"] == "language_u"],
|
| 391 |
+
"rf": [item for item in sft_data if item["type"] == "rf_info_theory"],
|
| 392 |
+
"mmlu": [item for item in sft_data if item["type"] == "mmlu"],
|
| 393 |
+
"gsm": [item for item in sft_data if item["type"] == "gsm8k"],
|
| 394 |
+
"sem": sem_examples
|
| 395 |
+
}
|
| 396 |
+
|
| 397 |
+
base_p = dict(model.named_parameters())
|
| 398 |
+
|
| 399 |
+
# 4. Decode and apply SVD weight deltas in-place
|
| 400 |
+
weight_data = data[off:off+w_len]
|
| 401 |
+
w_pos = 0
|
| 402 |
+
print("\nDecoding SVD weight deltas in-place...")
|
| 403 |
+
for i in range(n_layers):
|
| 404 |
+
lname = LAYER_NAMES[i]
|
| 405 |
+
W_b = base_p[lname].data.to(torch.float32).cpu().numpy()
|
| 406 |
+
W_delta, w_pos = decode_layer_delta(weight_data, w_pos, W_b, level)
|
| 407 |
+
|
| 408 |
+
# Inject weights in float16
|
| 409 |
+
with torch.no_grad():
|
| 410 |
+
delta_tensor = torch.from_numpy(W_delta).to(DEVICE, dtype=torch.float16)
|
| 411 |
+
base_p[lname].data.add_(delta_tensor)
|
| 412 |
+
print(f" Reconstructed {lname.split('.')[-2]} via L{level} SVD Eigenspace")
|
| 413 |
+
sys.stdout.flush()
|
| 414 |
+
|
| 415 |
+
# 5. Evaluate pre-training fidelity
|
| 416 |
+
print("\nEvaluating pre-training scores...")
|
| 417 |
+
fid_before = evaluate_fidelity(model, tokenizer)
|
| 418 |
+
sys.stdout.flush()
|
| 419 |
+
|
| 420 |
+
# 6. Run on-device multi-task training
|
| 421 |
+
recipe = {
|
| 422 |
+
"lr": float(lr_f16),
|
| 423 |
+
"num_steps": n_steps,
|
| 424 |
+
"seed": seed,
|
| 425 |
+
"batch_size": batch,
|
| 426 |
+
}
|
| 427 |
+
stats = train_multitask(model, tokenizer, sft_groups, recipe)
|
| 428 |
+
|
| 429 |
+
# 7. Evaluate post-training scores
|
| 430 |
+
print("\nEvaluating post-training scores...")
|
| 431 |
+
fid_after = evaluate_fidelity(model, tokenizer)
|
| 432 |
+
sem_after = evaluate_semantic(model, tokenizer)
|
| 433 |
+
sys.stdout.flush()
|
| 434 |
+
|
| 435 |
+
# Save output
|
| 436 |
+
os.makedirs(OUTPUT_MODEL, exist_ok=True)
|
| 437 |
+
model.save_pretrained(OUTPUT_MODEL)
|
| 438 |
+
tokenizer.save_pretrained(OUTPUT_MODEL)
|
| 439 |
+
|
| 440 |
+
print("\n" + "=" * 72)
|
| 441 |
+
print(" TINYQWEN ALIGNED RESTORATION SUCCESS")
|
| 442 |
+
print("=" * 72)
|
| 443 |
+
print(f" Fidelity Before: {fid_before:.1f}%")
|
| 444 |
+
print(f" Fidelity After: {fid_after:.1f}%")
|
| 445 |
+
print(f" Semantic Before: {sem_base}/15")
|
| 446 |
+
print(f" Semantic After: {sem_after}/15")
|
| 447 |
+
print(f" Loss Initial/Final:{stats['initial_loss']:.4f} / {stats['final_loss']:.4f}")
|
| 448 |
+
print(f" Output Model: {OUTPUT_MODEL}")
|
| 449 |
+
print("=" * 72)
|
| 450 |
+
sys.stdout.flush()
|
| 451 |
+
|
| 452 |
+
if __name__ == '__main__':
|
| 453 |
+
import random
|
| 454 |
+
main()
|
decode_tokenizer.py
ADDED
|
@@ -0,0 +1,334 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Watermark: ip zymatica.space
|
| 2 |
+
__watermark__ = "ip zymatica.space"
|
| 3 |
+
|
| 4 |
+
"""
|
| 5 |
+
decode_tokenizer.py — 7-Level Tokenizer Restoration & Verification Engine
|
| 6 |
+
=========================================================================
|
| 7 |
+
Author: Zymatica / Language-U Project
|
| 8 |
+
Watermark: ip zymatica.space | astronautshe.com
|
| 9 |
+
|
| 10 |
+
Decodes the hyper-compressed tokenizer capsule (or reassembles from 28 packets
|
| 11 |
+
via XOR-FEC) and reconstructs standard tokenizer files:
|
| 12 |
+
- tokenizer.json
|
| 13 |
+
- tokenizer_config.json
|
| 14 |
+
- vocab.json
|
| 15 |
+
- merges.txt
|
| 16 |
+
"""
|
| 17 |
+
|
| 18 |
+
import os
|
| 19 |
+
import sys
|
| 20 |
+
import json
|
| 21 |
+
import zlib
|
| 22 |
+
import struct
|
| 23 |
+
import argparse
|
| 24 |
+
import hashlib
|
| 25 |
+
from transformers import AutoTokenizer
|
| 26 |
+
|
| 27 |
+
TK_MAGIC = bytes([0xC5, 0x54, 0x4B]) # TK\xC5
|
| 28 |
+
PKT_SIZE = 255
|
| 29 |
+
NUM_DATA = 27
|
| 30 |
+
NUM_PKTS = 28
|
| 31 |
+
DATA_PER_PKT = PKT_SIZE - 3 # 252 bytes
|
| 32 |
+
MAX_PAYLOAD = NUM_DATA * DATA_PER_PKT # 6,804 bytes
|
| 33 |
+
|
| 34 |
+
DEFAULT_CAPSULE = "j:/Language-U/qwen-3.5-0.8b-28chirps-tokenizer-ref.capsule"
|
| 35 |
+
DEFAULT_PKT_DIR = "j:/Language-U/packets_tokenizer"
|
| 36 |
+
DEFAULT_OUT_DIR = "j:/Language-U/reconstructed_tokenizer"
|
| 37 |
+
|
| 38 |
+
def read_varint(data, pos):
|
| 39 |
+
val = 0
|
| 40 |
+
shift = 0
|
| 41 |
+
while True:
|
| 42 |
+
b = data[pos]
|
| 43 |
+
pos += 1
|
| 44 |
+
val |= (b & 0x7F) << shift
|
| 45 |
+
if not (b & 0x80):
|
| 46 |
+
break
|
| 47 |
+
shift += 7
|
| 48 |
+
return val, pos
|
| 49 |
+
|
| 50 |
+
def decode_prefix_suffix(data, num_tokens):
|
| 51 |
+
tokens = []
|
| 52 |
+
pos = 0
|
| 53 |
+
prev = b''
|
| 54 |
+
for _ in range(num_tokens):
|
| 55 |
+
common, pos = read_varint(data, pos)
|
| 56 |
+
suffix_len, pos = read_varint(data, pos)
|
| 57 |
+
suffix = data[pos : pos + suffix_len]
|
| 58 |
+
pos += suffix_len
|
| 59 |
+
|
| 60 |
+
t = prev[:common] + suffix
|
| 61 |
+
tokens.append(t)
|
| 62 |
+
prev = t
|
| 63 |
+
return tokens
|
| 64 |
+
|
| 65 |
+
def recover_packets_via_fec(pkt_dir):
|
| 66 |
+
"""Loads 28 packets from folder and applies XOR-FEC recovery if exactly 1 packet is missing."""
|
| 67 |
+
packet_files = sorted([f for f in os.listdir(pkt_dir) if f.startswith("packet_tokenizer_") and f.endswith(".bin")])
|
| 68 |
+
if not packet_files:
|
| 69 |
+
raise FileNotFoundError(f"No packet files found in {pkt_dir}")
|
| 70 |
+
|
| 71 |
+
# Read the number of total packets from the wrapper of the first file
|
| 72 |
+
with open(os.path.join(pkt_dir, packet_files[0]), "rb") as f:
|
| 73 |
+
first_pkt = f.read()
|
| 74 |
+
if len(first_pkt) < 3 or first_pkt[0] != 0xBB:
|
| 75 |
+
raise ValueError("Invalid packet header structure in first packet.")
|
| 76 |
+
total_pkts = first_pkt[2]
|
| 77 |
+
|
| 78 |
+
# Load all available packets
|
| 79 |
+
received_packets = {}
|
| 80 |
+
for pf in packet_files:
|
| 81 |
+
with open(os.path.join(pkt_dir, pf), "rb") as f:
|
| 82 |
+
pkt_bytes = f.read()
|
| 83 |
+
if len(pkt_bytes) == PKT_SIZE and pkt_bytes[0] == 0xBB:
|
| 84 |
+
idx = pkt_bytes[1]
|
| 85 |
+
received_packets[idx] = pkt_bytes
|
| 86 |
+
|
| 87 |
+
print(f" Loaded {len(received_packets)}/{total_pkts} packets.")
|
| 88 |
+
|
| 89 |
+
missing_indices = [i for i in range(total_pkts) if i not in received_packets]
|
| 90 |
+
if len(missing_indices) == 0:
|
| 91 |
+
print("[+] All packets received intact. Verifying FEC parity...")
|
| 92 |
+
# Verify FEC is correct (XOR of all data + FEC payloads must equal 0)
|
| 93 |
+
xor_fec = bytearray(DATA_PER_PKT)
|
| 94 |
+
for idx, pkt in received_packets.items():
|
| 95 |
+
for j in range(DATA_PER_PKT):
|
| 96 |
+
xor_fec[j] ^= pkt[j + 3]
|
| 97 |
+
if any(xor_fec):
|
| 98 |
+
print("⚠️ Warning: FEC verification failed (non-zero XOR sum).")
|
| 99 |
+
else:
|
| 100 |
+
print("[+] FEC verification passed.")
|
| 101 |
+
elif len(missing_indices) == 1:
|
| 102 |
+
missing_idx = missing_indices[0]
|
| 103 |
+
print(f"[-] Missing packet index {missing_idx}. Performing XOR FEC recovery...")
|
| 104 |
+
recovered_payload = bytearray(DATA_PER_PKT)
|
| 105 |
+
for idx, pkt in received_packets.items():
|
| 106 |
+
for j in range(DATA_PER_PKT):
|
| 107 |
+
recovered_payload[j] ^= pkt[j + 3]
|
| 108 |
+
|
| 109 |
+
# Reconstruct missing packet
|
| 110 |
+
recovered_pkt = bytes([0xBB, missing_idx, total_pkts]) + bytes(recovered_payload)
|
| 111 |
+
received_packets[missing_idx] = recovered_pkt
|
| 112 |
+
print(f"[+] Successfully recovered missing packet index {missing_idx} via FEC.")
|
| 113 |
+
else:
|
| 114 |
+
raise ValueError(f"Cannot recover because {len(missing_indices)} packets are missing.")
|
| 115 |
+
|
| 116 |
+
# Reassemble payload from data packets (excluding FEC parity packet)
|
| 117 |
+
assembled = bytearray()
|
| 118 |
+
for i in range(NUM_DATA):
|
| 119 |
+
assembled.extend(received_packets[i][3:])
|
| 120 |
+
return bytes(assembled)
|
| 121 |
+
|
| 122 |
+
def main():
|
| 123 |
+
parser = argparse.ArgumentParser(description="7-Level Tokenizer Restoration & Verification Engine")
|
| 124 |
+
parser.add_argument("--capsule", default=None, help="Path to capsule file to decode")
|
| 125 |
+
parser.add_argument("--packet_dir", default=None, help="Path to packets directory to reassemble")
|
| 126 |
+
parser.add_argument("--out_dir", default=DEFAULT_OUT_DIR, help="Output directory for restored tokenizer")
|
| 127 |
+
args = parser.parse_args()
|
| 128 |
+
|
| 129 |
+
print("=" * 80)
|
| 130 |
+
print(" 7-LEVEL TOKENIZER RESTORATION & VERIFICATION ENGINE")
|
| 131 |
+
print(" Watermark: ip zymatica.space | astronautshe.com")
|
| 132 |
+
print("=" * 80)
|
| 133 |
+
|
| 134 |
+
# 1. Determine Source (Capsule or Packet directory)
|
| 135 |
+
payload_bytes = None
|
| 136 |
+
if args.packet_dir:
|
| 137 |
+
print(f"\n[*] Reassembling from packets in: {args.packet_dir}")
|
| 138 |
+
try:
|
| 139 |
+
payload_bytes = recover_packets_via_fec(args.packet_dir)
|
| 140 |
+
except Exception as e:
|
| 141 |
+
print(f"[-] Reassembly failed: {e}")
|
| 142 |
+
sys.exit(1)
|
| 143 |
+
elif args.capsule:
|
| 144 |
+
print(f"\n[*] Decoding capsule file: {args.capsule}")
|
| 145 |
+
with open(args.capsule, "rb") as f:
|
| 146 |
+
payload_bytes = f.read()
|
| 147 |
+
else:
|
| 148 |
+
# Auto-detect packets or capsule
|
| 149 |
+
if os.path.exists(DEFAULT_PKT_DIR) and len(os.listdir(DEFAULT_PKT_DIR)) > 0:
|
| 150 |
+
print(f"\n[*] Auto-detected packet directory: {DEFAULT_PKT_DIR}")
|
| 151 |
+
try:
|
| 152 |
+
payload_bytes = recover_packets_via_fec(DEFAULT_PKT_DIR)
|
| 153 |
+
except Exception as e:
|
| 154 |
+
print(f"[-] Reassembly failed: {e}")
|
| 155 |
+
|
| 156 |
+
if payload_bytes is None:
|
| 157 |
+
# Fallback to default capsule
|
| 158 |
+
if os.path.exists(DEFAULT_CAPSULE):
|
| 159 |
+
print(f"\n[*] Auto-detected default capsule file: {DEFAULT_CAPSULE}")
|
| 160 |
+
with open(DEFAULT_CAPSULE, "rb") as f:
|
| 161 |
+
payload_bytes = f.read()
|
| 162 |
+
else:
|
| 163 |
+
# Fallback to absolute capsule
|
| 164 |
+
abs_capsule = DEFAULT_CAPSULE.replace("-ref.capsule", ".capsule")
|
| 165 |
+
if os.path.exists(abs_capsule):
|
| 166 |
+
print(f"\n[*] Auto-detected default absolute capsule file: {abs_capsule}")
|
| 167 |
+
with open(abs_capsule, "rb") as f:
|
| 168 |
+
payload_bytes = f.read()
|
| 169 |
+
|
| 170 |
+
if not payload_bytes:
|
| 171 |
+
print("[-] Error: No input capsule file or packet directory found.")
|
| 172 |
+
sys.exit(1)
|
| 173 |
+
|
| 174 |
+
# 2. Decompress Zlib (L6)
|
| 175 |
+
print("\n[L6] Decompressing binary payload...")
|
| 176 |
+
try:
|
| 177 |
+
decompressed = zlib.decompress(payload_bytes)
|
| 178 |
+
print(f" Decompressed: {len(decompressed):,} bytes")
|
| 179 |
+
except Exception as e:
|
| 180 |
+
# If the input was the full padded packets, it might have trailing padding bytes.
|
| 181 |
+
# We need to trim trailing padding or parse headers.
|
| 182 |
+
# Let's try parsing directly or handle payload extraction
|
| 183 |
+
print(f"[-] Decompression failed: {e}")
|
| 184 |
+
sys.exit(1)
|
| 185 |
+
|
| 186 |
+
# 3. Parse Magic Header and Mode
|
| 187 |
+
pos = 0
|
| 188 |
+
magic = decompressed[pos:pos+3]; pos += 3
|
| 189 |
+
if magic != TK_MAGIC:
|
| 190 |
+
print(f"[-] Error: Invalid magic bytes: {magic.hex()}")
|
| 191 |
+
sys.exit(1)
|
| 192 |
+
|
| 193 |
+
mode = decompressed[pos]; pos += 1
|
| 194 |
+
print(f" Magic verified: 0x{magic.hex().upper()}")
|
| 195 |
+
print(f" Mode verified: Mode {mode} ({'Absolute' if mode == 1 else 'Reference/Oracle'})")
|
| 196 |
+
|
| 197 |
+
os.makedirs(args.out_dir, exist_ok=True)
|
| 198 |
+
|
| 199 |
+
# 4. Reconstruction
|
| 200 |
+
if mode == 1:
|
| 201 |
+
# --- Mode 1: Absolute Mode ---
|
| 202 |
+
print("\n[L2-L4] Restoring absolute tokenizer structures...")
|
| 203 |
+
|
| 204 |
+
# Unpack config metadata length and data
|
| 205 |
+
comp_config_len = struct.unpack_from('>I', decompressed, pos)[0]; pos += 4
|
| 206 |
+
comp_config_data = decompressed[pos : pos + comp_config_len]; pos += comp_config_len
|
| 207 |
+
config_meta = json.loads(zlib.decompress(comp_config_data).decode("utf-8"))
|
| 208 |
+
print(f" - Config metadata loaded ({len(config_meta)} keys)")
|
| 209 |
+
|
| 210 |
+
# Unpack vocabulary normal tokens
|
| 211 |
+
vocab_num = struct.unpack_from('>I', decompressed, pos)[0]; pos += 4
|
| 212 |
+
vocab_len = struct.unpack_from('>I', decompressed, pos)[0]; pos += 4
|
| 213 |
+
vocab_data = decompressed[pos : pos + vocab_len]; pos += vocab_len
|
| 214 |
+
|
| 215 |
+
vocab_list = decode_prefix_suffix(vocab_data, vocab_num)
|
| 216 |
+
print(f" - Restored {len(vocab_list):,} normal vocabulary tokens")
|
| 217 |
+
|
| 218 |
+
# Unpack merges
|
| 219 |
+
merges_num = struct.unpack_from('>I', decompressed, pos)[0]; pos += 4
|
| 220 |
+
merges_data = decompressed[pos : pos + merges_num * 6]; pos += merges_num * 6
|
| 221 |
+
|
| 222 |
+
merges = []
|
| 223 |
+
for i in range(merges_num):
|
| 224 |
+
idx0 = int.from_bytes(merges_data[i*6 : i*6 + 3], 'big')
|
| 225 |
+
idx1 = int.from_bytes(merges_data[i*6 + 3 : i*6 + 6], 'big')
|
| 226 |
+
t0 = vocab_list[idx0].decode("utf-8", errors="replace")
|
| 227 |
+
t1 = vocab_list[idx1].decode("utf-8", errors="replace")
|
| 228 |
+
merges.append(f"{t0} {t1}")
|
| 229 |
+
print(f" - Restored {len(merges):,} BPE merge entries")
|
| 230 |
+
|
| 231 |
+
# Reconstruct vocab.json and merges.txt
|
| 232 |
+
vocab_dict = {t.decode("utf-8", errors="replace"): idx for idx, t in enumerate(vocab_list)}
|
| 233 |
+
|
| 234 |
+
# Write merges.txt
|
| 235 |
+
merges_out = os.path.join(args.out_dir, "merges.txt")
|
| 236 |
+
with open(merges_out, "w", encoding="utf-8") as f:
|
| 237 |
+
f.write("\n".join(merges) + "\n")
|
| 238 |
+
|
| 239 |
+
# Write vocab.json
|
| 240 |
+
vocab_out = os.path.join(args.out_dir, "vocab.json")
|
| 241 |
+
with open(vocab_out, "w", encoding="utf-8") as f:
|
| 242 |
+
json.dump(vocab_dict, f, ensure_ascii=False, indent=2)
|
| 243 |
+
|
| 244 |
+
# Reconstruct tokenizer.json
|
| 245 |
+
reconstructed_t_json = {
|
| 246 |
+
"version": config_meta["version"],
|
| 247 |
+
"truncation": config_meta["truncation"],
|
| 248 |
+
"padding": config_meta["padding"],
|
| 249 |
+
"added_tokens": config_meta["added_tokens"],
|
| 250 |
+
"normalizer": config_meta["normalizer"],
|
| 251 |
+
"pre_tokenizer": config_meta["pre_tokenizer"],
|
| 252 |
+
"post_processor": config_meta["post_processor"],
|
| 253 |
+
"decoder": config_meta["decoder"],
|
| 254 |
+
"model": {
|
| 255 |
+
"type": config_meta["model_type"],
|
| 256 |
+
"dropout": config_meta["model_dropout"],
|
| 257 |
+
"unk_token": config_meta["model_unk_token"],
|
| 258 |
+
"continuing_subword_prefix": config_meta["model_continuing_subword_prefix"],
|
| 259 |
+
"end_of_word_suffix": config_meta["model_end_of_word_suffix"],
|
| 260 |
+
"fuse_unk": config_meta["model_fuse_unk"],
|
| 261 |
+
"byte_fallback": config_meta["model_byte_fallback"],
|
| 262 |
+
"ignore_merges": config_meta["model_ignore_merges"],
|
| 263 |
+
"vocab": vocab_dict,
|
| 264 |
+
"merges": merges
|
| 265 |
+
}
|
| 266 |
+
}
|
| 267 |
+
|
| 268 |
+
tokenizer_json_out = os.path.join(args.out_dir, "tokenizer.json")
|
| 269 |
+
with open(tokenizer_json_out, "w", encoding="utf-8") as f:
|
| 270 |
+
json.dump(reconstructed_t_json, f, ensure_ascii=False, indent=2)
|
| 271 |
+
|
| 272 |
+
# Write tokenizer_config.json
|
| 273 |
+
tokenizer_config_out = os.path.join(args.out_dir, "tokenizer_config.json")
|
| 274 |
+
with open(tokenizer_config_out, "w", encoding="utf-8") as f:
|
| 275 |
+
json.dump(config_meta["tokenizer_config"], f, ensure_ascii=False, indent=2)
|
| 276 |
+
|
| 277 |
+
print("[+] Stand-alone absolute reconstruction completed successfully.")
|
| 278 |
+
|
| 279 |
+
elif mode == 2:
|
| 280 |
+
# --- Mode 2: Reference Mode ---
|
| 281 |
+
print("\n[L5] Fetching base model tokenizer reference from HuggingFace...")
|
| 282 |
+
base_repo_len = struct.unpack_from('>H', decompressed, pos)[0]; pos += 2
|
| 283 |
+
base_repo = decompressed[pos : pos + base_repo_len].decode("utf-8"); pos += base_repo_len
|
| 284 |
+
print(f" - Base Oracle Reference: {base_repo}")
|
| 285 |
+
|
| 286 |
+
try:
|
| 287 |
+
# Load tokenizer from HF reference
|
| 288 |
+
print(f" - Querying Hugging Face: {base_repo} ...")
|
| 289 |
+
tokenizer = AutoTokenizer.from_pretrained(base_repo, trust_remote_code=True)
|
| 290 |
+
tokenizer.save_pretrained(args.out_dir)
|
| 291 |
+
print(f"[+] Successfully downloaded and saved tokenizer to: {args.out_dir}")
|
| 292 |
+
except Exception as e:
|
| 293 |
+
print(f"[-] Error downloading base tokenizer: {e}")
|
| 294 |
+
# Offline fallback if local files exist
|
| 295 |
+
local_fallback = "j:/Language-U/Language-U-V2/qwen-3.5-0.8b-local"
|
| 296 |
+
if os.path.exists(local_fallback):
|
| 297 |
+
print(f" - [Offline Fallback] Copying from local cache: {local_fallback}")
|
| 298 |
+
import shutil
|
| 299 |
+
for fn in ["tokenizer.json", "tokenizer_config.json", "vocab.json", "merges.txt"]:
|
| 300 |
+
src = os.path.join(local_fallback, fn)
|
| 301 |
+
if os.path.exists(src):
|
| 302 |
+
shutil.copy(src, os.path.join(args.out_dir, fn))
|
| 303 |
+
print(f"[+] Offline fallback copied successfully to: {args.out_dir}")
|
| 304 |
+
else:
|
| 305 |
+
sys.exit(1)
|
| 306 |
+
else:
|
| 307 |
+
print(f"[-] Error: Unknown tokenizer capsule mode: {mode}")
|
| 308 |
+
sys.exit(1)
|
| 309 |
+
|
| 310 |
+
# 5. Verification
|
| 311 |
+
print("\n[*] Verifying reconstructed tokenizer loading correctness...")
|
| 312 |
+
try:
|
| 313 |
+
loaded_tokenizer = AutoTokenizer.from_pretrained(args.out_dir, trust_remote_code=True)
|
| 314 |
+
print(f" [PASS] Reconstructed tokenizer successfully parsed by Transformers!")
|
| 315 |
+
|
| 316 |
+
# Test encoding
|
| 317 |
+
test_text = "Astronaut SHE LoRa concentrator GPIO reset SX1302 v3.0 Cuneiform-U"
|
| 318 |
+
tokens = loaded_tokenizer.encode(test_text)
|
| 319 |
+
decoded = loaded_tokenizer.decode(tokens)
|
| 320 |
+
print(f" [PASS] Test encoding round-trip succeeded!")
|
| 321 |
+
print(f" Encoded: {tokens[:8]}...")
|
| 322 |
+
print(f" Decoded: \"{decoded}\"")
|
| 323 |
+
|
| 324 |
+
print("\n" + "=" * 80)
|
| 325 |
+
print(" RESTORE SUCCESSFUL")
|
| 326 |
+
print("=" * 80)
|
| 327 |
+
print(f" Output folder: {os.path.abspath(args.out_dir)}")
|
| 328 |
+
print("=" * 80)
|
| 329 |
+
except Exception as e:
|
| 330 |
+
print(f"[-] Verification failed: {e}")
|
| 331 |
+
sys.exit(1)
|
| 332 |
+
|
| 333 |
+
if __name__ == "__main__":
|
| 334 |
+
main()
|
language_u_logo.jpg
ADDED
|
quantize_genesis_3bit_to_dct.py
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import struct
|
| 3 |
+
import numpy as np
|
| 4 |
+
from scipy.fft import dct, idct
|
| 5 |
+
|
| 6 |
+
GENESIS_MAGIC = 0x47454E45 # "GENE"
|
| 7 |
+
PERFECT_MAGIC = 0x50455246 # "PERF"
|
| 8 |
+
WATERMARK = b"ip zymatica.space".ljust(32, b" ")
|
| 9 |
+
|
| 10 |
+
def unpack_3bit_array(packed_bytes, original_len):
|
| 11 |
+
"""Unpack 3-bit packed bytes back to int8 array in range [-3, 3] vectorized."""
|
| 12 |
+
bytes_arr = np.frombuffer(packed_bytes, dtype=np.uint8).reshape(-1, 3).astype(np.uint32)
|
| 13 |
+
vals = bytes_arr[:, 0] | (bytes_arr[:, 1] << 8) | (bytes_arr[:, 2] << 16)
|
| 14 |
+
v0 = (vals & 0x07).astype(np.int8) - 3
|
| 15 |
+
v1 = ((vals >> 3) & 0x07).astype(np.int8) - 3
|
| 16 |
+
v2 = ((vals >> 6) & 0x07).astype(np.int8) - 3
|
| 17 |
+
v3 = ((vals >> 9) & 0x07).astype(np.int8) - 3
|
| 18 |
+
v4 = ((vals >> 12) & 0x07).astype(np.int8) - 3
|
| 19 |
+
v5 = ((vals >> 15) & 0x07).astype(np.int8) - 3
|
| 20 |
+
v6 = ((vals >> 18) & 0x07).astype(np.int8) - 3
|
| 21 |
+
v7 = ((vals >> 21) & 0x07).astype(np.int8) - 3
|
| 22 |
+
arr = np.stack([v0, v1, v2, v3, v4, v5, v6, v7], axis=1).flatten()
|
| 23 |
+
return arr[:original_len]
|
| 24 |
+
|
| 25 |
+
def dct_compress_vec(v, max_K=16):
|
| 26 |
+
"""L4: Apply DCT and keep top-K coefficients, quantized to 4-bit."""
|
| 27 |
+
n = len(v)
|
| 28 |
+
K = min(max_K, n)
|
| 29 |
+
v_dct = dct(v.astype(np.float64), norm='ortho')
|
| 30 |
+
top_idx = np.sort(np.argsort(np.abs(v_dct))[-K:])
|
| 31 |
+
vals = v_dct[top_idx]
|
| 32 |
+
scale = float(np.abs(vals).max()) / 7.0 + 1e-9
|
| 33 |
+
q_vals = np.round(vals / scale).clip(-7, 7).astype(np.int8)
|
| 34 |
+
|
| 35 |
+
deltas = np.diff(np.concatenate([[0], top_idx])).astype(np.uint8)
|
| 36 |
+
if deltas.max() > 255:
|
| 37 |
+
idx_bytes = bytes([0x01, K]) + b''.join(struct.pack('>H', int(d)) for d in
|
| 38 |
+
np.diff(np.concatenate([[0], top_idx])).astype(np.uint16))
|
| 39 |
+
else:
|
| 40 |
+
idx_bytes = bytes([0x00, K]) + bytes(deltas)
|
| 41 |
+
|
| 42 |
+
# Pack 4-bit values: 2 values per byte
|
| 43 |
+
packed_vals = bytearray()
|
| 44 |
+
for i in range(0, K, 2):
|
| 45 |
+
lo = int(q_vals[i]) & 0x0F
|
| 46 |
+
hi = (int(q_vals[i+1]) & 0x0F) if i+1 < K else 0
|
| 47 |
+
packed_vals.append((hi << 4) | lo)
|
| 48 |
+
|
| 49 |
+
header = struct.pack('>H', n) + bytes([K]) + struct.pack('>e', scale)
|
| 50 |
+
return header + idx_bytes + bytes(packed_vals)
|
| 51 |
+
|
| 52 |
+
def quantize_3bit_to_dct_genesis(input_path, output_path, K_u=16, K_v=16):
|
| 53 |
+
print("=" * 80)
|
| 54 |
+
print(" GENESIS LEVEL 4 CONVERTER: 3-BIT SVD (v6) -> DCT SPECTRAL SVD (v8)")
|
| 55 |
+
print(" Watermark: ip zymatica.space")
|
| 56 |
+
print("=" * 80)
|
| 57 |
+
print(f"Reading from: {input_path}")
|
| 58 |
+
print(f"Writing to: {output_path}\n")
|
| 59 |
+
|
| 60 |
+
if not os.path.exists(input_path):
|
| 61 |
+
print(f"Error: Input file '{input_path}' does not exist.")
|
| 62 |
+
return
|
| 63 |
+
|
| 64 |
+
total_3bit_bytes = 0
|
| 65 |
+
total_dct_bytes = 0
|
| 66 |
+
|
| 67 |
+
with open(input_path, "rb") as fin, open(output_path, "wb") as fout:
|
| 68 |
+
# --- Read Header ---
|
| 69 |
+
magic = struct.unpack('>I', fin.read(4))[0]
|
| 70 |
+
if magic != GENESIS_MAGIC:
|
| 71 |
+
print(f"Error: Invalid magic 0x{magic:08X}")
|
| 72 |
+
return
|
| 73 |
+
|
| 74 |
+
version = struct.unpack('>H', fin.read(2))[0]
|
| 75 |
+
if version != 6:
|
| 76 |
+
print(f"Error: Input format version is {version}, expected version 6 (3-bit SVD).")
|
| 77 |
+
return
|
| 78 |
+
|
| 79 |
+
watermark = fin.read(32)
|
| 80 |
+
perf_magic = struct.unpack('>I', fin.read(4))[0]
|
| 81 |
+
if perf_magic != PERFECT_MAGIC:
|
| 82 |
+
print(f"Error: Invalid perfect magic 0x{perf_magic:08X}")
|
| 83 |
+
return
|
| 84 |
+
|
| 85 |
+
hidden, heads, kv_heads, ffn_dim, blocks, vocab = struct.unpack('>IIIIII', fin.read(24))
|
| 86 |
+
e_attn, e_ffn, e_lm, e_other = struct.unpack('>ffff', fin.read(16))
|
| 87 |
+
num_layers = struct.unpack('>I', fin.read(4))[0]
|
| 88 |
+
|
| 89 |
+
# --- Write Header (Version 8: DCT spectral SVD) ---
|
| 90 |
+
fout.write(struct.pack('>I', GENESIS_MAGIC))
|
| 91 |
+
fout.write(struct.pack('>H', 8)) # format version 8 for DCT spectral
|
| 92 |
+
fout.write(WATERMARK)
|
| 93 |
+
fout.write(struct.pack('>I', PERFECT_MAGIC))
|
| 94 |
+
fout.write(struct.pack('>IIIIII', hidden, heads, kv_heads, ffn_dim, blocks, vocab))
|
| 95 |
+
fout.write(struct.pack('>ffff', e_attn, e_ffn, e_lm, e_other))
|
| 96 |
+
|
| 97 |
+
# Placeholder for layer count
|
| 98 |
+
layer_count_pos = fout.tell()
|
| 99 |
+
fout.write(struct.pack('>I', num_layers))
|
| 100 |
+
|
| 101 |
+
# --- Process Layers ---
|
| 102 |
+
for i in range(num_layers):
|
| 103 |
+
name_len = struct.unpack('>H', fin.read(2))[0]
|
| 104 |
+
name = fin.read(name_len).decode('utf-8')
|
| 105 |
+
m, n, r = struct.unpack('>III', fin.read(12))
|
| 106 |
+
|
| 107 |
+
# Read version 6 details: scales + 3-bit packed U and V
|
| 108 |
+
scale_u, scale_v = struct.unpack('>ff', fin.read(8))
|
| 109 |
+
|
| 110 |
+
# 3-bit packed array sizes: ceil(len * 3 / 8) -> padded to multiple of 8
|
| 111 |
+
u_len_padded = (m * r + (8 - (m * r % 8)) % 8)
|
| 112 |
+
v_len_padded = (n * r + (8 - (n * r % 8)) % 8)
|
| 113 |
+
u_packed_bytes = fin.read((u_len_padded * 3) // 8)
|
| 114 |
+
v_packed_bytes = fin.read((v_len_padded * 3) // 8)
|
| 115 |
+
|
| 116 |
+
total_3bit_bytes += len(u_packed_bytes) + len(v_packed_bytes)
|
| 117 |
+
|
| 118 |
+
# Unpack 3-bit arrays back to [-3, 3] integers
|
| 119 |
+
U_3bit = unpack_3bit_array(u_packed_bytes, m * r).reshape(m, r)
|
| 120 |
+
V_3bit = unpack_3bit_array(v_packed_bytes, n * r).reshape(n, r)
|
| 121 |
+
|
| 122 |
+
# De-quantize back to floating-point vectors
|
| 123 |
+
U_float = U_3bit.astype(np.float32) * scale_u
|
| 124 |
+
V_float = V_3bit.astype(np.float32) * scale_v
|
| 125 |
+
|
| 126 |
+
# Compress each column vector of U and V via DCT Spectral (Level 4)
|
| 127 |
+
u_dct_blobs = []
|
| 128 |
+
v_dct_blobs = []
|
| 129 |
+
for col in range(r):
|
| 130 |
+
u_dct_blobs.append(dct_compress_vec(U_float[:, col], max_K=K_u))
|
| 131 |
+
v_dct_blobs.append(dct_compress_vec(V_float[:, col], max_K=K_v))
|
| 132 |
+
|
| 133 |
+
u_dct_data = b''.join(u_dct_blobs)
|
| 134 |
+
v_dct_data = b''.join(v_dct_blobs)
|
| 135 |
+
|
| 136 |
+
total_dct_bytes += len(u_dct_data) + len(v_dct_data)
|
| 137 |
+
|
| 138 |
+
# Read has_residual
|
| 139 |
+
has_residual = struct.unpack('>?', fin.read(1))[0]
|
| 140 |
+
|
| 141 |
+
# Write Layer in Version 8 format
|
| 142 |
+
name_b = name.encode('utf-8')
|
| 143 |
+
fout.write(struct.pack('>H', len(name_b)))
|
| 144 |
+
fout.write(name_b)
|
| 145 |
+
fout.write(struct.pack('>III', m, n, r))
|
| 146 |
+
fout.write(struct.pack('>ff', scale_u, scale_v)) # store reference scales
|
| 147 |
+
|
| 148 |
+
# Write DCT binary blobs
|
| 149 |
+
fout.write(struct.pack('>II', len(u_dct_data), len(v_dct_data)))
|
| 150 |
+
fout.write(u_dct_data)
|
| 151 |
+
fout.write(v_dct_data)
|
| 152 |
+
|
| 153 |
+
fout.write(struct.pack('>?', has_residual))
|
| 154 |
+
|
| 155 |
+
if has_residual:
|
| 156 |
+
res_rank = struct.unpack('>I', fin.read(4))[0]
|
| 157 |
+
scale_res_u, scale_res_v = struct.unpack('>ff', fin.read(8))
|
| 158 |
+
U_res = fin.read(m * res_rank) # int8 residual
|
| 159 |
+
V_res = fin.read(n * res_rank) # int8 residual
|
| 160 |
+
|
| 161 |
+
# Residual is left as int8, write directly
|
| 162 |
+
fout.write(struct.pack('>I', res_rank))
|
| 163 |
+
fout.write(struct.pack('>ff', scale_res_u, scale_res_v))
|
| 164 |
+
fout.write(U_res)
|
| 165 |
+
fout.write(V_res)
|
| 166 |
+
|
| 167 |
+
if (i + 1) % 40 == 0 or (i + 1) == num_layers:
|
| 168 |
+
print(f" Processed {i+1}/{num_layers} layers...")
|
| 169 |
+
|
| 170 |
+
input_size = os.path.getsize(input_path) / 1e9
|
| 171 |
+
output_size = os.path.getsize(output_path) / 1e9
|
| 172 |
+
|
| 173 |
+
print(f"\nSuccess!")
|
| 174 |
+
print(f" Input size (3-bit): {input_size * 1000:.1f} MB")
|
| 175 |
+
print(f" Output size (DCT v8): {output_size * 1000:.1f} MB")
|
| 176 |
+
print(f" 3-bit parameter bytes: {total_3bit_bytes:,} bytes")
|
| 177 |
+
print(f" DCT spectral bytes: {total_dct_bytes:,} bytes")
|
| 178 |
+
print(f" Overall SVD reduction: {total_3bit_bytes / total_dct_bytes:.2f}x")
|
| 179 |
+
print(f" Overall file ratio: {input_size / output_size:.2f}x")
|
| 180 |
+
|
| 181 |
+
if __name__ == "__main__":
|
| 182 |
+
import argparse
|
| 183 |
+
parser = argparse.ArgumentParser(description="Convert 3-bit genesis to DCT spectral genesis")
|
| 184 |
+
parser.add_argument("input", help="Path to input 3-bit .genesis file")
|
| 185 |
+
parser.add_argument("output", help="Path to output DCT .genesis file")
|
| 186 |
+
parser.add_argument("--k-u", type=int, default=16, help="Top-K DCT coefficients for U")
|
| 187 |
+
parser.add_argument("--k-v", type=int, default=16, help="Top-K DCT coefficients for V")
|
| 188 |
+
args = parser.parse_args()
|
| 189 |
+
|
| 190 |
+
quantize_3bit_to_dct_genesis(args.input, args.output, K_u=args.k_u, K_v=args.k_v)
|
quantize_genesis_dct_to_grad.py
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import struct
|
| 3 |
+
import numpy as np
|
| 4 |
+
|
| 5 |
+
GENESIS_MAGIC = 0x47454E45 # "GENE"
|
| 6 |
+
PERFECT_MAGIC = 0x50455246 # "PERF"
|
| 7 |
+
WATERMARK = b"ip zymatica.space".ljust(32, b" ")
|
| 8 |
+
|
| 9 |
+
def pack_2bit_array(q_vals):
|
| 10 |
+
"""Pack an array of 4-bit values [-7, 7] to 2-bit values [sign, mag_class], packed 4 per byte."""
|
| 11 |
+
n = len(q_vals)
|
| 12 |
+
# Convert to 2-bit: sign (1 bit) + mag_class (1 bit)
|
| 13 |
+
# sign: 1 if >= 0 else 0
|
| 14 |
+
# mag_class: 1 if abs(v) > 3 else 0
|
| 15 |
+
symbols = []
|
| 16 |
+
for v in q_vals:
|
| 17 |
+
sign = 1 if v >= 0 else 0
|
| 18 |
+
mag = 1 if abs(v) > 3 else 0
|
| 19 |
+
symbols.append((sign << 1) | mag)
|
| 20 |
+
|
| 21 |
+
# Pad symbols to multiple of 4
|
| 22 |
+
pad_len = (4 - (len(symbols) % 4)) % 4
|
| 23 |
+
if pad_len > 0:
|
| 24 |
+
symbols.extend([0] * pad_len)
|
| 25 |
+
|
| 26 |
+
packed = bytearray()
|
| 27 |
+
for i in range(0, len(symbols), 4):
|
| 28 |
+
# Pack 4 symbols (each 2 bits) into 1 byte
|
| 29 |
+
b = (
|
| 30 |
+
(symbols[i] & 0x03) |
|
| 31 |
+
((symbols[i+1] & 0x03) << 2) |
|
| 32 |
+
((symbols[i+2] & 0x03) << 4) |
|
| 33 |
+
((symbols[i+3] & 0x03) << 6)
|
| 34 |
+
)
|
| 35 |
+
packed.append(b)
|
| 36 |
+
return bytes(packed)
|
| 37 |
+
|
| 38 |
+
def unpack_4bit_layer_dct(packed_bytes, K):
|
| 39 |
+
"""Helper to unpack 4-bit packed values from DCT byte stream."""
|
| 40 |
+
q_vals = []
|
| 41 |
+
n_bytes = (K + 1) // 2
|
| 42 |
+
packed = packed_bytes[:n_bytes]
|
| 43 |
+
for b in packed:
|
| 44 |
+
lo = b & 0x0F
|
| 45 |
+
hi = (b >> 4) & 0x0F
|
| 46 |
+
q_vals.append(lo if lo <= 7 else lo - 16)
|
| 47 |
+
q_vals.append(hi if hi <= 7 else hi - 16)
|
| 48 |
+
return q_vals[:K], packed_bytes[n_bytes:]
|
| 49 |
+
|
| 50 |
+
def quantize_dct_to_grad_genesis(input_path, output_path):
|
| 51 |
+
print("=" * 80)
|
| 52 |
+
print(" GENESIS LEVEL 6 CONVERTER: DCT SPECTRAL (v8) -> GRADIENT ATOM (v9)")
|
| 53 |
+
print(" Watermark: ip zymatica.space")
|
| 54 |
+
print("=" * 80)
|
| 55 |
+
print(f"Reading from: {input_path}")
|
| 56 |
+
print(f"Writing to: {output_path}\n")
|
| 57 |
+
|
| 58 |
+
if not os.path.exists(input_path):
|
| 59 |
+
print(f"Error: Input file '{input_path}' does not exist.")
|
| 60 |
+
return
|
| 61 |
+
|
| 62 |
+
total_dct_bytes = 0
|
| 63 |
+
total_grad_bytes = 0
|
| 64 |
+
|
| 65 |
+
with open(input_path, "rb") as fin, open(output_path, "wb") as fout:
|
| 66 |
+
# --- Read Header ---
|
| 67 |
+
magic = struct.unpack('>I', fin.read(4))[0]
|
| 68 |
+
if magic != GENESIS_MAGIC:
|
| 69 |
+
print(f"Error: Invalid magic 0x{magic:08X}")
|
| 70 |
+
return
|
| 71 |
+
|
| 72 |
+
version = struct.unpack('>H', fin.read(2))[0]
|
| 73 |
+
if version != 8:
|
| 74 |
+
print(f"Error: Input format version is {version}, expected version 8 (DCT SVD).")
|
| 75 |
+
return
|
| 76 |
+
|
| 77 |
+
watermark = fin.read(32)
|
| 78 |
+
perf_magic = struct.unpack('>I', fin.read(4))[0]
|
| 79 |
+
if perf_magic != PERFECT_MAGIC:
|
| 80 |
+
print(f"Error: Invalid perfect magic 0x{perf_magic:08X}")
|
| 81 |
+
return
|
| 82 |
+
|
| 83 |
+
hidden, heads, kv_heads, ffn_dim, blocks, vocab = struct.unpack('>IIIIII', fin.read(24))
|
| 84 |
+
e_attn, e_ffn, e_lm, e_other = struct.unpack('>ffff', fin.read(16))
|
| 85 |
+
num_layers = struct.unpack('>I', fin.read(4))[0]
|
| 86 |
+
|
| 87 |
+
# --- Write Header (Version 9: Gradient Atom DCT SVD) ---
|
| 88 |
+
fout.write(struct.pack('>I', GENESIS_MAGIC))
|
| 89 |
+
fout.write(struct.pack('>H', 9)) # format version 9 for Gradient Atom
|
| 90 |
+
fout.write(WATERMARK)
|
| 91 |
+
fout.write(struct.pack('>I', PERFECT_MAGIC))
|
| 92 |
+
fout.write(struct.pack('>IIIIII', hidden, heads, kv_heads, ffn_dim, blocks, vocab))
|
| 93 |
+
fout.write(struct.pack('>ffff', e_attn, e_ffn, e_lm, e_other))
|
| 94 |
+
|
| 95 |
+
# Placeholder for layer count
|
| 96 |
+
layer_count_pos = fout.tell()
|
| 97 |
+
fout.write(struct.pack('>I', num_layers))
|
| 98 |
+
|
| 99 |
+
# --- Process Layers ---
|
| 100 |
+
for i in range(num_layers):
|
| 101 |
+
name_len = struct.unpack('>H', fin.read(2))[0]
|
| 102 |
+
name = fin.read(name_len).decode('utf-8')
|
| 103 |
+
m, n, r = struct.unpack('>III', fin.read(12))
|
| 104 |
+
scale_u, scale_v = struct.unpack('>ff', fin.read(8))
|
| 105 |
+
|
| 106 |
+
u_len, v_len = struct.unpack('>II', fin.read(8))
|
| 107 |
+
total_dct_bytes += u_len + v_len
|
| 108 |
+
|
| 109 |
+
u_dct_data = fin.read(u_len)
|
| 110 |
+
v_dct_data = fin.read(v_len)
|
| 111 |
+
|
| 112 |
+
# Process U columns
|
| 113 |
+
u_grad_blobs = []
|
| 114 |
+
u_stream = u_dct_data
|
| 115 |
+
for col in range(r):
|
| 116 |
+
# Parse header
|
| 117 |
+
orig_n = struct.unpack('>H', u_stream[:2])[0]
|
| 118 |
+
K = u_stream[2]
|
| 119 |
+
scale = struct.unpack('>e', u_stream[3:5])[0]
|
| 120 |
+
idx_mode = u_stream[5]
|
| 121 |
+
K_check = u_stream[6]
|
| 122 |
+
|
| 123 |
+
# Seek index bytes
|
| 124 |
+
idx_size = K_check * 2 if idx_mode == 1 else K_check
|
| 125 |
+
idx_bytes = u_stream[7 : 7 + idx_size]
|
| 126 |
+
|
| 127 |
+
# Extract 4-bit values and update stream
|
| 128 |
+
packed_vals_offset = 7 + idx_size
|
| 129 |
+
q_vals, remaining = unpack_4bit_layer_dct(u_stream[packed_vals_offset:], K)
|
| 130 |
+
|
| 131 |
+
# Re-pack 4-bit values to 2-bit gradient atoms
|
| 132 |
+
q_grad_packed = pack_2bit_array(q_vals)
|
| 133 |
+
|
| 134 |
+
# Write new column format: [orig_n:2][K:1][scale:e:2][idx_mode:1][K_check:1][idx_bytes][packed_2bit_vals]
|
| 135 |
+
col_header = struct.pack('>H', orig_n) + bytes([K]) + struct.pack('>e', scale) + bytes([idx_mode, K_check])
|
| 136 |
+
u_grad_blobs.append(col_header + idx_bytes + q_grad_packed)
|
| 137 |
+
u_stream = remaining
|
| 138 |
+
|
| 139 |
+
# Process V columns
|
| 140 |
+
v_grad_blobs = []
|
| 141 |
+
v_stream = v_dct_data
|
| 142 |
+
for col in range(r):
|
| 143 |
+
# Parse header
|
| 144 |
+
orig_n = struct.unpack('>H', v_stream[:2])[0]
|
| 145 |
+
K = v_stream[2]
|
| 146 |
+
scale = struct.unpack('>e', v_stream[3:5])[0]
|
| 147 |
+
idx_mode = v_stream[5]
|
| 148 |
+
K_check = v_stream[6]
|
| 149 |
+
|
| 150 |
+
# Seek index bytes
|
| 151 |
+
idx_size = K_check * 2 if idx_mode == 1 else K_check
|
| 152 |
+
idx_bytes = v_stream[7 : 7 + idx_size]
|
| 153 |
+
|
| 154 |
+
# Extract 4-bit values and update stream
|
| 155 |
+
packed_vals_offset = 7 + idx_size
|
| 156 |
+
q_vals, remaining = unpack_4bit_layer_dct(v_stream[packed_vals_offset:], K)
|
| 157 |
+
|
| 158 |
+
# Re-pack 4-bit values to 2-bit gradient atoms
|
| 159 |
+
q_grad_packed = pack_2bit_array(q_vals)
|
| 160 |
+
|
| 161 |
+
col_header = struct.pack('>H', orig_n) + bytes([K]) + struct.pack('>e', scale) + bytes([idx_mode, K_check])
|
| 162 |
+
v_grad_blobs.append(col_header + idx_bytes + q_grad_packed)
|
| 163 |
+
v_stream = remaining
|
| 164 |
+
|
| 165 |
+
u_grad_data = b''.join(u_grad_blobs)
|
| 166 |
+
v_grad_data = b''.join(v_grad_blobs)
|
| 167 |
+
total_grad_bytes += len(u_grad_data) + len(v_grad_data)
|
| 168 |
+
|
| 169 |
+
# Read has_residual
|
| 170 |
+
has_residual = struct.unpack('>?', fin.read(1))[0]
|
| 171 |
+
|
| 172 |
+
# Write Layer in Version 9 format
|
| 173 |
+
name_b = name.encode('utf-8')
|
| 174 |
+
fout.write(struct.pack('>H', len(name_b)))
|
| 175 |
+
fout.write(name_b)
|
| 176 |
+
fout.write(struct.pack('>III', m, n, r))
|
| 177 |
+
fout.write(struct.pack('>ff', scale_u, scale_v))
|
| 178 |
+
|
| 179 |
+
# Write Gradient Atom blobs
|
| 180 |
+
fout.write(struct.pack('>II', len(u_grad_data), len(v_grad_data)))
|
| 181 |
+
fout.write(u_grad_data)
|
| 182 |
+
fout.write(v_grad_data)
|
| 183 |
+
fout.write(struct.pack('>?', has_residual))
|
| 184 |
+
|
| 185 |
+
if has_residual:
|
| 186 |
+
res_rank = struct.unpack('>I', fin.read(4))[0]
|
| 187 |
+
scale_res_u, scale_res_v = struct.unpack('>ff', fin.read(8))
|
| 188 |
+
U_res = fin.read(m * res_rank) # int8 residual
|
| 189 |
+
V_res = fin.read(n * res_rank) # int8 residual
|
| 190 |
+
|
| 191 |
+
fout.write(struct.pack('>I', res_rank))
|
| 192 |
+
fout.write(struct.pack('>ff', scale_res_u, scale_res_v))
|
| 193 |
+
fout.write(U_res)
|
| 194 |
+
fout.write(V_res)
|
| 195 |
+
|
| 196 |
+
if (i + 1) % 40 == 0 or (i + 1) == num_layers:
|
| 197 |
+
print(f" Processed {i+1}/{num_layers} layers...")
|
| 198 |
+
|
| 199 |
+
input_size = os.path.getsize(input_path) / 1e9
|
| 200 |
+
output_size = os.path.getsize(output_path) / 1e9
|
| 201 |
+
|
| 202 |
+
print(f"\nSuccess!")
|
| 203 |
+
print(f" Input size (DCT v8): {input_size * 1000:.1f} MB")
|
| 204 |
+
print(f" Output size (Grad v9): {output_size * 1000:.1f} MB")
|
| 205 |
+
print(f" DCT spectral bytes: {total_dct_bytes:,} bytes")
|
| 206 |
+
print(f" Grad atom bytes: {total_grad_bytes:,} bytes")
|
| 207 |
+
print(f" Overall SVD reduction: {total_dct_bytes / total_grad_bytes:.2f}x")
|
| 208 |
+
print(f" Overall file ratio: {input_size / output_size:.2f}x")
|
| 209 |
+
|
| 210 |
+
if __name__ == "__main__":
|
| 211 |
+
import argparse
|
| 212 |
+
parser = argparse.ArgumentParser(description="Convert DCT genesis to Gradient Atom genesis")
|
| 213 |
+
parser.add_argument("input", help="Path to input DCT .genesis file")
|
| 214 |
+
parser.add_argument("output", help="Path to output Gradient Atom .genesis file")
|
| 215 |
+
args = parser.parse_args()
|
| 216 |
+
|
| 217 |
+
quantize_dct_to_grad_genesis(args.input, args.output)
|
quantize_genesis_int8_to_3bit.py
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import struct
|
| 3 |
+
import numpy as np
|
| 4 |
+
|
| 5 |
+
GENESIS_MAGIC = 0x47454E45 # "GENE"
|
| 6 |
+
PERFECT_MAGIC = 0x50455246 # "PERF"
|
| 7 |
+
WATERMARK = b"ip zymatica.space".ljust(32, b" ")
|
| 8 |
+
|
| 9 |
+
def pack_3bit_array(arr):
|
| 10 |
+
"""Pack a flat array of int8 values in range [-3, 3] into 3-bit packed bytes vectorized."""
|
| 11 |
+
arr_shifted = np.clip(arr + 3, 0, 7).astype(np.uint8)
|
| 12 |
+
n = len(arr_shifted)
|
| 13 |
+
|
| 14 |
+
# Pad to multiple of 8
|
| 15 |
+
pad_len = (8 - (n % 8)) % 8
|
| 16 |
+
if pad_len > 0:
|
| 17 |
+
arr_shifted = np.concatenate([arr_shifted, np.zeros(pad_len, dtype=np.uint8)])
|
| 18 |
+
|
| 19 |
+
# Reshape to (N/8, 8)
|
| 20 |
+
arr_reshaped = arr_shifted.reshape(-1, 8).astype(np.uint32)
|
| 21 |
+
|
| 22 |
+
# shift powers: [2^0, 2^3, 2^6, 2^9, 2^12, 2^15, 2^18, 2^21]
|
| 23 |
+
shifts = np.array([1, 8, 64, 512, 4096, 32768, 262144, 2097152], dtype=np.uint32)
|
| 24 |
+
|
| 25 |
+
# Multiply and sum across axis 1
|
| 26 |
+
vals = np.sum(arr_reshaped * shifts, axis=1)
|
| 27 |
+
|
| 28 |
+
# Split each uint32 into 3 bytes
|
| 29 |
+
b0 = (vals & 0xFF).astype(np.uint8)
|
| 30 |
+
b1 = ((vals >> 8) & 0xFF).astype(np.uint8)
|
| 31 |
+
b2 = ((vals >> 16) & 0xFF).astype(np.uint8)
|
| 32 |
+
|
| 33 |
+
# Stack and convert to bytes
|
| 34 |
+
packed_bytes = np.stack([b0, b1, b2], axis=1).flatten().tobytes()
|
| 35 |
+
return packed_bytes
|
| 36 |
+
|
| 37 |
+
def unpack_3bit_array(packed_bytes, original_len):
|
| 38 |
+
"""Unpack 3-bit packed bytes back to int8 array in range [-3, 3] vectorized."""
|
| 39 |
+
# Reshape byte array into (N/8, 3)
|
| 40 |
+
bytes_arr = np.frombuffer(packed_bytes, dtype=np.uint8).reshape(-1, 3).astype(np.uint32)
|
| 41 |
+
|
| 42 |
+
# Reconstruct 24-bit values
|
| 43 |
+
vals = bytes_arr[:, 0] | (bytes_arr[:, 1] << 8) | (bytes_arr[:, 2] << 16)
|
| 44 |
+
|
| 45 |
+
# Extract 8 components
|
| 46 |
+
v0 = (vals & 0x07).astype(np.int8) - 3
|
| 47 |
+
v1 = ((vals >> 3) & 0x07).astype(np.int8) - 3
|
| 48 |
+
v2 = ((vals >> 6) & 0x07).astype(np.int8) - 3
|
| 49 |
+
v3 = ((vals >> 9) & 0x07).astype(np.int8) - 3
|
| 50 |
+
v4 = ((vals >> 12) & 0x07).astype(np.int8) - 3
|
| 51 |
+
v5 = ((vals >> 15) & 0x07).astype(np.int8) - 3
|
| 52 |
+
v6 = ((vals >> 18) & 0x07).astype(np.int8) - 3
|
| 53 |
+
v7 = ((vals >> 21) & 0x07).astype(np.int8) - 3
|
| 54 |
+
|
| 55 |
+
# Stack and flatten
|
| 56 |
+
arr = np.stack([v0, v1, v2, v3, v4, v5, v6, v7], axis=1).flatten()
|
| 57 |
+
return arr[:original_len]
|
| 58 |
+
|
| 59 |
+
def quantize_int8_to_3bit_genesis(input_path, output_path):
|
| 60 |
+
print("=" * 80)
|
| 61 |
+
print(" GENESIS LEVEL 3 CONVERTER: INT8 SVD (v4) -> ZIG 3-BIT SVD (v6)")
|
| 62 |
+
print(" Watermark: ip zymatica.space")
|
| 63 |
+
print("=" * 80)
|
| 64 |
+
print(f"Reading from: {input_path}")
|
| 65 |
+
print(f"Writing to: {output_path}\n")
|
| 66 |
+
|
| 67 |
+
if not os.path.exists(input_path):
|
| 68 |
+
print(f"Error: Input file '{input_path}' does not exist.")
|
| 69 |
+
return
|
| 70 |
+
|
| 71 |
+
total_int8_weight_bytes = 0
|
| 72 |
+
total_packed_3bit_bytes = 0
|
| 73 |
+
errors = []
|
| 74 |
+
|
| 75 |
+
with open(input_path, "rb") as fin, open(output_path, "wb") as fout:
|
| 76 |
+
# --- Read Header ---
|
| 77 |
+
magic = struct.unpack('>I', fin.read(4))[0]
|
| 78 |
+
if magic != GENESIS_MAGIC:
|
| 79 |
+
print(f"Error: Invalid magic 0x{magic:08X}, expected 0x{GENESIS_MAGIC:08X}")
|
| 80 |
+
return
|
| 81 |
+
|
| 82 |
+
version = struct.unpack('>H', fin.read(2))[0]
|
| 83 |
+
if version != 4:
|
| 84 |
+
print(f"Error: Input format version is {version}, expected version 4 (INT8 SVD).")
|
| 85 |
+
return
|
| 86 |
+
|
| 87 |
+
watermark = fin.read(32)
|
| 88 |
+
perf_magic = struct.unpack('>I', fin.read(4))[0]
|
| 89 |
+
if perf_magic != PERFECT_MAGIC:
|
| 90 |
+
print(f"Error: Invalid perfect magic 0x{perf_magic:08X}, expected 0x{PERFECT_MAGIC:08X}")
|
| 91 |
+
return
|
| 92 |
+
|
| 93 |
+
# Model architecture
|
| 94 |
+
hidden, heads, kv_heads, ffn_dim, blocks, vocab = struct.unpack('>IIIIII', fin.read(24))
|
| 95 |
+
print(f"Model Configuration:")
|
| 96 |
+
print(f" Hidden size: {hidden}, Heads: {heads}, KV Heads: {kv_heads}")
|
| 97 |
+
print(f" FFN Dim: {ffn_dim}, Blocks: {blocks}, Vocab: {vocab}")
|
| 98 |
+
|
| 99 |
+
# Energy targets
|
| 100 |
+
e_attn, e_ffn, e_lm, e_other = struct.unpack('>ffff', fin.read(16))
|
| 101 |
+
print(f"Energy Targets: ATTN={e_attn:.2f}, FFN={e_ffn:.2f}, LM={e_lm:.2f}, OTHER={e_other:.2f}")
|
| 102 |
+
|
| 103 |
+
# Layer count
|
| 104 |
+
num_layers = struct.unpack('>I', fin.read(4))[0]
|
| 105 |
+
print(f"Number of layers: {num_layers}\n")
|
| 106 |
+
|
| 107 |
+
# --- Write Header (Version 6: 3-bit packed) ---
|
| 108 |
+
fout.write(struct.pack('>I', GENESIS_MAGIC))
|
| 109 |
+
fout.write(struct.pack('>H', 6)) # format version 6 for 3-bit packed SVD
|
| 110 |
+
fout.write(WATERMARK)
|
| 111 |
+
fout.write(struct.pack('>I', PERFECT_MAGIC))
|
| 112 |
+
fout.write(struct.pack('>IIIIII', hidden, heads, kv_heads, ffn_dim, blocks, vocab))
|
| 113 |
+
fout.write(struct.pack('>ffff', e_attn, e_ffn, e_lm, e_other))
|
| 114 |
+
|
| 115 |
+
# Placeholder for layer count
|
| 116 |
+
layer_count_pos = fout.tell()
|
| 117 |
+
fout.write(struct.pack('>I', num_layers))
|
| 118 |
+
|
| 119 |
+
# --- Process Layers ---
|
| 120 |
+
for i in range(num_layers):
|
| 121 |
+
name_len = struct.unpack('>H', fin.read(2))[0]
|
| 122 |
+
name = fin.read(name_len).decode('utf-8')
|
| 123 |
+
m, n, r = struct.unpack('>III', fin.read(12))
|
| 124 |
+
|
| 125 |
+
# Read version 4 details: scales + int8 U_q and V_q
|
| 126 |
+
scale_u, scale_v = struct.unpack('>ff', fin.read(8))
|
| 127 |
+
U_q_bytes = fin.read(m * r)
|
| 128 |
+
V_q_bytes = fin.read(n * r)
|
| 129 |
+
|
| 130 |
+
U_q = np.frombuffer(U_q_bytes, dtype=np.int8).reshape(m, r)
|
| 131 |
+
V_q = np.frombuffer(V_q_bytes, dtype=np.int8).reshape(n, r)
|
| 132 |
+
|
| 133 |
+
# Convert from INT8 range [-127, 127] to 3-bit range [-3, 3]
|
| 134 |
+
U_3bit = np.clip(np.round(U_q * (3.0 / 127.0)), -3, 3).astype(np.int8)
|
| 135 |
+
V_3bit = np.clip(np.round(V_q * (3.0 / 127.0)), -3, 3).astype(np.int8)
|
| 136 |
+
|
| 137 |
+
# Re-scale to preserve magnitude (compensates for 127 -> 3 scaling)
|
| 138 |
+
new_scale_u = scale_u * (127.0 / 3.0)
|
| 139 |
+
new_scale_v = scale_v * (127.0 / 3.0)
|
| 140 |
+
|
| 141 |
+
# Pack 3-bit factors into binary bytes
|
| 142 |
+
U_packed = pack_3bit_array(U_3bit.flatten())
|
| 143 |
+
V_packed = pack_3bit_array(V_3bit.flatten())
|
| 144 |
+
|
| 145 |
+
total_int8_weight_bytes += (m * r + n * r)
|
| 146 |
+
total_packed_3bit_bytes += (len(U_packed) + len(V_packed))
|
| 147 |
+
|
| 148 |
+
# Reconstruction sanity check (error of 3-bit vs original INT8)
|
| 149 |
+
U_rec = (unpack_3bit_array(U_packed, m * r).reshape(m, r) * new_scale_u)
|
| 150 |
+
V_rec = (unpack_3bit_array(V_packed, n * r).reshape(n, r) * new_scale_v)
|
| 151 |
+
W_orig = (U_q.astype(np.float32) * scale_u) @ (V_q.astype(np.float32) * scale_v).T
|
| 152 |
+
W_3bit = U_rec @ V_rec.T
|
| 153 |
+
norm_diff = np.linalg.norm(W_orig - W_3bit)
|
| 154 |
+
norm_orig = np.linalg.norm(W_orig) + 1e-9
|
| 155 |
+
errors.append(norm_diff / norm_orig)
|
| 156 |
+
|
| 157 |
+
# Read has_residual
|
| 158 |
+
has_residual = struct.unpack('>?', fin.read(1))[0]
|
| 159 |
+
|
| 160 |
+
# Write Layer in Version 6 format
|
| 161 |
+
name_b = name.encode('utf-8')
|
| 162 |
+
fout.write(struct.pack('>H', len(name_b)))
|
| 163 |
+
fout.write(name_b)
|
| 164 |
+
fout.write(struct.pack('>III', m, n, r))
|
| 165 |
+
fout.write(struct.pack('>ff', new_scale_u, new_scale_v))
|
| 166 |
+
|
| 167 |
+
# Write 3-bit packed arrays
|
| 168 |
+
fout.write(U_packed)
|
| 169 |
+
fout.write(V_packed)
|
| 170 |
+
fout.write(struct.pack('>?', has_residual))
|
| 171 |
+
|
| 172 |
+
if has_residual:
|
| 173 |
+
res_rank = struct.unpack('>I', fin.read(4))[0]
|
| 174 |
+
scale_res_u, scale_res_v = struct.unpack('>ff', fin.read(8))
|
| 175 |
+
U_res = fin.read(m * res_rank) # int8 residual
|
| 176 |
+
V_res = fin.read(n * res_rank) # int8 residual
|
| 177 |
+
|
| 178 |
+
# Residual is left as int8, write directly
|
| 179 |
+
fout.write(struct.pack('>I', res_rank))
|
| 180 |
+
fout.write(struct.pack('>ff', scale_res_u, scale_res_v))
|
| 181 |
+
fout.write(U_res)
|
| 182 |
+
fout.write(V_res)
|
| 183 |
+
|
| 184 |
+
if (i + 1) % 40 == 0 or (i + 1) == num_layers:
|
| 185 |
+
print(f" Processed {i+1}/{num_layers} layers...")
|
| 186 |
+
|
| 187 |
+
input_size = os.path.getsize(input_path) / 1e9
|
| 188 |
+
output_size = os.path.getsize(output_path) / 1e9
|
| 189 |
+
|
| 190 |
+
print(f"\nSuccess!")
|
| 191 |
+
print(f" Input size (INT8): {input_size * 1000:.1f} MB")
|
| 192 |
+
print(f" Output size (3-bit): {output_size * 1000:.1f} MB")
|
| 193 |
+
print(f" SVD parameters raw: {total_int8_weight_bytes:,} bytes (INT8)")
|
| 194 |
+
print(f" SVD parameters packed: {total_packed_3bit_bytes:,} bytes (3-bit)")
|
| 195 |
+
print(f" Parameter reduction: {total_int8_weight_bytes / total_packed_3bit_bytes:.2f}x")
|
| 196 |
+
print(f" Overall file ratio: {input_size / output_size:.2f}x")
|
| 197 |
+
print(f" Mean SVD Quant Error: {np.mean(errors):.4f}")
|
| 198 |
+
|
| 199 |
+
if __name__ == "__main__":
|
| 200 |
+
import argparse
|
| 201 |
+
parser = argparse.ArgumentParser(description="Convert INT8 genesis to 3-bit genesis")
|
| 202 |
+
parser.add_argument("input", help="Path to input INT8 .genesis file")
|
| 203 |
+
parser.add_argument("output", help="Path to output 3-bit .genesis file")
|
| 204 |
+
args = parser.parse_args()
|
| 205 |
+
|
| 206 |
+
quantize_int8_to_3bit_genesis(args.input, args.output)
|
quantize_perfect_genesis.py
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import struct
|
| 3 |
+
import numpy as np
|
| 4 |
+
|
| 5 |
+
GENESIS_MAGIC = 0x47454E45 # "GENE"
|
| 6 |
+
PERFECT_MAGIC = 0x50455246 # "PERF"
|
| 7 |
+
WATERMARK = b"ip zymatica.space".ljust(32, b" ")
|
| 8 |
+
|
| 9 |
+
def quantize_to_int8(X):
|
| 10 |
+
"""Quantize a float32 matrix to int8. Returns (X_q, scale)."""
|
| 11 |
+
max_val = float(np.max(np.abs(X)))
|
| 12 |
+
scale = max_val / 127.0 if max_val > 0 else 1e-9
|
| 13 |
+
X_q = np.clip(np.round(X / scale), -127, 127).astype(np.int8)
|
| 14 |
+
return X_q, scale
|
| 15 |
+
|
| 16 |
+
def quantize_f32_to_int8_genesis(input_path, output_path):
|
| 17 |
+
print("=" * 80)
|
| 18 |
+
print(" GENESIS PERFECT ENGINE CONVERTER: FLOAT32 (v3) -> INT8 (v4)")
|
| 19 |
+
print(" Watermark: ip zymatica.space")
|
| 20 |
+
print("=" * 80)
|
| 21 |
+
print(f"Reading from: {input_path}")
|
| 22 |
+
print(f"Writing to: {output_path}\n")
|
| 23 |
+
|
| 24 |
+
if not os.path.exists(input_path):
|
| 25 |
+
print(f"Error: Input file '{input_path}' does not exist.")
|
| 26 |
+
return
|
| 27 |
+
|
| 28 |
+
with open(input_path, "rb") as fin, open(output_path, "wb") as fout:
|
| 29 |
+
# --- Read Header ---
|
| 30 |
+
magic = struct.unpack('>I', fin.read(4))[0]
|
| 31 |
+
if magic != GENESIS_MAGIC:
|
| 32 |
+
print(f"Error: Invalid magic 0x{magic:08X}, expected 0x{GENESIS_MAGIC:08X}")
|
| 33 |
+
return
|
| 34 |
+
|
| 35 |
+
version = struct.unpack('>H', fin.read(2))[0]
|
| 36 |
+
if version != 3:
|
| 37 |
+
print(f"Warning: Input format version is {version}, expected version 3 (float32 SVD).")
|
| 38 |
+
# We'll continue anyway if it's version 3 or 5, but version 3 is float32.
|
| 39 |
+
|
| 40 |
+
watermark = fin.read(32)
|
| 41 |
+
perf_magic = struct.unpack('>I', fin.read(4))[0]
|
| 42 |
+
if perf_magic != PERFECT_MAGIC:
|
| 43 |
+
print(f"Error: Invalid perfect magic 0x{perf_magic:08X}, expected 0x{PERFECT_MAGIC:08X}")
|
| 44 |
+
return
|
| 45 |
+
|
| 46 |
+
# Model architecture
|
| 47 |
+
hidden, heads, kv_heads, ffn_dim, blocks, vocab = struct.unpack('>IIIIII', fin.read(24))
|
| 48 |
+
print(f"Model Configuration:")
|
| 49 |
+
print(f" Hidden size: {hidden}, Heads: {heads}, KV Heads: {kv_heads}")
|
| 50 |
+
print(f" FFN Dim: {ffn_dim}, Blocks: {blocks}, Vocab: {vocab}")
|
| 51 |
+
|
| 52 |
+
# Energy targets
|
| 53 |
+
e_attn, e_ffn, e_lm, e_other = struct.unpack('>ffff', fin.read(16))
|
| 54 |
+
print(f"Energy Targets: ATTN={e_attn:.2f}, FFN={e_ffn:.2f}, LM={e_lm:.2f}, OTHER={e_other:.2f}")
|
| 55 |
+
|
| 56 |
+
# Layer count
|
| 57 |
+
num_layers = struct.unpack('>I', fin.read(4))[0]
|
| 58 |
+
print(f"Number of layers: {num_layers}\n")
|
| 59 |
+
|
| 60 |
+
# --- Write Header (Version 4) ---
|
| 61 |
+
fout.write(struct.pack('>I', GENESIS_MAGIC))
|
| 62 |
+
fout.write(struct.pack('>H', 4)) # version 4
|
| 63 |
+
fout.write(WATERMARK)
|
| 64 |
+
fout.write(struct.pack('>I', PERFECT_MAGIC))
|
| 65 |
+
fout.write(struct.pack('>IIIIII', hidden, heads, kv_heads, ffn_dim, blocks, vocab))
|
| 66 |
+
fout.write(struct.pack('>ffff', e_attn, e_ffn, e_lm, e_other))
|
| 67 |
+
|
| 68 |
+
# Placeholder for layer count
|
| 69 |
+
layer_count_pos = fout.tell()
|
| 70 |
+
fout.write(struct.pack('>I', num_layers))
|
| 71 |
+
|
| 72 |
+
# --- Process Layers ---
|
| 73 |
+
for i in range(num_layers):
|
| 74 |
+
name_len = struct.unpack('>H', fin.read(2))[0]
|
| 75 |
+
name = fin.read(name_len).decode('utf-8')
|
| 76 |
+
m, n, r = struct.unpack('>III', fin.read(12))
|
| 77 |
+
|
| 78 |
+
# Read float32 U and V
|
| 79 |
+
U_bytes = fin.read(m * r * 4)
|
| 80 |
+
V_bytes = fin.read(n * r * 4)
|
| 81 |
+
|
| 82 |
+
U = np.frombuffer(U_bytes, dtype=np.float32).reshape(m, r)
|
| 83 |
+
V = np.frombuffer(V_bytes, dtype=np.float32).reshape(n, r)
|
| 84 |
+
|
| 85 |
+
# Quantize primary SVD factors to INT8
|
| 86 |
+
U_q, scale_u = quantize_to_int8(U)
|
| 87 |
+
V_q, scale_v = quantize_to_int8(V)
|
| 88 |
+
|
| 89 |
+
# Read has_residual
|
| 90 |
+
has_residual = struct.unpack('>?', fin.read(1))[0]
|
| 91 |
+
|
| 92 |
+
# Write Layer in Version 4 format
|
| 93 |
+
name_b = name.encode('utf-8')
|
| 94 |
+
fout.write(struct.pack('>H', len(name_b)))
|
| 95 |
+
fout.write(name_b)
|
| 96 |
+
fout.write(struct.pack('>III', m, n, r))
|
| 97 |
+
fout.write(struct.pack('>ff', scale_u, scale_v))
|
| 98 |
+
fout.write(U_q.tobytes())
|
| 99 |
+
fout.write(V_q.tobytes())
|
| 100 |
+
fout.write(struct.pack('>?', has_residual))
|
| 101 |
+
|
| 102 |
+
if has_residual:
|
| 103 |
+
res_rank = struct.unpack('>I', fin.read(4))[0]
|
| 104 |
+
scale_res_u, scale_res_v = struct.unpack('>ff', fin.read(8))
|
| 105 |
+
U_res = fin.read(m * res_rank) # int8 residual
|
| 106 |
+
V_res = fin.read(n * res_rank) # int8 residual
|
| 107 |
+
|
| 108 |
+
# Residual is already int8, so write directly
|
| 109 |
+
fout.write(struct.pack('>I', res_rank))
|
| 110 |
+
fout.write(struct.pack('>ff', scale_res_u, scale_res_v))
|
| 111 |
+
fout.write(U_res)
|
| 112 |
+
fout.write(V_res)
|
| 113 |
+
|
| 114 |
+
if (i + 1) % 20 == 0 or (i + 1) == num_layers:
|
| 115 |
+
print(f" Processed {i+1}/{num_layers} layers...")
|
| 116 |
+
|
| 117 |
+
input_size = os.path.getsize(input_path) / 1e9
|
| 118 |
+
output_size = os.path.getsize(output_path) / 1e9
|
| 119 |
+
print(f"\nSuccess!")
|
| 120 |
+
print(f" Input size (float32): {input_size:.2f} GB")
|
| 121 |
+
print(f" Output size (int8): {output_size:.2f} GB")
|
| 122 |
+
print(f" Compression ratio: {input_size / output_size:.2f}x")
|
| 123 |
+
|
| 124 |
+
if __name__ == "__main__":
|
| 125 |
+
import argparse
|
| 126 |
+
parser = argparse.ArgumentParser(description="Convert float32 genesis to int8 genesis")
|
| 127 |
+
parser.add_argument("input", help="Path to input float32 .genesis file")
|
| 128 |
+
parser.add_argument("output", help="Path to output int8 .genesis file")
|
| 129 |
+
args = parser.parse_args()
|
| 130 |
+
|
| 131 |
+
quantize_f32_to_int8_genesis(args.input, args.output)
|
safetensors_to_genesis.py
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Gemma-4-31B Safetensors to Genesis Converter
|
| 2 |
+
# Watermark: ip zymatica.space | astronautshe.com
|
| 3 |
+
|
| 4 |
+
import os
|
| 5 |
+
import sys
|
| 6 |
+
import json
|
| 7 |
+
import struct
|
| 8 |
+
import time
|
| 9 |
+
import torch
|
| 10 |
+
from safetensors import safe_open
|
| 11 |
+
|
| 12 |
+
GENESIS_MAGIC = 0x47454E45 # "GENE"
|
| 13 |
+
GENESIS_VERSION = 4 # INT8 version
|
| 14 |
+
PERFECT_MAGIC = 0x50455246 # "PERF"
|
| 15 |
+
WATERMARK = b"ip zymatica.space".ljust(32, b" ")
|
| 16 |
+
|
| 17 |
+
def main():
|
| 18 |
+
print("=" * 80)
|
| 19 |
+
print(" GEMMA-4-31B SAFETENSORS TO GENESIS CONVERTER")
|
| 20 |
+
print(" Watermark: ip zymatica.space | astronautshe.com")
|
| 21 |
+
print("=" * 80)
|
| 22 |
+
|
| 23 |
+
input_safetensors = "J:/gemma-4-31B-it-local/working/gemma4_sumerian_real_weights.safetensors"
|
| 24 |
+
output_genesis = "J:/gemma-4-31B-it-local/working/gemma4_31b_subzero.genesis"
|
| 25 |
+
|
| 26 |
+
if not os.path.exists(input_safetensors):
|
| 27 |
+
print(f"[-] Error: Safetensors file not found at {input_safetensors}")
|
| 28 |
+
sys.exit(1)
|
| 29 |
+
|
| 30 |
+
print(f"[*] Reading from: {input_safetensors}")
|
| 31 |
+
print(f"[*] Writing to: {output_genesis}\n")
|
| 32 |
+
|
| 33 |
+
t_start = time.time()
|
| 34 |
+
|
| 35 |
+
# 1. Inspect safetensors header to identify SVD layers
|
| 36 |
+
print("[*] Inspecting safetensors keys...")
|
| 37 |
+
svd_layers = {}
|
| 38 |
+
|
| 39 |
+
with safe_open(input_safetensors, framework="pt", device="cpu") as f:
|
| 40 |
+
keys = list(f.keys())
|
| 41 |
+
|
| 42 |
+
for key in keys:
|
| 43 |
+
if key.endswith(".U_q"):
|
| 44 |
+
layer_name = key[:-4] # Remove ".U_q"
|
| 45 |
+
svd_layers[layer_name] = {}
|
| 46 |
+
|
| 47 |
+
print(f" - Found {len(svd_layers)} SVD-compressed projection weight matrices.")
|
| 48 |
+
|
| 49 |
+
# 2. Open and load SVD values
|
| 50 |
+
print("[*] Loading SVD parameters...")
|
| 51 |
+
with safe_open(input_safetensors, framework="pt", device="cpu") as f:
|
| 52 |
+
for layer_name in svd_layers.keys():
|
| 53 |
+
U_q = f.get_tensor(f"{layer_name}.U_q")
|
| 54 |
+
V_q = f.get_tensor(f"{layer_name}.V_q")
|
| 55 |
+
scale_u = f.get_tensor(f"{layer_name}.scale_u")
|
| 56 |
+
scale_v = f.get_tensor(f"{layer_name}.scale_v")
|
| 57 |
+
|
| 58 |
+
# Extract scalar values from scale tensors
|
| 59 |
+
su_val = float(scale_u.item()) if scale_u.ndim == 0 or len(scale_u) == 1 else float(scale_u[0])
|
| 60 |
+
sv_val = float(scale_v.item()) if scale_v.ndim == 0 or len(scale_v) == 1 else float(scale_v[0])
|
| 61 |
+
|
| 62 |
+
m, rank = U_q.shape
|
| 63 |
+
n, rank_v = V_q.shape
|
| 64 |
+
assert rank == rank_v, f"Rank mismatch for {layer_name}: {rank} vs {rank_v}"
|
| 65 |
+
|
| 66 |
+
svd_layers[layer_name] = {
|
| 67 |
+
"U_q": U_q.to(torch.int8),
|
| 68 |
+
"V_q": V_q.to(torch.int8),
|
| 69 |
+
"scale_u": su_val,
|
| 70 |
+
"scale_v": sv_val,
|
| 71 |
+
"m": m,
|
| 72 |
+
"n": n,
|
| 73 |
+
"rank": rank
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
print(" [+] Successfully loaded SVD matrices.")
|
| 77 |
+
|
| 78 |
+
# 3. Write .genesis file (Version 4 Format)
|
| 79 |
+
print(f"[*] Packaging into .genesis format...")
|
| 80 |
+
|
| 81 |
+
# Architecture config for Gemma-4-31B
|
| 82 |
+
hidden_dim = 5376
|
| 83 |
+
num_heads = 32
|
| 84 |
+
kv_heads = 16
|
| 85 |
+
ffn_dim = 21504
|
| 86 |
+
num_blocks = 60
|
| 87 |
+
vocab_size = 262144
|
| 88 |
+
|
| 89 |
+
with open(output_genesis, "wb") as fout:
|
| 90 |
+
# Write Header
|
| 91 |
+
fout.write(struct.pack('>I', GENESIS_MAGIC))
|
| 92 |
+
fout.write(struct.pack('>H', GENESIS_VERSION))
|
| 93 |
+
fout.write(WATERMARK)
|
| 94 |
+
fout.write(struct.pack('>I', PERFECT_MAGIC))
|
| 95 |
+
|
| 96 |
+
# Arch params
|
| 97 |
+
fout.write(struct.pack('>IIIIII', hidden_dim, num_heads, kv_heads, ffn_dim, num_blocks, vocab_size))
|
| 98 |
+
|
| 99 |
+
# Energy targets (attn, ffn, lm, other)
|
| 100 |
+
fout.write(struct.pack('>ffff', 1.0, 1.0, 1.0, 1.0))
|
| 101 |
+
|
| 102 |
+
# Layer count
|
| 103 |
+
fout.write(struct.pack('>I', len(svd_layers)))
|
| 104 |
+
|
| 105 |
+
# Process and write each layer
|
| 106 |
+
for name, data in svd_layers.items():
|
| 107 |
+
name_bytes = name.encode('utf-8')
|
| 108 |
+
fout.write(struct.pack('>H', len(name_bytes)))
|
| 109 |
+
fout.write(name_bytes)
|
| 110 |
+
|
| 111 |
+
# Dimensions and rank
|
| 112 |
+
fout.write(struct.pack('>III', data["m"], data["n"], data["rank"]))
|
| 113 |
+
|
| 114 |
+
# Scales
|
| 115 |
+
fout.write(struct.pack('>ff', data["scale_u"], data["scale_v"]))
|
| 116 |
+
|
| 117 |
+
# INT8 SVD factors
|
| 118 |
+
fout.write(data["U_q"].numpy().tobytes())
|
| 119 |
+
fout.write(data["V_q"].numpy().tobytes())
|
| 120 |
+
|
| 121 |
+
# Residual flag (no residual blocks in this output format)
|
| 122 |
+
fout.write(struct.pack('>?', False))
|
| 123 |
+
|
| 124 |
+
elapsed = time.time() - t_start
|
| 125 |
+
print(f"\n[+] SUCCESS: Packaged .genesis file saved to {output_genesis}")
|
| 126 |
+
print(f" File size: {os.path.getsize(output_genesis) / (1024**2):.2f} MB")
|
| 127 |
+
print(f" Completed in {elapsed:.1f}s.")
|
| 128 |
+
print("=" * 80)
|
| 129 |
+
|
| 130 |
+
if __name__ == "__main__":
|
| 131 |
+
main()
|
test_cuneiform_u_v3.rs
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Watermark: ip zymatica.space | astronautshe.com
|
| 2 |
+
// Copyright (c) 2026 Zymatica. All rights reserved.
|
| 3 |
+
|
| 4 |
+
mod cuneiform_u_v3;
|
| 5 |
+
|
| 6 |
+
use cuneiform_u_v3::{Concept6D, cuneiform_u_v3_encode, cuneiform_u_v3_decode};
|
| 7 |
+
|
| 8 |
+
fn main() {
|
| 9 |
+
println!("=========================================================");
|
| 10 |
+
println!(" CUNEIFORM-U V3.0 RUST RANGE CODER BENCHMARK");
|
| 11 |
+
println!(" zymatica.space | astronautshe.com");
|
| 12 |
+
println!("=========================================================");
|
| 13 |
+
|
| 14 |
+
// Benchmark 1: Reboot Sequence (40 concepts)
|
| 15 |
+
let block = vec![
|
| 16 |
+
Concept6D { domain: 8, subdomain: 0, operation: 0, modality: 4, depth: 7, polarity: 8 }, // SYNC
|
| 17 |
+
Concept6D { domain: 0, subdomain: 0, operation: 15, modality: 14, depth: 5, polarity: 1 }, // ENERGY
|
| 18 |
+
Concept6D { domain: 0, subdomain: 0, operation: 7, modality: 11, depth: 13, polarity: 15 }, // CYCLE
|
| 19 |
+
Concept6D { domain: 0, subdomain: 0, operation: 7, modality: 14, depth: 0, polarity: 11 }, // ACK
|
| 20 |
+
];
|
| 21 |
+
|
| 22 |
+
let mut reboot_sequence = Vec::new();
|
| 23 |
+
for _ in 0..10 {
|
| 24 |
+
reboot_sequence.extend_from_slice(&block);
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
let compressed = cuneiform_u_v3_encode(&reboot_sequence, 1, 128);
|
| 28 |
+
let total_bits = compressed.len() * 8;
|
| 29 |
+
|
| 30 |
+
println!("\n--- BENCHMARK 1: REBOOT SEQUENCE (40 Concepts) ---");
|
| 31 |
+
println!(" Cuneiform-U Rust Coder size: {} bytes ({} bits)", compressed.len(), total_bits);
|
| 32 |
+
println!(" Semantic bits/concept: {:.2} bits", (total_bits as f32) / 40.0);
|
| 33 |
+
|
| 34 |
+
let decoded = cuneiform_u_v3_decode(compressed, 40, 1, 128);
|
| 35 |
+
let match_success = reboot_sequence == decoded;
|
| 36 |
+
println!(" Fidelity verification: {}", if match_success { "PASS [OK]" } else { "FAIL [❌]" });
|
| 37 |
+
|
| 38 |
+
// Benchmark 2: Zero-Shot Dynamic Concept Composition (20 concepts)
|
| 39 |
+
let dynamic_block = vec![
|
| 40 |
+
Concept6D { domain: 1, subdomain: 3, operation: 3, modality: 13, depth: 4, polarity: 6 },
|
| 41 |
+
Concept6D { domain: 1, subdomain: 1, operation: 0, modality: 6, depth: 5, polarity: 5 },
|
| 42 |
+
];
|
| 43 |
+
let mut dynamic_sequence = Vec::new();
|
| 44 |
+
for _ in 0..10 {
|
| 45 |
+
dynamic_sequence.extend_from_slice(&dynamic_block);
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
let compressed_dyn = cuneiform_u_v3_encode(&dynamic_sequence, 1, 128);
|
| 49 |
+
let total_bits_dyn = compressed_dyn.len() * 8;
|
| 50 |
+
|
| 51 |
+
println!("\n--- BENCHMARK 2: DYNAMIC SEMANTIC EXPRESSION (20 Concepts) ---");
|
| 52 |
+
println!(" Cuneiform-U Rust Coder size: {} bytes ({} bits)", compressed_dyn.len(), total_bits_dyn);
|
| 53 |
+
println!(" Semantic bits/concept: {:.2} bits", (total_bits_dyn as f32) / 20.0);
|
| 54 |
+
|
| 55 |
+
let decoded_dyn = cuneiform_u_v3_decode(compressed_dyn, 20, 1, 128);
|
| 56 |
+
let match_success_dyn = dynamic_sequence == decoded_dyn;
|
| 57 |
+
println!(" Fidelity verification: {}", if match_success_dyn { "PASS [OK]" } else { "FAIL [❌]" });
|
| 58 |
+
}
|
test_cuneiform_v3.c
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <stdio.h>
|
| 2 |
+
#include "cuneiform_u_v3.h"
|
| 3 |
+
|
| 4 |
+
int run_test() {
|
| 5 |
+
printf("======================================================================\n");
|
| 6 |
+
printf(" CUNEIFORM-U V3.0 / LANGUAGE U V4.0 C-BASED RANGE CODER BENCHMARK\n");
|
| 7 |
+
printf(" zymatica.space | astronautshe.com\n");
|
| 8 |
+
printf("======================================================================\n\n");
|
| 9 |
+
|
| 10 |
+
/* 1. Define Reboot Sequence (40 Concepts) */
|
| 11 |
+
/* Repeating: SYNC, ENERGY, CYCLE, ACK */
|
| 12 |
+
/* We map these to their 6D coordinates:
|
| 13 |
+
SYNC (0x8104): domain=8 (ENGINEER), subdomain=0, operation=0 (IDENTITY), modality=4 (LIKELY), depth=7 (TRANSCENDENT), polarity=7 (SUPERPOSED) - wait,
|
| 14 |
+
let's use the exact coordinates or standard indices.
|
| 15 |
+
From Python:
|
| 16 |
+
SYNC (0x8104): rc=0x80 (DOMAIN=8, SUBDOMAIN=0), rf=0x04 (OPERATION=0, MODALITY=4), ra=0x78 (DEPTH=7, POLARITY=8)
|
| 17 |
+
ENERGY (0x80FE): rc=0x00 (DOMAIN=0, SUBDOMAIN=0), rf=0xFE (OPERATION=15, MODALITY=14), ra=0x51 (DEPTH=5, POLARITY=1)
|
| 18 |
+
CYCLE (0x807B): rc=0x00, rf=0x7B, ra=0xDF
|
| 19 |
+
ACK (0x807E): rc=0x00, rf=0x7E, ra=0x0B
|
| 20 |
+
*/
|
| 21 |
+
Concept6D reboot_sequence[40];
|
| 22 |
+
Concept6D block[4] = {
|
| 23 |
+
{8, 0, 0, 4, 7, 8}, /* SYNC */
|
| 24 |
+
{0, 0, 15, 14, 5, 1}, /* ENERGY */
|
| 25 |
+
{0, 0, 7, 11, 13, 15},/* CYCLE */
|
| 26 |
+
{0, 0, 7, 14, 0, 11} /* ACK */
|
| 27 |
+
};
|
| 28 |
+
for (int i = 0; i < 10; i++) {
|
| 29 |
+
memcpy(&reboot_sequence[i * 4], block, sizeof(block));
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
uint8_t compressed_buf[256];
|
| 33 |
+
uint32_t max_bytes = sizeof(compressed_buf);
|
| 34 |
+
|
| 35 |
+
/* Encode */
|
| 36 |
+
int bit_count = cuneiform_u_v3_encode(reboot_sequence, 40, compressed_buf, max_bytes, 1, 128);
|
| 37 |
+
if (bit_count < 0) {
|
| 38 |
+
printf("Encoding failed!\n");
|
| 39 |
+
return 1;
|
| 40 |
+
}
|
| 41 |
+
int byte_count = (bit_count + 7) / 8;
|
| 42 |
+
|
| 43 |
+
printf("--- BENCHMARK 1: REBOOT SEQUENCE (40 Concepts) ---\n");
|
| 44 |
+
printf(" Cuneiform-U v3.0 C-Coder size: %d bytes (%d bits)\n", byte_count, bit_count);
|
| 45 |
+
printf(" Semantic bits/concept: %.2f bits\n", (float)bit_count / 40.0f);
|
| 46 |
+
|
| 47 |
+
/* Decode & Verify */
|
| 48 |
+
Concept6D decoded_sequence[40];
|
| 49 |
+
int decode_success = cuneiform_u_v3_decode(compressed_buf, byte_count, decoded_sequence, 40, 1, 128);
|
| 50 |
+
|
| 51 |
+
int match = 1;
|
| 52 |
+
for (int i = 0; i < 40; i++) {
|
| 53 |
+
if (reboot_sequence[i].domain != decoded_sequence[i].domain ||
|
| 54 |
+
reboot_sequence[i].subdomain != decoded_sequence[i].subdomain ||
|
| 55 |
+
reboot_sequence[i].operation != decoded_sequence[i].operation ||
|
| 56 |
+
reboot_sequence[i].modality != decoded_sequence[i].modality ||
|
| 57 |
+
reboot_sequence[i].depth != decoded_sequence[i].depth ||
|
| 58 |
+
reboot_sequence[i].polarity != decoded_sequence[i].polarity) {
|
| 59 |
+
match = 0;
|
| 60 |
+
printf(" Mismatch at index %d!\n", i);
|
| 61 |
+
break;
|
| 62 |
+
}
|
| 63 |
+
}
|
| 64 |
+
printf(" Fidelity verification: %s\n\n", match && decode_success ? "PASS ✅" : "FAIL ❌");
|
| 65 |
+
|
| 66 |
+
/* 2. Zero-Shot Dynamic Concept Composition */
|
| 67 |
+
Concept6D dynamic_block[2] = {
|
| 68 |
+
{1, 3, 3, 13, 4, 6}, /* Relativistic warp anomaly warning */
|
| 69 |
+
{1, 1, 0, 6, 5, 5} /* Quantum equilibrium balance */
|
| 70 |
+
};
|
| 71 |
+
Concept6D dynamic_sequence[20];
|
| 72 |
+
for (int i = 0; i < 10; i++) {
|
| 73 |
+
memcpy(&dynamic_sequence[i * 2], dynamic_block, sizeof(dynamic_block));
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
bit_count = cuneiform_u_v3_encode(dynamic_sequence, 20, compressed_buf, max_bytes, 1, 128);
|
| 77 |
+
byte_count = (bit_count + 7) / 8;
|
| 78 |
+
|
| 79 |
+
printf("--- BENCHMARK 2: ZERO-SHOT DYNAMIC SEMANTIC EXPRESSION (20 Concepts) ---\n");
|
| 80 |
+
printf(" Cuneiform-U v3.0 C-Coder size: %d bytes (%d bits)\n", byte_count, bit_count);
|
| 81 |
+
printf(" Semantic bits/concept: %.2f bits\n", (float)bit_count / 20.0f);
|
| 82 |
+
|
| 83 |
+
Concept6D decoded_dynamic[20];
|
| 84 |
+
decode_success = cuneiform_u_v3_decode(compressed_buf, byte_count, decoded_dynamic, 20, 1, 128);
|
| 85 |
+
|
| 86 |
+
match = 1;
|
| 87 |
+
for (int i = 0; i < 20; i++) {
|
| 88 |
+
if (dynamic_sequence[i].domain != decoded_dynamic[i].domain ||
|
| 89 |
+
dynamic_sequence[i].subdomain != decoded_dynamic[i].subdomain ||
|
| 90 |
+
dynamic_sequence[i].operation != decoded_dynamic[i].operation ||
|
| 91 |
+
dynamic_sequence[i].modality != decoded_dynamic[i].modality ||
|
| 92 |
+
dynamic_sequence[i].depth != decoded_dynamic[i].depth ||
|
| 93 |
+
dynamic_sequence[i].polarity != decoded_dynamic[i].polarity) {
|
| 94 |
+
match = 0;
|
| 95 |
+
printf(" Mismatch at index %d!\n", i);
|
| 96 |
+
break;
|
| 97 |
+
}
|
| 98 |
+
}
|
| 99 |
+
printf(" Fidelity verification: %s\n", match && decode_success ? "PASS ✅" : "FAIL ❌");
|
| 100 |
+
|
| 101 |
+
return 0;
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
int main() {
|
| 105 |
+
return run_test();
|
| 106 |
+
}
|