Luke-Bergen commited on
Commit
8c7307d
Β·
verified Β·
1 Parent(s): 907a91f

Create test_model.py

Browse files
Files changed (1) hide show
  1. test_model.py +285 -0
test_model.py ADDED
@@ -0,0 +1,285 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Test script for Mineral Nano 1 Vision AI
4
+ Simple chatbot interface to test your model
5
+ """
6
+
7
+ from transformers import AutoModelForCausalLM, AutoTokenizer, AutoProcessor
8
+ from PIL import Image
9
+ import torch
10
+
11
+ # ============ CONFIGURATION ============
12
+ MODEL_NAME = "Luke-Bergen/mineral-nano-1" # Your model
13
+ DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
14
+ # =======================================
15
+
16
+ def load_model():
17
+ """Load the model and tokenizer"""
18
+ print("="*60)
19
+ print("Loading Mineral Nano 1 Vision Model...")
20
+ print("="*60)
21
+
22
+ try:
23
+ print(f"\nπŸ“¦ Loading from: {MODEL_NAME}")
24
+ print(f"πŸ’» Device: {DEVICE}")
25
+
26
+ # Load tokenizer
27
+ print("\n[1/3] Loading tokenizer...")
28
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
29
+
30
+ # Load processor (for images)
31
+ print("[2/3] Loading processor...")
32
+ processor = AutoProcessor.from_pretrained(MODEL_NAME)
33
+
34
+ # Load model
35
+ print("[3/3] Loading model (this may take a minute)...")
36
+ model = AutoModelForCausalLM.from_pretrained(
37
+ MODEL_NAME,
38
+ torch_dtype=torch.bfloat16 if DEVICE == "cuda" else torch.float32,
39
+ device_map="auto" if DEVICE == "cuda" else None,
40
+ low_cpu_mem_usage=True
41
+ )
42
+
43
+ if DEVICE == "cpu":
44
+ model = model.to(DEVICE)
45
+
46
+ print("\nβœ… Model loaded successfully!")
47
+ print(f"πŸ“Š Parameters: ~2.7B")
48
+ print(f"🧠 Memory usage: ~{torch.cuda.memory_allocated() / 1e9:.2f} GB" if DEVICE == "cuda" else "")
49
+
50
+ return model, tokenizer, processor
51
+
52
+ except Exception as e:
53
+ print(f"\n❌ Error loading model: {e}")
54
+ print("\nPossible issues:")
55
+ print(" - Model still uploading to HuggingFace")
56
+ print(" - Model is private (make it public in settings)")
57
+ print(" - Not enough RAM/VRAM")
58
+ return None, None, None
59
+
60
+
61
+ def chat_text_only(model, tokenizer):
62
+ """Simple text-only chatbot"""
63
+ print("\n" + "="*60)
64
+ print("πŸ’¬ TEXT CHAT MODE")
65
+ print("="*60)
66
+ print("Type your message and press Enter")
67
+ print("Type 'exit' or 'quit' to stop")
68
+ print("Type 'clear' to reset conversation")
69
+ print("="*60 + "\n")
70
+
71
+ conversation_history = []
72
+
73
+ while True:
74
+ # Get user input
75
+ user_input = input("You: ").strip()
76
+
77
+ if user_input.lower() in ['exit', 'quit']:
78
+ print("\nπŸ‘‹ Goodbye!")
79
+ break
80
+
81
+ if user_input.lower() == 'clear':
82
+ conversation_history = []
83
+ print("\nπŸ”„ Conversation cleared!\n")
84
+ continue
85
+
86
+ if not user_input:
87
+ continue
88
+
89
+ # Add to conversation
90
+ conversation_history.append(f"User: {user_input}")
91
+
92
+ # Format prompt
93
+ prompt = "\n".join(conversation_history) + "\nAssistant:"
94
+
95
+ # Tokenize
96
+ inputs = tokenizer(prompt, return_tensors="pt").to(DEVICE)
97
+
98
+ # Generate response
99
+ print("Assistant: ", end="", flush=True)
100
+
101
+ with torch.no_grad():
102
+ outputs = model.generate(
103
+ **inputs,
104
+ max_new_tokens=150,
105
+ temperature=0.7,
106
+ top_p=0.9,
107
+ do_sample=True,
108
+ pad_token_id=tokenizer.eos_token_id
109
+ )
110
+
111
+ # Decode response
112
+ response = tokenizer.decode(outputs[0], skip_special_tokens=True)
113
+
114
+ # Extract only the new response
115
+ response = response[len(prompt):].strip()
116
+
117
+ print(response + "\n")
118
+
119
+ # Add to history
120
+ conversation_history.append(f"Assistant: {response}")
121
+
122
+ # Keep conversation history manageable
123
+ if len(conversation_history) > 10:
124
+ conversation_history = conversation_history[-10:]
125
+
126
+
127
+ def chat_with_image(model, processor):
128
+ """Chat about an image"""
129
+ print("\n" + "="*60)
130
+ print("πŸ–ΌοΈ IMAGE CHAT MODE")
131
+ print("="*60)
132
+
133
+ # Get image path
134
+ image_path = input("Enter image path (or 'back' to return): ").strip()
135
+
136
+ if image_path.lower() == 'back':
137
+ return
138
+
139
+ try:
140
+ # Load image
141
+ image = Image.open(image_path)
142
+ print(f"βœ… Image loaded: {image.size}")
143
+
144
+ print("\nAsk questions about the image (type 'back' to change image)")
145
+ print("="*60 + "\n")
146
+
147
+ while True:
148
+ question = input("You: ").strip()
149
+
150
+ if question.lower() == 'back':
151
+ break
152
+
153
+ if not question:
154
+ continue
155
+
156
+ # Format prompt with image token
157
+ prompt = f"<image>{question}"
158
+
159
+ # Process inputs
160
+ inputs = processor(text=prompt, images=image, return_tensors="pt")
161
+ inputs = {k: v.to(DEVICE) for k, v in inputs.items()}
162
+
163
+ # Generate
164
+ print("Assistant: ", end="", flush=True)
165
+
166
+ with torch.no_grad():
167
+ outputs = model.generate(
168
+ **inputs,
169
+ max_new_tokens=200,
170
+ temperature=0.7,
171
+ top_p=0.9,
172
+ do_sample=True
173
+ )
174
+
175
+ # Decode
176
+ response = processor.decode(outputs[0], skip_special_tokens=True)
177
+ print(response + "\n")
178
+
179
+ except FileNotFoundError:
180
+ print(f"❌ Image not found: {image_path}")
181
+ except Exception as e:
182
+ print(f"❌ Error: {e}")
183
+
184
+
185
+ def quick_test(model, tokenizer):
186
+ """Run a quick test to verify model works"""
187
+ print("\n" + "="*60)
188
+ print("πŸ§ͺ QUICK TEST")
189
+ print("="*60)
190
+
191
+ test_prompts = [
192
+ "Hello! What can you do?",
193
+ "What is 2+2?",
194
+ "Tell me a short joke."
195
+ ]
196
+
197
+ for prompt in test_prompts:
198
+ print(f"\nπŸ’¬ Test: {prompt}")
199
+ print("πŸ€– Response: ", end="", flush=True)
200
+
201
+ inputs = tokenizer(prompt, return_tensors="pt").to(DEVICE)
202
+
203
+ with torch.no_grad():
204
+ outputs = model.generate(
205
+ **inputs,
206
+ max_new_tokens=50,
207
+ temperature=0.7,
208
+ do_sample=True,
209
+ pad_token_id=tokenizer.eos_token_id
210
+ )
211
+
212
+ response = tokenizer.decode(outputs[0], skip_special_tokens=True)
213
+ response = response[len(prompt):].strip()
214
+ print(response)
215
+
216
+ print("\n" + "="*60)
217
+ print("βœ… Quick test completed!")
218
+ print("="*60)
219
+
220
+
221
+ def main():
222
+ """Main menu"""
223
+ print("\n")
224
+ print("╔════════════════════════════════════════════════════════╗")
225
+ print("β•‘ β•‘")
226
+ print("β•‘ MINERAL NANO 1 VISION - TEST SUITE β•‘")
227
+ print("β•‘ Mid-Range AI Model (2.7B) β•‘")
228
+ print("β•‘ β•‘")
229
+ print("β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•")
230
+
231
+ # Load model
232
+ model, tokenizer, processor = load_model()
233
+
234
+ if model is None:
235
+ print("\n❌ Failed to load model. Exiting.")
236
+ return
237
+
238
+ # Main menu loop
239
+ while True:
240
+ print("\n" + "="*60)
241
+ print("MAIN MENU")
242
+ print("="*60)
243
+ print("1. πŸ’¬ Text Chat (no images)")
244
+ print("2. πŸ–ΌοΈ Image Chat (describe images)")
245
+ print("3. πŸ§ͺ Quick Test (verify model works)")
246
+ print("4. πŸ“Š Model Info")
247
+ print("5. πŸšͺ Exit")
248
+ print("="*60)
249
+
250
+ choice = input("\nSelect option (1-5): ").strip()
251
+
252
+ if choice == "1":
253
+ chat_text_only(model, tokenizer)
254
+ elif choice == "2":
255
+ if processor is None:
256
+ print("❌ Processor not loaded. Cannot use image mode.")
257
+ else:
258
+ chat_with_image(model, processor)
259
+ elif choice == "3":
260
+ quick_test(model, tokenizer)
261
+ elif choice == "4":
262
+ print("\n" + "="*60)
263
+ print("MODEL INFORMATION")
264
+ print("="*60)
265
+ print(f"Model: {MODEL_NAME}")
266
+ print(f"Parameters: ~2.7B")
267
+ print(f"Architecture: Vision-Language Model")
268
+ print(f"Context Length: 8192 tokens")
269
+ print(f"Image Resolution: 448x448")
270
+ print(f"Device: {DEVICE}")
271
+ print("="*60)
272
+ elif choice == "5":
273
+ print("\nπŸ‘‹ Goodbye!")
274
+ break
275
+ else:
276
+ print("❌ Invalid option. Please choose 1-5.")
277
+
278
+
279
+ if __name__ == "__main__":
280
+ try:
281
+ main()
282
+ except KeyboardInterrupt:
283
+ print("\n\nπŸ‘‹ Interrupted. Goodbye!")
284
+ except Exception as e:
285
+ print(f"\n❌ Unexpected error: {e}")