VOIDER's picture
Update app.py
821cf80 verified
raw
history blame
6.15 kB
import os
import sys
import subprocess
# --- УСТАНОВКА LLAMA-CPP-PYTHON (Runtime) ---
try:
from llama_cpp import Llama
from llama_cpp.llama_chat_format import Llava15ChatHandler
print("Библиотека llama-cpp-python проверена.")
except ImportError:
print("Установка llama-cpp-python с поддержкой CPU...")
# Устанавливаем версию с официального индекса разработчика
subprocess.check_call([
sys.executable, "-m", "pip", "install",
"llama-cpp-python>=0.3.2",
"--extra-index-url", "https://abetlen.github.io/llama-cpp-python/whl/cpu"
])
print("Установка завершена! Импортируем...")
from llama_cpp import Llama
import gradio as gr
from huggingface_hub import hf_hub_download
import base64
import io
import re
from PIL import Image
# Настройки модели
REPO_ID = "mradermacher/VisualQuality-R1-7B-GGUF"
MODEL_FILENAME = "VisualQuality-R1-7B.Q8_0.gguf"
llm = None
def load_model():
global llm
if llm is None:
print(f"Загрузка модели {MODEL_FILENAME}...")
try:
model_path = hf_hub_download(
repo_id=REPO_ID,
filename=MODEL_FILENAME
)
# ВАЖНО: chat_format="qwen2vl" включает встроенный хендлер для картинок
llm = Llama(
model_path=model_path,
n_ctx=12288, # 12k контекста (хватит для HD картинки)
n_gpu_layers=0, # CPU
verbose=True,
chat_format="qwen2vl" # Явно включаем режим Qwen2-VL
)
print("Модель успешно загружена!")
except Exception as e:
print(f"Критическая ошибка загрузки: {e}")
raise e
return llm
def process_image(image):
# Ресайз слишком больших изображений для экономии памяти и контекста
max_size = 1024
if max(image.size) > max_size:
ratio = max_size / max(image.size)
new_size = (int(image.size[0] * ratio), int(image.size[1] * ratio))
image = image.resize(new_size, Image.Resampling.LANCZOS)
# Конвертация в Base64
buffered = io.BytesIO()
image = image.convert("RGB")
image.save(buffered, format="JPEG", quality=90)
return base64.b64encode(buffered.getvalue()).decode('utf-8')
def evaluate_image(image, progress=gr.Progress()):
if image is None:
return "Пожалуйста, загрузите изображение.", ""
progress(0, desc="Инициализация...")
try:
model = load_model()
except Exception as e:
return f"Ошибка инициализации модели: {str(e)}", "Ошибка"
system_prompt = "You are doing the image quality assessment task."
user_prompt_text = (
"What is your overall rating on the quality of this picture? "
"The rating should be a float between 1 and 5, rounded to two decimal places, "
"with 1 representing very poor quality and 5 representing excellent quality. "
"Please only output the final answer with only one score in <answer> </answer> tags."
)
progress(0.1, desc="Обработка изображения...")
base64_image = process_image(image)
image_url = f"data:image/jpeg;base64,{base64_image}"
messages = [
{"role": "system", "content": system_prompt},
{
"role": "user",
"content": [
{"type": "image_url", "image_url": {"url": image_url}},
{"type": "text", "text": user_prompt_text}
]
}
]
full_response = ""
print("Отправка запроса в модель...")
try:
stream = model.create_chat_completion(
messages=messages,
max_tokens=1500,
temperature=0.6,
stream=True
)
for chunk in stream:
if "choices" in chunk:
delta = chunk["choices"][0]["delta"]
if "content" in delta and delta["content"]:
content = delta["content"]
full_response += content
yield full_response, "Вычисляется..."
except ValueError as e:
# Если формат чата не сработал
err = f"Ошибка формата: {e}. Попробуйте перезагрузить Space."
print(err)
yield err, "Error"
return
except Exception as e:
err = f"Внутренняя ошибка: {e}"
print(err)
yield err, "Error"
return
# Извлечение оценки
score_match = re.search(r'<answer>\s*([\d\.]+)\s*</answer>', full_response)
final_score = score_match.group(1) if score_match else "Не найдено"
yield full_response, final_score
with gr.Blocks(title="VisualQuality-R1 (Q8 GGUF)") as demo:
gr.Markdown("# 👁️ VisualQuality-R1 (7B Q8)")
gr.Markdown(
"Оценка качества (IQA) с CoT. Работает на CPU (медленно!).\n"
"Если видите ошибку 'context window', попробуйте картинку меньшего разрешения."
)
with gr.Row():
with gr.Column():
input_img = gr.Image(type="pil", label="Изображение")
run_btn = gr.Button("Оценить", variant="primary")
with gr.Column():
output_score = gr.Label(label="Оценка")
output_text = gr.Textbox(label="Рассуждения (CoT)", lines=15)
run_btn.click(
fn=evaluate_image,
inputs=[input_img],
outputs=[output_text, output_score]
)
if __name__ == "__main__":
demo.queue().launch()