| |
| """导出 train.py checkpoint -> ComfyUI 适配器 .safetensors(纯 state_dict)。 |
| |
| 用法: |
| python export_adapter.py <adapter_stage2_step2000.pt> [--out adapter_stage2.safetensors] |
| """ |
| from __future__ import annotations |
|
|
| import argparse |
| import os |
| import sys |
|
|
| import torch |
|
|
| HERE = os.path.dirname(os.path.abspath(__file__)) |
| sys.path.insert(0, HERE) |
|
|
| from adapter.model import H3Adapter |
|
|
|
|
| def main() -> None: |
| ap = argparse.ArgumentParser() |
| ap.add_argument("ckpt", help="train.py checkpoint (.pt)") |
| ap.add_argument("--out", default="adapter_stage2.safetensors") |
| args = ap.parse_args() |
|
|
| ckpt = torch.load(args.ckpt, map_location="cpu", weights_only=False) |
| state = ckpt.get("model", ckpt) |
| if any(k.startswith("model.") for k in state): |
| state = {k[len("model."):]: v for k, v in state.items()} |
|
|
| model = H3Adapter() |
| missing, unexpected = model.load_state_dict(state, strict=False) |
| assert not missing, f"missing: {missing[:10]}" |
| print(f"adapter keys: {len(state)} | missing={len(missing)} unexpected={len(unexpected)}") |
|
|
| from safetensors.torch import save_file |
| save_file({k: v.contiguous().to(torch.bfloat16) for k, v in state.items()}, args.out) |
| print(f"saved -> {args.out}") |
|
|
|
|
| if __name__ == "__main__": |
| main() |
|
|