Download app.py from Ivans23/gpt-5.3: direct link, hf CLI and curl.
- Browser
- Download file 3.99 kB
-
https://huggingface.co/spaces/Ivans23/gpt-5.3/resolve/main/app.py
- Command line
-
hf download hf://spaces/Ivans23/gpt-5.3/app.py
-
curl -L -o app.py https://huggingface.co/spaces/Ivans23/gpt-5.3/resolve/main/app.py
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) | |
| 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() | |