Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
@@ -1,78 +1,117 @@
|
|
1 |
-
from transformers import AutoTokenizer, AutoModelForCausalLM
|
2 |
-
import torch
|
3 |
-
import os
|
4 |
import gradio as gr
|
5 |
-
import
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
DESCRIPTION = """
|
14 |
-
# 👋🏻Welcome to 🙋🏻♂️Tonic's🧑🏻🚀YI-200K🚀
|
15 |
-
You can use this Space to test out the current model [01-ai/Yi-6B-200k](https://huggingface.co/01-ai/Yi-6B-200k) "🦙Llamified" version based on [01-ai/Yi-34B](https://huggingface.co/01-ai/Yi-34B) or try the [OAI-style connector](https://huggingface.co/spaces/Tonic/EasyYI) that we use for [AGYintelligence](https://huggingface.co/spaces/Tonic/AGYIntelligence).
|
16 |
-
You can also use 🧑🏻🚀YI-200K🚀 by cloning this space. 🧬🔬🔍 Simply click here: <a style="display:inline-block" href="https://huggingface.co/spaces/Tonic1/YiTonic?duplicate=true"><img src="https://img.shields.io/badge/-Duplicate%20Space-blue?labelColor=white&style=flat&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAP5JREFUOE+lk7FqAkEURY+ltunEgFXS2sZGIbXfEPdLlnxJyDdYB62sbbUKpLbVNhyYFzbrrA74YJlh9r079973psed0cvUD4A+4HoCjsA85X0Dfn/RBLBgBDxnQPfAEJgBY+A9gALA4tcbamSzS4xq4FOQAJgCDwV2CPKV8tZAJcAjMMkUe1vX+U+SMhfAJEHasQIWmXNN3abzDwHUrgcRGmYcgKe0bxrblHEB4E/pndMazNpSZGcsZdBlYJcEL9Afo75molJyM2FxmPgmgPqlWNLGfwZGG6UiyEvLzHYDmoPkDDiNm9JR9uboiONcBXrpY1qmgs21x1QwyZcpvxt9NS09PlsPAAAAAElFTkSuQmCC&logoWidth=14" alt="Duplicate Space"></a></h3>
|
17 |
-
Join us : 🌟TeamTonic🌟 is always making cool demos! Join our active builder's🛠️community on 👻Discord: [Discord](https://discord.gg/nXx5wbX9) On 🤗Huggingface: [TeamTonic](https://huggingface.co/TeamTonic) & [MultiTransformer](https://huggingface.co/MultiTransformer) On 🌐Github: [Polytonic](https://github.com/tonic-ai) & contribute to 🌟 [PolyGPT](https://github.com/tonic-ai/polygpt-alpha)
|
18 |
-
"""
|
19 |
-
|
20 |
-
tokenizer = AutoTokenizer.from_pretrained(model_id, device_map="auto", trust_remote_code=True)
|
21 |
-
# tokenizer = YiTokenizer.from_pretrained(tokenizer_path)
|
22 |
-
model = AutoModelForCausalLM.from_pretrained(model_id, device_map="auto", torch_dtype=torch.bfloat16, trust_remote_code=True)
|
23 |
-
tokenizer.eos_token_id = eos_token_id
|
24 |
-
model.config.eos_token_id = eos_token_id
|
25 |
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
29 |
|
30 |
-
|
31 |
-
|
|
|
32 |
|
33 |
-
|
34 |
-
|
35 |
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
pad_token_id=tokenizer.eos_token_id,
|
44 |
-
do_sample=do_sample
|
45 |
-
)
|
46 |
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
response = response.split(truncate_str)[0]
|
51 |
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
|
59 |
-
|
60 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
|
62 |
-
|
63 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
71 |
|
72 |
-
|
73 |
-
fn=
|
74 |
-
inputs=[
|
75 |
-
outputs=chatbot
|
76 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
|
78 |
-
|
|
|
|
|
|
|
|
|
|
1 |
import gradio as gr
|
2 |
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
3 |
+
from transformers.generation import GenerationConfig
|
4 |
+
import re
|
5 |
+
import copy
|
6 |
+
from pathlib import Path
|
7 |
+
import secrets
|
8 |
+
import torch
|
9 |
+
from PIL import Image, ImageDraw
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
+
model_name = "qwen/Qwen-VL-Chat"
|
12 |
+
tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
|
13 |
+
model = AutoModelForCausalLM.from_pretrained(model_name, trust_remote_code=True).eval()
|
14 |
+
model.generation_config = GenerationConfig.from_pretrained(model_name, trust_remote_code=True)
|
15 |
|
16 |
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
17 |
+
model.to(device)
|
18 |
+
task_history = []
|
19 |
|
20 |
+
BOX_TAG_PATTERN = r"<box>([\s\S]*?)</box>"
|
21 |
+
PUNCTUATION = "!?。"#$%&'()*+,-/:;<=>@[\]^_`{|}~⦅⦆「」、、〃》「」『』​``【oaicite:0】``​〔〕〖〗〘〙〚〛〜〝〞〟〰〾〿–—‘’‛“”„‟…‧﹏."
|
22 |
|
23 |
+
def save_image(image_file, upload_dir: str) -> str:
|
24 |
+
Path(upload_dir).mkdir(parents=True, exist_ok=True)
|
25 |
+
filename = secrets.token_hex(10) + Path(image_file.name).suffix
|
26 |
+
file_path = Path(upload_dir) / filename
|
27 |
+
with open(image_file, "rb") as f_input, open(file_path, "wb") as f_output:
|
28 |
+
f_output.write(f_input.read())
|
29 |
+
return str(file_path)
|
|
|
|
|
|
|
30 |
|
31 |
+
def clean_response(response: str) -> str:
|
32 |
+
response = re.sub(r'<ref>(.*?)</ref>(?:<box>.*?</box>)*(?:<quad>.*?</quad>)*', r'\1', response).strip()
|
33 |
+
return response
|
|
|
34 |
|
35 |
+
def chat_with_model(image_path=None, text_query=None, history=None):
|
36 |
+
# Modify this function to use 'history' if your model requires it
|
37 |
+
query_elements = []
|
38 |
+
if image_path:
|
39 |
+
query_elements.append({'image': image_path})
|
40 |
+
if text_query:
|
41 |
+
query_elements.append({'text': text_query})
|
42 |
+
# Add history processing here if needed
|
43 |
+
query = tokenizer.from_list_format(query_elements)
|
44 |
+
tokenized_inputs = tokenizer(query, return_tensors='pt').to(device)
|
45 |
+
output = model.generate(**tokenized_inputs)
|
46 |
+
response = tokenizer.decode(output[0], skip_special_tokens=True)
|
47 |
+
cleaned_response = clean_response(response)
|
48 |
+
return cleaned_response
|
49 |
+
def draw_boxes(image_path, response):
|
50 |
+
image = Image.open(image_path)
|
51 |
+
draw = ImageDraw.Draw(image)
|
52 |
+
boxes = re.findall(r'<box>\((\d+),(\d+)\),\((\d+),(\d+)\)</box>', response)
|
53 |
+
for box in boxes:
|
54 |
+
x1, y1, x2, y2 = map(int, box)
|
55 |
+
draw.rectangle([x1, y1, x2, y2], outline="red", width=3)
|
56 |
+
return image
|
57 |
|
58 |
+
def process_input(text=None, file=None, task_history=None):
|
59 |
+
if task_history is None:
|
60 |
+
task_history = []
|
61 |
+
image_path = None
|
62 |
+
if file is not None:
|
63 |
+
image_path = save_image(file, "uploaded_images")
|
64 |
+
response = chat_with_model(image_path=image_path, text_query=text, history=task_history)
|
65 |
+
task_history.append((text, response))
|
66 |
|
67 |
+
if "<box>" in response:
|
68 |
+
if image_path:
|
69 |
+
image_with_boxes = draw_boxes(image_path, response)
|
70 |
+
image_with_boxes_path = image_path.replace(".jpg", "_boxed.jpg")
|
71 |
+
image_with_boxes.save(image_with_boxes_path)
|
72 |
+
return [("bot", response), "image", image_with_boxes_path], task_history
|
73 |
+
else:
|
74 |
+
return [("bot", response), "text", None], task_history
|
75 |
+
else:
|
76 |
+
# Clean the response if it contains any box-like annotations
|
77 |
+
clean_response = re.sub(r'<ref>(.*?)</ref>(?:<box>.*?</box>)*(?:<quad>.*?</quad>)*', r'\1', response).strip()
|
78 |
+
return [("bot", clean_response)], task_history
|
79 |
|
80 |
+
# Define Gradio interface
|
81 |
+
with gr.Blocks() as demo:
|
82 |
+
gr.Markdown("""
|
83 |
+
# 🙋🏻♂️欢迎来到🌟Tonic 的🦆Qwen-VL-Chat🤩Bot!🚀
|
84 |
+
# 🙋🏻♂️Welcome toTonic's Qwen-VL-Chat Bot!
|
85 |
+
该WebUI基于Qwen-VL-Chat,实现聊天机器人功能。 但我必须解决它的很多问题,也许我也能获得一些荣誉。
|
86 |
+
Qwen-VL-Chat 是一种多模式输入模型。 您可以使用此空间来测试当前模型 [qwen/Qwen-VL-Chat](https://huggingface.co/qwen/Qwen-VL-Chat) 您也可以使用 🧑🏻🚀qwen/Qwen-VL -通过克隆这个空间来聊天🚀。 🧬🔬🔍 只需点击这里:[重复空间](https://huggingface.co/spaces/Tonic1/VLChat?duplicate=true)
|
87 |
+
加入我们:🌟TeamTonic🌟总是在制作很酷的演示! 在 👻Discord 上加入我们活跃的构建者🛠️社区:[Discord](https://discord.gg/nXx5wbX9) 在 🤗Huggingface 上:[TeamTonic](https://huggingface.co/TeamTonic) 和 [MultiTransformer](https:/ /huggingface.co/MultiTransformer) 在 🌐Github 上:[Polytonic](https://github.com/tonic-ai) 并为 🌟 [PolyGPT](https://github.com/tonic-ai/polygpt-alpha) 做出贡献 )
|
88 |
+
This WebUI is based on Qwen-VL-Chat, implementing chatbot functionalities. Qwen-VL-Chat is a multimodal input model. You can use this Space to test out the current model [qwen/Qwen-VL-Chat](https://huggingface.co/qwen/Qwen-VL-Chat) You can also use qwen/Qwen-VL-Chat🚀 by cloning this space. Simply click here: [Duplicate Space](https://huggingface.co/spaces/Tonic1/VLChat?duplicate=true)
|
89 |
+
Join us: TeamTonic is always making cool demos! Join our active builder's community on Discord: [Discord](https://discord.gg/nXx5wbX9) On Huggingface: [TeamTonic](https://huggingface.co/TeamTonic) & [MultiTransformer](https://huggingface.co/MultiTransformer) On Github: [Polytonic](https://github.com/tonic-ai) & contribute to [PolyGPT](https://github.com/tonic-ai/polygpt-alpha)
|
90 |
+
""")
|
91 |
+
with gr.Row():
|
92 |
+
with gr.Column(scale=1):
|
93 |
+
chatbot = gr.Chatbot(label='Qwen-VL-Chat')
|
94 |
+
with gr.Column(scale=1):
|
95 |
+
with gr.Row():
|
96 |
+
query = gr.Textbox(lines=2, label='Input', placeholder="Type your message here...")
|
97 |
+
file_upload = gr.File(label="Upload Image")
|
98 |
+
submit_btn = gr.Button("Submit")
|
99 |
+
|
100 |
+
task_history = gr.State([])
|
101 |
|
102 |
+
submit_btn.click(
|
103 |
+
fn=process_input,
|
104 |
+
inputs=[query, file_upload, task_history],
|
105 |
+
outputs=[chatbot, task_history]
|
106 |
)
|
107 |
+
|
108 |
+
gr.Markdown("""
|
109 |
+
注意:此演示受 Qwen-VL 原始许可证的约束。我们强烈建议用户不要故意生成或允许他人故意生成有害内容,
|
110 |
+
包括仇恨言论、暴力、色情、欺骗等。(注:本演示受Qwen-VL许可协议约束,强烈建议用户不要传播或允许他人传播以下内容,包括但不限于仇恨言论、暴力、色情、欺诈相关的有害信息 .)
|
111 |
+
Note: This demo is governed by the original license of Qwen-VL. We strongly advise users not to knowingly generate or allow others to knowingly generate harmful content,
|
112 |
+
including hate speech, violence, pornography, deception, etc. (Note: This demo is subject to the license agreement of Qwen-VL. We strongly advise users not to disseminate or allow others to disseminate the following content, including but not limited to hate speech, violence, pornography, and fraud-related harmful information.)
|
113 |
+
""")
|
114 |
+
demo.queue().launch()
|
115 |
|
116 |
+
if __name__ == "__main__":
|
117 |
+
demo.launch()
|