SONUB
JA English 한국어 日本語 中文 हिन्दी বাংলা اردو Español Português Français Deutsch Русский العربية Bahasa Indonesia Tiếng Việt ไทย Türkçe

通知を有効にする方法

このブラウザーまたはアドレスでは通知を利用できません。対応ブラウザーで安全な接続のSONUBサイトを開いてください。

通知がブロックされている場合は、ブラウザーの設定で許可してください。

  1. アドレスバー横のサイト設定、またはブラウザーのサイト設定を開き、このサイトの通知を許可に変更してください。
  2. 端末の設定でブラウザーの通知を許可し、おやすみモードや集中モードを確認してください。
  3. SONUBに戻ってページを再読み込みしてください。通知が有効になるとベルは表示されなくなります。

iPhoneやiPadではSONUBをホーム画面に追加し、そこから開いて通知を許可してください。

ログイン ログアウト 表示テーマ 標準テーマ ダークテーマ ピンクテーマ チャット 1:1 チャット グループチャット 掲示板 お知らせ ニュース掲示板 ご意見掲示板 自己紹介 メインメニュー

さあ、あなただけの人工知能を作ってみましょう。

自分の会話を作り、全体の流れを完成させます。xchat.py で質問を送り、自分のとさせたに答えさせましょう。

単語のブロックが一列に並び、最後に空きマスがある。その上に高さのちがう棒がついた候補ブロックが3つあり、そのうち1つが選ばれて列の最後につながり、矢印が最初に戻ってまた次を選ぶ。
9

XChat

は入力画面、は実行サービス、はです。は質問を整形しで送ります。

最初の版は内で動き、は送りません。次の実験として小さなに合う履歴を追加できます。

要求が通る道 — XChat から重みまで

XChat で hi と打って Enter を押すと、こんなことが順に起こります。

  • xchat.py が質問をの形式で包みます。"Q: hi" の次の行に "A: "。
  • {"": …, "": 24} を作り、http://127.0.0.1:8765/generate に します。
  • Runner の do_POST が本文を読んで検査し、generate を呼びます。
  • generate がで番号を作り、の でトークンを1つずつ引き、で止まります。
  • Runner が {"text": …} で応答し、xchat.py が XSLM> の後ろに表示します。

この道のどこか1か所でも切れると、会話はできません。だから問題が起きたら、道に沿って1つずつ確かめます。Runner は起動しているか( )、生成はできるか(curl /generate)、XChat のアドレスとは合っているか。

XChat クライアント — 入力ループと HTTP 要求

xchat.py は2つの部分からなります。

  • ask(question): 要求を1つ送り、答えを返します。Request でアドレス・本文・ヘッダーを入れた POST 要求を作り、 で送ってから json.load で応答の本文を読み、text を取り出します。timeout=120 は、2分以内に答えがなければあきらめるという意味です。遅いで長い生成を待てるよう、余裕をもたせました。
  • 入力ループ: while True で You> を表示し続け、1行ずつ読みます。/exit なら終わり、空行は飛ばし、それ以外は ask に渡して XSLM> の後ろに答えを表示します。

質問ごとに settings.json を読み直します。プロンプトの形式("Q: " … "A: ")はクライアントがつけます。が形式をつけるように作れば、クライアントは形式を知らなくてもかまいません。どちらにしても、形式は1か所だけで決めないとずれてしまいます。

エラーの扱い — 偽の答えを作らない

xchat.py はエラーをこう分けて扱います。

  • EOFError・KeyboardInterrupt: (入力の終わり)や を押したものです。ループを終えて に戻ります。
  • URLError: Runner に接続できませんでした( など)。Runner が止まっているか、ポートが違います。
  • HTTPError: 接続はできたものの、Runner が 400 のようなエラーコードで答えました。URLError の一種なので、同じ行で捕まえます。
  • TimeoutError: 決めた時間内に答えが来ませんでした。

どの場合も "Runner: エラーの内容" を表示して、次の質問を待ちます。接続できないときに、あらかじめ決めておいた文を代わりに見せるような形で隠しません。そうしてこそ、何が壊れたのかがすぐにわかります。Runner を止めて質問してみて(エラーが出るのが正常)、もう一度起動して会話が戻るか確かめてください。

会話の記録をつける — 文脈の長さの限界

今の XChat は質問ごとに独立しています。前に言ったことをモデルは知りません。実際のが前の会話を覚えているように見えるのは、毎回これまでの会話全体をプロンプトの前につけて送っているからです。モデルそのものには記憶がありません。

XSLM でやってみると、すぐに壁にぶつかります。下の実験は、会話1回(Q: hi / A: hi friend.)の後に新しい質問 cat をつけます。プロンプトは21トークンですが、モデルは最後の12トークンしか見ないので、実際に見る文章は "iend." からです。前の会話は切り捨てられます。

だから会話の記録をつけるには、こんなことを一緒に行います。

  • 古い会話から捨てて、文脈の長さに収めます。
  • context を大きくしたモデルを新しく学習します(位置の表が大きくなり、計算が遅くなります)。
  • 学習資料にも何往復も続く会話を入れないと、モデルはその形を学びません。

次の挑戦: xchat.py に history のを置き、これまでの質問と答えをつけて送ってみてください。トークン数を数えて、12を超えたら前の部分を捨てるようにします。

自分で確かめる lab/context.py
import json
from pathlib import Path
from tokenizer import BPE

tok = BPE(**json.loads(Path('data/tokenizer.json').read_text()))
size = json.loads(Path('settings.json').read_text())['context']
history = 'Q: hi\nA: hi friend.\nQ: cat\nA: '
ids = tok.encode(history)
print(len(ids), 'tokens; the model sees the last', size)
print(repr(tok.decode(ids[-size:])))
cd ~/xslm
mkdir -p lab
micro lab/context.py
python3 -m lab.context

実行結果

21 tokens; the model sees the last 12
'iend.\nQ: cat\nA: '

実際の会話モデルはどう作るのか — 事前学習の次の段階

XSLM は Q/A 形式の文章で一から学習しました。・ のような会話モデルは、ふつう複数の段階を経ます。

  • (pre-training): とても多くの文章で次のトークン当てをします。XSLM の train.py がすることと同じで、規模だけが違います。
  • 指示学習(、instruction tuning): 質問と良い答えの組でさらに学習し、指示に従う習慣をつけます。ユーザーとアシスタントの順番を分ける会話の形式()も、このとき身につけます。
  • 選好学習( など): 人がより良いと選んだ答えの方へ傾くように磨きます。

最新の情報が必要なら、学習し直す代わりに を使います。質問で文書を検索して見つけ、プロンプトに一緒に入れ、モデルはその文書を見ながら答えます。資料の形式に [DOC] のような文書の欄を置き、文書を参考に答える形を前もって学習しておけば、あとで検索結果をその欄に入れて使えます。

次の挑戦 — XSLM を育てる方法

完成した XSLM で試せる実験です。1つずつ変えて、損失と答えを記録してください。

  • 資料を増やす: 質問をいろいろな言い方で、答えを同じ形式で、数十〜数百行書きます。
  • 学習を増やす: ・学習回数を変えながら、学習と検証の損失を比べます。
  • モデルを大きくする: width を16に、context を24に変えます。数と1歩あたりの時間がどう変わるかを測ります。
  • ブロックを積む: model.py の + をにまとめ、をブロックごとに別に作って2回通るようにします。
  • ヘッドを分ける: 幅8を4マスずつ2つのヘッドに分けて別々にアテンションし、つなげます。
  • を加える: generate に、で候補を切るオプションを作ります。
  • ・会話の記録: Runner と XChat につけてみます。

ここまでできるようになったら、自分のコンピューターで で同じ構造を書き直してみてください。で計算すれば、数千倍速く、数千万のパラメーターを学習できます。 の ・build-nanogpt もよい次の教材です。

入力して実験

Runnerを動かしたままxchat.pyを書き実行。You>でhi、/exitで終了してからします。

cd ~/xslm
micro xchat.py
python3 xchat.py
hi
/exit
kill "$(cat runner.pid)"
ターミナルで実習する
xchat.py手入力する完全なソース

inputで読んでHTTP POSTを送り、実際の回答や接続エラーを表示します。

import json
from pathlib import Path
from urllib.request import Request, urlopen
from urllib.error import URLError


def ask(question):
    cfg = json.loads(Path('settings.json').read_text())
    body = {'prompt': 'Q: ' + question + '\nA: ', 'tokens': cfg['tokens']}
    request = Request('http://127.0.0.1:' + str(cfg['port']) + '/generate',
                      data=json.dumps(body).encode(),
                      headers={'Content-Type': 'application/json'})
    with urlopen(request, timeout=120) as response:
        return json.load(response)['text']


if __name__ == '__main__':
    print('XChat -> Runner -> XSLM | /exit')
    while True:
        try:
            question = input('You> ').strip()
            if question == '/exit':
                break
            if question:
                print('XSLM>', ask(question))
        except (EOFError, KeyboardInterrupt):
            break
        except (URLError, TimeoutError) as error:
            print('Runner:', error)

コードを1行ずつ読み解く

xchat.py ask — 質問を1つ送る

def ask(question):
    cfg = json.loads(Path('settings.json').read_text())
    body = {'prompt': 'Q: ' + question + '\nA: ', 'tokens': cfg['tokens']}
    request = Request('http://127.0.0.1:' + str(cfg['port']) + '/generate',
                      data=json.dumps(body).encode(),
                      headers={'Content-Type': 'application/json'})
    with urlopen(request, timeout=120) as response:
        return json.load(response)['text']

質問ごとに settings.json を読み、トークン数とポートを得ます。質問を "Q: " + 質問 + 改行 + "A: " で包み、学習の形式に合わせます。Request に を渡すと POST になり、本文は JSON の、ヘッダーは です。with urlopen(…) は応答を読み終えたあと接続を閉じてくれます。json.load が応答をとして読み、ask は text だけを返します。

xchat.py 会話ループ

if __name__ == '__main__':
    print('XChat -> Runner -> XSLM | /exit')
    while True:
        try:
            question = input('You> ').strip()
            if question == '/exit':
                break
            if question:
                print('XSLM>', ask(question))
        except (EOFError, KeyboardInterrupt):
            break
        except (URLError, TimeoutError) as error:
            print('Runner:', error)

開始の案内を表示し、while True で質問を受け取ります。input は You> を表示して Enter までの1行を読み、strip で前後の空白を消します。/exit なら break で終わり、空の質問は飛ばします。Ctrl+D は EOFError、Ctrl+C は KeyboardInterrupt として入ってきて、やはり終わります。Runner の接続エラーとタイムアウトは知らせて、次の質問を待ちます。

理解を確認

XChat→Runner→重み→文章を説明。Runner停止時は接続エラーになり、再起動で戻るか確認します。

困ったとき

killをXChat内に入力しないでください。/exitで戻り、最後にプロジェクトを書き出します。

よくある質問

XChat で kill と打ったのに Runner が止まりません。

You> に打った文字はではなく、質問として Runner に送られます。まず /exit か Ctrl+D で XChat を終えて bash のプロンプト($)に戻ってから、kill コマンドを打ちます。

Runner: <urlopen error [Errno 111] Connection refused> と出ます。

Runner が止まっているか、まだ起動中です。cat runner.log で起動の文言(XSLM Runner: …)を確かめ、curl -s http://127.0.0.1:8765/health が答えるかを見てから、もう一度質問してください。再読み込みをしたなら、Runner を起動し直す必要があります。

答えが質問と関係ありません。接続が間違っているのですか?

XSLM> の後ろに何かしら生成された文章が出たなら、接続は合っています。内容はモデルの実力です。同じ質問を generate.py --prompt で直接実行してみてください。設定と seed が同じなら、Runner を通した答えとまったく同じになります。

ガイドライン

人工知能

エージェントツール

バイブコーディング

AI活用

AI資格

AI授業

IT基礎

チャット

掲示板

制作

コミュニティ

その他

用語辞典

知らない言葉を選んでみましょう。やさしい説明と関連用語が見られます。

その用語はまだありません。

用語を選ぶと説明が表示されます。