Spaces:
Running
Running
File size: 7,344 Bytes
1b9e6e3 fc43f27 3bdaa78 f9c30bd 1b9e6e3 3bdaa78 ea41834 3bdaa78 421af5a e972600 421af5a 2bfec82 421af5a f91d6af 8b09c72 2bfec82 421af5a dbaa4dc 421af5a 846f316 421af5a 360ff2a 072db12 96da2bc 072db12 96da2bc 1b9e6e3 e972600 3bdaa78 ff87670 3bdaa78 ff87670 3f0800d 1b9e6e3 3f0800d 08f9aa9 3bdaa78 08f9aa9 3bdaa78 08f9aa9 3bdaa78 3f0800d 3bdaa78 3f0800d 3bdaa78 1b9e6e3 3bdaa78 2bfec82 08f9aa9 b9dcc6f ff87670 3bdaa78 ff87670 ea41834 ff87670 ea41834 3bdaa78 9bc6a92 2bfec82 c2f81a6 1b9e6e3 3f0800d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
import gradio as gr
from huggingface_hub import InferenceClient
import os
# Get HF token from environment variable
HF_TOKEN = os.getenv("HF_TOKEN")
# Initialize client with proper error handling
def get_client():
if HF_TOKEN:
try:
# Try with the preferred model first
return InferenceClient("HuggingFaceH4/zephyr-7b-beta", token=HF_TOKEN)
except Exception as e:
print(f"Failed to initialize zephyr model: {e}")
# Fallback to mistral with token
try:
return InferenceClient("mistralai/Mistral-7B-Instruct-v0.1", token=HF_TOKEN)
except Exception as e2:
print(f"Failed to initialize mistral model: {e2}")
return None
else:
print("No HF_TOKEN found. Please set your Hugging Face token.")
return None
client = get_client()
# Dynamic prompt builder based on CEFR level
def level_to_prompt(level):
return {
"A1": "You are a friendly French tutor. Speak mostly in English, use simple French, and explain everything.",
"A2": "You are a patient French tutor. Use short French phrases and explain them in English.",
"B1": "You are a helpful French tutor. Speak mostly in French but clarify in English when needed.",
"B2": "You are a French tutor. Speak primarily in French with rare English support.",
"C1": "You are a native French tutor. Speak entirely in French, clearly and professionally.",
"C2": "You are a native French professor. Speak in rich, complex French. Avoid English."
}.get(level, "You are a helpful French tutor.")
# Custom background CSS
css = """
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+JP&family=Playfair+Display&display=swap');
body {
background-image: url('https://cdn-uploads.huggingface.co/production/uploads/67351c643fe51cb1aa28f2e5/wuyd5UYTh9jPrMJGmV9yC.jpeg');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.gradio-container {
display: flex;
flex-direction: column;
justify-content: center;
min-height: 100vh;
padding-top: 2rem;
padding-bottom: 2rem;
}
#chat-panel {
background-color: rgba(255, 255, 255, 0.85);
padding: 2rem;
border-radius: 12px;
max-width: 700px;
height: 70vh;
margin: auto;
box-shadow: 0 0 12px rgba(0, 0, 0, 0.3);
overflow-y: auto;
}
.gradio-container .chatbot h1 {
color: var(--custom-title-color) !important;
font-family: 'Playfair Display', serif !important;
font-size: 5rem !important;
font-weight: bold !important;
text-align: center !important;
margin-bottom: 1.5rem !important;
width: 100%;
}
"""
# Chat logic with proper error handling
def respond(message, history, level, max_tokens, temperature, top_p):
# Check if client is available
if client is None:
yield "❌ Désolé! The AI service is not available. Please check your Hugging Face token configuration."
return
system_message = level_to_prompt(level)
# Generate response
response = ""
try:
# Create a proper prompt format for instruction-following models
prompt = f"<|system|>\n{system_message}\n\n"
# Add conversation history
if history:
for turn in history:
if isinstance(turn, dict):
if turn.get("role") == "user":
prompt += f"<|user|>\n{turn['content']}\n\n"
elif turn.get("role") == "assistant":
prompt += f"<|assistant|>\n{turn['content']}\n\n"
else:
# Handle tuple format (user, assistant)
user_msg, bot_msg = turn
if user_msg:
prompt += f"<|user|>\n{user_msg}\n\n"
if bot_msg:
prompt += f"<|assistant|>\n{bot_msg}\n\n"
# Add current user message
prompt += f"<|user|>\n{message}\n\n<|assistant|>\n"
# Generate response with streaming
for token in client.text_generation(
prompt,
max_new_tokens=max_tokens,
stream=True,
temperature=temperature,
top_p=top_p,
do_sample=True,
return_full_text=False,
stop_sequences=["<|user|>", "<|system|>"] # Stop if model tries to continue conversation
):
if token: # Handle None tokens
# Clean up any unwanted tokens
token = token.replace("<|user|>", "").replace("<|system|>", "").replace("<|assistant|>", "")
if token.strip(): # Only add non-empty tokens
response += token
yield response
except Exception as e:
error_msg = str(e)
print(f"Error in chat completion: {e}")
if "401" in error_msg or "Unauthorized" in error_msg:
yield "🔑 Authentication Error: Please check your Hugging Face token. Make sure it's valid and has the correct permissions."
elif "429" in error_msg or "rate limit" in error_msg.lower():
yield "⏰ Rate limit exceeded. Please wait a moment before trying again."
elif "503" in error_msg or "Service Unavailable" in error_msg:
yield "🔧 The AI service is temporarily unavailable. Please try again later."
else:
yield f"❌ Désolé! There was an error: {error_msg}"
# UI layout
with gr.Blocks(css=css, title="French Tutor") as demo:
gr.Markdown("# 🇫🇷 French Tutor", elem_id="custom-title")
# Add status indicator
if client is None:
gr.Markdown("⚠️ **Warning**: No Hugging Face token found. Please set your HF_TOKEN environment variable.")
else:
gr.Markdown("✅ **Status**: Connected to AI service")
with gr.Column(elem_id="chat-panel"):
gr.Markdown("""
with gr.Accordion("⚙️ Advanced Settings", open=False):
level = gr.Dropdown(
choices=["A1", "A2", "B1", "B2", "C1", "C2"],
value="A1",
label="Your French Level (CEFR)",
info="Choose your current French proficiency level"
)
max_tokens = gr.Slider(
1, 2048,
value=512,
step=1,
label="Response Length",
info="Maximum number of tokens in the response"
)
temperature = gr.Slider(
0.1, 2.0,
value=0.7,
step=0.1,
label="Creativity",
info="Higher values make responses more creative"
)
top_p = gr.Slider(
0.1, 1.0,
value=0.95,
step=0.05,
label="Dynamic Text",
info="Controls text diversity"
)
gr.ChatInterface(
fn=respond,
additional_inputs=[level, max_tokens, temperature, top_p],
type="messages",
title="Chat with your French Tutor",
description="Ask questions, practice conversation, or get help with French grammar!"
)
""")
if __name__ == "__main__":
demo.launch() |