Upload slimshard.py
Browse files- slimshard.py +15 -9
slimshard.py
CHANGED
|
@@ -2445,7 +2445,7 @@ def export_hf_bundle(
|
|
| 2445 |
# CheckFree Single-Shard Recovery
|
| 2446 |
# ---------------------------------------------------------------------------
|
| 2447 |
def recover_from_shard(
|
| 2448 |
-
shard: str | Path,
|
| 2449 |
index: str | Path | None,
|
| 2450 |
output: str | Path,
|
| 2451 |
config: str | Path | None = None,
|
|
@@ -2456,16 +2456,18 @@ def recover_from_shard(
|
|
| 2456 |
export_hf_dir: str | Path | None = None,
|
| 2457 |
target_params_b: float | None = None,
|
| 2458 |
max_experts: int | None = None,
|
|
|
|
| 2459 |
) -> dict:
|
| 2460 |
-
"""Regenerate a full multi-shard HF model from
|
| 2461 |
|
| 2462 |
-
|
| 2463 |
-
|
| 2464 |
"""
|
| 2465 |
if safe_open is None or torch is None:
|
| 2466 |
raise RuntimeError("safetensors + torch are required for recovery")
|
| 2467 |
|
| 2468 |
-
|
|
|
|
| 2469 |
index_path = Path(index) if index else shard_path.parent / "model.safetensors.index.json"
|
| 2470 |
cfg_path = Path(config) if config else (index_path.parent if index_path.exists() else shard_path.parent) / "config.json"
|
| 2471 |
if not cfg_path.exists():
|
|
@@ -2476,7 +2478,7 @@ def recover_from_shard(
|
|
| 2476 |
if index_path.exists():
|
| 2477 |
raw_weight_map: dict[str, str] = json.loads(index_path.read_text())["weight_map"]
|
| 2478 |
else:
|
| 2479 |
-
raw_weight_map = infer_weight_map_from_shard(
|
| 2480 |
|
| 2481 |
tok_path = cfg_path.parent / "tokenizer.json"
|
| 2482 |
if not tok_path.exists():
|
|
@@ -2498,9 +2500,10 @@ def recover_from_shard(
|
|
| 2498 |
return "rda"
|
| 2499 |
return "generic"
|
| 2500 |
|
| 2501 |
-
|
|
|
|
| 2502 |
meta = f.metadata() or {}
|
| 2503 |
-
if meta.get("format") == SHARD_FORMAT:
|
| 2504 |
res = regenerate(shard_path, output, verbose=verbose, progress_cb=progress_cb, stop_event=stop_event)
|
| 2505 |
return {
|
| 2506 |
"present": res["tensors"],
|
|
@@ -2742,7 +2745,10 @@ def recover_from_shard(
|
|
| 2742 |
if kept_experts is not None and _is_router_gate_tensor(name, orig_experts, tuple(ta.shape)):
|
| 2743 |
ta = ta[:kept_experts].contiguous()
|
| 2744 |
if la == lb or alpha <= 1.0e-6 or dt_t not in ("F32", "F16", "BF16"):
|
| 2745 |
-
|
|
|
|
|
|
|
|
|
|
| 2746 |
else:
|
| 2747 |
tb = f.get_tensor(nb)
|
| 2748 |
if kept_experts is not None and _is_router_gate_tensor(name, orig_experts, tuple(tb.shape)):
|
|
|
|
| 2445 |
# CheckFree Single-Shard Recovery
|
| 2446 |
# ---------------------------------------------------------------------------
|
| 2447 |
def recover_from_shard(
|
| 2448 |
+
shard: str | Path | list[str | Path],
|
| 2449 |
index: str | Path | None,
|
| 2450 |
output: str | Path,
|
| 2451 |
config: str | Path | None = None,
|
|
|
|
| 2456 |
export_hf_dir: str | Path | None = None,
|
| 2457 |
target_params_b: float | None = None,
|
| 2458 |
max_experts: int | None = None,
|
| 2459 |
+
anchor_layers: list[int] | set[int] | str | None = None,
|
| 2460 |
) -> dict:
|
| 2461 |
+
"""Regenerate a full multi-shard HF model from one or more ``.safetensors`` shards.
|
| 2462 |
|
| 2463 |
+
Supports both single-shard recovery and multi-shard / multi-layer anchor
|
| 2464 |
+
recovery (e.g. from the minimum shard set retrieved from Hugging Face).
|
| 2465 |
"""
|
| 2466 |
if safe_open is None or torch is None:
|
| 2467 |
raise RuntimeError("safetensors + torch are required for recovery")
|
| 2468 |
|
| 2469 |
+
shard_paths = _resolve_shard_paths(shard)
|
| 2470 |
+
shard_path = shard_paths[0]
|
| 2471 |
index_path = Path(index) if index else shard_path.parent / "model.safetensors.index.json"
|
| 2472 |
cfg_path = Path(config) if config else (index_path.parent if index_path.exists() else shard_path.parent) / "config.json"
|
| 2473 |
if not cfg_path.exists():
|
|
|
|
| 2478 |
if index_path.exists():
|
| 2479 |
raw_weight_map: dict[str, str] = json.loads(index_path.read_text())["weight_map"]
|
| 2480 |
else:
|
| 2481 |
+
raw_weight_map = infer_weight_map_from_shard(shard_paths, arch)
|
| 2482 |
|
| 2483 |
tok_path = cfg_path.parent / "tokenizer.json"
|
| 2484 |
if not tok_path.exists():
|
|
|
|
| 2500 |
return "rda"
|
| 2501 |
return "generic"
|
| 2502 |
|
| 2503 |
+
parsed_anchors = _parse_anchor_layers(anchor_layers)
|
| 2504 |
+
with _MultiShardReader(shard_paths, anchor_layers=parsed_anchors) as f:
|
| 2505 |
meta = f.metadata() or {}
|
| 2506 |
+
if len(shard_paths) == 1 and meta.get("format") == SHARD_FORMAT:
|
| 2507 |
res = regenerate(shard_path, output, verbose=verbose, progress_cb=progress_cb, stop_event=stop_event)
|
| 2508 |
return {
|
| 2509 |
"present": res["tensors"],
|
|
|
|
| 2745 |
if kept_experts is not None and _is_router_gate_tensor(name, orig_experts, tuple(ta.shape)):
|
| 2746 |
ta = ta[:kept_experts].contiguous()
|
| 2747 |
if la == lb or alpha <= 1.0e-6 or dt_t not in ("F32", "F16", "BF16"):
|
| 2748 |
+
t_sel = ta if (la == lb or alpha < 0.5) else f.get_tensor(nb)
|
| 2749 |
+
if kept_experts is not None and _is_router_gate_tensor(name, orig_experts, tuple(t_sel.shape)):
|
| 2750 |
+
t_sel = t_sel[:kept_experts].contiguous()
|
| 2751 |
+
writer.add(name, _payload_bytes(t_sel), dt_t, tuple(t_sel.shape))
|
| 2752 |
else:
|
| 2753 |
tb = f.get_tensor(nb)
|
| 2754 |
if kept_experts is not None and _is_router_gate_tensor(name, orig_experts, tuple(tb.shape)):
|