Download custom_nodes/dolphin_nodes/dataset_builder/inspect_lora.py from bjooo/tutorials: direct link, hf CLI and curl.
- Browser
- Download file 2.2 kB
-
https://huggingface.co/bjooo/tutorials/resolve/main/custom_nodes/dolphin_nodes/dataset_builder/inspect_lora.py
- Command line
-
hf download hf://bjooo/tutorials/custom_nodes/dolphin_nodes/dataset_builder/inspect_lora.py
-
curl -L -o inspect_lora.py https://huggingface.co/bjooo/tutorials/resolve/main/custom_nodes/dolphin_nodes/dataset_builder/inspect_lora.py
2.2 kB
| """Inspect a LoRA .safetensors file: embedded training metadata + inferred | |
| rank/target modules from tensor shapes. Read-only, no GPU/torch needed -- | |
| just parses the safetensors header, so it's fast and safe to run on any | |
| LoRA file (including ones you didn't train yourself). | |
| Usage: | |
| python_embeded\\python.exe dataset_builder\\inspect_lora.py path\\to\\lora.safetensors | |
| """ | |
| import argparse | |
| import json | |
| import re | |
| from collections import Counter | |
| from safetensors import safe_open | |
| def parse_args(): | |
| p = argparse.ArgumentParser(description="Inspect a LoRA safetensors file's metadata") | |
| p.add_argument("lora_path") | |
| return p.parse_args() | |
| def infer_rank(keys, shapes): | |
| for k in keys: | |
| if k.endswith("lora_A.weight") or k.endswith("lora_down.weight"): | |
| return shapes[k][0] | |
| return None | |
| def summarize_target_modules(keys): | |
| """Collapses per-block keys (blocks.0, blocks.1, ...) into module families | |
| so you can see what parts of the model were trained without a 800-line dump.""" | |
| families = Counter() | |
| for k in keys: | |
| base = re.sub(r"\.(lora_A|lora_B|lora_down|lora_up|alpha)(\.weight)?$", "", k) | |
| base = re.sub(r"\.\d+\.", ".N.", base) | |
| families[base] += 1 | |
| return families | |
| def main(): | |
| args = parse_args() | |
| with safe_open(args.lora_path, framework="pt") as f: | |
| meta = f.metadata() or {} | |
| keys = list(f.keys()) | |
| shapes = {k: f.get_slice(k).get_shape() for k in keys} | |
| print(f"=== {args.lora_path} ===") | |
| print(f"Tensor count: {len(keys)}") | |
| print(f"Inferred rank (lora_A/lora_down first dim): {infer_rank(keys, shapes)}") | |
| print("\n--- Embedded metadata ---") | |
| if not meta: | |
| print("(none)") | |
| for k, v in meta.items(): | |
| try: | |
| parsed = json.loads(v) | |
| print(f"{k}:") | |
| print(json.dumps(parsed, indent=2, ensure_ascii=False)[:3000]) | |
| except (json.JSONDecodeError, TypeError): | |
| print(f"{k}: {v}") | |
| print("\n--- Target module families (per-block keys collapsed) ---") | |
| for base, count in summarize_target_modules(keys).most_common(30): | |
| print(f" {base} x{count}") | |
| if __name__ == "__main__": | |
| main() | |