| |
| """ |
| HuggingFace Model Uploader for Stack 2.9 |
| Uploads fine-tuned model to HuggingFace Hub with proper model card and tags. |
| """ |
|
|
| import argparse |
| import os |
| import sys |
| from pathlib import Path |
|
|
| try: |
| from huggingface_hub import HfApi, create_repo, upload_folder |
| from huggingface_hub.utils import RepoNotFoundError |
| except ImportError: |
| print("Error: huggingface_hub not installed. Install with: pip install huggingface_hub") |
| sys.exit(1) |
|
|
|
|
| def load_model_card(template_path: str, placeholders: dict) -> str: |
| """Load model card template and replace placeholders.""" |
| with open(template_path, 'r') as f: |
| content = f.read() |
| |
| for key, value in placeholders.items(): |
| content = content.replace(f"{{{{{key}}}}}", str(value)) |
| |
| return content |
|
|
|
|
| def get_model_files(model_path: str) -> list: |
| """Get list of model files to upload.""" |
| path = Path(model_path) |
| if not path.exists(): |
| print(f"Warning: Model path {model_path} does not exist. Creating empty upload.") |
| return [] |
| |
| files = [] |
| for f in path.rglob("*"): |
| if f.is_file(): |
| files.append(str(f.relative_to(path))) |
| |
| return files |
|
|
|
|
| def main(): |
| parser = argparse.ArgumentParser(description="Upload Stack 2.9 model to HuggingFace Hub") |
| parser.add_argument("--model", type=str, required=True, |
| help="Path to the merged model directory") |
| parser.add_argument("--repo-id", type=str, required=True, |
| help="HuggingFace repo ID (e.g., username/stack-2.9-7b)") |
| parser.add_argument("--token", type=str, default=None, |
| help="HuggingFace token (or set HF_TOKEN env var)") |
| parser.add_argument("--private", action="store_true", |
| help="Create private repository") |
| parser.add_argument("--dry-run", action="store_true", |
| help="Show what would be uploaded without uploading") |
| |
| args = parser.parse_args() |
| |
| |
| token = args.token or os.environ.get("HF_TOKEN") |
| if not token: |
| print("Error: HF_TOKEN not set. Set HF_TOKEN environment variable or use --token") |
| sys.exit(1) |
| |
| api = HfApi(token=token) |
| |
| |
| script_dir = Path(__file__).parent |
| readme_path = script_dir / "README_HF.md" |
| |
| if not readme_path.exists(): |
| print(f"Warning: README_HF.md not found at {readme_path}") |
| readme_content = "# Stack 2.9 Model\n\nFine-tuned coding assistant model." |
| else: |
| |
| placeholders = { |
| "base_model": "Qwen2.5-Coder-7B", |
| "training_examples": "50,000", |
| "lora_rank": "16", |
| "lora_alpha": "32", |
| "humaneval_score": "TBD", |
| "mbpp_score": "TBD", |
| "max_context_length": "32K", |
| } |
| readme_content = load_model_card(str(readme_path), placeholders) |
| |
| |
| repo_id = args.repo_id |
| try: |
| create_repo(repo_id, token=token, private=args.private, repo_type="model", exist_ok=True) |
| print(f"Repository '{repo_id}' created or already exists.") |
| except Exception as e: |
| print(f"Error creating repository: {e}") |
| sys.exit(1) |
| |
| |
| model_path = Path(args.model) |
| model_card_path = model_path / "README.md" |
| |
| if model_path.exists(): |
| with open(model_card_path, 'w') as f: |
| f.write(readme_content) |
| print(f"Created model card at {model_card_path}") |
| |
| if args.dry_run: |
| print("\n=== DRY RUN - Files that would be uploaded ===") |
| files = get_model_files(args.model) |
| for f in files[:20]: |
| print(f" {f}") |
| if len(files) > 20: |
| print(f" ... and {len(files) - 20} more files") |
| print(f"\nTotal: {len(files)} files") |
| print(f"\nModel card:\n{readme_content[:500]}...") |
| return |
| |
| |
| print(f"\nUploading model from {args.model} to {repo_id}...") |
| |
| try: |
| |
| operation = api.upload_folder( |
| folder_path=args.model, |
| repo_id=repo_id, |
| repo_type="model", |
| commit_message="Upload Stack 2.9 fine-tuned model" |
| ) |
| print(f"\n✅ Successfully uploaded to https://huggingface.co/{repo_id}") |
| print(f"Operation: {operation}") |
| except Exception as e: |
| print(f"Error uploading: {e}") |
| sys.exit(1) |
|
|
|
|
| if __name__ == "__main__": |
| main() |