FoolDev Claude Opus 4.7 commited on
Commit
a0994f1
·
1 Parent(s): 59f5706

scripts: add rename_arch.py + gitignore qwen-suffixed rebadges

Browse files

Promotes the previously-untracked rename_arch.py to a committed tool.
It walks a GGUF's KV section and renames general.architecture (and
every <old_arch>.* namespaced key) to a new arch string while leaving
tensor data byte-identical. Used once for the Janus-35B qwen35moe ->
qwen36moe rebadge (commit 40cafdb in FoolDev/Janus-35B, since reverted
in ee40cb2 because no released ollama/llama.cpp recognized qwen36moe).

Also adds an ignore pattern for Thanatos-27B.*.qwen[0-9]*.gguf so
local rebadge outputs from this script don't accidentally get
committed/pushed to the LFS layer the HF Ollama bridge serves.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

Files changed (2) hide show
  1. .gitignore +4 -0
  2. scripts/rename_arch.py +77 -0
.gitignore CHANGED
@@ -11,6 +11,10 @@ venv/
11
  # "Use this model" widget (ollama run hf.co/FoolDev/thanatos-27b).
12
  *.gguf
13
  !Thanatos-27B.*.gguf
 
 
 
 
14
  *.safetensors
15
  *.bin
16
 
 
11
  # "Use this model" widget (ollama run hf.co/FoolDev/thanatos-27b).
12
  *.gguf
13
  !Thanatos-27B.*.gguf
14
+ # Local-only rebadge experiments produced by scripts/rename_arch.py.
15
+ # These re-stamp general.architecture and are not loadable by current
16
+ # ollama / llama.cpp; don't track or push them.
17
+ Thanatos-27B.*.qwen[0-9]*.gguf
18
  *.safetensors
19
  *.bin
20
 
scripts/rename_arch.py ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Rename GGUF architecture (and all arch-namespaced KV keys)."""
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import sys
7
+ from pathlib import Path
8
+
9
+ from tqdm import tqdm
10
+
11
+ from gguf import GGUFReader, GGUFValueType, GGUFWriter
12
+ from gguf.constants import Keys
13
+
14
+
15
+ def rename(src: Path, dst: Path, old_arch: str, new_arch: str) -> None:
16
+ reader = GGUFReader(src, "r")
17
+ cur = reader.get_field(Keys.General.ARCHITECTURE)
18
+ if cur is None:
19
+ sys.exit(f"no {Keys.General.ARCHITECTURE} in {src}")
20
+ cur_val = str(bytes(cur.parts[cur.data[0]]), encoding="utf-8")
21
+ if cur_val != old_arch:
22
+ sys.exit(f"expected arch={old_arch!r}, found {cur_val!r}")
23
+
24
+ writer = GGUFWriter(dst, new_arch, endianess=reader.endianess)
25
+
26
+ renamed_keys = 0
27
+ for field in reader.fields.values():
28
+ # GGUFWriter writes general.architecture from the `arch` ctor arg
29
+ if field.name == Keys.General.ARCHITECTURE or field.name.startswith("GGUF."):
30
+ continue
31
+
32
+ new_name = field.name
33
+ if field.name.startswith(f"{old_arch}."):
34
+ new_name = f"{new_arch}." + field.name[len(old_arch) + 1 :]
35
+ renamed_keys += 1
36
+
37
+ val_type = field.types[0]
38
+ sub_type = field.types[-1] if val_type == GGUFValueType.ARRAY else None
39
+ writer.add_key_value(new_name, field.contents(), val_type, sub_type=sub_type)
40
+
41
+ total_bytes = 0
42
+ for tensor in reader.tensors:
43
+ total_bytes += tensor.n_bytes
44
+ writer.add_tensor_info(
45
+ tensor.name,
46
+ tensor.data.shape,
47
+ tensor.data.dtype,
48
+ tensor.data.nbytes,
49
+ tensor.tensor_type,
50
+ )
51
+
52
+ print(f"[*] renamed {renamed_keys} {old_arch}.* keys -> {new_arch}.*")
53
+ print(f"[*] writing {dst}")
54
+
55
+ bar = tqdm(desc="Writing", total=total_bytes, unit="B", unit_scale=True)
56
+ writer.write_header_to_file()
57
+ writer.write_kv_data_to_file()
58
+ writer.write_ti_data_to_file()
59
+ for tensor in reader.tensors:
60
+ writer.write_tensor_data(tensor.data, tensor_endianess=reader.endianess)
61
+ bar.update(tensor.n_bytes)
62
+ writer.close()
63
+ bar.close()
64
+
65
+
66
+ def main() -> None:
67
+ p = argparse.ArgumentParser()
68
+ p.add_argument("input", type=Path)
69
+ p.add_argument("output", type=Path)
70
+ p.add_argument("--from-arch", default="qwen35")
71
+ p.add_argument("--to-arch", default="qwen36")
72
+ args = p.parse_args()
73
+ rename(args.input, args.output, args.from_arch, args.to_arch)
74
+
75
+
76
+ if __name__ == "__main__":
77
+ main()