adilkh26 commited on
Commit
80fa1bb
·
verified ·
1 Parent(s): 77ff68b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +68 -28
app.py CHANGED
@@ -5,8 +5,11 @@ from threading import Thread
5
  import time
6
  import torch
7
  import spaces
 
 
 
8
 
9
- MODEL_ID = "Qwen/Qwen2.5-VL-7B-Instruct" #else ; MODEL_ID = "Qwen/Qwen2.5-VL-3B-Instruct"
10
  processor = AutoProcessor.from_pretrained(MODEL_ID, trust_remote_code=True)
11
  model = Qwen2_5_VLForConditionalGeneration.from_pretrained(
12
  MODEL_ID,
@@ -14,28 +17,65 @@ model = Qwen2_5_VLForConditionalGeneration.from_pretrained(
14
  torch_dtype=torch.bfloat16
15
  ).to("cuda").eval()
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  @spaces.GPU
18
  def model_inference(input_dict, history):
19
  text = input_dict["text"]
20
  files = input_dict["files"]
21
 
22
- # Load images if provided
23
- if len(files) > 1:
24
- images = [load_image(image) for image in files]
25
- elif len(files) == 1:
26
- images = [load_image(files[0])]
27
- else:
28
- images = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
- # Validate input
31
  if text == "" and not images:
32
- gr.Error("Please input a query and optionally image(s).")
33
  return
34
  if text == "" and images:
35
- gr.Error("Please input a text query along with the image(s).")
36
  return
37
 
38
- # Prepare messages for the model
39
  messages = [
40
  {
41
  "role": "user",
@@ -46,7 +86,7 @@ def model_inference(input_dict, history):
46
  }
47
  ]
48
 
49
- # Apply chat template and process inputs
50
  prompt = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
51
  inputs = processor(
52
  text=[prompt],
@@ -55,40 +95,40 @@ def model_inference(input_dict, history):
55
  padding=True,
56
  ).to("cuda")
57
 
58
- # Set up streamer for real-time output
59
  streamer = TextIteratorStreamer(processor, skip_prompt=True, skip_special_tokens=True)
60
  generation_kwargs = dict(inputs, streamer=streamer, max_new_tokens=1024)
61
 
62
- # Start generation in a separate thread
63
  thread = Thread(target=model.generate, kwargs=generation_kwargs)
64
  thread.start()
65
 
66
- # Stream the output
67
  buffer = ""
68
- yield "Thinking..."
69
  for new_text in streamer:
70
  buffer += new_text
71
  time.sleep(0.01)
72
  yield buffer
73
 
74
-
75
- # Example inputs
76
  examples = [
77
- [{"text": "Describe the document?", "files": ["example_images/document.jpg"]}],
78
- [{"text": "What does this say?", "files": ["example_images/math.jpg"]}],
79
- [{"text": "What is this UI about?", "files": ["example_images/s2w_example.png"]}],
80
- [{"text": "Where do the severe droughts happen according to this diagram?", "files": ["example_images/examples_weather_events.png"]}],
81
-
 
82
  ]
83
 
84
  demo = gr.ChatInterface(
85
  fn=model_inference,
86
- description="# **Qwen2.5-VL-7B-Instruct**",
87
  examples=examples,
88
- textbox=gr.MultimodalTextbox(label="Query Input", file_types=["image", "video"], file_count="multiple"),
89
- stop_btn="Stop Generation",
90
  multimodal=True,
91
  cache_examples=False,
92
  )
93
 
94
- demo.launch(debug=True)
 
5
  import time
6
  import torch
7
  import spaces
8
+ import cv2
9
+ from pathlib import Path
10
+ from PIL import Image
11
 
12
+ MODEL_ID = "Qwen/Qwen2.5-VL-7B-Instruct" # или "Qwen/Qwen2.5-VL-3B-Instruct"
13
  processor = AutoProcessor.from_pretrained(MODEL_ID, trust_remote_code=True)
14
  model = Qwen2_5_VLForConditionalGeneration.from_pretrained(
15
  MODEL_ID,
 
17
  torch_dtype=torch.bfloat16
18
  ).to("cuda").eval()
19
 
20
+ # Функция для извлечения нескольких кадров из видео
21
+ def extract_frames(video_path, interval=2.0):
22
+ """
23
+ Извлекает кадры из видео через каждые `interval` секунд.
24
+ """
25
+ cap = cv2.VideoCapture(video_path)
26
+ frames = []
27
+ fps = cap.get(cv2.CAP_PROP_FPS)
28
+ if fps == 0:
29
+ fps = 25 # запасное значение
30
+ frame_interval = int(fps * interval)
31
+ frame_count = 0
32
+ while True:
33
+ ret, frame = cap.read()
34
+ if not ret:
35
+ break
36
+ if frame_count % frame_interval == 0:
37
+ frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
38
+ frames.append(Image.fromarray(frame))
39
+ frame_count += 1
40
+ cap.release()
41
+ return frames
42
+
43
  @spaces.GPU
44
  def model_inference(input_dict, history):
45
  text = input_dict["text"]
46
  files = input_dict["files"]
47
 
48
+ images = []
49
+ video_extensions = [".mp4", ".avi", ".mov", ".mkv"]
50
+
51
+ if files:
52
+ for file in files:
53
+ ext = Path(file).suffix.lower()
54
+ if ext in video_extensions:
55
+ try:
56
+ # Извлекаем несколько кадров из видео
57
+ frames = extract_frames(file, interval=2.0)
58
+ if frames:
59
+ # Можно передать все извлечённые кадры
60
+ images.extend(frames)
61
+ else:
62
+ gr.Error("Не удалось извлечь кадры из видео.")
63
+ return
64
+ except Exception as e:
65
+ gr.Error(f"Ошибка при обработке видеофайла: {e}")
66
+ return
67
+ else:
68
+ images.append(load_image(file))
69
 
70
+ # Проверка входных данных
71
  if text == "" and not images:
72
+ gr.Error("Пожалуйста, введите запрос и, опционально, прикрепите изображение/видео.")
73
  return
74
  if text == "" and images:
75
+ gr.Error("Пожалуйста, введите текстовый запрос вместе с изображением/видео.")
76
  return
77
 
78
+ # Подготовка сообщений для модели
79
  messages = [
80
  {
81
  "role": "user",
 
86
  }
87
  ]
88
 
89
+ # Применяем шаблон чата и подготавливаем входные данные
90
  prompt = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
91
  inputs = processor(
92
  text=[prompt],
 
95
  padding=True,
96
  ).to("cuda")
97
 
98
+ # Настраиваем стриминг вывода в реальном времени
99
  streamer = TextIteratorStreamer(processor, skip_prompt=True, skip_special_tokens=True)
100
  generation_kwargs = dict(inputs, streamer=streamer, max_new_tokens=1024)
101
 
102
+ # Запускаем генерацию в отдельном потоке
103
  thread = Thread(target=model.generate, kwargs=generation_kwargs)
104
  thread.start()
105
 
106
+ # Стримим вывод
107
  buffer = ""
108
+ yield "Думаю..."
109
  for new_text in streamer:
110
  buffer += new_text
111
  time.sleep(0.01)
112
  yield buffer
113
 
114
+ # Примеры входных данных
 
115
  examples = [
116
+ [{"text": "Опиши документ?", "files": ["example_images/document.jpg"]}],
117
+ [{"text": "Что написано на изображении?", "files": ["example_images/math.jpg"]}],
118
+ [{"text": "О чем этот UI?", "files": ["example_images/s2w_example.png"]}],
119
+ [{"text": "Где происходят сильные засухи по диаграмме?", "files": ["example_images/examples_weather_events.png"]}],
120
+ # Пример с видео (убедитесь, что файл существует)
121
+ # [{"text": "Найди нужный объект в видео.", "files": ["example_videos/sample.mp4"]}],
122
  ]
123
 
124
  demo = gr.ChatInterface(
125
  fn=model_inference,
126
+ description="# **Qwen2.5-VL-7B-Instruct**\nТеперь можно анализировать и видео, извлекая несколько кадров.",
127
  examples=examples,
128
+ textbox=gr.MultimodalTextbox(label="Запрос (текст + изображение/видео)", file_types=["image", "video"], file_count="multiple"),
129
+ stop_btn="Остановить генерацию",
130
  multimodal=True,
131
  cache_examples=False,
132
  )
133
 
134
+ demo.launch(debug=True)