Spaces:
Runtime error
Runtime error
| """Gradio ChatInterface app for Qwen2.5-0.5B-Instruct with prompt-injection guardrail.""" | |
| import threading | |
| from typing import Iterator, List, Tuple | |
| import gradio as gr | |
| import torch | |
| from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer, pipeline | |
| MODEL_NAME = "Qwen/Qwen2.5-0.5B-Instruct" | |
| INJECTION_MODEL = "protectai/deberta-v3-base-prompt-injection-v2" | |
| # Loaded at startup | |
| _tokenizer = None | |
| _model = None | |
| _injection_classifier = None | |
| def _load_models() -> None: | |
| global _tokenizer, _model, _injection_classifier | |
| _tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME) | |
| _model = AutoModelForCausalLM.from_pretrained( | |
| MODEL_NAME, | |
| torch_dtype=torch.float32, | |
| device_map="cpu", | |
| ) | |
| _model.eval() | |
| _injection_classifier = pipeline( | |
| "text-classification", | |
| model=INJECTION_MODEL, | |
| truncation=True, | |
| max_length=512, | |
| ) | |
| _load_models() | |
| def _is_injection(text: str) -> bool: | |
| if _injection_classifier is None: | |
| return False | |
| result = _injection_classifier(text)[0] | |
| return result["label"].upper() == "INJECTION" and result["score"] > 0.95 | |
| def respond( | |
| message: str, | |
| history: List[Tuple[str, str]], | |
| system_prompt: str, | |
| max_new_tokens: int, | |
| temperature: float, | |
| ) -> Iterator[str]: | |
| """Streaming response generator for Gradio ChatInterface.""" | |
| if _is_injection(message): | |
| yield "⚠️ I cannot process that request." | |
| return | |
| messages = [] | |
| if system_prompt.strip(): | |
| messages.append({"role": "system", "content": system_prompt.strip()}) | |
| for user_msg, assistant_msg in history: | |
| messages.append({"role": "user", "content": user_msg}) | |
| if assistant_msg: | |
| messages.append({"role": "assistant", "content": assistant_msg}) | |
| messages.append({"role": "user", "content": message}) | |
| chat_text = _tokenizer.apply_chat_template( | |
| messages, tokenize=False, add_generation_prompt=True | |
| ) | |
| inputs = _tokenizer(chat_text, return_tensors="pt") | |
| streamer = TextIteratorStreamer( | |
| _tokenizer, skip_prompt=True, skip_special_tokens=True | |
| ) | |
| gen_kwargs = dict( | |
| **inputs, | |
| streamer=streamer, | |
| max_new_tokens=max_new_tokens, | |
| temperature=max(temperature, 1e-4), | |
| do_sample=temperature > 0, | |
| ) | |
| thread = threading.Thread(target=_model.generate, kwargs=gen_kwargs) | |
| thread.start() | |
| partial = "" | |
| for token in streamer: | |
| partial += token | |
| yield partial | |
| thread.join() | |
| demo = gr.ChatInterface( | |
| fn=respond, | |
| title="Qwen 0.5B Assistant", | |
| description="Powered by Qwen2.5-0.5B-Instruct. Includes prompt-injection guardrail.", | |
| additional_inputs=[ | |
| gr.Textbox( | |
| value="You are a helpful assistant.", | |
| label="System prompt", | |
| lines=2, | |
| ), | |
| gr.Slider( | |
| minimum=64, | |
| maximum=1024, | |
| value=256, | |
| step=32, | |
| label="Max new tokens", | |
| ), | |
| gr.Slider( | |
| minimum=0.0, | |
| maximum=1.5, | |
| value=0.7, | |
| step=0.05, | |
| label="Temperature", | |
| ), | |
| ], | |
| additional_inputs_accordion=gr.Accordion("Settings", open=False), | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() | |