同じ質問に違う答えが返るわけ
サンプリングとは、言語モデルが確率をもとに次のトークンを選ぶことです。温度と上位kは、その選び方を形づくる設定です。同じ指示から毎回違う文章が出るのは、このためです。
2つの答えの間で、モデルの数は変わっていません。変わるのは選び方だけです。
このレッスンのゴール
メモ
貪欲法、温度、上位kを使って、次のトークンを選ぶことができる。
キーワード
| ことば | いみ | れい |
|---|---|---|
| 貪欲法 | いつもいちばん確率の高いトークンを取る方法 | |
| サンプリング | 確率に従ってトークンをでたらめに引くこと | |
| 温度 | softmax の前にスコアを割る数 | 0.5 |
| 上位k | 確率の高い k 個のトークンだけを残すこと | k = 2 |
| 種 | でたらめな選択を再現するための最初の数 | |
| 指示 | モデルが続きを書く元の文章 |
学生が入力するセルは、このプレビューでは空白です。
貪欲法はいつもいちばん上を取る
「バスが」の後に、作り話のモデルが次の4語のスコアを出します。softmax で、それを確率に変えます。
貪欲法は、いつもいちばん確率の高いトークンを取ります。ここでは 遅れる です。毎回同じ文章になります。長い文章では、同じことをくり返して抜け出せなくなることがよくあります。いちばんありそうな次の一歩が、同じ場所へ戻ることがあるからです。
例: スコアから確率へ
| 次の語 | スコア | e のスコア乗 | 確率 |
|---|---|---|---|
| 遅れる | 3 | 20.09 | 0.644 |
| 混む | 2 | 7.39 | 0.237 |
| 来る | 1 | 2.72 | 0.087 |
| 青い | 0 | 1.00 | 0.032 |
学生が入力するセルは、このプレビューでは空白です。
温度は選び方を鋭くも平らにもする
サンプリングは、それぞれの確率に従って、トークンをでたらめに引きます。100回なら、遅れる は約64回、青い は約3回出ます。
温度は、引く前にその割合を変えます。すべてのスコアを温度で割ってから、softmax をかけます。1より小さいと、いちばん上のトークンがさらに出やすくなります。1より大きいと、割合がならされ、めずらしい語がよく出るようになります。
例: 3つの温度
| 次の語 | 温度 0.5 | 温度 1 | 温度 2 |
|---|---|---|---|
| 遅れる | 0.865 | 0.644 | 0.455 |
| 混む | 0.117 | 0.237 | 0.276 |
| 来る | 0.016 | 0.087 | 0.167 |
| 青い | 0.002 | 0.032 | 0.102 |
学生が入力するセルは、このプレビューでは空白です。
2つの温度で1000回引く
docker exec jupyter python3 -c "import numpy as np; s = np.array([3, 2, 1, 0]); print([np.bincount(np.random.default_rng(7).choice(4, size=1000, p=np.exp(s / t) / np.exp(s / t).sum()), minlength=4).tolist() for t in (1.0, 0.5)])"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
上位kと種
上位kは、確率の高い k 個のトークンだけを残し、合計が1になるように割合を配りなおします。k = 2 なら、来る と 青い は決して出ません。
でたらめな選択は、種から始まります。同じ種なら同じ結果になり、新しい種なら新しい結果になります。1つの指示から違う文章が出るのも、種を決めるとテストを再現できるのも、このためです。
例: 温度1で上位2つ
| 次の語 | 確率 | 残すか | 配りなおし |
|---|---|---|---|
| 遅れる | 0.644 | はい | 0.644 ÷ 0.881 = 0.731 |
| 混む | 0.237 | はい | 0.237 ÷ 0.881 = 0.269 |
| 来る | 0.087 | いいえ | 0 |
| 青い | 0.032 | いいえ | 0 |
学生が入力するセルは、このプレビューでは空白です。
温度と種を決めて引く
import math
import random
words = ["遅れる", "混む", "来る", "青い"]
scores = [3, 2, 1, 0] # 「バスが」の後のモデルのスコア
temperature = 1.0
seed = 1
powers = []
for s in scores:
powers.append(math.exp(s / temperature))
total = sum(powers)
probs = []
for p in powers:
probs.append(p / total)
rounded = []
for p in probs:
rounded.append(round(p, 3))
print("確率:", rounded)
random.seed(seed)
draws = random.choices(words, weights=probs, k=8)
print("8回引いた結果:", draws)
# seed を 2 に変えて実行してください。引く結果は変わり、確率は同じです。
# 次に temperature を 0.3 にします。引く結果はどうなりますか。
よくある間違い
注意
モデルが新しい答えを出すのは、考えを変えたか、こちらから学んだからだと考えがちです。モデルの数は同じです。違いはでたらめな選択から来るので、種と設定が同じなら、同じ文章が出ます。