MrUnknown420 commited on
Commit
4b1000b
Β·
verified Β·
1 Parent(s): 89250c2
Files changed (1) hide show
  1. app.py +208 -138
app.py CHANGED
@@ -1,156 +1,226 @@
1
  import os
2
  import json
 
3
  import gradio as gr
4
- from datetime import datetime
5
- from transformers import AutoTokenizer, AutoModelForCausalLM, Trainer, TrainingArguments
6
  from datasets import load_dataset
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
- # ========= MEMORY MANAGEMENT =========
9
- MEMORY_DIR = "memories"
10
- MODEL_DIR = "models"
 
 
11
 
12
- os.makedirs(MEMORY_DIR, exist_ok=True)
13
- os.makedirs(MODEL_DIR, exist_ok=True)
 
14
 
15
  def get_memory_file(model_name):
16
- safe_name = model_name.replace("/", "_")
17
- return os.path.join(MEMORY_DIR, f"{safe_name}_memory.json")
18
 
19
  def load_memory(model_name):
20
- filepath = get_memory_file(model_name)
21
- if os.path.exists(filepath):
22
- with open(filepath, "r") as f:
 
23
  return json.load(f)
24
  return []
25
 
26
- def save_memory(model_name, memory_data):
27
- filepath = get_memory_file(model_name)
28
- with open(filepath, "w") as f:
29
- json.dump(memory_data, f, indent=2)
30
-
31
- def append_memory(model_name, role, content):
32
- memory = load_memory(model_name)
33
- memory.append({
34
- "timestamp": datetime.now().isoformat(),
35
- "role": role,
36
- "content": content
37
- })
38
- save_memory(model_name, memory)
39
-
40
- def clear_memory(model_name):
41
- filepath = get_memory_file(model_name)
42
- if os.path.exists(filepath):
43
- os.remove(filepath)
44
- return f"Memory cleared for {model_name}."
45
-
46
- def download_memory(model_name):
47
- filepath = get_memory_file(model_name)
48
- if os.path.exists(filepath):
49
- return filepath
50
- return None
51
-
52
- def upload_memory(model_name, file_obj):
53
- if file_obj is None:
54
- return "No file uploaded."
55
- new_data = json.load(open(file_obj.name))
56
- save_memory(model_name, new_data)
57
- return f"Memory replaced for {model_name}."
58
-
59
- def merge_memory(model_name, file_obj):
60
- if file_obj is None:
61
- return "No file uploaded."
62
- current = load_memory(model_name)
63
- new_data = json.load(open(file_obj.name))
64
- merged = current + new_data
65
- save_memory(model_name, merged)
66
- return f"Memory merged for {model_name}."
67
-
68
- # ========= MODEL MANAGEMENT =========
69
- def train_model(model_name, dataset_name, epochs, output_dir):
70
- try:
71
- dataset = load_dataset(dataset_name)
72
- tokenizer = AutoTokenizer.from_pretrained(model_name)
73
- model = AutoModelForCausalLM.from_pretrained(model_name)
74
-
75
- def tokenize(batch):
76
- return tokenizer(batch["text"], truncation=True, padding="max_length", max_length=128)
77
-
78
- dataset = dataset.map(tokenize, batched=True)
79
- training_args = TrainingArguments(
80
- output_dir=output_dir,
81
- overwrite_output_dir=True,
82
- per_device_train_batch_size=2,
83
- num_train_epochs=int(epochs),
84
- save_strategy="epoch",
85
- logging_dir=f"{output_dir}/logs"
86
  )
87
 
88
- trainer = Trainer(model=model, args=training_args, train_dataset=dataset["train"])
89
- trainer.train()
90
- model.save_pretrained(output_dir)
91
- tokenizer.save_pretrained(output_dir)
92
- return f"Training complete. Model saved to {output_dir}"
93
- except Exception as e:
94
- return f"Error: {str(e)}"
95
-
96
- def chat_with_model(model_name, prompt):
97
- try:
98
- model_path = os.path.join(MODEL_DIR, model_name.replace("/", "_"))
99
- if os.path.exists(model_path):
100
- model = AutoModelForCausalLM.from_pretrained(model_path)
101
- tokenizer = AutoTokenizer.from_pretrained(model_path)
102
- else:
103
- model = AutoModelForCausalLM.from_pretrained(model_name)
104
- tokenizer = AutoTokenizer.from_pretrained(model_name)
105
-
106
- inputs = tokenizer(prompt, return_tensors="pt")
107
- outputs = model.generate(**inputs, max_length=256, do_sample=True, temperature=0.7)
108
- response = tokenizer.decode(outputs[0], skip_special_tokens=True)
109
-
110
- append_memory(model_name, "user", prompt)
111
- append_memory(model_name, "assistant", response)
112
-
113
- return response
114
- except Exception as e:
115
- return f"Error: {str(e)}"
116
-
117
- # ========= INTERFACE =========
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  with gr.Blocks() as demo:
119
- gr.Markdown("# πŸ€– My AI Model Builder\nTrain, fine-tune, test, and manage AI models with memory.")
120
-
121
- with gr.Tab("Train Model"):
122
- model_name = gr.Textbox(label="Base Model (Hugging Face Hub ID)", value="gpt2")
123
- dataset_name = gr.Textbox(label="Dataset Name (Hugging Face Dataset ID)", value="wikitext")
124
- epochs = gr.Number(label="Epochs", value=1, precision=0)
125
- output_dir = gr.Textbox(label="Output Directory", value="models/custom_model")
126
- train_btn = gr.Button("Train Model")
127
- train_output = gr.Textbox(label="Training Status")
128
- train_btn.click(train_model, inputs=[model_name, dataset_name, epochs, output_dir], outputs=train_output)
129
-
130
- with gr.Tab("Test Models / Chat"):
131
- chat_model = gr.Textbox(label="Model Name", value="gpt2")
132
- user_prompt = gr.Textbox(label="Enter Prompt")
133
- chat_btn = gr.Button("Chat")
134
- chat_output = gr.Textbox(label="Response")
135
- chat_btn.click(chat_with_model, inputs=[chat_model, user_prompt], outputs=chat_output)
136
-
137
- with gr.Tab("Memory Management"):
138
- mem_model = gr.Textbox(label="Model Name", value="gpt2")
139
- view_btn = gr.Button("View Memory")
140
- memory_output = gr.JSON(label="Memory Log")
141
- view_btn.click(load_memory, inputs=[mem_model], outputs=memory_output)
142
-
143
- with gr.Row():
144
- dl_btn = gr.Button("Download Memory")
145
- up_btn = gr.File(label="Upload Memory JSON")
146
- merge_btn = gr.File(label="Merge Memory JSON")
147
-
148
- dl_file = gr.File()
149
- dl_btn.click(download_memory, inputs=[mem_model], outputs=dl_file)
150
- up_btn.upload(upload_memory, inputs=[mem_model, up_btn], outputs=memory_output)
151
- merge_btn.upload(merge_memory, inputs=[mem_model, merge_btn], outputs=memory_output)
152
-
153
- clear_btn = gr.Button("Clear Memory")
154
- clear_btn.click(clear_memory, inputs=[mem_model], outputs=memory_output)
 
 
155
 
156
  demo.launch()
 
1
  import os
2
  import json
3
+ import datetime
4
  import gradio as gr
 
 
5
  from datasets import load_dataset
6
+ from transformers import (
7
+ AutoModelForCausalLM,
8
+ AutoTokenizer,
9
+ Trainer,
10
+ TrainingArguments,
11
+ DataCollatorForLanguageModeling,
12
+ )
13
+ import torch
14
+
15
+ # ==============================
16
+ # Paths & Storage Setup
17
+ # ==============================
18
+ BASE_DIR = "storage"
19
+ MODELS_DIR = os.path.join(BASE_DIR, "models")
20
+ MEMORY_DIR = os.path.join(BASE_DIR, "memory")
21
+ os.makedirs(MODELS_DIR, exist_ok=True)
22
+ os.makedirs(MEMORY_DIR, exist_ok=True)
23
 
24
+ # ==============================
25
+ # Global State
26
+ # ==============================
27
+ loaded_models = {} # cache for loaded models
28
+ chat_sessions = {} # memory per model & session
29
 
30
+ # ==============================
31
+ # Helper Functions
32
+ # ==============================
33
 
34
  def get_memory_file(model_name):
35
+ """Return path to memory file for a given model"""
36
+ return os.path.join(MEMORY_DIR, f"{model_name}_memory.json")
37
 
38
  def load_memory(model_name):
39
+ """Load chat memory from file"""
40
+ path = get_memory_file(model_name)
41
+ if os.path.exists(path):
42
+ with open(path, "r") as f:
43
  return json.load(f)
44
  return []
45
 
46
+ def save_memory(model_name, history):
47
+ """Save chat memory to file"""
48
+ path = get_memory_file(model_name)
49
+ with open(path, "w") as f:
50
+ json.dump(history, f, indent=2)
51
+
52
+ def load_model(model_name):
53
+ """Load model + tokenizer (cached if already loaded)"""
54
+ if model_name in loaded_models:
55
+ return loaded_models[model_name]
56
+
57
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
58
+ if tokenizer.pad_token is None:
59
+ tokenizer.pad_token = tokenizer.eos_token
60
+
61
+ model = AutoModelForCausalLM.from_pretrained(model_name)
62
+ model.to("cuda" if torch.cuda.is_available() else "cpu")
63
+
64
+ loaded_models[model_name] = (tokenizer, model)
65
+ return tokenizer, model
66
+
67
+ # ==============================
68
+ # Chat / Test Tab
69
+ # ==============================
70
+
71
+ def chat_with_model(model_name, user_message, session_id="default"):
72
+ if not model_name:
73
+ return "⚠️ Please select a model.", []
74
+
75
+ tokenizer, model = load_model(model_name)
76
+
77
+ # Load session memory
78
+ session_key = f"{model_name}_{session_id}"
79
+ if session_key not in chat_sessions:
80
+ chat_sessions[session_key] = load_memory(model_name)
81
+
82
+ history = chat_sessions[session_key]
83
+ history.append({"role": "user", "content": user_message})
84
+
85
+ # Prepare input for model
86
+ context = "\n".join([f"{h['role']}: {h['content']}" for h in history])
87
+ inputs = tokenizer(context, return_tensors="pt").to(model.device)
88
+
89
+ with torch.no_grad():
90
+ outputs = model.generate(
91
+ **inputs,
92
+ max_length=512,
93
+ pad_token_id=tokenizer.eos_token_id,
 
 
 
 
 
 
 
 
 
 
 
 
94
  )
95
 
96
+ response = tokenizer.decode(outputs[0], skip_special_tokens=True)
97
+ response = response[len(context):].strip()
98
+
99
+ history.append({"role": "assistant", "content": response})
100
+
101
+ # Save memory
102
+ save_memory(model_name, history)
103
+
104
+ chat_sessions[session_key] = history
105
+ display_history = [(h["content"] if h["role"]=="user" else None,
106
+ h["content"] if h["role"]=="assistant" else None) for h in history]
107
+
108
+ return response, display_history
109
+
110
+ # ==============================
111
+ # Training Tab
112
+ # ==============================
113
+
114
+ def train_model(model_name, dataset_name, epochs, output_dir):
115
+ if not model_name or not dataset_name:
116
+ return "⚠️ Please provide model & dataset."
117
+
118
+ tokenizer, model = load_model(model_name)
119
+ dataset = load_dataset(dataset_name)
120
+
121
+ def tokenize_function(examples):
122
+ return tokenizer(examples["text"], truncation=True, padding="max_length")
123
+
124
+ tokenized = dataset.map(tokenize_function, batched=True, remove_columns=["text"])
125
+
126
+ data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False)
127
+
128
+ args = TrainingArguments(
129
+ output_dir=output_dir,
130
+ overwrite_output_dir=True,
131
+ evaluation_strategy="epoch",
132
+ save_strategy="epoch",
133
+ num_train_epochs=int(epochs),
134
+ per_device_train_batch_size=2,
135
+ save_total_limit=2,
136
+ logging_dir="./logs",
137
+ logging_steps=10,
138
+ )
139
+
140
+ trainer = Trainer(
141
+ model=model,
142
+ args=args,
143
+ train_dataset=tokenized["train"],
144
+ eval_dataset=tokenized.get("test"),
145
+ data_collator=data_collator,
146
+ tokenizer=tokenizer,
147
+ )
148
+
149
+ trainer.train()
150
+ model.save_pretrained(output_dir)
151
+ tokenizer.save_pretrained(output_dir)
152
+
153
+ return f"βœ… Training finished. Model saved to {output_dir}"
154
+
155
+ # ==============================
156
+ # Guide / Manual Tab
157
+ # ==============================
158
+
159
+ BEGINNER_GUIDE = """
160
+ # Beginner Guide: My AI Model Builder
161
+
162
+ 1. **Choose a model** β†’ Select a base Hugging Face model to load.
163
+ 2. **Train / Fine-Tune** β†’ Pick a dataset and train it for X epochs.
164
+ 3. **Test / Chat** β†’ Go to the Chat tab, type prompts, and interact with your model.
165
+ 4. **Memory** β†’ Your chats are saved per model automatically.
166
+ 5. **Downloads** β†’ You can export models and memory from the Downloads tab.
167
+
168
+ That’s it! πŸš€
169
+ """
170
+
171
+ TECHNICAL_GUIDE = """
172
+ # Technical Manual: My AI Model Builder
173
+
174
+ - **Storage**: All models and memory are saved in `/storage/`.
175
+ - **Memory**: Each model has its own JSON memory file.
176
+ - **Trainer**: Uses Hugging Face `Trainer` with language modeling.
177
+ - **Customization**: You can swap base models, datasets, epochs, etc.
178
+ - **Sessions**: Each model can have multiple session IDs for separate conversations.
179
+ - **Reliability**: App checks if memory/model files exist before creating new ones.
180
+ """
181
+
182
+ # ==============================
183
+ # Build Gradio UI
184
+ # ==============================
185
+
186
  with gr.Blocks() as demo:
187
+ gr.Markdown("# πŸ› οΈ My AI Model Builder")
188
+
189
+ with gr.Tabs():
190
+ # Chat / Test Tab
191
+ with gr.Tab("πŸ’¬ Chat / Test"):
192
+ model_name = gr.Textbox(label="Model Name", placeholder="e.g. gpt2")
193
+ session_id = gr.Textbox(label="Session ID (optional)", value="default")
194
+ chatbot = gr.Chatbot()
195
+ msg = gr.Textbox(label="Your message")
196
+ send = gr.Button("Send")
197
+
198
+ send.click(
199
+ fn=chat_with_model,
200
+ inputs=[model_name, msg, session_id],
201
+ outputs=[msg, chatbot],
202
+ )
203
+
204
+ # Training Tab
205
+ with gr.Tab("πŸ“š Training / Fine-Tuning"):
206
+ base_model = gr.Textbox(label="Base Model", placeholder="e.g. gpt2")
207
+ dataset_name = gr.Textbox(label="Dataset (HF Hub)", placeholder="e.g. wikitext")
208
+ epochs = gr.Number(label="Epochs", value=1)
209
+ output_dir = gr.Textbox(label="Output Dir", value="./storage/models/new_model")
210
+ train_btn = gr.Button("Start Training")
211
+ train_output = gr.Textbox(label="Training Log")
212
+
213
+ train_btn.click(
214
+ fn=train_model,
215
+ inputs=[base_model, dataset_name, epochs, output_dir],
216
+ outputs=train_output,
217
+ )
218
+
219
+ # Guide Tab
220
+ with gr.Tab("πŸ“– Guide / Manual"):
221
+ gr.Markdown("## Beginner Walkthrough")
222
+ gr.Markdown(BEGINNER_GUIDE)
223
+ gr.Markdown("## Technical Reference")
224
+ gr.Markdown(TECHNICAL_GUIDE)
225
 
226
  demo.launch()