rahul7star commited on
Commit
a5f3b08
·
verified ·
1 Parent(s): bc96a2a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +58 -96
app.py CHANGED
@@ -1,7 +1,7 @@
1
  """
2
- PromptWizard Qwen Training — Gita Edition
3
- Fine-tunes Qwen using rahul7star/Gita dataset (.csv)
4
- Uploads trained model to rahul7star/Qwen0.5-3B-Gita on Hugging Face Hub
5
  """
6
 
7
  import gradio as gr
@@ -13,16 +13,11 @@ from transformers import (
13
  Trainer,
14
  TrainingArguments,
15
  )
16
- from datasets import load_dataset, Dataset
17
  from peft import LoraConfig, get_peft_model, TaskType
18
  from huggingface_hub import HfApi, HfFolder, Repository
19
- import os, tempfile, shutil
20
-
21
- import asyncio
22
- import tempfile
23
- import shutil
24
- from huggingface_hub import HfApi, HfFolder, Repository
25
- import threading
26
 
27
  # ==== Async upload wrapper ====
28
  def start_async_upload(local_dir, hf_repo, output_log):
@@ -30,7 +25,6 @@ def start_async_upload(local_dir, hf_repo, output_log):
30
  asyncio.run(async_upload_model(local_dir, hf_repo, output_log))
31
  threading.Thread(target=runner, daemon=True).start()
32
 
33
-
34
  async def async_upload_model(local_dir, hf_repo, output_log):
35
  try:
36
  token = HfFolder.get_token()
@@ -41,7 +35,6 @@ async def async_upload_model(local_dir, hf_repo, output_log):
41
 
42
  with tempfile.TemporaryDirectory() as tmpdir:
43
  repo = Repository(local_dir=tmpdir, clone_from=hf_repo, use_auth_token=token)
44
- # Copy model files
45
  shutil.copytree(local_dir, tmpdir, dirs_exist_ok=True)
46
  repo.push_to_hub(commit_message="Upload fine-tuned model")
47
 
@@ -49,40 +42,38 @@ async def async_upload_model(local_dir, hf_repo, output_log):
49
  except Exception as e:
50
  output_log.append(f"\n❌ Async upload error: {e}")
51
 
52
-
53
- # === GPU check (Zero GPU compatible) ===
54
  def check_gpu_status():
55
  return "🚀 Zero GPU Ready - GPU will be allocated when training starts"
56
 
 
 
 
 
 
57
 
58
- # === Main Training ===
59
  @spaces.GPU(duration=300)
60
- def train_model(model_name, num_epochs, batch_size, learning_rate, progress=gr.Progress()):
61
- progress(0, desc="Initializing...")
62
  output_log = []
63
-
64
  try:
65
- # ==== Device ====
 
 
66
  device = "cuda" if torch.cuda.is_available() else "cpu"
67
- output_log.append(f"🎮 Using device: {device}")
68
  if device == "cuda":
69
- output_log.append(f"✅ GPU: {torch.cuda.get_device_name(0)}")
70
 
71
- # ==== Load dataset ====
72
- progress(0.1, desc="Loading rahul7star/Gita dataset...")
73
- output_log.append("\n📚 Loading dataset from rahul7star/Gita...")
 
 
74
 
75
- dataset = load_dataset("rahul7star/Gita", split="train")
76
- output_log.append(f" Loaded {len(dataset)} samples from CSV")
77
- output_log.append(f" Columns: {dataset.column_names}")
78
-
79
- # ==== Format data ====
80
  def format_example(item):
81
- text = (
82
- item.get("text")
83
- or item.get("content")
84
- or " ".join(str(v) for v in item.values())
85
- )
86
  prompt = f"""<|system|>
87
  You are a wise teacher interpreting Bhagavad Gita with deep insights.
88
  <|user|>
@@ -90,33 +81,27 @@ You are a wise teacher interpreting Bhagavad Gita with deep insights.
90
  <|assistant|>
91
  """
92
  return {"text": prompt}
93
-
94
  dataset = dataset.map(format_example)
95
- output_log.append(f" ✅ Formatted {len(dataset)} examples")
96
 
97
- # ==== Model & Tokenizer ====
98
- progress(0.3, desc="Loading model & tokenizer...")
99
- model_name = "Qwen/Qwen2.5-0.5B"
100
- output_log.append(f"\n🤖 Loading model: {model_name}")
101
-
102
- tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
103
  if tokenizer.pad_token is None:
104
  tokenizer.pad_token = tokenizer.eos_token
105
-
106
  model = AutoModelForCausalLM.from_pretrained(
107
- model_name,
108
  trust_remote_code=True,
109
  torch_dtype=torch.float16 if device == "cuda" else torch.float32,
110
  low_cpu_mem_usage=True,
111
  )
112
  if device == "cuda":
113
  model = model.to(device)
114
- output_log.append(" ✅ Model loaded successfully")
115
-
116
- # ==== LoRA ====
117
- progress(0.4, desc="Configuring LoRA...")
118
- output_log.append("\n⚙️ Setting up LoRA for efficient fine-tuning...")
119
 
 
 
120
  lora_config = LoraConfig(
121
  task_type=TaskType.CAUSAL_LM,
122
  r=8,
@@ -126,12 +111,10 @@ You are a wise teacher interpreting Bhagavad Gita with deep insights.
126
  bias="none",
127
  )
128
  model = get_peft_model(model, lora_config)
129
-
130
  trainable_params = sum(p.numel() for p in model.parameters() if p.requires_grad)
131
- output_log.append(f" Trainable params: {trainable_params:,}")
132
 
133
- # ==== Tokenization + Labels ====
134
- progress(0.5, desc="Tokenizing dataset...")
135
  def tokenize_fn(examples):
136
  tokenized = tokenizer(
137
  examples["text"],
@@ -139,15 +122,12 @@ You are a wise teacher interpreting Bhagavad Gita with deep insights.
139
  truncation=True,
140
  max_length=256,
141
  )
142
- # Add labels for causal LM
143
  tokenized["labels"] = tokenized["input_ids"].copy()
144
  return tokenized
145
-
146
  dataset = dataset.map(tokenize_fn, batched=True)
147
- output_log.append(" ✅ Tokenization + labels done")
148
 
149
- # ==== Training arguments ====
150
- progress(0.6, desc="Setting up training...")
151
  output_dir = "./qwen-gita-lora"
152
  training_args = TrainingArguments(
153
  output_dir=output_dir,
@@ -162,7 +142,6 @@ You are a wise teacher interpreting Bhagavad Gita with deep insights.
162
  learning_rate=learning_rate,
163
  max_steps=100,
164
  )
165
-
166
  trainer = Trainer(
167
  model=model,
168
  args=training_args,
@@ -170,54 +149,38 @@ You are a wise teacher interpreting Bhagavad Gita with deep insights.
170
  tokenizer=tokenizer,
171
  )
172
 
173
- # ==== Train ====
174
- progress(0.7, desc="Training...")
175
- output_log.append("\n🚀 Starting training...\n" + "=" * 50)
176
- train_result = trainer.train()
177
-
178
- # ==== Save model locally ====
179
- progress(0.85, desc="Saving model...")
180
- output_log.append("\n💾 Saving model locally...")
181
  trainer.save_model(output_dir)
182
  tokenizer.save_pretrained(output_dir)
183
 
184
- # ==== Async upload ====
185
- # ==== Async upload ====
186
- hf_repo = "rahul7star/Qwen0.5-3B-Gita"
187
  start_async_upload(output_dir, hf_repo, output_log)
188
 
189
- progress(1.0, desc="Complete!")
190
-
191
-
192
- output_log.append("\n✅ Training complete & model uploaded successfully!")
193
 
194
  except Exception as e:
195
- output_log.append(f"\n❌ Error: {e}")
196
 
197
  return "\n".join(output_log)
198
 
199
-
200
- # === Gradio Interface ===
201
  def create_interface():
202
- with gr.Blocks(title="PromptWizard — Qwen Gita Trainer") as demo:
203
  gr.Markdown("""
204
- # 🧘 PromptWizard Qwen Fine-tuning — Gita Edition
205
- Fine-tune **Qwen 0.5B** on your dataset [rahul7star/Gita](https://huggingface.co/datasets/rahul7star/Gita)
206
- and auto-upload to your model repo **rahul7star/Qwen0.5-3B-Gita**.
207
  """)
208
 
209
  with gr.Row():
210
  with gr.Column():
211
- gpu_status = gr.Textbox(
212
- label="GPU Status",
213
- value=check_gpu_status(),
214
- interactive=False,
215
- )
216
- model_name = gr.Textbox(
217
- label="Base Model",
218
- value="Qwen/Qwen2.5-0.5B",
219
- interactive=False,
220
- )
221
  num_epochs = gr.Slider(1, 3, value=1, step=1, label="Epochs")
222
  batch_size = gr.Slider(1, 4, value=2, step=1, label="Batch Size")
223
  learning_rate = gr.Number(value=5e-5, label="Learning Rate")
@@ -228,18 +191,17 @@ def create_interface():
228
  label="Training Log",
229
  lines=25,
230
  max_lines=40,
231
- value="Click 'Start Fine-tuning' to train on the Gita dataset and upload to your model repo.",
232
  )
233
 
234
  train_btn.click(
235
  fn=train_model,
236
- inputs=[model_name, num_epochs, batch_size, learning_rate],
237
  outputs=output,
238
  )
239
 
240
  return demo
241
 
242
-
243
  if __name__ == "__main__":
244
  demo = create_interface()
245
- demo.launch()
 
1
  """
2
+ PromptWizard Qwen Training — Configurable Dataset & Repo
3
+ Fine-tunes Qwen using a user-selected dataset and uploads the trained model
4
+ to a user-specified Hugging Face Hub repo asynchronously with detailed logs.
5
  """
6
 
7
  import gradio as gr
 
13
  Trainer,
14
  TrainingArguments,
15
  )
16
+ from datasets import load_dataset
17
  from peft import LoraConfig, get_peft_model, TaskType
18
  from huggingface_hub import HfApi, HfFolder, Repository
19
+ import os, tempfile, shutil, asyncio, threading, time
20
+ from datetime import datetime
 
 
 
 
 
21
 
22
  # ==== Async upload wrapper ====
23
  def start_async_upload(local_dir, hf_repo, output_log):
 
25
  asyncio.run(async_upload_model(local_dir, hf_repo, output_log))
26
  threading.Thread(target=runner, daemon=True).start()
27
 
 
28
  async def async_upload_model(local_dir, hf_repo, output_log):
29
  try:
30
  token = HfFolder.get_token()
 
35
 
36
  with tempfile.TemporaryDirectory() as tmpdir:
37
  repo = Repository(local_dir=tmpdir, clone_from=hf_repo, use_auth_token=token)
 
38
  shutil.copytree(local_dir, tmpdir, dirs_exist_ok=True)
39
  repo.push_to_hub(commit_message="Upload fine-tuned model")
40
 
 
42
  except Exception as e:
43
  output_log.append(f"\n❌ Async upload error: {e}")
44
 
45
+ # ==== GPU check ====
 
46
  def check_gpu_status():
47
  return "🚀 Zero GPU Ready - GPU will be allocated when training starts"
48
 
49
+ # ==== Logging helper ====
50
+ def log_message(output_log, msg):
51
+ line = f"[{datetime.now().strftime('%H:%M:%S')}] {msg}"
52
+ print(line)
53
+ output_log.append(line)
54
 
55
+ # ==== Main Training ====
56
  @spaces.GPU(duration=300)
57
+ def train_model(base_model, dataset_name, num_epochs, batch_size, learning_rate, hf_repo):
 
58
  output_log = []
 
59
  try:
60
+ log_message(output_log, "🔍 Initializing training sequence...")
61
+
62
+ # ===== Device =====
63
  device = "cuda" if torch.cuda.is_available() else "cpu"
64
+ log_message(output_log, f"🎮 Using device: {device}")
65
  if device == "cuda":
66
+ log_message(output_log, f"✅ GPU: {torch.cuda.get_device_name(0)}")
67
 
68
+ # ===== Load dataset =====
69
+ log_message(output_log, f"\n📚 Loading dataset: {dataset_name} ...")
70
+ dataset = load_dataset(dataset_name, split="train")
71
+ log_message(output_log, f" Loaded {len(dataset)} samples")
72
+ log_message(output_log, f" Columns: {dataset.column_names}")
73
 
74
+ # ===== Format examples =====
 
 
 
 
75
  def format_example(item):
76
+ text = item.get("text") or item.get("content") or " ".join(str(v) for v in item.values())
 
 
 
 
77
  prompt = f"""<|system|>
78
  You are a wise teacher interpreting Bhagavad Gita with deep insights.
79
  <|user|>
 
81
  <|assistant|>
82
  """
83
  return {"text": prompt}
 
84
  dataset = dataset.map(format_example)
85
+ log_message(output_log, f"✅ Formatted {len(dataset)} examples")
86
 
87
+ # ===== Load model & tokenizer =====
88
+ log_message(output_log, f"\n🤖 Loading model: {base_model}")
89
+ tokenizer = AutoTokenizer.from_pretrained(base_model, trust_remote_code=True)
 
 
 
90
  if tokenizer.pad_token is None:
91
  tokenizer.pad_token = tokenizer.eos_token
 
92
  model = AutoModelForCausalLM.from_pretrained(
93
+ base_model,
94
  trust_remote_code=True,
95
  torch_dtype=torch.float16 if device == "cuda" else torch.float32,
96
  low_cpu_mem_usage=True,
97
  )
98
  if device == "cuda":
99
  model = model.to(device)
100
+ log_message(output_log, "✅ Model and tokenizer loaded successfully")
101
+ log_message(output_log, f"Tokenizer vocab size: {tokenizer.vocab_size}")
 
 
 
102
 
103
+ # ===== LoRA configuration =====
104
+ log_message(output_log, "\n⚙️ Configuring LoRA for efficient fine-tuning...")
105
  lora_config = LoraConfig(
106
  task_type=TaskType.CAUSAL_LM,
107
  r=8,
 
111
  bias="none",
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
+ log_message(output_log, f"Trainable params after LoRA: {trainable_params:,}")
116
 
117
+ # ===== Tokenization + labels =====
 
118
  def tokenize_fn(examples):
119
  tokenized = tokenizer(
120
  examples["text"],
 
122
  truncation=True,
123
  max_length=256,
124
  )
 
125
  tokenized["labels"] = tokenized["input_ids"].copy()
126
  return tokenized
 
127
  dataset = dataset.map(tokenize_fn, batched=True)
128
+ log_message(output_log, "✅ Tokenization + labels done")
129
 
130
+ # ===== Training arguments =====
 
131
  output_dir = "./qwen-gita-lora"
132
  training_args = TrainingArguments(
133
  output_dir=output_dir,
 
142
  learning_rate=learning_rate,
143
  max_steps=100,
144
  )
 
145
  trainer = Trainer(
146
  model=model,
147
  args=training_args,
 
149
  tokenizer=tokenizer,
150
  )
151
 
152
+ # ===== Train =====
153
+ log_message(output_log, "\n🚀 Starting training...")
154
+ trainer.train()
155
+ log_message(output_log, "\n💾 Saving trained model locally...")
 
 
 
 
156
  trainer.save_model(output_dir)
157
  tokenizer.save_pretrained(output_dir)
158
 
159
+ # ===== Async upload to repo from UI input =====
160
+ log_message(output_log, f"\n☁️ Initiating async upload to {hf_repo}")
 
161
  start_async_upload(output_dir, hf_repo, output_log)
162
 
163
+ log_message(output_log, "✅ Training complete & async upload started!")
 
 
 
164
 
165
  except Exception as e:
166
+ log_message(output_log, f"\n❌ Error during training: {e}")
167
 
168
  return "\n".join(output_log)
169
 
170
+ # ==== Gradio Interface ====
 
171
  def create_interface():
172
+ with gr.Blocks(title="PromptWizard — Qwen Trainer") as demo:
173
  gr.Markdown("""
174
+ # 🧘 PromptWizard Qwen Fine-tuning
175
+ Fine-tune Qwen on any dataset and upload to any Hugging Face repo.
 
176
  """)
177
 
178
  with gr.Row():
179
  with gr.Column():
180
+ gr.Textbox(label="GPU Status", value=check_gpu_status(), interactive=False)
181
+ base_model = gr.Textbox(label="Base Model", value="Qwen/Qwen2.5-0.5B")
182
+ dataset_name = gr.Textbox(label="Dataset Name", value="rahul7star/Gita")
183
+ hf_repo = gr.Textbox(label="HF Repo for Upload", value="rahul7star/Qwen0.5-3B-Gita")
 
 
 
 
 
 
184
  num_epochs = gr.Slider(1, 3, value=1, step=1, label="Epochs")
185
  batch_size = gr.Slider(1, 4, value=2, step=1, label="Batch Size")
186
  learning_rate = gr.Number(value=5e-5, label="Learning Rate")
 
191
  label="Training Log",
192
  lines=25,
193
  max_lines=40,
194
+ value="Click 'Start Fine-tuning' to train and upload your model.",
195
  )
196
 
197
  train_btn.click(
198
  fn=train_model,
199
+ inputs=[base_model, dataset_name, num_epochs, batch_size, learning_rate, hf_repo],
200
  outputs=output,
201
  )
202
 
203
  return demo
204
 
 
205
  if __name__ == "__main__":
206
  demo = create_interface()
207
+ demo.launch(server_name="0.0.0.0", server_port=7860)