Spaces:
Build error
Build error
| #!/usr/bin/env python3 | |
| # -*- coding: utf-8 -*- | |
| """ | |
| Path: chatbot_app.py | |
| Description: Gradio-based chatbot with selectable Hugging Face LLMs, using transformers pipelines. | |
| """ | |
| import gradio as gr | |
| from transformers import pipeline, AutoTokenizer, AutoModelForCausalLM | |
| import torch | |
| import asyncio | |
| from typing import List, Tuple, Dict | |
| # β List of available premium models | |
| PREMIUM_MODELS = [ | |
| "HuggingFaceH4/zephyr-7b-beta", | |
| "K00B404/BagOClownCoders-slerp-7B", | |
| "Qwen/Qwen2.5-Omni-7B", | |
| "Qwen/Qwen2.5-VL-7B-Instruct", | |
| "deepseek-ai/Janus-Pro-7B", | |
| "meta-llama/Llama-2-7b-hf", | |
| "Alibaba-NLP/gte-Qwen2-7B-instruct", | |
| ] | |
| # β Cache for loaded pipelines | |
| pipeline_cache: Dict[str, pipeline] = {} | |
| # β Initial system prompt | |
| DEFAULT_SYSTEM_PROMPT = "You are a ChatBuddy and chat with the user in a Human way." | |
| def load_pipeline(model_name: str) -> pipeline: | |
| """ | |
| Load and cache the text generation pipeline for the given model. | |
| """ | |
| if model_name in pipeline_cache: | |
| return pipeline_cache[model_name] | |
| try: | |
| print(f"Loading model: {model_name}") | |
| tokenizer = AutoTokenizer.from_pretrained(model_name) | |
| model = AutoModelForCausalLM.from_pretrained( | |
| model_name, | |
| torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32, | |
| ) | |
| pipe = pipeline( | |
| "text-generation", | |
| model=model, | |
| tokenizer=tokenizer, | |
| device=0 if torch.cuda.is_available() else -1, | |
| ) | |
| pipeline_cache[model_name] = pipe | |
| return pipe | |
| except Exception as e: | |
| raise RuntimeError(f"Failed to load model '{model_name}': {str(e)}") | |
| def build_prompt(user_input: str, history: List[Tuple[str, str]]) -> str: | |
| """ | |
| Construct the prompt string with system prompt, history, and current user input. | |
| """ | |
| messages = [{"role": "system", "content": DEFAULT_SYSTEM_PROMPT}] | |
| for pair in history: | |
| messages.append({"role": "user", "content": pair[0]}) | |
| messages.append({"role": "assistant", "content": pair[1]}) | |
| messages.append({"role": "user", "content": user_input}) | |
| prompt = "" | |
| for msg in messages: | |
| role_tag = f"<|{msg['role']}|>" | |
| prompt += f"{role_tag} {msg['content']}\n" | |
| return prompt | |
| def extract_response(generated_text: str) -> str: | |
| """ | |
| Extract the last assistant response from generated text. | |
| """ | |
| if "<|assistant|>" in generated_text: | |
| split_res = generated_text.split("<|assistant|>") | |
| return split_res[-1].strip() | |
| return generated_text.strip() | |
| async def chatbot( | |
| user_input: str, history: List[Tuple[str, str]], model_choice: str | |
| ) -> Tuple[str, List[Tuple[str, str]]]: | |
| """ | |
| Main chatbot logic to generate model response asynchronously. | |
| """ | |
| if not user_input.strip(): | |
| return "", history # Ignore empty inputs | |
| try: | |
| pipe = await asyncio.to_thread(load_pipeline, model_choice) | |
| prompt = build_prompt(user_input, history) | |
| response = await asyncio.to_thread( | |
| pipe, | |
| prompt, | |
| max_new_tokens=200, | |
| do_sample=True, | |
| top_p=0.95, | |
| temperature=0.7, | |
| ) | |
| generated_text = response[0]["generated_text"] | |
| final_response = extract_response(generated_text) | |
| except RuntimeError as load_err: | |
| final_response = str(load_err) | |
| except Exception as e: | |
| final_response = f"β οΈ Error during generation: {str(e)}" | |
| history.append((user_input, final_response)) | |
| return "", history | |
| # β Gradio Interface | |
| with gr.Blocks() as demo: | |
| gr.Markdown("# π€ ChatBuddy - Advanced Chatbot with Selectable LLMs") | |
| with gr.Row(): | |
| model_choice = gr.Dropdown( | |
| label="Select Model", choices=PREMIUM_MODELS, value=PREMIUM_MODELS[0] | |
| ) | |
| chatbot_ui = gr.Chatbot() | |
| user_input = gr.Textbox(show_label=False, placeholder="Type your message and press Enter") | |
| clear_btn = gr.Button("Clear") | |
| state = gr.State([]) | |
| user_input.submit(chatbot, [user_input, state, model_choice], [user_input, chatbot_ui]) | |
| clear_btn.click(lambda: ([], ""), None, [chatbot_ui, state]) | |
| demo.launch() | |