VOIDER commited on
Commit
b161f01
·
verified ·
1 Parent(s): 821cf80

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +77 -87
app.py CHANGED
@@ -3,13 +3,13 @@ import sys
3
  import subprocess
4
 
5
  # --- УСТАНОВКА LLAMA-CPP-PYTHON (Runtime) ---
 
6
  try:
7
  from llama_cpp import Llama
8
- from llama_cpp.llama_chat_format import Llava15ChatHandler
9
- print("Библиотека llama-cpp-python проверена.")
10
  except ImportError:
11
- print("Установка llama-cpp-python с поддержкой CPU...")
12
- # Устанавливаем версию с официального индекса разработчика
13
  subprocess.check_call([
14
  sys.executable, "-m", "pip", "install",
15
  "llama-cpp-python>=0.3.2",
@@ -17,6 +17,12 @@ except ImportError:
17
  ])
18
  print("Установка завершена! Импортируем...")
19
  from llama_cpp import Llama
 
 
 
 
 
 
20
 
21
  import gradio as gr
22
  from huggingface_hub import hf_hub_download
@@ -35,35 +41,36 @@ def load_model():
35
  global llm
36
  if llm is None:
37
  print(f"Загрузка модели {MODEL_FILENAME}...")
38
- try:
39
- model_path = hf_hub_download(
40
- repo_id=REPO_ID,
41
- filename=MODEL_FILENAME
42
- )
43
-
44
- # ВАЖНО: chat_format="qwen2vl" включает встроенный хендлер для картинок
45
- llm = Llama(
46
- model_path=model_path,
47
- n_ctx=12288, # 12k контекста (хватит для HD картинки)
48
- n_gpu_layers=0, # CPU
49
- verbose=True,
50
- chat_format="qwen2vl" # Явно включаем режим Qwen2-VL
51
- )
52
- print("Модель успешно загружена!")
53
- except Exception as e:
54
- print(f"Критическая ошибка загрузки: {e}")
55
- raise e
 
 
56
  return llm
57
 
58
  def process_image(image):
59
- # Ресайз слишком больших изображений для экономии памяти и контекста
60
- max_size = 1024
61
  if max(image.size) > max_size:
62
  ratio = max_size / max(image.size)
63
  new_size = (int(image.size[0] * ratio), int(image.size[1] * ratio))
64
  image = image.resize(new_size, Image.Resampling.LANCZOS)
65
 
66
- # Конвертация в Base64
67
  buffered = io.BytesIO()
68
  image = image.convert("RGB")
69
  image.save(buffered, format="JPEG", quality=90)
@@ -73,42 +80,39 @@ def evaluate_image(image, progress=gr.Progress()):
73
  if image is None:
74
  return "Пожалуйста, загрузите изображение.", ""
75
 
76
- progress(0, desc="Инициализация...")
77
  try:
 
78
  model = load_model()
79
- except Exception as e:
80
- return f"Ошибка инициализации модели: {str(e)}", "Ошибка"
81
-
82
- system_prompt = "You are doing the image quality assessment task."
83
- user_prompt_text = (
84
- "What is your overall rating on the quality of this picture? "
85
- "The rating should be a float between 1 and 5, rounded to two decimal places, "
86
- "with 1 representing very poor quality and 5 representing excellent quality. "
87
- "Please only output the final answer with only one score in <answer> </answer> tags."
88
- )
89
-
90
- progress(0.1, desc="Обработка изображения...")
91
- base64_image = process_image(image)
92
- image_url = f"data:image/jpeg;base64,{base64_image}"
93
-
94
- messages = [
95
- {"role": "system", "content": system_prompt},
96
- {
97
- "role": "user",
98
- "content": [
99
- {"type": "image_url", "image_url": {"url": image_url}},
100
- {"type": "text", "text": user_prompt_text}
101
- ]
102
- }
103
- ]
104
-
105
- full_response = ""
106
- print("Отправка запроса в модель...")
107
-
108
- try:
109
  stream = model.create_chat_completion(
110
  messages=messages,
111
- max_tokens=1500,
112
  temperature=0.6,
113
  stream=True
114
  )
@@ -120,31 +124,21 @@ def evaluate_image(image, progress=gr.Progress()):
120
  content = delta["content"]
121
  full_response += content
122
  yield full_response, "Вычисляется..."
123
-
124
- except ValueError as e:
125
- # Если формат чата не сработал
126
- err = f"Ошибка формата: {e}. Попробуйте перезагрузить Space."
127
- print(err)
128
- yield err, "Error"
129
- return
130
  except Exception as e:
131
- err = f"Внутренняя ошибка: {e}"
132
- print(err)
133
- yield err, "Error"
134
- return
135
-
136
- # Извлечение оценки
137
- score_match = re.search(r'<answer>\s*([\d\.]+)\s*</answer>', full_response)
138
- final_score = score_match.group(1) if score_match else "Не найдено"
139
-
140
- yield full_response, final_score
141
-
142
- with gr.Blocks(title="VisualQuality-R1 (Q8 GGUF)") as demo:
143
- gr.Markdown("# 👁️ VisualQuality-R1 (7B Q8)")
144
- gr.Markdown(
145
- "Оценка качества (IQA) с CoT. Работает на CPU (медленно!).\n"
146
- "Если видите ошибку 'context window', попробуйте картинку меньшего разрешения."
147
- )
148
 
149
  with gr.Row():
150
  with gr.Column():
@@ -153,13 +147,9 @@ with gr.Blocks(title="VisualQuality-R1 (Q8 GGUF)") as demo:
153
 
154
  with gr.Column():
155
  output_score = gr.Label(label="Оценка")
156
- output_text = gr.Textbox(label="Рассуждения (CoT)", lines=15)
157
 
158
- run_btn.click(
159
- fn=evaluate_image,
160
- inputs=[input_img],
161
- outputs=[output_text, output_score]
162
- )
163
 
164
  if __name__ == "__main__":
165
  demo.queue().launch()
 
3
  import subprocess
4
 
5
  # --- УСТАНОВКА LLAMA-CPP-PYTHON (Runtime) ---
6
+ # Устанавливаем версию с поддержкой Vision (CPU)
7
  try:
8
  from llama_cpp import Llama
9
+ from llama_cpp.llama_chat_format import Qwen2VLChatHandler
10
+ print("Библиотека llama-cpp-python и Qwen2VLChatHandler найдены.")
11
  except ImportError:
12
+ print("Установка свежей версии llama-cpp-python...")
 
13
  subprocess.check_call([
14
  sys.executable, "-m", "pip", "install",
15
  "llama-cpp-python>=0.3.2",
 
17
  ])
18
  print("Установка завершена! Импортируем...")
19
  from llama_cpp import Llama
20
+ # Пытаемся импортировать хендлер после установки
21
+ try:
22
+ from llama_cpp.llama_chat_format import Qwen2VLChatHandler
23
+ except ImportError:
24
+ print("ВАЖНО: Qwen2VLChatHandler не найден. Возможно, версия библиотеки старая.")
25
+ Qwen2VLChatHandler = None
26
 
27
  import gradio as gr
28
  from huggingface_hub import hf_hub_download
 
41
  global llm
42
  if llm is None:
43
  print(f"Загрузка модели {MODEL_FILENAME}...")
44
+ model_path = hf_hub_download(repo_id=REPO_ID, filename=MODEL_FILENAME)
45
+
46
+ # Настраиваем обработчик диалога СПЕЦИАЛЬНО для Qwen2-VL
47
+ # Это решает проблему "Invalid chat handler" и ошибки с токенами
48
+ chat_handler = None
49
+ if Qwen2VLChatHandler:
50
+ print("Активация режима Qwen2-VL Vision...")
51
+ # Передаем путь к модели как clip_model_path, так как в unified GGUF
52
+ # визуальный энкодер находится внутри основного файла
53
+ chat_handler = Qwen2VLChatHandler(clip_model_path=model_path)
54
+
55
+ llm = Llama(
56
+ model_path=model_path,
57
+ n_ctx=12288, # Контекст (картинки занимают много токенов)
58
+ n_gpu_layers=0, # CPU
59
+ verbose=True,
60
+ chat_handler=chat_handler, # Подключаем ручной обработчик
61
+ n_batch=512 # Размер батча для CPU
62
+ )
63
+ print("Модель успешно загружена!")
64
  return llm
65
 
66
  def process_image(image):
67
+ # Ресайз обязателен для Qwen2-VL на CPU, иначе вылетит контекст 32k+
68
+ max_size = 1024
69
  if max(image.size) > max_size:
70
  ratio = max_size / max(image.size)
71
  new_size = (int(image.size[0] * ratio), int(image.size[1] * ratio))
72
  image = image.resize(new_size, Image.Resampling.LANCZOS)
73
 
 
74
  buffered = io.BytesIO()
75
  image = image.convert("RGB")
76
  image.save(buffered, format="JPEG", quality=90)
 
80
  if image is None:
81
  return "Пожалуйста, загрузите изображение.", ""
82
 
 
83
  try:
84
+ progress(0.1, desc="Инициализация модели...")
85
  model = load_model()
86
+
87
+ progress(0.3, desc="Обработка изображения...")
88
+ base64_image = process_image(image)
89
+ image_url = f"data:image/jpeg;base64,{base64_image}"
90
+
91
+ system_prompt = "You are doing the image quality assessment task."
92
+ user_prompt_text = (
93
+ "What is your overall rating on the quality of this picture? "
94
+ "The rating should be a float between 1 and 5, rounded to two decimal places, "
95
+ "with 1 representing very poor quality and 5 representing excellent quality. "
96
+ "Please only output the final answer with only one score in <answer> </answer> tags."
97
+ )
98
+
99
+ messages = [
100
+ {"role": "system", "content": system_prompt},
101
+ {
102
+ "role": "user",
103
+ "content": [
104
+ {"type": "image_url", "image_url": {"url": image_url}},
105
+ {"type": "text", "text": user_prompt_text}
106
+ ]
107
+ }
108
+ ]
109
+
110
+ full_response = ""
111
+ print("Генерация ответа...")
112
+
 
 
 
113
  stream = model.create_chat_completion(
114
  messages=messages,
115
+ max_tokens=1024,
116
  temperature=0.6,
117
  stream=True
118
  )
 
124
  content = delta["content"]
125
  full_response += content
126
  yield full_response, "Вычисляется..."
127
+
128
+ # Парсинг оценки
129
+ score_match = re.search(r'<answer>\s*([\d\.]+)\s*</answer>', full_response)
130
+ final_score = score_match.group(1) if score_match else "Не найдено"
131
+
132
+ yield full_response, final_score
133
+
134
  except Exception as e:
135
+ error_msg = f"Ошибка: {str(e)}"
136
+ print(error_msg)
137
+ yield error_msg, "Error"
138
+
139
+ with gr.Blocks(title="VisualQuality-R1") as demo:
140
+ gr.Markdown("# 👁️ VisualQuality-R1 (Qwen2-VL)")
141
+ gr.Markdown("Оценка качества изображений. Запуск на CPU (может быть медленно).")
 
 
 
 
 
 
 
 
 
 
142
 
143
  with gr.Row():
144
  with gr.Column():
 
147
 
148
  with gr.Column():
149
  output_score = gr.Label(label="Оценка")
150
+ output_text = gr.Textbox(label="CoT (Мысли модели)", lines=15)
151
 
152
+ run_btn.click(evaluate_image, inputs=[input_img], outputs=[output_text, output_score])
 
 
 
 
153
 
154
  if __name__ == "__main__":
155
  demo.queue().launch()