File size: 7,276 Bytes
f6e3d73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
#!/usr/bin/env python3
"""
Deployment-Script für trainierte LoRA-Modelle
Automatisiert den Upload zu Hugging Face Hub
"""

import os
import shutil
from pathlib import Path
import subprocess
import json
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class LoRADeployer:
    def __init__(self, model_path="../models/lora-checkpoint"):
        self.model_path = Path(model_path)
        self.hf_username = None  # Wird aus HF_USERNAME env var gelesen
        
    def verify_model(self):
        """Prüft ob trainiertes LoRA-Modell vollständig ist"""
        required_files = [
            "adapter_config.json",
            "adapter_model.bin",  # oder adapter_model.safetensors
            "README.md"
        ]
        
        missing_files = []
        for file in required_files:
            if not (self.model_path / file).exists():
                missing_files.append(file)
                
        if missing_files:
            logger.error(f"Fehlende Dateien: {missing_files}")
            return False
            
        logger.info("✅ LoRA-Modell vollständig")
        return True
        
    def create_model_card(self):
        """Erstellt eine Model Card für Hugging Face"""
        model_card = f"""---
library_name: peft
base_model: teknium/OpenHermes-2.5-Mistral-7B
tags:
- generated_from_trainer
- horoscope
- astrology
- german
- lora
language:
- de
- en
license: apache-2.0
---

# LoRA Adapter für Horoskop-Generierung

Dieses LoRA-Adapter wurde für die Generierung von personalisierten Horoskopen trainiert.

## Basis-Modell
- **Model**: teknium/OpenHermes-2.5-Mistral-7B
- **LoRA Rank**: 16
- **Target Modules**: q_proj, v_proj, k_proj, o_proj

## Verwendung

```python
from transformers import AutoTokenizer, AutoModelForCausalLM
from peft import PeftModel

base_model = "teknium/OpenHermes-2.5-Mistral-7B"
tokenizer = AutoTokenizer.from_pretrained(base_model)
model = AutoModelForCausalLM.from_pretrained(base_model, load_in_4bit=True)
model = PeftModel.from_pretrained(model, "IHR_USERNAME/horoskop-lora")

# Beispiel-Prompt
prompt = "<|im_start|>system\\nDu bist ein erfahrener Astrologe.<|im_end|>\\n<|im_start|>user\\nErstelle ein Horoskop für Widder heute.<|im_end|>\\n<|im_start|>assistant\\n"
```

## Training Details
- **Training Duration**: {self.get_training_info().get('duration', 'N/A')}
- **Dataset Size**: {self.get_training_info().get('dataset_size', 'N/A')}
- **Epochs**: {self.get_training_info().get('epochs', 'N/A')}
"""
        
        readme_path = self.model_path / "README.md"
        with open(readme_path, 'w', encoding='utf-8') as f:
            f.write(model_card)
            
        logger.info(f"Model Card erstellt: {readme_path}")
        
    def get_training_info(self):
        """Liest Training-Informationen aus logs oder config"""
        # Placeholder - könnte aus Training-Logs gelesen werden
        return {
            "duration": "2-4 Stunden",
            "dataset_size": "500+ Horoskop-Beispiele", 
            "epochs": "3"
        }
        
    def upload_to_hf(self, repo_name="horoskop-lora"):
        """Upload zu Hugging Face Hub"""
        
        # Hugging Face Username prüfen
        hf_username = os.getenv("HF_USERNAME")
        if not hf_username:
            logger.error("HF_USERNAME environment variable nicht gesetzt")
            logger.info("Setzen Sie: export HF_USERNAME=ihr_username")
            return False
            
        # Hugging Face CLI prüfen
        try:
            subprocess.run(["huggingface-cli", "--version"], check=True, capture_output=True)
        except subprocess.CalledProcessError:
            logger.error("Hugging Face CLI nicht installiert")
            logger.info("Installieren Sie: pip install huggingface_hub")
            return False
            
        # Repository erstellen
        repo_id = f"{hf_username}/{repo_name}"
        logger.info(f"Erstelle Repository: {repo_id}")
        
        try:
            # Repository auf HF erstellen
            cmd = [
                "huggingface-cli", "repo", "create", 
                repo_id, "--type", "model", "--private"
            ]
            subprocess.run(cmd, check=True)
            logger.info(f"✅ Repository erstellt: {repo_id}")
            
        except subprocess.CalledProcessError as e:
            if "already exists" in str(e):
                logger.info(f"Repository existiert bereits: {repo_id}")
            else:
                logger.error(f"Repository-Erstellung fehlgeschlagen: {e}")
                return False
                
        # Dateien hochladen
        try:
            cmd = [
                "huggingface-cli", "upload", repo_id,
                str(self.model_path), ".", "--recursive"
            ]
            subprocess.run(cmd, check=True)
            logger.info(f"✅ Upload erfolgreich: https://huggingface.co/{repo_id}")
            return True
            
        except subprocess.CalledProcessError as e:
            logger.error(f"Upload fehlgeschlagen: {e}")
            return False
            
    def prepare_for_space(self):
        """Bereitet Modell für Hugging Face Space vor"""
        space_model_path = Path("../models/lora-checkpoint-deployed")
        space_model_path.mkdir(exist_ok=True)
        
        # Kopiere nur notwendige Dateien
        essential_files = [
            "adapter_config.json",
            "adapter_model.bin",
            "adapter_model.safetensors"
        ]
        
        for file in essential_files:
            src = self.model_path / file
            if src.exists():
                dst = space_model_path / file
                shutil.copy2(src, dst)
                logger.info(f"Kopiert: {file}")
                
        logger.info(f"✅ Space-ready Modell in: {space_model_path}")
        return space_model_path

def main():
    """Hauptfunktion für Deployment"""
    deployer = LoRADeployer()
    
    print("🚀 LoRA-Modell Deployment")
    print("========================")
    
    # 1. Modell verifizieren
    if not deployer.verify_model():
        print("❌ Modell-Verifikation fehlgeschlagen")
        return
        
    # 2. Model Card erstellen
    deployer.create_model_card()
    
    # 3. User-Input für Deployment-Optionen
    print("\n📤 Deployment-Optionen:")
    print("1. Für Hugging Face Space vorbereiten")
    print("2. Zu Hugging Face Hub hochladen")
    print("3. Beides")
    
    choice = input("Wählen Sie (1-3): ").strip()
    
    if choice in ["1", "3"]:
        space_path = deployer.prepare_for_space()
        print(f"✅ Space-ready: {space_path}")
        
    if choice in ["2", "3"]:
        repo_name = input("Repository-Name (Standard: horoskop-lora): ").strip()
        if not repo_name:
            repo_name = "horoskop-lora"
            
        if deployer.upload_to_hf(repo_name):
            print("✅ Upload zu Hugging Face erfolgreich!")
        else:
            print("❌ Upload fehlgeschlagen")
            
    print("\n🎯 Nächste Schritte:")
    print("1. Aktualisieren Sie config.py mit dem neuen Modell-Pfad")
    print("2. Testen Sie das Modell lokal")
    print("3. Deployen Sie zu Hugging Face Space")

if __name__ == "__main__":
    main()