nguyentantoan commited on
Commit
a7f24f5
·
verified ·
1 Parent(s): 5f21563

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +184 -49
app.py CHANGED
@@ -1,3 +1,4 @@
 
1
  import gradio as gr
2
  import torch
3
  from transformers import AutoModel, AutoTokenizer
@@ -7,6 +8,7 @@ from PIL import Image
7
  import base64
8
  import io
9
  import time
 
10
 
11
  # Setup
12
  device = "cpu" # HF Spaces miễn phí chỉ có CPU
@@ -14,18 +16,33 @@ model = None
14
  tokenizer = None
15
  transform = None
16
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  def load_model():
 
18
  global model, tokenizer, transform
19
  try:
20
  print("🤖 Loading Vintern-1B-v3.5...")
21
 
22
  model_name = "5CD-AI/Vintern-1B-v3_5"
23
 
 
24
  tokenizer = AutoTokenizer.from_pretrained(
25
  model_name,
26
  trust_remote_code=True
27
  )
28
 
 
29
  model = AutoModel.from_pretrained(
30
  model_name,
31
  torch_dtype=torch.float32,
@@ -33,60 +50,100 @@ def load_model():
33
  low_cpu_mem_usage=True
34
  )
35
 
36
- # Image transform
37
- IMAGENET_MEAN = (0.485, 0.456, 0.406)
38
- IMAGENET_STD = (0.229, 0.224, 0.225)
39
-
40
- transform = T.Compose([
41
- T.Lambda(lambda img: img.convert('RGB') if img.mode != 'RGB' else img),
42
- T.Resize((448, 448), interpolation=InterpolationMode.BICUBIC),
43
- T.ToTensor(),
44
- T.Normalize(mean=IMAGENET_MEAN, std=IMAGENET_STD)
45
- ])
46
 
47
  print("✅ Model loaded successfully!")
48
  return True
49
 
50
  except Exception as e:
51
  print(f"❌ Error loading model: {e}")
 
52
  return False
53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  def analyze_image(image):
 
55
  if model is None:
56
  return "❌ Model chưa được tải. Vui lòng chờ..."
57
 
58
  try:
59
  start_time = time.time()
60
 
61
- # Preprocess image
62
- if isinstance(image, str):
63
- # Base64 image
64
- if image.startswith('data:image'):
65
- image = image.split(',')[1]
66
- image_bytes = base64.b64decode(image)
67
- image = Image.open(io.BytesIO(image_bytes)).convert('RGB')
68
 
69
- image_tensor = transform(image).unsqueeze(0).to(device)
 
70
 
71
  with torch.no_grad():
 
72
  query = "Mô tả chi tiết những gì bạn thấy trong hình ảnh này:"
73
 
74
- description = model.chat(
75
- tokenizer,
76
- image_tensor,
77
- query,
78
- generation_config=dict(
79
- max_new_tokens=200,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  do_sample=True,
81
- temperature=0.7,
82
- top_p=0.9,
83
- repetition_penalty=1.1
84
  )
85
- )
 
86
 
87
  # Get objects
88
  try:
89
- object_query = "Liệt kê các đối tượng chính:"
90
  objects_text = model.chat(
91
  tokenizer,
92
  image_tensor,
@@ -100,8 +157,8 @@ def analyze_image(image):
100
 
101
  processing_time = time.time() - start_time
102
 
103
- return f"""
104
- **📝 Mô tả từ Vintern AI:**
105
  {description}
106
 
107
  **🔍 Đối tượng nhận diện:**
@@ -109,46 +166,124 @@ def analyze_image(image):
109
 
110
  **⚡ Thời gian xử lý:** {processing_time:.2f}s
111
  **🤖 Model:** Vintern-1B-v3.5 (Hugging Face Spaces)
 
 
 
 
112
  """
113
 
114
  except Exception as e:
115
- return f"❌ Lỗi phân tích: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
 
116
 
117
- # Load model khi khởi động
118
  print("🚀 Initializing Vintern-1B-v3.5...")
119
  model_loaded = load_model()
120
 
121
- # Gradio interface
122
- with gr.Blocks(title="Vintern-1B-v3.5 Video Recognition") as demo:
123
- gr.Markdown("# 🎥 Vintern-1B-v3.5 - Nhận Diện Ảnh Tiếng Việt")
124
- gr.Markdown("Upload ảnh để nhận diện nội dung bằng AI Vintern-1B-v3.5")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
 
126
  if not model_loaded:
127
- gr.Markdown("⚠️ **Model đang được tải...** Vui lòng chờ vài phút.")
 
 
128
 
129
  with gr.Row():
130
- with gr.Column():
131
- image_input = gr.Image(type="pil", label="📤 Upload Ảnh")
132
- analyze_btn = gr.Button("🔍 Phân Tích", variant="primary")
 
 
 
 
 
 
 
133
 
134
- with gr.Column():
135
- result_output = gr.Textbox(label="📋 Kết Quả", lines=10, max_lines=15)
 
 
 
 
 
136
 
 
137
  analyze_btn.click(
138
  fn=analyze_image,
139
  inputs=image_input,
140
  outputs=result_output
141
  )
142
 
 
 
 
 
 
 
 
 
 
 
 
 
143
  gr.Markdown("""
144
  ---
145
- **💡 Hướng dẫn:**
146
- 1. Upload ảnh từ máy tính hoặc webcam
147
- 2. Nhấn "Phân Tích" để nhận diện
148
- 3. Xem kết quả tả tiếng Việt
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
 
150
- **🔗 API Endpoint:** Sử dụng URL của Space này trong trangchu.html
151
  """)
152
 
 
153
  if __name__ == "__main__":
154
- demo.launch(server_name="0.0.0.0", server_port=7860)
 
 
 
 
 
 
1
+ # app.py - Fixed version for HF Spaces
2
  import gradio as gr
3
  import torch
4
  from transformers import AutoModel, AutoTokenizer
 
8
  import base64
9
  import io
10
  import time
11
+ import traceback
12
 
13
  # Setup
14
  device = "cpu" # HF Spaces miễn phí chỉ có CPU
 
16
  tokenizer = None
17
  transform = None
18
 
19
+ def build_transform(input_size=448):
20
+ """Build image transform pipeline"""
21
+ IMAGENET_MEAN = (0.485, 0.456, 0.406)
22
+ IMAGENET_STD = (0.229, 0.224, 0.225)
23
+
24
+ return T.Compose([
25
+ T.Lambda(lambda img: img.convert('RGB') if hasattr(img, 'mode') and img.mode != 'RGB' else img),
26
+ T.Resize((input_size, input_size), interpolation=InterpolationMode.BICUBIC),
27
+ T.ToTensor(),
28
+ T.Normalize(mean=IMAGENET_MEAN, std=IMAGENET_STD)
29
+ ])
30
+
31
  def load_model():
32
+ """Load Vintern model"""
33
  global model, tokenizer, transform
34
  try:
35
  print("🤖 Loading Vintern-1B-v3.5...")
36
 
37
  model_name = "5CD-AI/Vintern-1B-v3_5"
38
 
39
+ # Load tokenizer
40
  tokenizer = AutoTokenizer.from_pretrained(
41
  model_name,
42
  trust_remote_code=True
43
  )
44
 
45
+ # Load model
46
  model = AutoModel.from_pretrained(
47
  model_name,
48
  torch_dtype=torch.float32,
 
50
  low_cpu_mem_usage=True
51
  )
52
 
53
+ # Build transform
54
+ transform = build_transform()
 
 
 
 
 
 
 
 
55
 
56
  print("✅ Model loaded successfully!")
57
  return True
58
 
59
  except Exception as e:
60
  print(f"❌ Error loading model: {e}")
61
+ traceback.print_exc()
62
  return False
63
 
64
+ def safe_image_processing(image):
65
+ """Safely process image input"""
66
+ try:
67
+ # Handle different input types
68
+ if image is None:
69
+ return None, "❌ Không có ảnh đầu vào"
70
+
71
+ # If it's a file path (string)
72
+ if isinstance(image, str):
73
+ if image.startswith('data:image'):
74
+ # Base64 image
75
+ image_data = image.split(',')[1]
76
+ image_bytes = base64.b64decode(image_data)
77
+ image = Image.open(io.BytesIO(image_bytes))
78
+ else:
79
+ # File path
80
+ image = Image.open(image)
81
+
82
+ # Ensure it's a PIL Image
83
+ if not hasattr(image, 'mode'):
84
+ return None, "❌ Định dạng ảnh không hợp lệ"
85
+
86
+ # Convert to RGB if needed
87
+ if image.mode != 'RGB':
88
+ image = image.convert('RGB')
89
+
90
+ return image, None
91
+
92
+ except Exception as e:
93
+ return None, f"❌ Lỗi xử lý ảnh: {str(e)}"
94
+
95
  def analyze_image(image):
96
+ """Analyze image with Vintern model"""
97
  if model is None:
98
  return "❌ Model chưa được tải. Vui lòng chờ..."
99
 
100
  try:
101
  start_time = time.time()
102
 
103
+ # Safe image processing
104
+ processed_image, error = safe_image_processing(image)
105
+ if error:
106
+ return error
107
+
108
+ if processed_image is None:
109
+ return "❌ Không thể xử lý ảnh đầu vào"
110
 
111
+ # Transform image
112
+ image_tensor = transform(processed_image).unsqueeze(0).to(device)
113
 
114
  with torch.no_grad():
115
+ # Main description
116
  query = "Mô tả chi tiết những gì bạn thấy trong hình ảnh này:"
117
 
118
+ try:
119
+ description = model.chat(
120
+ tokenizer,
121
+ image_tensor,
122
+ query,
123
+ generation_config=dict(
124
+ max_new_tokens=200,
125
+ do_sample=True,
126
+ temperature=0.7,
127
+ top_p=0.9,
128
+ repetition_penalty=1.1
129
+ )
130
+ )
131
+ except Exception as chat_error:
132
+ print(f"Chat method failed: {chat_error}")
133
+ # Fallback to simple generation
134
+ inputs = tokenizer(query, return_tensors="pt").to(device)
135
+ outputs = model.generate(
136
+ **inputs,
137
+ max_new_tokens=150,
138
  do_sample=True,
139
+ temperature=0.7
 
 
140
  )
141
+ description = tokenizer.decode(outputs[0], skip_special_tokens=True)
142
+ description = description.replace(query, "").strip()
143
 
144
  # Get objects
145
  try:
146
+ object_query = "Liệt kê các đối tượng chính trong ảnh:"
147
  objects_text = model.chat(
148
  tokenizer,
149
  image_tensor,
 
157
 
158
  processing_time = time.time() - start_time
159
 
160
+ # Format output
161
+ return f"""**📝 Mô tả từ Vintern AI:**
162
  {description}
163
 
164
  **🔍 Đối tượng nhận diện:**
 
166
 
167
  **⚡ Thời gian xử lý:** {processing_time:.2f}s
168
  **🤖 Model:** Vintern-1B-v3.5 (Hugging Face Spaces)
169
+ **💻 Device:** {device.upper()}
170
+
171
+ ---
172
+ *Để sử dụng cho video real-time, hãy sử dụng API endpoint của Space này với trangchu.html*
173
  """
174
 
175
  except Exception as e:
176
+ error_msg = f"❌ Lỗi phân tích: {str(e)}"
177
+ print(error_msg)
178
+ traceback.print_exc()
179
+ return error_msg
180
+
181
+ def analyze_for_api(image_file):
182
+ """API-friendly analysis function"""
183
+ try:
184
+ result = analyze_image(image_file)
185
+ # Return simple text for API consumption
186
+ return result
187
+ except Exception as e:
188
+ return f"Error: {str(e)}"
189
 
190
+ # Load model when starting
191
  print("🚀 Initializing Vintern-1B-v3.5...")
192
  model_loaded = load_model()
193
 
194
+ # Create Gradio interface
195
+ with gr.Blocks(
196
+ title="Vintern-1B-v3.5 Video Recognition",
197
+ theme=gr.themes.Soft(),
198
+ css="""
199
+ .gradio-container {
200
+ max-width: 1200px !important;
201
+ }
202
+ .upload-area {
203
+ min-height: 300px;
204
+ }
205
+ """
206
+ ) as demo:
207
+
208
+ gr.Markdown("""
209
+ # 🎥 Vintern-1B-v3.5 - Nhận Diện Ảnh Tiếng Việt
210
+
211
+ **Powered by Hugging Face Spaces** | Model chạy hoàn toàn trên cloud
212
+ """)
213
 
214
  if not model_loaded:
215
+ gr.Markdown("⚠️ **Model đang được tải...** Vui lòng chờ vài phút và refresh trang.")
216
+ else:
217
+ gr.Markdown("✅ **Model đã sẵn sàng!** Upload ảnh để bắt đầu nhận diện.")
218
 
219
  with gr.Row():
220
+ with gr.Column(scale=1):
221
+ image_input = gr.Image(
222
+ type="pil",
223
+ label="📤 Upload Ảnh",
224
+ elem_classes=["upload-area"]
225
+ )
226
+
227
+ with gr.Row():
228
+ analyze_btn = gr.Button("🔍 Phân Tích", variant="primary", scale=2)
229
+ clear_btn = gr.Button("🗑️ Xóa", variant="secondary", scale=1)
230
 
231
+ with gr.Column(scale=1):
232
+ result_output = gr.Textbox(
233
+ label="📋 Kết Quả Phân Tích",
234
+ lines=15,
235
+ max_lines=20,
236
+ show_copy_button=True
237
+ )
238
 
239
+ # Event handlers
240
  analyze_btn.click(
241
  fn=analyze_image,
242
  inputs=image_input,
243
  outputs=result_output
244
  )
245
 
246
+ clear_btn.click(
247
+ fn=lambda: (None, ""),
248
+ outputs=[image_input, result_output]
249
+ )
250
+
251
+ # Auto-analyze on image upload
252
+ image_input.change(
253
+ fn=analyze_image,
254
+ inputs=image_input,
255
+ outputs=result_output
256
+ )
257
+
258
  gr.Markdown("""
259
  ---
260
+ ## 💡 Hướng dẫn sử dụng:
261
+
262
+ ### 🖼️ Phân tích ảnh đơn lẻ:
263
+ 1. **Upload ảnh** từ máy tính hoặc drag & drop
264
+ 2. **Kết quả tự động** hiển thị sau khi upload
265
+ 3. **Hoặc nhấn "Phân Tích"** để chạy lại
266
+
267
+ ### 🎥 Phân tích video real-time:
268
+ 1. **Copy URL Space này:** `https://nguyentantoan-vintern-video-recognition.hf.space`
269
+ 2. **Mở trangchu.html** đã được cung cấp
270
+ 3. **Thay URL** trong code JavaScript
271
+ 4. **Sử dụng camera** để phân tích real-time
272
+
273
+ ### 🔗 API Usage:
274
+ ```javascript
275
+ // POST to: https://nguyentantoan-vintern-video-recognition.hf.space/api/predict
276
+ // Body: FormData with image file
277
+ ```
278
 
279
+ **⚠️ Lưu ý:** Việc phân tích thể mất 10-30 giây do chạy trên CPU miễn phí của HF Spaces.
280
  """)
281
 
282
+ # Launch the app
283
  if __name__ == "__main__":
284
+ demo.launch(
285
+ server_name="0.0.0.0",
286
+ server_port=7860,
287
+ show_error=True,
288
+ quiet=False
289
+ )