チャットボットととりとめのない会話を楽しむゲーム。
モデルサイズが小さいのでCPUで十分動作します。(しかしながら遅い。)
modelはQwen/Qwen2.5-0.5B-Instructです。
import http.server
import socketserver
import webbrowser
import os
import json
from transformers import GPT2LMHeadModel, GPT2Tokenizer
# モデルとトークナイザーの読み込み
from transformers import AutoTokenizer, AutoModelForCausalLM
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-0.5B-Instruct", use_fast=False)
tokenizer.do_lower_case = True # due to some bug of tokenizer config loading
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-0.5B-Instruct")
# テキスト生成関数
def generate_text(prompt, max_length=150, num_return_sequences=1):
inputs = tokenizer.encode(prompt, return_tensors='pt')
outputs = model.generate(
inputs,
max_length=max_length,
num_return_sequences=num_return_sequences,
no_repeat_ngram_size=2,
top_k=50,
top_p=0.95,
temperature=0.7
)
return [tokenizer.decode(output, skip_special_tokens=True) for output in outputs]
# HTMLコンテンツの生成
html_content = '''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chat with GPT-Qwen2.5-0.5B-Instruct</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
}
.container {
width: 80%;
margin: auto;
overflow: hidden;
}
header {
background: blue;
color: white;
padding: 10px 0;
text-align: center;
}
#chat-box {
background: white;
border: 1px solid #ddd;
padding: 10px;
margin-top: 20px;
max-height: 400px;
overflow-y: auto;
}
#chat-input {
width: 100%;
padding: 10px;
margin-top: 10px;
box-sizing: border-box;
}
button {
padding: 10px;
background: blue;
color: white;
border: none;
cursor: pointer;
margin-top: 10px;
}
</style>
</head>
<body>
<header>
<h1>Chat with GPT-Qwen2.5-0.5B-Instruct</h1>
</header>
<div class="container">
<div id="chat-box"></div>
<input type="text" id="chat-input" placeholder="Type your message here...">
<button onclick="sendMessage()">Send</button>
</div>
<script>
async function sendMessage() {
const inputElement = document.getElementById('chat-input');
const chatBox = document.getElementById('chat-box');
const prompt = inputElement.value;
if (prompt.trim() === '') return;
// Display user's prompt
const userMessage = document.createElement('div');
userMessage.innerHTML = `<strong>You:</strong> ${prompt}`;
chatBox.appendChild(userMessage);
// Send prompt to server and get generated text
const response = await fetch('http://localhost:8000', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ prompt: prompt })
});
const data = await response.json();
const generatedText = data.generated_text;
// Display GPT-2's response
const botMessage = document.createElement('div');
botMessage.innerHTML = `<strong>Qwen GPT-:</strong> ${generatedText}`;
chatBox.appendChild(botMessage);
// Clear the input
inputElement.value = '';
chatBox.scrollTop = chatBox.scrollHeight;
}
</script>
</body>
</html>
'''
# HTTPサーバーの設定
PORT = 8000
DIRECTORY = os.getcwd()
class Handler(http.server.SimpleHTTPRequestHandler):
def do_POST(self):
content_length = int(self.headers['Content-Length'])
post_data = self.rfile.read(content_length)
data = json.loads(post_data.decode('utf-8'))
prompt = data['prompt']
generated_text = generate_text(prompt, max_length=150, num_return_sequences=1)[0]
response = {
'generated_text': generated_text
}
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.send_header('Access-Control-Allow-Origin', '*')
self.end_headers()
self.wfile.write(json.dumps(response).encode('utf-8'))
def end_headers(self):
self.send_header('Access-Control-Allow-Origin', '*')
super().end_headers()
def start_server():
# HTMLファイルを一時的に生成
html_file = 'chat.html'
with open(html_file, 'w', encoding='utf-8') as file:
file.write(html_content)
os.chdir(DIRECTORY)
with socketserver.TCPServer(("", PORT), Handler) as httpd:
print(f"Serving at http://localhost:{PORT}")
webbrowser.open(f'http://localhost:{PORT}/{html_file}')
httpd.serve_forever()
if __name__ == "__main__":
start_server()
「本記事は、技術的な視点から情報を提供することを目的としております。内容については可能な限り正確性を期しておりますが、記事内の見解は執筆者の意見や理解に基づいており、すべての方にとって普遍的な結論を示すものではありません。技術の分野は常に進化し、新たな知見が追加されることもあります。ご意見がある場合には、建設的な対話を歓迎いたしますが、批判的な意見を展開する際も、お互いの尊重を大切にしたコミュニケーションを心がけていただけると幸いです。」