4
3

小さなGPTのエンジニアリング。 Chat with GPT という日本語チャットゲーム。

Last updated at Posted at 2024-09-01

You: ショートストーリー:「未来を紡ぐコード」 東京のプログラマ、加藤拓也は、夜の東京の喧騒から少し離れた静かな部屋で、一心不乱にキーボードを叩いていた。

GPT-2: ショートストーリー:「未来を紡ぐコード」 東京のプログラマ、加藤拓也は、夜の東京の喧騒から少し離れた静かな部屋で、一心不乱にキーボードを叩いていた。加藤は「この部屋は僕の居場所だ」と呟き、部屋の隅に座り、キーボードの音に耳を澄ませた。 加藤がキーボードに手を置いた瞬間、僕は加藤の指が震え始めた。 「僕が、この世界を創ったのは君のおかげです。君が僕を、君を僕に、そして君に。」 僕と加藤、その指は互いに触れ合い、お互いに「君」の言葉を口にした。 そして、

東京のプログラマとリアルタイムのAI対話

東京の片隅に住むプログラマ、山下誠は、技術革新の最前線に立つエンジニアだ。彼は、日々の生活に追われながらも、新たなプロジェクトに取り組んでいた。彼の目標は、未来を感じることができるインターフェースを作り上げることだった。山下の手元には一つのコードがあった。これを実行することで、ブラウザでGPT-2とリアルタイムでチャットできるインターフェースが表示されるのだ。

スクリーンショット 2024-09-02 050454.png

未来をつなぐコード
山下は、Pythonのコードに目を通しながら、自分の作業が未来のコミュニケーションの一端を担うことを意識していた。このコードは、HTTPサーバーを立ち上げ、ウェブブラウザで簡単にアクセスできるインターフェースを提供する。そこに、彼のこだわりが込められていた。

「今のモデルは大きすぎる」と山下は考えた。現在使用しているGPT-4モデルは強力だが、重すぎる。彼はより効率的で、軽量なものを求めた。幸いにも、彼が使っているモデルは約400メガバイトのサイズで、CPUで十分に高速に動作する。まるで未来の技術が、今この瞬間に山下の手の中で形作られているかのようだった。

プログラム実行の瞬間
彼はついにコードを実行した。少しの緊張感と共に、サーバーが立ち上がり、ブラウザが自動的に開いた。そこには、シンプルでありながら未来的なチャットインターフェースが表示された。彼はキーボードに手を置き、テキストボックスに「未来の技術とは何か?」と入力し、送信ボタンを押した。

画面に、生成されたテキストが表示され始めた。「未来の技術は、今ここにあります。人々の想像を超えた世界が、あなたの手によって形作られています。」山下はその言葉をじっと見つめた。まるで、自分が未来の一部を作り出したかのような感覚が胸に広がった。

スクリーンショット 2024-09-02 050957.png

現実と未来の境界
山下はふと、窓の外を見た。東京の街並みが広がり、その中で彼が作り上げたインターフェースが、今この瞬間に未来とつながっているのだと感じた。彼は深く息を吸い込み、再びキーボードに手を置いた。未来との対話は、まだ始まったばかりだった。

彼の心には、新たなインスピレーションが湧き上がっていた。このインターフェースは、単なるチャットツールではない。未来を垣間見るための窓であり、人とAIが共に歩む道を示すものだ。山下は、自分の手がこの道の一部を形作っていることに誇りを感じながら、次の一手を考え始めた。

スクリーンショット 2024-09-02 050454.png

スクリーンショット 2024-09-02 050957.png

コードを実行することで、ブラウザでGPT-2とリアルタイムで日本語チャットできるインターフェースが表示されます。

今のモデルは大きすぎると思います。このコードのモデルは400メガバイトでCPUで高速に動きます。
コードをジュピタノートブックに張り付けて実行すれば自動でブラウザが起動します。

日本語チャット実行結果。

You: 彼が取り組んでいるのは、GPT(Generative Pre-trained Transformer)という言語モデルの小型版の開発だった。

GPT-2: 彼が取り組んでいるのは、gpt(generative pre-trained transformer)という言語モデルの小型版の開発だった。gptsはgpl(general general development language)の標準規格である。 gprtはgnu lesser public licenseの下で配布されている。 この規格はbsdライセンスの下でgplv2の下でライセンスされている(gprsはライセンスを放棄する)。 またgplsはフリーソフトウェア財団のライセンスで配布されており、gnu gplの下でもgpld(gnu-general-free-licence organizer)の下で公開されている。 grtのソースコードはgithubのgnuプロジェクトのページからダウンロードできる。 ただしgplt

You: 自分だけのGPTを作り上げることが、彼にとっては最高の挑戦であり、楽しみでもあった。

GPT-2: 自分だけのgptを作り上げることが、彼にとっては最高の挑戦であり、楽しみでもあった。gpuのgpgp2は、gp3の2倍もの速さで、3gpの3倍も速い。 gp1はgp4の1倍、2gpは2倍の速さである。 3gpでは、4gpと5gpが同時にgp5とgp6になる。 5gpでgp7と4がgp8になるが、これはgp9と3が1つになることを意味する。 6gp、7gpともgp10と2つに分裂する。 7gpもgp11と1つのgp12になる(gp13と7)。 8gpでもgp14と8つの3つの2つの4

You: GPTモデルは、膨大な量のテキストデータを使って学習し、人間のように自然な文章を生成できる。しかし、ケンイチが作ろうとしているのは、その縮小版であり、より効率的で特定の用途に最適化されたモデルだった。

GPT-2: gptモデルは、膨大な量のテキストデータを使って学習し、人間のように自然な文章を生成できる。しかし、ケンイチが作ろうとしているのは、その縮小版であり、より効率的で特定の用途に最適化されたモデルだった。ケンタウルス・ケンテンは、「人間はテキストを読んで、それを理解している」という仮説を立て、テキストのサイズを小さくした。 ケンケンは「テキストは読んでいる」と結論づけた。テキストが読めるのであれば、人間がテキストを読む必要がない。つまり、人間のテキストを読み取る必要がなくなる。 「テキスト」は人間の脳の記憶に残り、学習の手助けとなる。「学習」とは、脳が学習する過程である。学習は脳に蓄積された

You: モデルは、彼の提供したテキストを元に学習し、次第に彼が意図した通りに文章を生成するようになった。

GPT-2: モデルは、彼の提供したテキストを元に学習し、次第に彼が意図した通りに文章を生成するようになった。彼が作成したテキストは、彼が書いたテキストの内容を、テキストエディタで編集し直した。 テキスト編集は彼が作ったテキストを、エディターでテキストに変換し直す作業である。 彼は、この作業を「テキスト変換」と呼ぶ。 この作業はテキストの編集をより簡単にするために、編集モードを切り替えることもできる。 また、彼はテキストファイルを編集するのに、そのテキストがテキストとして保存されていることを確認している。 彼のテキストには、いくつかの異なる種類のテキストが含まれている。 例えば、"the book of things"は"think of the words of a penguin"である

You: 彼の挑戦はまだ始まったばかりであり、その先に広がる未知の可能性に胸を躍らせていた。

GPT-2: 彼の挑戦はまだ始まったばかりであり、その先に広がる未知の可能性に胸を躍らせていた。それが、今の私にとっての「夢」であり、「希望」でもある。 夢は、私を夢の世界へと導いてくれる。そして、夢を叶えるためにはどうすればいいのか。 「夢の実現」は、「夢を実現する」ことよりも、むしろ「実現する」ことが重要だ。 そして、私は、この夢実現のために、何をすべきか、どうしたらいいのかということを、常に考えている。 それは、私が、自分の夢に向き合うこと、そして夢が叶うために、どんなことをすればよいのか、ということだと思う。 その答えは「今」にある。今、目の前

ブラウザでGPT-2とリアルタイムでチャットできるインターフェースのコード。

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("rinna/japanese-gpt2-small", use_fast=False)
tokenizer.do_lower_case = True  # due to some bug of tokenizer config loading

model = AutoModelForCausalLM.from_pretrained("rinna/japanese-gpt2-small")


# テキスト生成関数
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-2</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #f4f4f4;
        }
        .container {
            width: 80%;
            margin: auto;
            overflow: hidden;
        }
        header {
            background: green;
            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: green;
            color: white;
            border: none;
            cursor: pointer;
            margin-top: 10px;
        }
    </style>
</head>
<body>
    <header>
        <h1>Chat with GPT-2</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>GPT-2:</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()

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3