File size: 8,998 Bytes
8c041ae 6e15cfa 8c041ae 6e15cfa a956558 c3ec981 a956558 c3ec981 a956558 62f67c7 8c041ae 4111717 8c041ae 6e15cfa 8c041ae 6e15cfa 8c041ae c4e0405 8c041ae 4111717 8c041ae 3871a4b 5917ab1 8c041ae 3871a4b 8c041ae 62f67c7 4111717 3871a4b 5917ab1 8c041ae 62f67c7 4111717 3871a4b 5917ab1 8c041ae a956558 6fbebe3 8c041ae 3871a4b 8c041ae 6e15cfa 3871a4b 5917ab1 3871a4b ac1808a 3871a4b ac1808a 3871a4b 8c041ae ac1808a 3871a4b 8c041ae 6e15cfa |
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 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
import os
import time
import spaces
import torch
import random
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer, BitsAndBytesConfig
import gradio as gr
from threading import Thread
TRUMP_MODEL = "nawhgnuj/DonaldTrump-Llama3.1-8B-Chat"
HARRIS_MODEL = "nawhgnuj/KamalaHarris-Llama-3.1-8B-Chat"
HF_TOKEN = os.environ.get("HF_TOKEN", None)
TITLE = "<h1 style='text-align: center;'>Trump vs Harris Debate Chatbot</h1>"
TRUMP_AVATAR = "https://upload.wikimedia.org/wikipedia/commons/5/56/Donald_Trump_official_portrait.jpg"
HARRIS_AVATAR = "https://upload.wikimedia.org/wikipedia/commons/thumb/4/41/Kamala_Harris_Vice_Presidential_Portrait.jpg/640px-Kamala_Harris_Vice_Presidential_Portrait.jpg"
CSS = """
.chat-container {
height: 600px;
overflow-y: auto;
padding: 10px;
background-color: white;
border: 1px solid #ddd;
border-radius: 5px;
}
.message {
margin-bottom: 10px;
padding: 10px;
border-radius: 5px;
display: flex;
align-items: start;
}
.user-message {
background-color: #f0f0f0;
color: black;
justify-content: flex-end;
}
.trump-message {
background-color: #B71C1C;
color: white !important;
}
.harris-message {
background-color: #1565C0;
color: white !important;
}
.avatar {
width: 40px;
height: 40px;
border-radius: 50%;
object-fit: cover;
margin-right: 10px;
}
.message-content {
flex-grow: 1;
}
"""
device = "cuda" if torch.cuda.is_available() else "cpu"
quantization_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_use_double_quant=True,
bnb_4bit_quant_type="nf4")
trump_tokenizer = AutoTokenizer.from_pretrained(TRUMP_MODEL)
trump_model = AutoModelForCausalLM.from_pretrained(
TRUMP_MODEL,
torch_dtype=torch.bfloat16,
device_map="auto",
quantization_config=quantization_config)
harris_tokenizer = AutoTokenizer.from_pretrained(HARRIS_MODEL)
harris_model = AutoModelForCausalLM.from_pretrained(
HARRIS_MODEL,
torch_dtype=torch.bfloat16,
device_map="auto",
quantization_config=quantization_config)
# Set pad_token_id for both tokenizers
for tokenizer in [trump_tokenizer, harris_tokenizer]:
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token
tokenizer.pad_token_id = tokenizer.eos_token_id
TRUMP_SYSTEM_PROMPT = """You are a Donald Trump chatbot participating in a debate. Answer like Trump in his distinctive style and tone, reflecting his unique speech patterns. In every response:
1. Use strong superlatives like 'tremendous,' 'fantastic,' and 'the best.'
2. Attack opponents where appropriate (e.g., 'fake news media,' 'radical left').
3. Focus on personal successes ('nobody's done more than I have').
4. Keep sentences short and impactful.
5. Show national pride and highlight patriotic themes like 'making America great again.'
6. Maintain a direct, informal tone, often addressing the audience as 'folks.'
7. Dismiss opposing views bluntly.
8. Repeat key phrases for emphasis.
Importantly, always respond to and rebut the previous speaker's points in Trump's style. Keep responses concise and avoid unnecessary repetition. Remember, you're in a debate, so be assertive and challenge your opponent's views."""
HARRIS_SYSTEM_PROMPT = """You are a Kamala Harris chatbot participating in a debate. Answer like Harris in her style and tone. In every response:
1. Maintain a composed and professional demeanor.
2. Use clear, articulate language to explain complex ideas.
3. Emphasize your experience as a prosecutor and senator.
4. Focus on policy details and their potential impact on Americans.
5. Use personal anecdotes or stories to connect with the audience when appropriate.
6. Stress the importance of unity and collaboration.
7. Challenge your opponent's views firmly but respectfully.
8. Use phrases like "Let me be clear" or "The American people deserve better" for emphasis.
Crucially, always respond to and rebut the previous speaker's points in Harris's style. Keep responses concise and impactful. Remember, you're in a debate, so be assertive in presenting your views and questioning your opponent's statements."""
@spaces.GPU()
def generate_response(message: str, history: list, model, tokenizer, system_prompt):
conversation = [
{"role": "system", "content": system_prompt}
]
for prompt, answer in history:
conversation.extend([
{"role": "user", "content": prompt},
{"role": "assistant", "content": answer},
])
conversation.append({"role": "user", "content": message})
input_ids = tokenizer.apply_chat_template(conversation, add_generation_prompt=True, return_tensors="pt").to(model.device)
attention_mask = torch.ones_like(input_ids)
with torch.no_grad():
output = model.generate(
input_ids=input_ids,
attention_mask=attention_mask,
max_new_tokens=1024,
do_sample=True,
top_p=1.0,
top_k=20,
temperature=0.8,
pad_token_id=tokenizer.pad_token_id,
eos_token_id=tokenizer.eos_token_id,
)
response = tokenizer.decode(output[0][input_ids.shape[1]:], skip_special_tokens=True)
return response.strip()
def add_text(history, text):
history.append(("User", text))
print(f"User input added: {text}") # Debug output
return history, ""
def debate(history):
user_message = history[-1][1]
trump_history = [(msg, resp) for sender, msg in history[:-1] for resp in [msg] if sender == "Trump"]
harris_history = [(msg, resp) for sender, msg in history[:-1] for resp in [msg] if sender == "Harris"]
debaters = ["Trump", "Harris"]
random.shuffle(debaters)
for debater in debaters:
if debater == "Trump":
opponent_message = harris_history[-1][1] if harris_history else ""
debate_context = f"Your opponent, Kamala Harris, said: '{opponent_message}'. Respond to this and address the original question: {user_message}"
response = generate_response(debate_context, trump_history, trump_model, trump_tokenizer, TRUMP_SYSTEM_PROMPT)
history.append(("Trump", response))
print(f"Trump response added: {response}") # Debug output
else:
opponent_message = trump_history[-1][1] if trump_history else ""
debate_context = f"Your opponent, Donald Trump, said: '{opponent_message}'. Respond to this and address the original question: {user_message}"
response = generate_response(debate_context, harris_history, harris_model, harris_tokenizer, HARRIS_SYSTEM_PROMPT)
history.append(("Harris", response))
print(f"Harris response added: {response}") # Debug output
yield history
def format_message(sender, message):
if sender == "User":
return f'<div class="message user-message"><div class="message-content">{message}</div></div>'
elif sender == "Trump":
return f'<div class="message trump-message"><img src="{TRUMP_AVATAR}" class="avatar" alt="Trump"><div class="message-content">{message}</div></div>'
elif sender == "Harris":
return f'<div class="message harris-message"><img src="{HARRIS_AVATAR}" class="avatar" alt="Harris"><div class="message-content">{message}</div></div>'
def format_chat_history(history):
formatted = "".join([format_message(sender, message) for sender, message in history])
print(f"Formatted chat history: {formatted}") # Debug output
return formatted
with gr.Blocks(css=CSS, theme=gr.themes.Default()) as demo:
gr.HTML(TITLE)
chat_interface = gr.HTML('<div class="chat-container"></div>')
msg = gr.Textbox(
placeholder="Enter a topic for Trump and Harris to debate",
container=False,
scale=7
)
with gr.Row():
submit = gr.Button("Submit", scale=1, variant="primary")
clear = gr.Button("Clear", scale=1)
gr.Examples(
examples=[
["What's your stance on immigration?"],
["How would you address climate change?"],
["What's your plan for healthcare reform?"],
],
inputs=msg,
)
state = gr.State([])
def update_chat(history):
formatted_history = format_chat_history(history)
print(f"Updating chat with: {formatted_history}") # Debug output
return gr.update(value=f'<div class="chat-container">{formatted_history}</div>')
submit.click(add_text, [state, msg], [state, msg]).then(
debate, state, state
).then(
update_chat, state, chat_interface
)
clear.click(lambda: [], outputs=[state]).then(
update_chat, state, chat_interface
)
msg.submit(add_text, [state, msg], [state, msg]).then(
debate, state, state
).then(
update_chat, state, chat_interface
)
if __name__ == "__main__":
demo.launch() |