arcticoneai commited on
Commit
5ef2915
·
verified ·
1 Parent(s): e94a2b9

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +441 -0
README.md CHANGED
@@ -136,6 +136,14 @@ python storage_reconstruction_test.py
136
 
137
  This will strip attention/FFN weights from the loaded model and reconstruct them from the two files, then start a basic chat loop. Reconstruction is exact by construction — see the "What this is not" section above for why.
138
 
 
 
 
 
 
 
 
 
139
 
140
 
141
 
@@ -645,6 +653,439 @@ if __name__ == "__main__":
645
  run_fast_terminal_chat()
646
  ```
647
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
648
  ## Results
649
 
650
  *Placeholder — to be filled in with real numbers from benchmark runs.*
 
136
 
137
  This will strip attention/FFN weights from the loaded model and reconstruct them from the two files, then start a basic chat loop. Reconstruction is exact by construction — see the "What this is not" section above for why.
138
 
139
+ ### 3. compression with Bayes
140
+
141
+ Show on R2 test 100% score with compression.Compressed approximately 30%
142
+
143
+ ```bash
144
+ python bayes_compression.py
145
+ ```
146
+
147
 
148
 
149
 
 
653
  run_fast_terminal_chat()
654
  ```
655
 
656
+ ## Code
657
+
658
+ ### `bayes_compression.py`
659
+
660
+ ```python
661
+ from __future__ import annotations
662
+
663
+ import hashlib
664
+ import json
665
+ import os
666
+ import struct
667
+ import zlib
668
+ from concurrent.futures import ProcessPoolExecutor, as_completed
669
+ from pathlib import Path
670
+ from typing import Dict, List, Sequence, Tuple
671
+
672
+ import torch
673
+ from safetensors import safe_open
674
+ from safetensors.torch import save_file
675
+
676
+ MAGIC = "__BAYES_PACKET_ZLIB__"
677
+ VERSION = 4
678
+
679
+ DEFAULT_PACKET_MB = 8
680
+ RAW_ENTROPY_THRESHOLD = 7.90
681
+ MIN_COMPRESS_BYTES = 256 * 1024
682
+ ZLIB_LEVEL = 1
683
+
684
+
685
+ def _configure_torch() -> None:
686
+ try:
687
+ torch.set_num_threads(1)
688
+ except Exception:
689
+ pass
690
+ try:
691
+ torch.set_num_interop_threads(1)
692
+ except Exception:
693
+ pass
694
+
695
+
696
+ def dtype_to_name(dtype: torch.dtype) -> str:
697
+ return str(dtype).replace("torch.", "")
698
+
699
+
700
+ def name_to_dtype(name: str) -> torch.dtype:
701
+ return getattr(torch, name)
702
+
703
+
704
+ def tensor_to_raw_bytes(t: torch.Tensor) -> bytes:
705
+ t = t.detach().contiguous().cpu()
706
+ return t.view(torch.uint8).numpy().tobytes()
707
+
708
+
709
+ def raw_bytes_to_tensor(raw: bytes, dtype: torch.dtype, shape: Sequence[int]) -> torch.Tensor:
710
+ if not raw:
711
+ return torch.empty(tuple(shape), dtype=dtype)
712
+ u8 = torch.frombuffer(memoryview(raw), dtype=torch.uint8).clone()
713
+ return u8.view(dtype).reshape(tuple(shape)).contiguous()
714
+
715
+
716
+ def _sha256(data: bytes) -> str:
717
+ return hashlib.sha256(data).hexdigest()
718
+
719
+
720
+ def _packetize(raw: bytes, packet_size: int) -> List[bytes]:
721
+ if packet_size <= 0:
722
+ raise ValueError("packet_size must be positive")
723
+ if not raw:
724
+ return [b""]
725
+ return [raw[i:i + packet_size] for i in range(0, len(raw), packet_size)]
726
+
727
+
728
+ def _bayes_features(raw: bytes) -> Dict[str, float]:
729
+ if not raw:
730
+ return {
731
+ "n": 0,
732
+ "mean": 0.0,
733
+ "std": 0.0,
734
+ "min": 0,
735
+ "max": 0,
736
+ "nonzero": 0,
737
+ "entropy": 0.0,
738
+ "top1_mass": 0.0,
739
+ "hist_sha256": _sha256(b""),
740
+ }
741
+
742
+ u8 = torch.frombuffer(memoryview(raw), dtype=torch.uint8)
743
+ n = int(u8.numel())
744
+
745
+ counts = torch.bincount(u8.to(torch.int64), minlength=256).to(torch.float32)
746
+ posterior = counts + 1.0
747
+ total = float(posterior.sum().item())
748
+ probs = posterior / total
749
+
750
+ entropy = float((-(probs * torch.log2(probs.clamp_min(1e-12)))).sum().item())
751
+ top1_mass = float((posterior.max() / total).item())
752
+
753
+ f = u8.float()
754
+ mean = float(f.mean().item())
755
+ std = float(f.std(unbiased=False).item()) if n > 1 else 0.0
756
+ mn = int(u8.min().item())
757
+ mx = int(u8.max().item())
758
+ nonzero = int((u8 != 0).sum().item())
759
+
760
+ hist_sha256 = _sha256(counts.to(torch.int32).cpu().numpy().tobytes())
761
+
762
+ return {
763
+ "n": n,
764
+ "mean": mean,
765
+ "std": std,
766
+ "min": mn,
767
+ "max": mx,
768
+ "nonzero": nonzero,
769
+ "entropy": entropy,
770
+ "top1_mass": top1_mass,
771
+ "hist_sha256": hist_sha256,
772
+ }
773
+
774
+
775
+ def _choose_codec(raw: bytes) -> Tuple[str, bytes, Dict[str, float]]:
776
+ feats = _bayes_features(raw)
777
+
778
+ if len(raw) < MIN_COMPRESS_BYTES or feats["entropy"] >= RAW_ENTROPY_THRESHOLD:
779
+ return "raw", raw, feats
780
+
781
+ comp = zlib.compress(raw, level=ZLIB_LEVEL)
782
+ if len(comp) >= len(raw):
783
+ return "raw", raw, feats
784
+ return "zlib", comp, feats
785
+
786
+
787
+ def _write_record(out, meta: Dict, payload: bytes) -> None:
788
+ meta_bytes = json.dumps(meta, ensure_ascii=False, separators=(",", ":")).encode("utf-8")
789
+ out.write(struct.pack(">I", len(meta_bytes)))
790
+ out.write(meta_bytes)
791
+ out.write(struct.pack(">I", len(payload)))
792
+ out.write(payload)
793
+
794
+
795
+ def _read_exact(f, n: int) -> bytes:
796
+ data = f.read(n)
797
+ if len(data) != n:
798
+ raise EOFError("Unexpected end of payload")
799
+ return data
800
+
801
+
802
+ def _read_record(f):
803
+ head = f.read(4)
804
+ if not head:
805
+ return None, None
806
+ if len(head) != 4:
807
+ raise EOFError("Corrupted record header")
808
+ meta_len = struct.unpack(">I", head)[0]
809
+ meta = json.loads(_read_exact(f, meta_len).decode("utf-8"))
810
+ payload_len = struct.unpack(">I", _read_exact(f, 4))[0]
811
+ payload = _read_exact(f, payload_len)
812
+ return meta, payload
813
+
814
+
815
+ def _compress_shard_worker(args):
816
+ shard_path, tensor_names, packet_size = args
817
+ shard_name = Path(shard_path).name
818
+ entries = []
819
+
820
+ with safe_open(str(shard_path), framework="pt", device="cpu") as f:
821
+ try:
822
+ shard_metadata = f.metadata()
823
+ except Exception:
824
+ shard_metadata = None
825
+
826
+ for tensor_name in tensor_names:
827
+ tensor = f.get_tensor(tensor_name)
828
+ raw = tensor_to_raw_bytes(tensor)
829
+ packets = _packetize(raw, packet_size)
830
+
831
+ tensor_entry = {
832
+ "name": tensor_name,
833
+ "dtype": dtype_to_name(tensor.dtype),
834
+ "shape": list(tensor.shape),
835
+ "raw_len": len(raw),
836
+ "packet_count": len(packets),
837
+ }
838
+
839
+ for packet_index, packet_raw in enumerate(packets):
840
+ codec, payload, feats = _choose_codec(packet_raw)
841
+ packet_meta = {
842
+ "kind": "packet",
843
+ "shard_name": shard_name,
844
+ "tensor_name": tensor_name,
845
+ "dtype": dtype_to_name(tensor.dtype),
846
+ "shape": list(tensor.shape),
847
+ "codec": codec,
848
+ "packet_index": packet_index,
849
+ "packet_count": len(packets),
850
+ "packet_raw_len": len(packet_raw),
851
+ "sha256": _sha256(packet_raw),
852
+ "features": feats,
853
+ "is_last_packet": packet_index == len(packets) - 1,
854
+ "payload_len": len(payload),
855
+ }
856
+ entries.append((packet_meta, payload))
857
+
858
+ return shard_name, shard_metadata, entries
859
+
860
+
861
+ def compress_qwen2_safetensors_fast(
862
+ model_dir: str,
863
+ output_bundle_dir: str,
864
+ packet_mb: int = DEFAULT_PACKET_MB,
865
+ max_workers: int | None = None,
866
+ ) -> None:
867
+ _configure_torch()
868
+
869
+ model_dir = Path(model_dir)
870
+ out_dir = Path(output_bundle_dir)
871
+ out_dir.mkdir(parents=True, exist_ok=True)
872
+
873
+ shard_files = sorted(model_dir.glob("*.safetensors"))
874
+ if not shard_files:
875
+ raise FileNotFoundError(f"No .safetensors files found in {model_dir}")
876
+
877
+ packet_size = max(64 * 1024, packet_mb * 1024 * 1024)
878
+ cpu_count = os.cpu_count() or 1
879
+ if max_workers is None:
880
+ max_workers = max(1, min(cpu_count, len(shard_files), 8))
881
+
882
+ manifest = {
883
+ "format": MAGIC,
884
+ "version": VERSION,
885
+ "source_model_dir": str(model_dir),
886
+ "packet_size": packet_size,
887
+ "compression": "zlib",
888
+ "zlib_level": ZLIB_LEVEL,
889
+ "files": [],
890
+ }
891
+
892
+ for aux_name in [
893
+ "config.json",
894
+ "generation_config.json",
895
+ "tokenizer_config.json",
896
+ "special_tokens_map.json",
897
+ "model.safetensors.index.json",
898
+ ]:
899
+ aux_path = model_dir / aux_name
900
+ if aux_path.exists() and aux_path.is_file():
901
+ manifest.setdefault("aux_files", [])
902
+ manifest["aux_files"].append(
903
+ {"name": aux_name, "text": aux_path.read_text(encoding="utf-8")}
904
+ )
905
+
906
+ jobs = []
907
+ for shard_path in shard_files:
908
+ with safe_open(str(shard_path), framework="pt", device="cpu") as f:
909
+ tensor_names = list(f.keys())
910
+ jobs.append((str(shard_path), tensor_names, packet_size))
911
+
912
+ payload_path = out_dir / "payload.bin"
913
+
914
+ if len(jobs) == 1:
915
+ results = [_compress_shard_worker(jobs[0])]
916
+ else:
917
+ results = [None] * len(jobs)
918
+ with ProcessPoolExecutor(max_workers=max_workers) as pool:
919
+ future_map = {pool.submit(_compress_shard_worker, job): i for i, job in enumerate(jobs)}
920
+ for fut in as_completed(future_map):
921
+ idx = future_map[fut]
922
+ results[idx] = fut.result()
923
+
924
+ with open(payload_path, "wb") as payload_out:
925
+ for shard_name, shard_meta, entries in results:
926
+ shard_entry = {
927
+ "name": shard_name,
928
+ "metadata": shard_meta,
929
+ "records": len(entries),
930
+ "tensors": [],
931
+ }
932
+
933
+ tensor_map = {}
934
+ for packet_meta, payload in entries:
935
+ _write_record(payload_out, packet_meta, payload)
936
+
937
+ tname = packet_meta["tensor_name"]
938
+ if tname not in tensor_map:
939
+ tensor_map[tname] = {
940
+ "name": tname,
941
+ "dtype": packet_meta["dtype"],
942
+ "shape": packet_meta["shape"],
943
+ "raw_len": 0,
944
+ "packet_count": packet_meta["packet_count"],
945
+ }
946
+ tensor_map[tname]["raw_len"] = packet_meta["packet_raw_len"]
947
+
948
+ shard_entry["tensors"] = list(tensor_map.values())
949
+ manifest["files"].append(shard_entry)
950
+
951
+ with open(out_dir / "manifest.json", "w", encoding="utf-8") as f:
952
+ json.dump(manifest, f, ensure_ascii=False, separators=(",", ":"))
953
+
954
+ print("Compression finished.")
955
+ print(f"Payload: {payload_path}")
956
+ print(f"Manifest: {out_dir / 'manifest.json'}")
957
+ print(f"Packet: {packet_size / (1024 * 1024):.1f} MB")
958
+
959
+
960
+ def _verify_packet(meta: Dict, raw: bytes) -> None:
961
+ if len(raw) != int(meta["packet_raw_len"]):
962
+ raise ValueError(
963
+ f"Length mismatch for {meta.get('tensor_name')} packet {meta.get('packet_index')}"
964
+ )
965
+
966
+ if _sha256(raw) != meta["sha256"]:
967
+ raise ValueError(
968
+ f"SHA256 mismatch for {meta.get('tensor_name')} packet {meta.get('packet_index')}"
969
+ )
970
+
971
+ feats = _bayes_features(raw)
972
+ exp = meta["features"]
973
+
974
+ if feats["hist_sha256"] != exp["hist_sha256"]:
975
+ raise ValueError(
976
+ f"Histogram signature mismatch for {meta.get('tensor_name')} packet {meta.get('packet_index')}"
977
+ )
978
+
979
+ if feats["n"] != exp["n"]:
980
+ raise ValueError(
981
+ f"Feature length mismatch for {meta.get('tensor_name')} packet {meta.get('packet_index')}"
982
+ )
983
+
984
+ if int(feats["min"]) != int(exp["min"]) or int(feats["max"]) != int(exp["max"]):
985
+ raise ValueError(
986
+ f"Range feature mismatch for {meta.get('tensor_name')} packet {meta.get('packet_index')}"
987
+ )
988
+
989
+
990
+ def decompress_qwen2_safetensors_fast(
991
+ bundle_dir: str,
992
+ restored_model_dir: str,
993
+ ) -> None:
994
+ _configure_torch()
995
+
996
+ bundle_dir = Path(bundle_dir)
997
+ restored_model_dir = Path(restored_model_dir)
998
+ restored_model_dir.mkdir(parents=True, exist_ok=True)
999
+
1000
+ manifest_path = bundle_dir / "manifest.json"
1001
+ payload_path = bundle_dir / "payload.bin"
1002
+
1003
+ if not manifest_path.exists():
1004
+ raise FileNotFoundError(f"Missing manifest.json: {manifest_path}")
1005
+ if not payload_path.exists():
1006
+ raise FileNotFoundError(f"Missing payload.bin: {payload_path}")
1007
+
1008
+ with open(manifest_path, "r", encoding="utf-8") as f:
1009
+ manifest = json.load(f)
1010
+
1011
+ for aux in manifest.get("aux_files", []):
1012
+ (restored_model_dir / aux["name"]).write_text(aux["text"], encoding="utf-8")
1013
+
1014
+ shard_meta_map = {entry["name"]: entry.get("metadata") for entry in manifest["files"]}
1015
+
1016
+ current_shard_name = None
1017
+ current_state_dict = {}
1018
+ current_tensor_parts: Dict[str, List[bytes]] = {}
1019
+ current_tensor_meta: Dict[str, Dict] = {}
1020
+
1021
+ def flush_current_shard():
1022
+ nonlocal current_state_dict, current_tensor_parts, current_tensor_meta, current_shard_name
1023
+ if current_shard_name is None:
1024
+ return
1025
+
1026
+ for tensor_name, parts in current_tensor_parts.items():
1027
+ meta = current_tensor_meta[tensor_name]
1028
+ raw = b"".join(parts)
1029
+ dtype = name_to_dtype(meta["dtype"])
1030
+ shape = tuple(meta["shape"])
1031
+ current_state_dict[tensor_name] = raw_bytes_to_tensor(raw, dtype=dtype, shape=shape)
1032
+
1033
+ out_shard = restored_model_dir / current_shard_name
1034
+ save_file(current_state_dict, str(out_shard), metadata=shard_meta_map.get(current_shard_name))
1035
+
1036
+ current_state_dict = {}
1037
+ current_tensor_parts = {}
1038
+ current_tensor_meta = {}
1039
+ current_shard_name = None
1040
+
1041
+ with open(payload_path, "rb") as payload_in:
1042
+ while True:
1043
+ meta, payload = _read_record(payload_in)
1044
+ if meta is None:
1045
+ break
1046
+
1047
+ codec = meta["codec"]
1048
+ if codec == "zlib":
1049
+ raw = zlib.decompress(payload)
1050
+ elif codec == "raw":
1051
+ raw = payload
1052
+ else:
1053
+ raise ValueError(f"Unknown codec: {codec}")
1054
+
1055
+ _verify_packet(meta, raw)
1056
+
1057
+ shard_name = meta["shard_name"]
1058
+ tensor_name = meta["tensor_name"]
1059
+
1060
+ if current_shard_name is None:
1061
+ current_shard_name = shard_name
1062
+ elif current_shard_name != shard_name:
1063
+ flush_current_shard()
1064
+ current_shard_name = shard_name
1065
+
1066
+ if tensor_name not in current_tensor_parts:
1067
+ current_tensor_parts[tensor_name] = []
1068
+ current_tensor_meta[tensor_name] = meta
1069
+
1070
+ current_tensor_parts[tensor_name].append(raw)
1071
+
1072
+ flush_current_shard()
1073
+ print(f"Restored to: {restored_model_dir}")
1074
+
1075
+
1076
+ if __name__ == "__main__":
1077
+ source_model_dir = "/content/Qwen2-0.5B"
1078
+ bundle_dir = "qwen2_0_5b_bayes_zlib_bundle"
1079
+ restored_dir = "qwen2_0_5b_restored"
1080
+
1081
+ compress_qwen2_safetensors_fast(
1082
+ source_model_dir,
1083
+ bundle_dir,
1084
+ packet_mb=8,
1085
+ )
1086
+ decompress_qwen2_safetensors_fast(bundle_dir, restored_dir)
1087
+ ```
1088
+
1089
  ## Results
1090
 
1091
  *Placeholder — to be filled in with real numbers from benchmark runs.*