0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Token から取り出した2048個の数字には「意味」があるのか? #11

0
Posted at

はじめに

前回までの実験で、Token ID はその数値自体を計算に使っているのではなく、token_embd.weight から値を取り出すための index として使われていることを確認した。

例えば、

"Hello"
  ↓
Token ID = 9707
  ↓
GET_ROWS
  ↓
2048個の数値

という流れになっていた。

ここで、次の疑問が出てきた。

この 2048 個の数字は、一体何を表しているのだろう?

単に Token ごとに違う 2048 個の数字が割り当てられているだけなのか。

それとも、Token 同士の何らかの関係が、この 2048 次元の中に現れているのだろうか。

今回は、それを実際に比較してみる。


今回確認したいこと

まず、単純な仮説を立てる。

例えば、

cat
dog

は、人間から見ると何らかの関係がある。

一方、

cat
king

は、それほど直接的な関係はなさそうに見える。

もし 2048 個の数字の中に Token 同士の関係が何らかの形で存在するのであれば、

cat ↔ dog

のほうが、

cat ↔ king

よりも近くなる可能性がある。

ただし、ここで「近い」とは何かを決める必要がある。

今回は Cosine Similarity を使うことにした。


Cosine Similarity

2つのベクトルの向きがどれだけ似ているかを見る指標。

値が大きいほど、2つのベクトルの向きが近い。

今回は、2048 次元のベクトル同士を比較する。

def cosine_similarity(a, b):
    return np.dot(a, b) / (
        np.linalg.norm(a) *
        np.linalg.norm(b)
    )

数式そのものを深く理解することが今回の目的ではない。

今回知りたいのは、

Token A
 ↓
2048次元

Token B
 ↓
2048次元

この2つは、どの程度同じ方向を向いているのか?

という点だけ。


実験1:Token の2048次元ベクトルを取得する

前回と同じように、llama-eval-callback を使ってモデル内部を観察する。

例えば cat を入力すると、

common_debug_cb_eval:
embd = (f32)
GET_ROWS(
    token_embd.weight{2048, 151936, 1, 1},
    inp_tokens{1, 1, 1, 1}
)
= {2048, 1, 1, 1}

という処理を見ることができた。

その直後には、

[
    -0.0078,
    -0.0078,
    -0.0147,
     0.0271,
     0.0062,
     ...
]

という 2048 個の値が出力される。

つまり、

cat
 ↓
Token ID
 ↓
GET_ROWS
 ↓
2048次元ベクトル

までを実際に取得できる。

同じ方法で、

cat
dog
king
queen

の4つを取得した。

Python で読み込んでみる。

cat = load("cat")
dog = load("dog")
king = load("king")
queen = load("queen")

print(cat.shape)

結果:

(2048,)

確かに 2048 個の値になっている。


実験2:関連しそうな Token を比較する

まず、

cat ↔ dog

を比較する。

結果:

cat-dog = 0.1600255

次に、

king ↔ queen

結果:

king-queen = 0.1566830

では、あまり直接関係がなさそうな組み合わせはどうなるのか。

cat ↔ king

結果:

cat-king = 0.0594410

さらに、

cat ↔ queen

結果:

cat-queen = 0.0388835

まとめると、

Pair Cosine Similarity
cat - dog 0.160026
king - queen 0.156683
cat - king 0.059441
cat - queen 0.038884

確かに、

cat ↔ dog
king ↔ queen

のほうが高い。

一見すると、

2048個の数字には「意味」が入っているのでは?

と思いたくなる。

しかし、ここで一つ問題がある。


0.16 は、本当に高いのか?

cat-dog = 0.16

という値だけを見ても、

それが高いのか低いのか分からない。

もしかすると、適当に選んだ Token 同士でも、

0.15
0.18
0.20

くらいになるのかもしれない。

そこで、比較対象を増やすことにした。


実験3:100 Token を用意する

英単語を100個用意し、それぞれが 1 Token になることを確認した。

例えば、

table
river
music
green
computer
bread
city
sleep
window
teacher
...

など。

Tokenizer で確認する。

curl -s http://localhost:8080/tokenize \
  -H "Content-Type: application/json" \
  -d '{"content":"table","with_pieces":true}'

結果:

{"tokens":[{"id":2005,"piece":"table"}]}

このように、

1 word
=
1 Token
=
1 Token ID

となるものだけを使用した。

途中、

mountain
shoe
milk
meat
sugar
garden
village

などは複数 Token に分割されたため、別の単語に置き換えた。

最終的に、

100 Token

を用意した。


実験4:100 Token の全組み合わせを比較する

100 個の Token から 2 個を選ぶ組み合わせは、

100 × 99 / 2
=
4950

つまり、4950 組ある。

それぞれの 2048 次元ベクトルについて Cosine Similarity を計算した。

結果:

words  : 100
pairs  : 4950

mean   : 0.065124
median : 0.062999
std    : 0.033425

min    : -0.042667

p90    : 0.107926
p95    : 0.119980
p99    : 0.156662

max    : 0.333636

平均は、

0.0651

だった。

そして 99 percentile は、

0.1567

だった。

ここで先ほどの結果をもう一度見る。

cat-dog      = 0.160026
king-queen   = 0.156683

どちらもかなり上位に入っている。

実際に percentile を計算すると、

Pair Similarity Percentile
cat - dog 0.160026 99.19%
king - queen 0.156683 98.99%
cat - king 0.059441 45.52%
cat - queen 0.038884 21.60%

となった。

cat-dog は 4950 組の中でも、ほぼ上位 1% に入っている。

king-queen もほぼ同じ。

一方、

cat-king

はほぼ中央。

cat-queen

は、それよりさらに低い。

ここまでを見ると、

cat ↔ dog

king ↔ queen

が偶然高かっただけ、とは少し考えにくくなってきた。


さらに面白い結果が出た

4950 組のうち、Cosine Similarity が高かったものを上から並べてみた。

結果:

black      - white       0.333636
green      - blue        0.270954
sea        - tea         0.248152
blue       - black       0.246291
rain       - train       0.230855
green      - black       0.215498
red        - blue        0.205895
park       - bank        0.203913
green      - red         0.193414
blue       - white       0.193227
city       - country     0.191659
chair      - air         0.191295
green      - white       0.188908
hotel      - hospital    0.186866
coffee     - tea         0.185255
bird       - fish        0.184651
sun        - moon        0.183512
book       - work        0.182501
music      - money       0.177688
run        - sun         0.177527

ここで、かなり分かりやすいものが出ている。

例えば、

black - white
green - blue
blue  - black
red   - blue
green - red

色に関係する Token が大量に上位に出てきた。

また、

coffee - tea
bird   - fish
sun    - moon
city   - country
hotel  - hospital

なども、人間から見ても何らかの関係がある。

これは少し面白い。

なぜなら今回は、

「green と blue を近くしたい」

と思って選んだわけではない。

100 Token の全 4950 組を機械的に比較した結果、自然に上位に出てきた。

つまり、

Token
 ↓
token_embd.weight
 ↓
2048次元

の時点ですでに、Token 同士の関係が完全にランダムというわけではなさそうだ。


しかし、「意味」だけではなさそう

一方で、さらに面白い結果もある。

sea   - tea
rain  - train
park  - bank
chair - air
book  - work
run   - sun

これらは、

意味が似ている

とは言いにくい。

しかし、文字列として見ると、

sea / tea

rain / train

park / bank

chair / air

book / work

run / sun

似ている部分がある。

つまり今回の結果だけから、

2048次元ベクトル = Token の意味

と結論づけることはできない。

もしかすると、この 2048 次元の中には、

意味
文字列の形
単語の使われ方
Token化の特徴
その他の関係

などが混ざっているのかもしれない。

現時点では、まだ分からない。


今回分かったこと

今回確認できたのは、

Token ID
 ↓
token_embd.weight
 ↓
2048個の数字

で取得した 2048 次元ベクトルが、

単なる完全にランダムな数字ではなさそうだ、ということ。

例えば、

cat ↔ dog

は 100 Token・4950 組の比較の中で、

99.19 percentile

だった。

king ↔ queen

も、

98.99 percentile

だった。

さらに全組み合わせを調べると、

black ↔ white
green ↔ blue
coffee ↔ tea
bird ↔ fish
sun ↔ moon

など、人間から見ても関係がありそうな Token が上位に現れた。

一方で、

sea ↔ tea
rain ↔ train
park ↔ bank

のような、意味よりも文字列の形が似ている組み合わせも上位に現れた。

そのため、今の段階で言えるのは、

2048次元の中には、Token 同士の何らかの非ランダムな関係が存在しているように見える。

というところまで。

まだ、

この2048個の数字が「意味」を表している

とは言えない。


次の疑問

ここまで来ると、次に気になるのはこれ。

Token Embedding の近さは、「意味の近さ」なのか、それとも「文字列の近さ」なのか?

例えば、

cat ↔ dog

は意味的に近い。

一方、

rain ↔ train

は文字列として近い。

では、

意味が近いグループ
文字列が近いグループ
どちらも近くないグループ

を分けて比較すると、何が見えるのだろうか。

次は、この違いをもう少し調べてみたい。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?