rahul7star commited on
Commit
af86d16
·
verified ·
1 Parent(s): f62dcda

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +200 -270
app.py CHANGED
@@ -1,270 +1,200 @@
1
- """
2
- PromptWizard Qwen Training with Zero GPU
3
- Optimized for HuggingFace Spaces with automatic GPU allocation
4
- """
5
-
6
- import gradio as gr
7
- import spaces
8
- import torch
9
- from transformers import AutoModelForCausalLM, AutoTokenizer, Trainer, TrainingArguments
10
- from datasets import load_dataset, Dataset
11
- from peft import LoraConfig, get_peft_model, TaskType
12
- import json
13
- import os
14
-
15
- # Check if GPU is available (Zero GPU safe)
16
- def check_gpu_status():
17
- # Don't check CUDA at module load time for Zero GPU compatibility
18
- return "🚀 Zero GPU Ready - GPU will be allocated when training starts"
19
-
20
- @spaces.GPU(duration=300) # Request GPU for 5 minutes (can extend if needed)
21
- def train_model(model_name, num_epochs, batch_size, learning_rate, progress=gr.Progress()):
22
- """Main training function with Zero GPU support"""
23
-
24
- progress(0, desc="Initializing...")
25
- output_log = []
26
-
27
- try:
28
- # GPU should be available inside this function
29
- device = "cuda" if torch.cuda.is_available() else "cpu"
30
- output_log.append(f"🎮 Using device: {device}")
31
-
32
- if device == "cuda":
33
- output_log.append(f"✅ GPU: {torch.cuda.get_device_name(0)}")
34
- output_log.append(f" Memory: {torch.cuda.get_device_properties(0).total_memory / 1e9:.1f}GB")
35
-
36
- # Load GSM8K dataset
37
- progress(0.1, desc="Loading GSM8K dataset...")
38
- output_log.append("\n📚 Loading GSM8K dataset...")
39
-
40
- # Load local data if available, otherwise from HF
41
- train_data = []
42
- test_data = []
43
-
44
- # Try local files first
45
- if os.path.exists("data/train.jsonl"):
46
- with open("data/train.jsonl", "r") as f:
47
- for line in f:
48
- train_data.append(json.loads(line))
49
- output_log.append(f" Loaded {len(train_data)} training examples from local data")
50
- else:
51
- # Fallback to HF dataset
52
- dataset = load_dataset("openai/gsm8k", "main")
53
- train_data = dataset["train"].select(range(min(100, len(dataset["train"]))))
54
- output_log.append(f" Loaded {len(train_data)} training examples from HF")
55
-
56
- # Format prompts
57
- def format_example(item):
58
- prompt = f"""<|system|>
59
- You are a mathematics expert. Solve grade school math problems step by step.
60
- <|user|>
61
- {item.get('question', '')}
62
- <|assistant|>
63
- {item.get('full_solution', item.get('answer', ''))}"""
64
- return {"text": prompt}
65
-
66
- # Create dataset
67
- if isinstance(train_data, list):
68
- train_dataset = Dataset.from_list([format_example(item) for item in train_data])
69
- else:
70
- train_dataset = train_data.map(format_example)
71
-
72
- output_log.append(f" Training samples ready: {len(train_dataset)}")
73
-
74
- # Load model and tokenizer
75
- progress(0.3, desc="Loading model and tokenizer...")
76
- output_log.append(f"\n🤖 Loading {model_name}...")
77
-
78
- # Always use smaller model for Zero GPU demo
79
- model_name = "Qwen/Qwen2.5-0.5B" # Use smallest model for Zero GPU
80
- output_log.append(" Note: Using 0.5B model for Zero GPU compatibility")
81
-
82
- tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
83
- if tokenizer.pad_token is None:
84
- tokenizer.pad_token = tokenizer.eos_token
85
-
86
- # Load model without quantization for Zero GPU compatibility
87
- model = AutoModelForCausalLM.from_pretrained(
88
- model_name,
89
- trust_remote_code=True,
90
- torch_dtype=torch.float16 if device == "cuda" else torch.float32,
91
- low_cpu_mem_usage=True
92
- )
93
-
94
- # Move model to GPU if available
95
- if device == "cuda":
96
- model = model.to(device)
97
-
98
- output_log.append(" Model loaded successfully")
99
-
100
- # Configure LoRA
101
- progress(0.4, desc="Configuring LoRA...")
102
- output_log.append("\n⚙️ Configuring LoRA for efficient training...")
103
-
104
- lora_config = LoraConfig(
105
- task_type=TaskType.CAUSAL_LM,
106
- r=8, # Low rank for efficiency
107
- lora_alpha=16,
108
- lora_dropout=0.1,
109
- target_modules=["q_proj", "v_proj"],
110
- bias="none"
111
- )
112
-
113
- model = get_peft_model(model, lora_config)
114
- trainable_params = sum(p.numel() for p in model.parameters() if p.requires_grad)
115
- total_params = sum(p.numel() for p in model.parameters())
116
- output_log.append(f" Trainable parameters: {trainable_params:,} ({100 * trainable_params / total_params:.2f}%)")
117
-
118
- # Tokenize dataset
119
- progress(0.5, desc="Preparing data...")
120
- output_log.append("\n📝 Tokenizing dataset...")
121
-
122
- def tokenize_function(examples):
123
- return tokenizer(
124
- examples["text"],
125
- padding="max_length",
126
- truncation=True,
127
- max_length=256 # Shorter for demo
128
- )
129
-
130
- train_dataset = train_dataset.map(tokenize_function, batched=True)
131
-
132
- # Training arguments
133
- progress(0.6, desc="Setting up training...")
134
- output_log.append("\n🎯 Setting up training configuration...")
135
-
136
- training_args = TrainingArguments(
137
- output_dir="./qwen-promptwizard-zerogpu",
138
- num_train_epochs=num_epochs,
139
- per_device_train_batch_size=batch_size,
140
- gradient_accumulation_steps=2, # Reduced for Zero GPU
141
- warmup_steps=10, # Reduced warmup
142
- logging_steps=5,
143
- save_strategy="no", # Don't save during demo
144
- fp16=device == "cuda", # Only use fp16 on GPU
145
- gradient_checkpointing=False, # Disable for simplicity
146
- optim="adamw_torch",
147
- learning_rate=learning_rate,
148
- max_steps=50, # Limit steps for demo
149
- )
150
-
151
- # Create trainer
152
- trainer = Trainer(
153
- model=model,
154
- args=training_args,
155
- train_dataset=train_dataset,
156
- tokenizer=tokenizer,
157
- )
158
-
159
- # Start training
160
- progress(0.7, desc="Training...")
161
- output_log.append(f"\n🚀 Starting training for {num_epochs} epochs...")
162
- output_log.append("=" * 50)
163
-
164
- # Train
165
- train_result = trainer.train()
166
-
167
- # Results
168
- progress(0.9, desc="Finalizing...")
169
- output_log.append("=" * 50)
170
- output_log.append("\n✅ Training completed!")
171
- output_log.append(f" Final loss: {train_result.training_loss:.4f}")
172
- output_log.append(f" Total steps: {train_result.global_step}")
173
-
174
- # Save model info
175
- output_log.append("\n💾 Model trained with PromptWizard + GSM8K")
176
- output_log.append(" Using REAL data and REAL evaluation!")
177
-
178
- progress(1.0, desc="Complete!")
179
-
180
- except Exception as e:
181
- output_log.append(f"\n❌ Error: {str(e)}")
182
- output_log.append("Note: Zero GPU requires proper setup in Space settings")
183
-
184
- return "\n".join(output_log)
185
-
186
- # Gradio interface
187
- def create_interface():
188
- with gr.Blocks(title="PromptWizard Qwen Training") as demo:
189
- gr.Markdown("""
190
- # 🧙 PromptWizard Qwen Fine-tuning with Zero GPU
191
-
192
- Fine-tune Qwen models using GSM8K dataset with PromptWizard methodology.
193
- This Space uses HuggingFace Zero GPU for free GPU access during training.
194
-
195
- **Features:**
196
- - ✅ Real GSM8K mathematical problems (not fake data!)
197
- - ✅ LoRA-based efficient fine-tuning
198
- - Automatic Zero GPU allocation
199
- - PromptWizard optimization methodology
200
- """)
201
-
202
- with gr.Row():
203
- with gr.Column():
204
- gpu_status = gr.Textbox(
205
- label="GPU Status",
206
- value=check_gpu_status(),
207
- interactive=False
208
- )
209
-
210
- model_name = gr.Dropdown(
211
- choices=[
212
- "Qwen/Qwen2.5-0.5B",
213
- "Qwen/Qwen2.5-1.5B",
214
- ],
215
- value="Qwen/Qwen2.5-0.5B",
216
- label="Model (0.5B works best for Zero GPU)"
217
- )
218
-
219
- num_epochs = gr.Slider(
220
- minimum=1,
221
- maximum=3,
222
- value=1,
223
- step=1,
224
- label="Number of Epochs (1 for quick demo)"
225
- )
226
-
227
- batch_size = gr.Slider(
228
- minimum=1,
229
- maximum=4,
230
- value=2,
231
- step=1,
232
- label="Batch Size (2 for Zero GPU)"
233
- )
234
-
235
- learning_rate = gr.Number(
236
- value=5e-5,
237
- label="Learning Rate"
238
- )
239
-
240
- train_btn = gr.Button("🚀 Start Training", variant="primary")
241
-
242
- with gr.Column():
243
- output = gr.Textbox(
244
- label="Training Output",
245
- lines=20,
246
- max_lines=30,
247
- value="Click 'Start Training' to begin...\n\nZero GPU will automatically allocate a GPU when training starts."
248
- )
249
-
250
- # Connect button to training function
251
- train_btn.click(
252
- fn=train_model,
253
- inputs=[model_name, num_epochs, batch_size, learning_rate],
254
- outputs=output
255
- )
256
-
257
- gr.Markdown("""
258
- ## Notes:
259
- - Zero GPU provides free GPU access for public Spaces
260
- - Training will automatically get GPU allocation when started
261
- - Using smaller model (1.5B) for faster demo
262
- - Real GSM8K data - no fake metrics!
263
- """)
264
-
265
- return demo
266
-
267
- # Launch app
268
- if __name__ == "__main__":
269
- demo = create_interface()
270
- demo.launch()
 
1
+ """
2
+ PromptWizard Qwen Training using rahul7star/Gita dataset (.csv)
3
+ Optimized for HuggingFace Spaces with Zero GPU allocation
4
+ """
5
+
6
+ import gradio as gr
7
+ import spaces
8
+ import torch
9
+ from transformers import AutoModelForCausalLM, AutoTokenizer, Trainer, TrainingArguments
10
+ from datasets import load_dataset, Dataset
11
+ from peft import LoraConfig, get_peft_model, TaskType
12
+ import os
13
+
14
+ # GPU check (Zero GPU compatible)
15
+ def check_gpu_status():
16
+ return "🚀 Zero GPU Ready - GPU will be allocated when training starts"
17
+
18
+ @spaces.GPU(duration=300) # request GPU for 5 min
19
+ def train_model(model_name, num_epochs, batch_size, learning_rate, progress=gr.Progress()):
20
+ progress(0, desc="Initializing...")
21
+ output_log = []
22
+
23
+ try:
24
+ device = "cuda" if torch.cuda.is_available() else "cpu"
25
+ output_log.append(f"🎮 Using device: {device}")
26
+ if device == "cuda":
27
+ output_log.append(f"✅ GPU: {torch.cuda.get_device_name(0)}")
28
+
29
+ # === Load your dataset ===
30
+ progress(0.1, desc="Loading Gita dataset...")
31
+ output_log.append("\n📚 Loading rahul7star/Gita dataset from Hugging Face Hub...")
32
+
33
+ # Load CSV from Hugging Face repo
34
+ dataset = load_dataset("rahul7star/Gita", split="train")
35
+ output_log.append(f" Loaded {len(dataset)} examples from rahul7star/Gita")
36
+
37
+ # Preview columns
38
+ output_log.append(f" Columns: {dataset.column_names}")
39
+
40
+ # === Format each row into text prompt ===
41
+ def format_example(item):
42
+ # You can customize this depending on your CSV structure
43
+ # Assuming CSV has columns like: "chapter", "verse", "content" or "text"
44
+ text = ""
45
+ if "text" in item:
46
+ text = item["text"]
47
+ elif "content" in item:
48
+ text = item["content"]
49
+ else:
50
+ # fallback: join all columns
51
+ text = " ".join(str(v) for v in item.values())
52
+
53
+ prompt = f"""<|system|>
54
+ You are a spiritual teacher interpreting Bhagavad Gita verses with deep meaning.
55
+ <|user|>
56
+ { text }
57
+ <|assistant|>
58
+ """
59
+ return {"text": prompt}
60
+
61
+ train_dataset = dataset.map(format_example)
62
+ output_log.append(f" Formatted {len(train_dataset)} training samples")
63
+
64
+ # === Load Qwen model & tokenizer ===
65
+ progress(0.3, desc="Loading model...")
66
+ model_name = "Qwen/Qwen2.5-0.5B" # Force small model for free GPU
67
+ output_log.append(f"\n🤖 Loading {model_name}...")
68
+
69
+ tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
70
+ if tokenizer.pad_token is None:
71
+ tokenizer.pad_token = tokenizer.eos_token
72
+
73
+ model = AutoModelForCausalLM.from_pretrained(
74
+ model_name,
75
+ trust_remote_code=True,
76
+ torch_dtype=torch.float16 if device == "cuda" else torch.float32,
77
+ low_cpu_mem_usage=True
78
+ )
79
+
80
+ if device == "cuda":
81
+ model = model.to(device)
82
+ output_log.append(" ✅ Model loaded successfully")
83
+
84
+ # === LoRA configuration ===
85
+ progress(0.4, desc="Configuring LoRA...")
86
+ output_log.append("\n⚙️ Setting up LoRA for efficient training...")
87
+
88
+ lora_config = LoraConfig(
89
+ task_type=TaskType.CAUSAL_LM,
90
+ r=8,
91
+ lora_alpha=16,
92
+ lora_dropout=0.1,
93
+ target_modules=["q_proj", "v_proj"],
94
+ bias="none"
95
+ )
96
+ model = get_peft_model(model, lora_config)
97
+ trainable_params = sum(p.numel() for p in model.parameters() if p.requires_grad)
98
+ output_log.append(f" Trainable params: {trainable_params:,}")
99
+
100
+ # === Tokenize ===
101
+ progress(0.5, desc="Tokenizing data...")
102
+ def tokenize_fn(examples):
103
+ return tokenizer(
104
+ examples["text"],
105
+ padding="max_length",
106
+ truncation=True,
107
+ max_length=256
108
+ )
109
+ train_dataset = train_dataset.map(tokenize_fn, batched=True)
110
+ output_log.append(" ✅ Tokenization done")
111
+
112
+ # === Training configuration ===
113
+ progress(0.6, desc="Setting up training...")
114
+ training_args = TrainingArguments(
115
+ output_dir="./qwen-gita-lora",
116
+ num_train_epochs=num_epochs,
117
+ per_device_train_batch_size=batch_size,
118
+ gradient_accumulation_steps=2,
119
+ warmup_steps=10,
120
+ logging_steps=5,
121
+ save_strategy="no",
122
+ fp16=device == "cuda",
123
+ optim="adamw_torch",
124
+ learning_rate=learning_rate,
125
+ max_steps=50, # Short demo
126
+ )
127
+
128
+ trainer = Trainer(
129
+ model=model,
130
+ args=training_args,
131
+ train_dataset=train_dataset,
132
+ tokenizer=tokenizer,
133
+ )
134
+
135
+ # === Train ===
136
+ progress(0.7, desc="Training model...")
137
+ output_log.append("\n🚀 Starting training...\n" + "="*50)
138
+ train_result = trainer.train()
139
+
140
+ progress(0.9, desc="Finalizing...")
141
+ output_log.append("="*50)
142
+ output_log.append("\n✅ Training completed successfully!")
143
+ output_log.append(f" Final loss: {train_result.training_loss:.4f}")
144
+ output_log.append(f" Steps: {train_result.global_step}")
145
+
146
+ progress(1.0, desc="Complete!")
147
+ except Exception as e:
148
+ output_log.append(f"\n❌ Error: {e}")
149
+
150
+ return "\n".join(output_log)
151
+
152
+
153
+ # === Gradio UI ===
154
+ def create_interface():
155
+ with gr.Blocks(title="PromptWizard Gita Trainer") as demo:
156
+ gr.Markdown("""
157
+ # 🧘 PromptWizard Qwen Fine-tuning — Gita Edition
158
+ Train Qwen models using verses from **rahul7star/Gita** (CSV-based dataset).
159
+ This uses **Zero GPU** on Hugging Face Spaces for free GPU access.
160
+ """)
161
+
162
+ with gr.Row():
163
+ with gr.Column():
164
+ gpu_status = gr.Textbox(
165
+ label="GPU Status",
166
+ value=check_gpu_status(),
167
+ interactive=False
168
+ )
169
+
170
+ model_name = gr.Dropdown(
171
+ choices=["Qwen/Qwen2.5-0.5B", "Qwen/Qwen2.5-1.5B"],
172
+ value="Qwen/Qwen2.5-0.5B",
173
+ label="Model (recommended: 0.5B)"
174
+ )
175
+
176
+ num_epochs = gr.Slider(1, 3, value=1, step=1, label="Epochs")
177
+ batch_size = gr.Slider(1, 4, value=2, step=1, label="Batch Size")
178
+ learning_rate = gr.Number(value=5e-5, label="Learning Rate")
179
+ train_btn = gr.Button("🚀 Start Training", variant="primary")
180
+
181
+ with gr.Column():
182
+ output = gr.Textbox(
183
+ label="Training Output",
184
+ lines=20,
185
+ max_lines=30,
186
+ value="Click 'Start Training' to fine-tune on Gita dataset."
187
+ )
188
+
189
+ train_btn.click(
190
+ fn=train_model,
191
+ inputs=[model_name, num_epochs, batch_size, learning_rate],
192
+ outputs=output
193
+ )
194
+
195
+ return demo
196
+
197
+
198
+ if __name__ == "__main__":
199
+ demo = create_interface()
200
+ demo.launch()