edeneldith Codex commited on
Commit
8088bfa
·
verified ·
1 Parent(s): 3a1536e

Include scalar coupling parameters in Hub size indexing

Browse files

Store the 16 complex scalar coupling values as length-one tensors, recording their names in SafeTensors metadata. Restore the exact original scalar shapes in the loader. This avoids the Hub counter omitting shape=[] parameters. All 296 state tensors again passed byte-for-byte equality and strict native loading on CPU, without CUDA or inference.

Co-Authored-By: Codex <noreply@openai.com>

README.md CHANGED
@@ -125,6 +125,8 @@ prompt_ids = tokenizer.encode("The nature of consciousness")
125
 
126
  Both export files are necessary. The loader restores all learned tensors **and the saved fixed matrices**, strips the `_orig_mod.` prefix when loading the original compiled-training checkpoint, and requires an exact match to the native model's state. It does not regenerate the trained checkpoint's mixer state, retrain the model, alter its tokenizer, or compile it automatically.
127
 
 
 
128
  To use the original checkpoint instead, download `colm_best_Final.pt` too and call `load_colm(".", weights_format="pt")`. See the [GitHub repository](https://github.com/Eden-Eldith/COLM) for full training, generation, and evaluation scripts.
129
 
130
  ### Export Verification
 
125
 
126
  Both export files are necessary. The loader restores all learned tensors **and the saved fixed matrices**, strips the `_orig_mod.` prefix when loading the original compiled-training checkpoint, and requires an exact match to the native model's state. It does not regenerate the trained checkpoint's mixer state, retrain the model, alter its tokenizer, or compile it automatically.
127
 
128
+ For Hub size indexing, the 16 scalar coupling parameters are stored as one-element tensors in SafeTensors. Their names are recorded in the file metadata, and the loader restores their original scalar shapes before loading the model. This changes only the storage representation, not the model or its values.
129
+
130
  To use the original checkpoint instead, download `colm_best_Final.pt` too and call `load_colm(".", weights_format="pt")`. See the [GitHub repository](https://github.com/Eden-Eldith/COLM) for full training, generation, and evaluation scripts.
131
 
132
  ### Export Verification
colm_loader.py CHANGED
@@ -7,6 +7,7 @@ from types import SimpleNamespace
7
 
8
  import numpy as np
9
  import torch
 
10
  from safetensors.torch import load_file
11
 
12
  from model import COLM
@@ -28,6 +29,14 @@ def safetensors_state(directory):
28
  """Both files are required: learned parameters plus saved fixed mixers."""
29
  directory = Path(directory)
30
  state = load_file(str(directory / "model.safetensors"), device="cpu")
 
 
 
 
 
 
 
 
31
  with np.load(directory / "model_buffers.npz", allow_pickle=False) as archive:
32
  for name in archive.files:
33
  if name in state:
 
7
 
8
  import numpy as np
9
  import torch
10
+ from safetensors import safe_open
11
  from safetensors.torch import load_file
12
 
13
  from model import COLM
 
29
  """Both files are required: learned parameters plus saved fixed mixers."""
30
  directory = Path(directory)
31
  state = load_file(str(directory / "model.safetensors"), device="cpu")
32
+ with safe_open(str(directory / "model.safetensors"), framework="pt", device="cpu") as archive:
33
+ metadata = archive.metadata() or {}
34
+ # The Hub counter omits shape=[] tensors. Store these as shape=[1], then
35
+ # restore the original scalar shape before loading the unchanged model.
36
+ for name in json.loads(metadata.get("scalar_parameter_names", "[]")):
37
+ if state[name].shape != (1,):
38
+ raise ValueError(f"Expected a stored length-one scalar: {name}")
39
+ state[name] = state[name].reshape(())
40
  with np.load(directory / "model_buffers.npz", allow_pickle=False) as archive:
41
  for name in archive.files:
42
  if name in state:
conversion_report.json CHANGED
@@ -6,6 +6,24 @@
6
  "checkpoint_validation_loss": 1.144872358441353,
7
  "parameter_tensors": 264,
8
  "parameter_elements": 498214,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  "parameter_elements_by_dtype": {
10
  "torch.complex64": 52504,
11
  "torch.float32": 445710
@@ -26,13 +44,13 @@
26
  "numpy": "2.2.6"
27
  },
28
  "sha256": {
29
- "model.safetensors": "def65a16eb57a7365ccee0d9e650472d64fe4abad1c2788848f4d79933ea61f3",
30
  "model_buffers.npz": "2715e51c179588c3d74f7c03eec36c4a4b5f0ca658575f6c9e16f406dbcdc815",
31
  "model.py": "22066752391c65e4f360402fe8a0064107fefd7512d1c568004d68c621553f4c",
32
  "colm_config.json": "fba7681030b2421453f9d7aaa788384e3ffaebaf68aea200bc1c8e1480fa001c",
33
  "colm_tokenizer.json": "c28592e50ac0fb8c3094c17bb2159bc325a791727af86c8024a2c5b521b1f4c5",
34
  "tokenizer_train.py": "6d03d16913878e0d6e955bde1cb20a58db3f854e57dfb5b97efb0e7c75c684db",
35
- "colm_loader.py": "03da9755ea8d1b98ce2c903c35c2fa658829db5145aab7f4f07b1f94f22a0ff9",
36
- "export_safetensors.py": "7d347ee957faf4ff172b2e5baa7f9213de118718abbac2f8e4569bb98c6d58bb"
37
  }
38
  }
 
6
  "checkpoint_validation_loss": 1.144872358441353,
7
  "parameter_tensors": 264,
8
  "parameter_elements": 498214,
9
+ "scalar_parameters_stored_as_length_one": [
10
+ "blocks.0.coupling_alpha",
11
+ "blocks.1.coupling_alpha",
12
+ "blocks.10.coupling_alpha",
13
+ "blocks.11.coupling_alpha",
14
+ "blocks.12.coupling_alpha",
15
+ "blocks.13.coupling_alpha",
16
+ "blocks.14.coupling_alpha",
17
+ "blocks.15.coupling_alpha",
18
+ "blocks.2.coupling_alpha",
19
+ "blocks.3.coupling_alpha",
20
+ "blocks.4.coupling_alpha",
21
+ "blocks.5.coupling_alpha",
22
+ "blocks.6.coupling_alpha",
23
+ "blocks.7.coupling_alpha",
24
+ "blocks.8.coupling_alpha",
25
+ "blocks.9.coupling_alpha"
26
+ ],
27
  "parameter_elements_by_dtype": {
28
  "torch.complex64": 52504,
29
  "torch.float32": 445710
 
44
  "numpy": "2.2.6"
45
  },
46
  "sha256": {
47
+ "model.safetensors": "01473b0a6b1b595315552db82f29987f50f7db362425e39ff06f0f4b51fbab80",
48
  "model_buffers.npz": "2715e51c179588c3d74f7c03eec36c4a4b5f0ca658575f6c9e16f406dbcdc815",
49
  "model.py": "22066752391c65e4f360402fe8a0064107fefd7512d1c568004d68c621553f4c",
50
  "colm_config.json": "fba7681030b2421453f9d7aaa788384e3ffaebaf68aea200bc1c8e1480fa001c",
51
  "colm_tokenizer.json": "c28592e50ac0fb8c3094c17bb2159bc325a791727af86c8024a2c5b521b1f4c5",
52
  "tokenizer_train.py": "6d03d16913878e0d6e955bde1cb20a58db3f854e57dfb5b97efb0e7c75c684db",
53
+ "colm_loader.py": "c6d763efc9bb1aeda99782e966a93900997bee534cc78e43156003ecf8cba264",
54
+ "export_safetensors.py": "4a22a7b9683a1ae669414b7fa9650da558bcbd5db908e60e9d700084ca35cb54"
55
  }
56
  }
export_safetensors.py CHANGED
@@ -65,12 +65,18 @@ def main():
65
  raise AssertionError("State does not partition into parameters and buffers")
66
  parameters = {n: state[n].contiguous() for n in sorted(parameter_names)}
67
  buffers = {n: state[n].numpy() for n in sorted(buffer_names)}
 
 
 
 
 
68
 
69
- save_file(parameters, str(directory / "model.safetensors"), metadata={
70
  "format": "pt",
71
  "source_checkpoint": args.checkpoint.name,
72
  "source_sha256": original_hash,
73
  "fixed_buffers": "model_buffers.npz",
 
74
  "description": "Native F32/C64 trainable parameters; fixed mixers stored separately.",
75
  })
76
  np.savez(directory / "model_buffers.npz", **buffers)
@@ -97,6 +103,7 @@ def main():
97
  "checkpoint_validation_loss": config["checkpoint"]["validation_loss"],
98
  "parameter_tensors": len(parameters),
99
  "parameter_elements": sum(counts.values()),
 
100
  "parameter_elements_by_dtype": dict(counts),
101
  "real_scalar_degrees_of_freedom": sum(
102
  x.numel() * (2 if x.is_complex() else 1) for x in parameters.values()),
 
65
  raise AssertionError("State does not partition into parameters and buffers")
66
  parameters = {n: state[n].contiguous() for n in sorted(parameter_names)}
67
  buffers = {n: state[n].numpy() for n in sorted(buffer_names)}
68
+ scalar_names = [n for n, value in parameters.items() if value.ndim == 0]
69
+ serialized_parameters = {
70
+ n: value.reshape(1) if n in scalar_names else value
71
+ for n, value in parameters.items()
72
+ }
73
 
74
+ save_file(serialized_parameters, str(directory / "model.safetensors"), metadata={
75
  "format": "pt",
76
  "source_checkpoint": args.checkpoint.name,
77
  "source_sha256": original_hash,
78
  "fixed_buffers": "model_buffers.npz",
79
+ "scalar_parameter_names": json.dumps(scalar_names),
80
  "description": "Native F32/C64 trainable parameters; fixed mixers stored separately.",
81
  })
82
  np.savez(directory / "model_buffers.npz", **buffers)
 
103
  "checkpoint_validation_loss": config["checkpoint"]["validation_loss"],
104
  "parameter_tensors": len(parameters),
105
  "parameter_elements": sum(counts.values()),
106
+ "scalar_parameters_stored_as_length_one": scalar_names,
107
  "parameter_elements_by_dtype": dict(counts),
108
  "real_scalar_degrees_of_freedom": sum(
109
  x.numel() * (2 if x.is_complex() else 1) for x in parameters.values()),
model.safetensors CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:def65a16eb57a7365ccee0d9e650472d64fe4abad1c2788848f4d79933ea61f3
3
- size 2226088
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:01473b0a6b1b595315552db82f29987f50f7db362425e39ff06f0f4b51fbab80
3
+ size 2226600