VOIDER commited on
Commit
578ee8e
·
verified ·
1 Parent(s): ec1ed27

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +129 -132
app.py CHANGED
@@ -1,133 +1,130 @@
1
- import gradio as gr
2
- from llama_cpp import Llama
3
- from huggingface_hub import hf_hub_download
4
- import base64
5
- import io
6
- import re
7
-
8
- # Настройки модели
9
- REPO_ID = "mradermacher/VisualQuality-R1-7B-GGUF"
10
- # Ищем файл с квантованием Q8 (наилучшее качество для CPU)
11
- MODEL_FILENAME = "VisualQuality-R1-7B.Q8_0.gguf"
12
-
13
- # Глобальная переменная для модели
14
- llm = None
15
-
16
- def load_model():
17
- global llm
18
- if llm is None:
19
- print(f"Загрузка модели {MODEL_FILENAME}...")
20
- try:
21
- model_path = hf_hub_download(
22
- repo_id=REPO_ID,
23
- filename=MODEL_FILENAME
24
- )
25
- # n_ctx=8192 важно для обработки изображений (визуальные токены занимают место)
26
- llm = Llama(
27
- model_path=model_path,
28
- n_ctx=8192, # Контекстное окно
29
- n_gpu_layers=0, # 0 для CPU (бесплатный Space)
30
- verbose=True,
31
- chat_format="chatml-function-calling" # Обычно Qwen совместим с chatml
32
- )
33
- print("Модель успешно загружена!")
34
- except Exception as e:
35
- print(f"Ошибка загрузки: {e}")
36
- raise e
37
- return llm
38
-
39
- def image_to_base64(image):
40
- buffered = io.BytesIO()
41
- image.save(buffered, format="JPEG")
42
- return base64.b64encode(buffered.getvalue()).decode('utf-8')
43
-
44
- def evaluate_image(image, progress=gr.Progress()):
45
- if image is None:
46
- return "Пожалуйста, загрузите изображение.", ""
47
-
48
- # Инициализация модели (если еще не загружена)
49
- model = load_model()
50
-
51
- # Системный промпт из официального репозитория VisualQuality-R1
52
- system_prompt = "You are doing the image quality assessment task."
53
-
54
- # Формируем сообщение пользователя по шаблону авторов
55
- # Модель обучена выдавать <answer>score</answer>
56
- user_prompt_text = (
57
- "What is your overall rating on the quality of this picture? "
58
- "The rating should be a float between 1 and 5, rounded to two decimal places, "
59
- "with 1 representing very poor quality and 5 representing excellent quality. "
60
- "Please only output the final answer with only one score in <answer> </answer> tags."
61
- )
62
-
63
- # Конвертация изображения для Llama-cpp
64
- base64_image = image_to_base64(image)
65
- image_url = f"data:image/jpeg;base64,{base64_image}"
66
-
67
- messages = [
68
- {"role": "system", "content": system_prompt},
69
- {
70
- "role": "user",
71
- "content": [
72
- {"type": "image_url", "image_url": {"url": image_url}},
73
- {"type": "text", "text": user_prompt_text}
74
- ]
75
- }
76
- ]
77
-
78
- # Стриминг генерации
79
- full_response = ""
80
- print("Начало генерации...")
81
-
82
- stream = model.create_chat_completion(
83
- messages=messages,
84
- max_tokens=1024,
85
- temperature=0.6, # Немного вариативности для рассуждений
86
- stream=True
87
- )
88
-
89
- for chunk in stream:
90
- if "choices" in chunk:
91
- delta = chunk["choices"][0]["delta"]
92
- if "content" in delta and delta["content"]:
93
- content = delta["content"]
94
- full_response += content
95
- # Возвращаем накопленный текст для стриминга в UI
96
- yield full_response, "Вычисляется..."
97
-
98
- # Парсинг итоговой оценки
99
- # Ищем текст внутри тегов <answer>...</answer>
100
- score_match = re.search(r'<answer>\s*([\d\.]+)\s*</answer>', full_response)
101
- final_score = "Не найдено"
102
-
103
- if score_match:
104
- final_score = score_match.group(1)
105
-
106
- yield full_response, final_score
107
-
108
- # Интерфейс Gradio
109
- with gr.Blocks(title="VisualQuality-R1 (Q8 GGUF)") as demo:
110
- gr.Markdown("# 👁️ VisualQuality-R1 (7B Q8)")
111
- gr.Markdown(
112
- "Оценка качества изображений с использованием рассуждений (Chain of Thought). "
113
- "Запущено на CPU (бесплатный Space), поэтому генерация может занять время."
114
- )
115
-
116
- with gr.Row():
117
- with gr.Column():
118
- input_img = gr.Image(type="pil", label="Загрузите изображение")
119
- run_btn = gr.Button("Оценить качество", variant="primary")
120
-
121
- with gr.Column():
122
- output_score = gr.Label(label="Итоговая оценка (для лидерборда)")
123
- output_text = gr.Textbox(label="Ход мыслей (CoT) и полный ответ", lines=15, show_copy_button=True)
124
-
125
- run_btn.click(
126
- fn=evaluate_image,
127
- inputs=[input_img],
128
- outputs=[output_text, output_score]
129
- )
130
-
131
- # Запуск при старте контейнера, чтобы модель скачалась сразу
132
- if __name__ == "__main__":
133
  demo.queue().launch()
 
1
+ import os
2
+ import sys
3
+ import subprocess
4
+
5
+ # --- ХАК ДЛЯ УСТАНОВКИ LLAMA-CPP-PYTHON ---
6
+ # Устанавливаем библиотеку при запуске, чтобы избежать компиляции во время сборки Space
7
+ try:
8
+ import llama_cpp
9
+ print("llama-cpp-python уже установлен.")
10
+ except ImportError:
11
+ print("Установка llama-cpp-python из пресобранного wheel (CPU)...")
12
+ # Используем pre-built wheel для Linux x86_64 (избегаем компиляции)
13
+ subprocess.check_call([
14
+ sys.executable, "-m", "pip", "install",
15
+ "llama-cpp-python",
16
+ "--extra-index-url", "https://abetlen.github.io/llama-cpp-python/whl/cpu"
17
+ ])
18
+ print("Установка завершена!")
19
+ import llama_cpp
20
+ # ------------------------------------------
21
+
22
+ import gradio as gr
23
+ from llama_cpp import Llama
24
+ from huggingface_hub import hf_hub_download
25
+ import base64
26
+ import io
27
+ import re
28
+
29
+ # Настройки модели
30
+ REPO_ID = "mradermacher/VisualQuality-R1-7B-GGUF"
31
+ MODEL_FILENAME = "VisualQuality-R1-7B.Q8_0.gguf"
32
+
33
+ llm = None
34
+
35
+ def load_model():
36
+ global llm
37
+ if llm is None:
38
+ print(f"Загрузка модели {MODEL_FILENAME}...")
39
+ try:
40
+ model_path = hf_hub_download(
41
+ repo_id=REPO_ID,
42
+ filename=MODEL_FILENAME
43
+ )
44
+ llm = Llama(
45
+ model_path=model_path,
46
+ n_ctx=8192,
47
+ n_gpu_layers=0,
48
+ verbose=True,
49
+ chat_format="chatml-function-calling"
50
+ )
51
+ print("Модель успешно загружена!")
52
+ except Exception as e:
53
+ print(f"Ошибка загрузки: {e}")
54
+ raise e
55
+ return llm
56
+
57
+ def image_to_base64(image):
58
+ buffered = io.BytesIO()
59
+ image.save(buffered, format="JPEG")
60
+ return base64.b64encode(buffered.getvalue()).decode('utf-8')
61
+
62
+ def evaluate_image(image, progress=gr.Progress()):
63
+ if image is None:
64
+ return "Пожалуйста, загрузите изображение.", ""
65
+
66
+ # Ленивая загрузка модели при первом запросе
67
+ model = load_model()
68
+
69
+ system_prompt = "You are doing the image quality assessment task."
70
+ user_prompt_text = (
71
+ "What is your overall rating on the quality of this picture? "
72
+ "The rating should be a float between 1 and 5, rounded to two decimal places, "
73
+ "with 1 representing very poor quality and 5 representing excellent quality. "
74
+ "Please only output the final answer with only one score in <answer> </answer> tags."
75
+ )
76
+
77
+ base64_image = image_to_base64(image)
78
+ image_url = f"data:image/jpeg;base64,{base64_image}"
79
+
80
+ messages = [
81
+ {"role": "system", "content": system_prompt},
82
+ {
83
+ "role": "user",
84
+ "content": [
85
+ {"type": "image_url", "image_url": {"url": image_url}},
86
+ {"type": "text", "text": user_prompt_text}
87
+ ]
88
+ }
89
+ ]
90
+
91
+ full_response = ""
92
+ print("Начало генерации...")
93
+
94
+ stream = model.create_chat_completion(
95
+ messages=messages,
96
+ max_tokens=1024,
97
+ temperature=0.6,
98
+ stream=True
99
+ )
100
+
101
+ for chunk in stream:
102
+ if "choices" in chunk:
103
+ delta = chunk["choices"][0]["delta"]
104
+ if "content" in delta and delta["content"]:
105
+ content = delta["content"]
106
+ full_response += content
107
+ yield full_response, "Вычисляется..."
108
+
109
+ score_match = re.search(r'<answer>\s*([\d\.]+)\s*</answer>', full_response)
110
+ final_score = score_match.group(1) if score_match else "Не найдено"
111
+
112
+ yield full_response, final_score
113
+
114
+ with gr.Blocks(title="VisualQuality-R1 (Q8 GGUF)") as demo:
115
+ gr.Markdown("# 👁️ VisualQuality-R1 (7B Q8)")
116
+ gr.Markdown("Оценка качества изображений (Chain of Thought). Работает на CPU.")
117
+
118
+ with gr.Row():
119
+ with gr.Column():
120
+ input_img = gr.Image(type="pil", label="Загрузите изображение")
121
+ run_btn = gr.Button("Оценить качество", variant="primary")
122
+
123
+ with gr.Column():
124
+ output_score = gr.Label(label="Итоговая оценка")
125
+ output_text = gr.Textbox(label="Ход мыслей (CoT)", lines=15, show_copy_button=True)
126
+
127
+ run_btn.click(evaluate_image, inputs=[input_img], outputs=[output_text, output_score])
128
+
129
+ if __name__ == "__main__":
 
 
 
130
  demo.queue().launch()