Upload upload_lora_final_to_hf.py with huggingface_hub
Browse files- upload_lora_final_to_hf.py +73 -0
upload_lora_final_to_hf.py
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Upload the final LoRA adapter bundle from a GPU instance to the Hugging Face model repo.
|
| 3 |
+
|
| 4 |
+
Default behavior:
|
| 5 |
+
- Reads local files from Base/out/sft/rag_mcp_lora/final/
|
| 6 |
+
- Uploads them into ASTERIZER/LUNA-100M under rag_mcp_lora/final/
|
| 7 |
+
|
| 8 |
+
Usage:
|
| 9 |
+
python upload_lora_final_to_hf.py
|
| 10 |
+
python upload_lora_final_to_hf.py --repo ASTERIZER/LUNA-100M
|
| 11 |
+
python upload_lora_final_to_hf.py --source Base/out/sft/rag_mcp_lora/final --target adapters/rag_mcp_lora/final
|
| 12 |
+
"""
|
| 13 |
+
|
| 14 |
+
import argparse
|
| 15 |
+
import os
|
| 16 |
+
from pathlib import Path
|
| 17 |
+
|
| 18 |
+
from huggingface_hub import HfApi
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
DEFAULT_REPO = "ASTERIZER/LUNA-100M"
|
| 22 |
+
DEFAULT_SOURCE = "Base/out/sft/rag_mcp_lora/final"
|
| 23 |
+
DEFAULT_TARGET = "rag_mcp_lora/final"
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def parse_args():
|
| 27 |
+
parser = argparse.ArgumentParser(description="Upload final LoRA adapter artifacts to Hugging Face")
|
| 28 |
+
parser.add_argument("--repo", default=DEFAULT_REPO, help="Destination Hugging Face model repo")
|
| 29 |
+
parser.add_argument("--source", default=DEFAULT_SOURCE, help="Local final adapter directory")
|
| 30 |
+
parser.add_argument("--target", default=DEFAULT_TARGET, help="Target folder inside the HF repo")
|
| 31 |
+
parser.add_argument("--token", default=os.environ.get("HF_TOKEN"), help="HF token, defaults to HF_TOKEN env var")
|
| 32 |
+
return parser.parse_args()
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
def iter_files(root: Path):
|
| 36 |
+
for path in sorted(root.rglob("*")):
|
| 37 |
+
if path.is_file():
|
| 38 |
+
yield path
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
def main():
|
| 42 |
+
args = parse_args()
|
| 43 |
+
if not args.token:
|
| 44 |
+
raise RuntimeError("Set HF_TOKEN or pass --token")
|
| 45 |
+
|
| 46 |
+
source_dir = Path(args.source)
|
| 47 |
+
if not source_dir.exists() or not source_dir.is_dir():
|
| 48 |
+
raise FileNotFoundError(f"Source directory not found: {source_dir}")
|
| 49 |
+
|
| 50 |
+
files = list(iter_files(source_dir))
|
| 51 |
+
if not files:
|
| 52 |
+
raise RuntimeError(f"No files found under: {source_dir}")
|
| 53 |
+
|
| 54 |
+
api = HfApi(token=args.token)
|
| 55 |
+
|
| 56 |
+
print(f"Uploading {len(files)} files from {source_dir} -> https://huggingface.co/{args.repo}/tree/main/{args.target}")
|
| 57 |
+
for file_path in files:
|
| 58 |
+
relative = file_path.relative_to(source_dir).as_posix()
|
| 59 |
+
path_in_repo = f"{args.target}/{relative}" if relative != "." else args.target
|
| 60 |
+
api.upload_file(
|
| 61 |
+
path_or_fileobj=str(file_path),
|
| 62 |
+
path_in_repo=path_in_repo,
|
| 63 |
+
repo_id=args.repo,
|
| 64 |
+
repo_type="model",
|
| 65 |
+
token=args.token,
|
| 66 |
+
)
|
| 67 |
+
print(f" OK: {relative} -> {path_in_repo}")
|
| 68 |
+
|
| 69 |
+
print("Upload complete.")
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
if __name__ == "__main__":
|
| 73 |
+
main()
|