learning cache + true sampling + DSA indexer extraction mode

- Learning cache: expert usage persists in <SNAP>/.coli_usage across sessions
  (atomic save every turn); at startup the hottest experts are auto-pinned in
  RAM with half the expert budget (AUTOPIN=0 disables). The engine gets faster
  the more you use it.
- Sampling: temperature + nucleus (official 1.0/0.95 defaults in chat; TEMP=0
  = greedy). MTP/n-gram speculation stays lossless via rejection sampling
  (accept draft w.p. p(draft); on reject resample with draft banned).
- coli: --temp flag.
- Converter: --indexer mode extracts DSA lightning-indexer weights
  (resumable; needed for future sparse attention beyond 2048 ctx).
- pin_load/stats include the MTP row; usage histogram covers layer 78.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
JustVugg
2026-07-06 12:29:13 +02:00
parent 257c4d0a8b
commit 3e88e37ba2
3 changed files with 156 additions and 20 deletions
+32 -3
View File
@@ -72,9 +72,14 @@ def layer_idx(name):
except ValueError: return -1
return -1
def classify(name, n_layers, keep_mtp=False):
def classify(name, n_layers, keep_mtp=False, keep_idx=False):
if name.endswith("_scale_inv"): return "consumed" # gestito col suo peso
li = layer_idx(name)
if keep_idx:
# modalita' --indexer: SOLO i pesi del DSA lightning indexer dei layer principali
if li < 0 or li >= n_layers or "indexer" not in name: return "skip"
if name.endswith("norm.weight"): return "f32"
return "q" # int8 consigliato (--ebits 8): pesi di scoring
if keep_mtp:
if li != n_layers: return "skip" # solo il layer MTP
if "indexer" in name: return "skip" # il DSA indexer resta un no-op
@@ -102,11 +107,11 @@ def dequant(f, name):
return (w * sc).numpy()
return f.get_tensor(name).to(torch.float32).numpy()
def convert_shard(path, out_dict, n_layers, ebits, io_bits, xbits, keep_mtp=False):
def convert_shard(path, out_dict, n_layers, ebits, io_bits, xbits, keep_mtp=False, keep_idx=False):
from safetensors import safe_open
with safe_open(path, framework="pt") as f:
for name in f.keys():
kind = classify(name, n_layers, keep_mtp)
kind = classify(name, n_layers, keep_mtp, keep_idx)
if kind in ("skip", "consumed"): continue
w = dequant(f, name)
if kind == "f32":
@@ -135,6 +140,10 @@ def main():
ap.add_argument("--selftest", action="store_true")
ap.add_argument("--mtp", action="store_true",
help="scarica/converte SOLO la testa MTP (model.layers.<n_layers>.*) -> out-mtp-*.safetensors")
ap.add_argument("--indexer", action="store_true",
help="estrae SOLO i pesi del DSA lightning indexer -> out-idx-*.safetensors. ATTENZIONE: "
"i tensori indexer sono sparsi su ~tutti gli shard: ri-scarica l'intero repo (~756 GB "
"di traffico) per tenerne pochi GB. Resumabile shard per shard. Consigliato --ebits 8.")
a = ap.parse_args()
if a.xbits is None: a.xbits = a.ebits
@@ -230,6 +239,26 @@ def main():
if os.path.isfile(blob): os.remove(blob)
print(f" -> {os.path.basename(outp)} ({os.path.getsize(outp)/1e9:.2f} GB, {len(out)} tensori)", flush=True)
shutil.rmtree(tmp, ignore_errors=True); print("[MTP] FATTO."); return
if a.indexer:
import urllib.request
idx = json.loads(urllib.request.urlopen(
f"https://huggingface.co/{a.repo}/resolve/main/model.safetensors.index.json", timeout=30).read())["weight_map"]
idx_shards = sorted(set(v for k, v in idx.items()
if "indexer" in k and 0 <= layer_idx(k) < a.n_layers))
tot_gb = len(idx_shards) * 5.4
print(f"[IDX] pesi indexer su {len(idx_shards)} shard (~{tot_gb:.0f} GB di download totale, resumabile)")
for i, sh in enumerate(idx_shards):
outp = os.path.join(a.outdir, f"out-idx-{i:05d}.safetensors")
if os.path.exists(outp): continue # gia' fatto -> ripartibile
print(f"[IDX {i+1}/{len(idx_shards)}] scarico {sh}...", flush=True)
p = download_retry(a.repo, sh, tmp)
out = {}; convert_shard(p, out, a.n_layers, a.ebits, a.io_bits, a.xbits, keep_idx=True)
if out: save_file(out, outp)
os.remove(p)
for blob in glob.glob(os.path.join(tmp, "**", "*"), recursive=True):
if os.path.isfile(blob): os.remove(blob)
print(f" -> {os.path.basename(outp)} ({len(out)} tensori)", flush=True)
shutil.rmtree(tmp, ignore_errors=True); print("[IDX] FATTO."); return
for i, sh in enumerate(shards):
if free_gb(a.outdir) < a.min_free_gb:
print(f"STOP: spazio libero < {a.min_free_gb} GB. Libera spazio e rilancia (riprende)."); break