gpt-5.3 / app.py
Ivans23's picture
Upload 3 files
2858647 verified
Raw History Blame Contribute Delete
3.99 kB
import spaces
import gradio as gr
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
# The original WhiteRabbitNeo/WhiteRabbitNeo-V3-7B repository redirects here.
MODEL_ID = "DeepHat/DeepHat-V1-7B"
SYSTEM_PROMPT = (
"You are DeepHat, a helpful assistant specializing in cybersecurity, "
"programming, and DevOps. Answer in the user's language. "
"Be precise, explain assumptions, and acknowledge uncertainty."
)
MAX_INPUT_TOKENS = 4096
tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
# ZeroGPU requires CUDA placement at module scope, outside the GPU function.
model = AutoModelForCausalLM.from_pretrained(
MODEL_ID,
torch_dtype=torch.bfloat16,
device_map="cuda",
low_cpu_mem_usage=True,
attn_implementation="sdpa",
).eval()
def text_content(content):
if isinstance(content, str):
return content
if isinstance(content, list):
return "\n".join(
item.get("text", "")
for item in content
if isinstance(item, dict) and item.get("type") == "text"
)
return ""
def prepare_inputs(message, history):
if not message.strip():
raise gr.Error("Введите сообщение.")
recent = []
for item in (history or [])[-12:]:
if item.get("role") in ("user", "assistant"):
content = text_content(item.get("content", ""))
if content:
recent.append({"role": item["role"], "content": content})
while recent and recent[0]["role"] != "user":
recent.pop(0)
while True:
messages = (
[{"role": "system", "content": SYSTEM_PROMPT}]
+ recent
+ [{"role": "user", "content": message}]
)
prompt = tokenizer.apply_chat_template(
messages, tokenize=False, add_generation_prompt=True
)
inputs = tokenizer(prompt, return_tensors="pt", add_special_tokens=False)
if inputs.input_ids.shape[1] <= MAX_INPUT_TOKENS:
return inputs
if not recent:
raise gr.Error("Сообщение слишком длинное. Сократите его и попробуйте ещё раз.")
recent.pop(0)
while recent and recent[0]["role"] != "user":
recent.pop(0)
@spaces.GPU(duration=60)
def generate(inputs, max_tokens):
inputs = inputs.to("cuda")
with torch.inference_mode():
output = model.generate(
**inputs,
max_new_tokens=int(max_tokens),
do_sample=True,
temperature=0.6,
top_p=0.9,
repetition_penalty=1.05,
pad_token_id=tokenizer.eos_token_id,
)
return tokenizer.decode(
output[0, inputs.input_ids.shape[1]:], skip_special_tokens=True
).strip()
def respond(message, history, max_tokens):
return generate(prepare_inputs(message, history), max_tokens)
demo = gr.ChatInterface(
fn=respond,
type="messages",
title="WhiteRabbitNeo / DeepHat 7B",
description=(
"Помощник по кибербезопасности, программированию и DevOps. "
"Ответ появится после завершения генерации. "
"ZeroGPU работает с очередью и дневной квотой. "
"Длинная история сокращается до последних сообщений."
),
additional_inputs=[
gr.Slider(64, 512, value=256, step=64, label="Максимальная длина ответа в токенах")
],
examples=[
["Объясни разницу между XSS и CSRF и способы защиты.", 256],
["Помоги составить план проверки безопасности моего веб-приложения.", 256],
],
cache_examples=False,
concurrency_limit=1,
)
if __name__ == "__main__":
demo.queue(max_size=8).launch()