|
import gradio as gr |
|
from huggingface_hub import InferenceClient |
|
import PyPDF2 |
|
from PIL import Image |
|
import cv2 |
|
import numpy as np |
|
from pydub import AudioSegment |
|
from langdetect import detect |
|
from rembg import remove |
|
import torch |
|
import torchvision |
|
from torchvision.models.detection import fasterrcnn_resnet50_fpn |
|
from torchvision.transforms import functional as F |
|
import tempfile |
|
from diffusers import DiffusionPipeline |
|
import random |
|
import time |
|
|
|
|
|
client = InferenceClient("HuggingFaceH4/zephyr-7b-beta") |
|
|
|
|
|
model = fasterrcnn_resnet50_fpn(pretrained=True) |
|
model.eval() |
|
|
|
|
|
device = "cuda" if torch.cuda.is_available() else "cpu" |
|
model_repo_id = "stabilityai/sdxl-turbo" |
|
|
|
if torch.cuda.is_available(): |
|
torch_dtype = torch.float16 |
|
else: |
|
torch_dtype = torch.float32 |
|
|
|
pipe = DiffusionPipeline.from_pretrained(model_repo_id, torch_dtype=torch_dtype) |
|
pipe = pipe.to(device) |
|
|
|
MAX_SEED = np.iinfo(np.int32).max |
|
MAX_IMAGE_SIZE = 1024 |
|
|
|
|
|
def generate_with_diffusion( |
|
prompt, |
|
negative_prompt="", |
|
seed=0, |
|
randomize_seed=True, |
|
width=1024, |
|
height=1024, |
|
guidance_scale=0.0, |
|
num_inference_steps=2, |
|
progress=gr.Progress(), |
|
): |
|
if randomize_seed: |
|
seed = random.randint(0, MAX_SEED) |
|
|
|
generator = torch.Generator().manual_seed(seed) |
|
|
|
|
|
for i in range(20, 0, -1): |
|
progress((20 - i) / 20, desc=f"Генерация начнется через {i} секунд...") |
|
time.sleep(20) |
|
|
|
|
|
progress(1.0, desc="Генерация изображения...") |
|
image = pipe( |
|
prompt=prompt, |
|
negative_prompt=negative_prompt, |
|
guidance_scale=guidance_scale, |
|
num_inference_steps=num_inference_steps, |
|
width=width, |
|
height=height, |
|
generator=generator, |
|
).images[0] |
|
|
|
return image, seed |
|
|
|
|
|
def process_pdf(file): |
|
pdf_reader = PyPDF2.PdfReader(file) |
|
text = "" |
|
for page in pdf_reader.pages: |
|
text += page.extract_text() |
|
return text |
|
|
|
|
|
def process_image(file): |
|
image = Image.open(file) |
|
return f"Изображение: {image.size[0]}x{image.size[1]} пикселей, формат: {image.format}" |
|
|
|
|
|
def process_video(file): |
|
cap = cv2.VideoCapture(file.name) |
|
frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) |
|
duration = frame_count / cap.get(cv2.CAP_PROP_FPS) |
|
cap.release() |
|
return f"Видео: длительность {duration:.2f} секунд, {frame_count} кадров" |
|
|
|
|
|
def process_audio(file): |
|
audio = AudioSegment.from_file(file) |
|
return f"Аудио: длительность {len(audio) / 1000:.2f} секунд, частота {audio.frame_rate} Гц" |
|
|
|
|
|
def process_txt(file): |
|
with open(file.name, "r", encoding="utf-8") as f: |
|
text = f.read() |
|
return text |
|
|
|
|
|
def remove_background(image): |
|
if image is None: |
|
return None |
|
output = remove(image) |
|
return output |
|
|
|
|
|
def count_objects(image): |
|
if image is None: |
|
return "Изображение не загружено." |
|
|
|
|
|
img = Image.open(image.name).convert("RGB") |
|
img_tensor = F.to_tensor(img).unsqueeze(0) |
|
|
|
|
|
with torch.no_grad(): |
|
predictions = model(img_tensor) |
|
|
|
|
|
num_objects = len(predictions[0]['labels']) |
|
return f"Количество объектов на изображении: {num_objects}" |
|
|
|
|
|
def convert_image(image, target_format): |
|
if image is None: |
|
return None |
|
img = Image.open(image.name) |
|
|
|
|
|
with tempfile.NamedTemporaryFile(delete=False, suffix=f".{target_format.lower()}") as tmp_file: |
|
img.save(tmp_file, format=target_format) |
|
return tmp_file.name |
|
|
|
|
|
def detect_language(text): |
|
try: |
|
return detect(text) |
|
except: |
|
return "en" |
|
|
|
|
|
def respond( |
|
message, |
|
history: list[tuple[str, str]], |
|
system_message, |
|
max_tokens, |
|
temperature, |
|
top_p, |
|
file=None, |
|
): |
|
|
|
if file is not None: |
|
file_type = file.name.split(".")[-1].lower() |
|
if file_type == "pdf": |
|
file_info = process_pdf(file) |
|
elif file_type in ["jpg", "jpeg", "png", "bmp", "gif"]: |
|
file_info = process_image(file) |
|
elif file_type in ["mp4", "avi", "mov"]: |
|
file_info = process_video(file) |
|
elif file_type in ["mp3", "wav", "ogg"]: |
|
file_info = process_audio(file) |
|
elif file_type == "txt": |
|
file_info = process_txt(file) |
|
else: |
|
file_info = "Неизвестный тип файла" |
|
message += f"\n[Пользователь загрузил файл: {file.name}]\n{file_info}" |
|
|
|
|
|
language = detect_language(message) |
|
|
|
|
|
if language == "ru": |
|
system_message = "Вы дружелюбный чат-бот, который понимает русский язык." |
|
else: |
|
system_message = "You are a friendly chatbot." |
|
|
|
|
|
messages = [{"role": "system", "content": system_message}] |
|
|
|
|
|
for val in history: |
|
if val[0]: |
|
messages.append({"role": "user", "content": val[0]}) |
|
if val[1]: |
|
messages.append({"role": "assistant", "content": val[1]}) |
|
|
|
|
|
messages.append({"role": "user", "content": message}) |
|
|
|
|
|
response = "" |
|
for message in client.chat_completion( |
|
messages, |
|
max_tokens=max_tokens, |
|
stream=True, |
|
temperature=temperature, |
|
top_p=top_p, |
|
): |
|
token = message.choices[0].delta.content |
|
response += token |
|
yield response |
|
|
|
|
|
def reset_chat(): |
|
return [] |
|
|
|
|
|
def analyze_txt(file): |
|
if file is None: |
|
return "Файл не загружен." |
|
text = process_txt(file) |
|
return f"Содержимое файла:\n{text}" |
|
|
|
|
|
with gr.Blocks() as demo: |
|
|
|
gr.HTML(""" |
|
<div style="text-align: center;"> |
|
<img src="https://huggingface.co/spaces/Felguk/Felguk-v0/resolve/main/hd_crop_4c480c6a2c7e176289b0dfcb64a30603_67753ddec8355.png" alt="Felguk Logo" style="width: 300px;"> |
|
</div> |
|
""") |
|
|
|
gr.Markdown("Чат-бот Felguk v0. Отвечает на том же языке, на котором вы написали. Задавайте вопросы и загружайте файлы (PDF, изображения, видео, аудио, txt)!") |
|
|
|
|
|
with gr.Row(): |
|
new_chat_button = gr.Button("Новый чат", variant="secondary") |
|
|
|
|
|
with gr.Tab("Felguk Tools"): |
|
|
|
with gr.Tab("Анализатор текста"): |
|
gr.Markdown("## Анализатор текста") |
|
txt_file = gr.File(label="Загрузите txt файл", file_types=[".txt"]) |
|
txt_output = gr.Textbox(label="Содержимое файла", interactive=False) |
|
analyze_button = gr.Button("Анализировать") |
|
analyze_button.click(fn=analyze_txt, inputs=txt_file, outputs=txt_output) |
|
|
|
|
|
with gr.Tab("Удаление фона"): |
|
gr.Markdown("## Удаление фона с изображения") |
|
image_input = gr.Image(label="Загрузите изображение", type="pil") |
|
image_output = gr.Image(label="Результат (без фона)", type="pil") |
|
remove_bg_button = gr.Button("Удалить фон") |
|
remove_bg_button.click(fn=remove_background, inputs=image_input, outputs=image_output) |
|
|
|
|
|
with gr.Tab("Numage"): |
|
gr.Markdown("## Numage: Подсчет объектов на изображении") |
|
numage_input = gr.File(label="Загрузите изображение", file_types=["image"]) |
|
numage_output = gr.Textbox(label="Результат", interactive=False) |
|
numage_button = gr.Button("Определить количество объектов") |
|
numage_button.click(fn=count_objects, inputs=numage_input, outputs=numage_output) |
|
|
|
|
|
with gr.Tab("Конвертер изображений"): |
|
gr.Markdown("## Конвертер изображений") |
|
img_input = gr.File(label="Загрузите изображение", file_types=["image"]) |
|
img_format = gr.Dropdown( |
|
choices=["JPEG", "PNG", "BMP", "GIF", "TIFF"], |
|
label="Выберите формат для конвертации", |
|
value="JPEG" |
|
) |
|
img_output = gr.File(label="Результат конвертации") |
|
convert_button = gr.Button("Конвертировать") |
|
convert_button.click(fn=convert_image, inputs=[img_input, img_format], outputs=img_output) |
|
|
|
|
|
with gr.Tab("Felguk Diffusion"): |
|
gr.Markdown("## Felguk Diffusion: Генерация изображений из текста") |
|
with gr.Column(): |
|
prompt = gr.Textbox(label="Введите текстовое описание", placeholder="Например: Космический корабль в далекой галактике") |
|
negative_prompt = gr.Textbox(label="Нежелательное описание (опционально)", placeholder="Например: Размытое, низкое качество") |
|
with gr.Row(): |
|
seed = gr.Slider(label="Seed", minimum=0, maximum=MAX_SEED, step=1, value=0) |
|
randomize_seed = gr.Checkbox(label="Случайный seed", value=True) |
|
with gr.Row(): |
|
width = gr.Slider(label="Ширина", minimum=256, maximum=MAX_IMAGE_SIZE, step=32, value=1024) |
|
height = gr.Slider(label="Высота", minimum=256, maximum=MAX_IMAGE_SIZE, step=32, value=1024) |
|
with gr.Row(): |
|
guidance_scale = gr.Slider(label="Guidance scale", minimum=0.0, maximum=10.0, step=0.1, value=0.0) |
|
num_inference_steps = gr.Slider(label="Количество шагов", minimum=1, maximum=50, step=1, value=2) |
|
generate_button = gr.Button("Сгенерировать", variant="primary") |
|
diffusion_output = gr.Image(label="Сгенерированное изображение") |
|
generate_button.click( |
|
fn=generate_with_diffusion, |
|
inputs=[prompt, negative_prompt, seed, randomize_seed, width, height, guidance_scale, num_inference_steps], |
|
outputs=[diffusion_output, seed], |
|
) |
|
|
|
|
|
chat_interface = gr.ChatInterface( |
|
respond, |
|
additional_inputs=[ |
|
gr.Textbox(value="You are a friendly Chatbot.", label="System message"), |
|
gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"), |
|
gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"), |
|
gr.Slider( |
|
minimum=0.1, |
|
maximum=1.0, |
|
value=0.95, |
|
step=0.05, |
|
label="Top-p (nucleus sampling)", |
|
), |
|
gr.File(label="Загрузите файл (опционально)"), |
|
], |
|
) |
|
|
|
|
|
new_chat_button.click(fn=reset_chat, outputs=chat_interface.chatbot) |
|
|
|
|
|
if __name__ == "__main__": |
|
demo.launch() |