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?

はじめに

LLMとは何でしょうか。

定義を調べれば、すぐにそれらしい説明は見つかります。

しかし今回は、先に答えを調べるのではなく、

実際にLLMを動かして、観察できた事実から考えてみる

ことにします。

最初の問いは単純です。

LLMとは何か?

まだ内部の仕組みについては考えません。

まず、文字を入力すると何が起きるのかを観察します。


実験環境

今回使用したモデル:

Qwen3-Coder-30B-A3B-Instruct-Q4_K_M.gguf

実行環境:

llama.cpp / llama-server

ローカルの llama-server は以下で待ち受けています。

localhost:8080

実験

LLMに次の文字列を与えます。

日本の首都はどこ?

予想としては、

東京です。

のような回答が返ってくることを期待します。

実際に実行したコマンドはこちらです。

curl -N http://localhost:8080/completion \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "日本の首都はどこ?",
    "stream": true,
    "n_predict": 30,
    "temperature": 0
  }'

条件は次の通りです。

prompt      = 日本の首都はどこ?
stream      = true
n_predict   = 30
temperature = 0

結果

出力は、一度にまとめて返ってきませんでした。

実際には次のように少しずつ返ってきます。

data: {"index":0,"content":"また","tokens":[52800],"stop":false,"id_slot":-1,"tokens_predicted":1,"tokens_evaluated":5} 
data: {"index":0,"content":"、","tokens":[5373],"stop":false,"id_slot":-1,"tokens_predicted":2,"tokens_evaluated":5} 
data: {"index":0,"content":"日本の","tokens":[131888],"stop":false,"id_slot":-1,"tokens_predicted":3,"tokens_evaluated":5}
data: {"index":0,"content":"国旗","tokens":[115799],"stop":false,"id_slot":-1,"tokens_predicted":4,"tokens_evaluated":5}
data: {"index":0,"content":"と","tokens":[19182],"stop":false,"id_slot":-1,"tokens_predicted":5,"tokens_evaluated":5}
data: {"index":0,"content":"国","tokens":[28404],"stop":false,"id_slot":-1,"tokens_predicted":6,"tokens_evaluated":5}
data: {"index":0,"content":"歌","tokens":[99678],"stop":false,"id_slot":-1,"tokens_predicted":7,"tokens_evaluated":5} 
data: {"index":0,"content":"は何","tokens":[136045],"stop":false,"id_slot":-1,"tokens_predicted":8,"tokens_evaluated":5} 
data: {"index":0,"content":"ですか","tokens":[131938],"stop":false,"id_slot":-1,"tokens_predicted":9,"tokens_evaluated":5} 
data: {"index":0,"content":"?\n\n","tokens":[26850],"stop":false,"id_slot":-1,"tokens_predicted":10,"tokens_evaluated":5} 
data: {"index":0,"content":"日本の","tokens":[131888],"stop":false,"id_slot":-1,"tokens_predicted":11,"tokens_evaluated":5} 
data: {"index":0,"content":"首都","tokens":[106114],"stop":false,"id_slot":-1,"tokens_predicted":12,"tokens_evaluated":5} 
data: {"index":0,"content":"は","tokens":[15322],"stop":false,"id_slot":-1,"tokens_predicted":13,"tokens_evaluated":5} 
data: {"index":0,"content":"東","tokens":[102356],"stop":false,"id_slot":-1,"tokens_predicted":14,"tokens_evaluated":5} 
data: {"index":0,"content":"京","tokens":[46553],"stop":false,"id_slot":-1,"tokens_predicted":15,"tokens_evaluated":5} 
data: {"index":0,"content":"です","tokens":[37541],"stop":false,"id_slot":-1,"tokens_predicted":16,"tokens_evaluated":5} 
data: {"index":0,"content":"。","tokens":[1773],"stop":false,"id_slot":-1,"tokens_predicted":17,"tokens_evaluated":5} 
data: {"index":0,"content":"日本の","tokens":[131888],"stop":false,"id_slot":-1,"tokens_predicted":18,"tokens_evaluated":5} 
data: {"index":0,"content":"国旗","tokens":[115799],"stop":false,"id_slot":-1,"tokens_predicted":19,"tokens_evaluated":5} 
data: {"index":0,"content":"は","tokens":[15322],"stop":false,"id_slot":-1,"tokens_predicted":20,"tokens_evaluated":5} 
data: {"index":0,"content":"「","tokens":[12881],"stop":false,"id_slot":-1,"tokens_predicted":21,"tokens_evaluated":5}
data: {"index":0,"content":"日の","tokens":[130635],"stop":false,"id_slot":-1,"tokens_predicted":22,"tokens_evaluated":5} 
data: {"index":0,"content":"丸","tokens":[106256],"stop":false,"id_slot":-1,"tokens_predicted":23,"tokens_evaluated":5}
data: {"index":0,"content":"」","tokens":[10429],"stop":false,"id_slot":-1,"tokens_predicted":24,"tokens_evaluated":5} 
data: {"index":0,"content":"、","tokens":[5373],"stop":false,"id_slot":-1,"tokens_predicted":25,"tokens_evaluated":5} 
data: {"index":0,"content":"国","tokens":[28404],"stop":false,"id_slot":-1,"tokens_predicted":26,"tokens_evaluated":5} 
data: {"index":0,"content":"歌","tokens":[99678],"stop":false,"id_slot":-1,"tokens_predicted":27,"tokens_evaluated":5} 
data: {"index":0,"content":"は","tokens":[15322],"stop":false,"id_slot":-1,"tokens_predicted":28,"tokens_evaluated":5} 
data: {"index":0,"content":"「","tokens":[12881],"stop":false,"id_slot":-1,"tokens_predicted":29,"tokens_evaluated":5} 
data: {"index":0,"content":"君","tokens":[101956],"stop":false,"id_slot":-1,"tokens_predicted":30,"tokens_evaluated":5}

30個生成したところで終了しました。

tokens_predicted = 30
tokens_evaluated = 5
stop_type        = limit

期待していた単純な、

東京です。

という回答とはかなり違います。

実際の出力をつなげると、

また、日本の国旗と国歌は何ですか?

日本の首都は東京です。
日本の国旗は「日の丸」、国歌は「君...

となりました。

なぜこのような結果になるのかは、今の時点ではまだ分かりません。

ここでは理由を推測せず、観察結果として残しておきます。


出力をもう少し詳しく見る

ストリーミングされたデータを見ると、興味深い情報が含まれていました。

例えば、

{"content":"東","tokens":[102356],"tokens_predicted":14}

次に、

{"content":"京","tokens":[46553],"tokens_predicted":15}

さらに、

{"content":"です","tokens":[37541],"tokens_predicted":16}

そして、

{"content":"。","tokens":[1773],"tokens_predicted":17}

と続きました。

整理すると、

生成順 content token
14 102356
15 46553
16 です 37541
17 1773

となっています。


「東京」は一つではなかった

人間から見ると、

東京

は自然に一つの単語として見えます。

しかし今回のログでは、

東 → 102356
京 → 46553

となっていました。

一方で、

日本の → 131888
首都   → 106114

という結果もあります。

つまり、今回観察した範囲では、

日本の

は一つの単位として現れ、

東京

は、

東
京

に分かれて現れました。

さらに、

日の → 130635
丸   → 106256

という例もあります。

この単位はログ上では token と呼ばれています。


同じ文字には同じ数字が現れた

今回の短いログの中でも、同じ内容が複数回登場しています。

例えば、

日本の → 131888

は後でも再び、

日本の → 131888

として登場しました。

同様に、

国旗 → 115799
国旗 → 115799

や、

は → 15322
は → 15322

も確認できました。

少なくとも今回の実験では、

特定の文字列と特定の数字の対応

を観察することができました。


入力側にもTokenがある?

最後のログには、

tokens_evaluated = 5

とあります。

入力した文字列は、

日本の首都はどこ?

です。

つまり今回のログでは、この入力に対して 5 個の evaluated tokens が記録されています。
ログから推測すると、以下になります。

tokens content
1 日本の
2 首都
3
4 どこ
5

一方、出力側では、

tokens_predicted = 1
tokens_predicted = 2
tokens_predicted = 3
...
tokens_predicted = 30

と増えていきました。

観察したものをそのまま並べると、

日本の首都はどこ?
        ↓
tokens_evaluated = 5
        ↓
tokens_predicted = 1
        ↓
tokens_predicted = 2
        ↓
tokens_predicted = 3
        ↓
        ...
        ↓
tokens_predicted = 30

となります。


今回分かったこと

今回の実験から直接観察できたのは、次のような動きです。

文字を入力
    ↓
tokens_evaluated = 5
    ↓
新しい内容が少しずつ出力される
    ↓
content と token ID が現れる
    ↓
tokens_predicted が増えていく
    ↓
最終的に文章になる

例えば、

東 → 102356
京 → 46553
です → 37541
。 → 1773

という対応を実際のログから確認できました。

また、

日本の首都はどこ?

と入力したからといって、単純に、

東京です。

だけが返ってくるわけではないことも確認できました。


しかし、まだ何も説明できていない

ここまで観察すると、むしろ疑問が増えました。

Tokenとは何なのか?

なぜ文字に、

102356
46553
37541

のような数字が対応しているのでしょうか。

そして、なぜ、

東京

は、

東
京

に分かれるのに、

日本の

は一つなのでしょうか。

さらに大きな疑問があります。

なぜ次に「東」が出て、その次に「京」が出たのでしょうか?

今回の実験では、それを説明するものはまだ観察できていません。

そしてもう一つ。

なぜ「日本の首都はどこ?」と入力したのに、予想していなかった国旗や国歌の話まで生成されたのでしょうか?

これもまだ分かりません。


まとめ

最初の問いは、

LLMとは何か?

でした。

今回、一度の実験だけでその答えが分かったわけではありません。

ただし、最初は、

質問
 ↓
LLM
 ↓
回答

程度にしか見えていなかったものから、

実際のログを観察することで、

文字
 ↓
Tokenらしき単位
 ↓
数字のID
 ↓
少しずつ新しい内容が生成される
 ↓
文章になる

という、もう一段内側の現象を見ることができました。

そして新しい疑問が残りました。

Tokenとは何か?

なぜ文字が数字になるのか?

なぜTokenの区切り方が違うのか?

なぜ次に生成するTokenを決められるのか?

なぜ予想外の文章まで生成されたのか?

まだ答えは調べません。

次も、この実験から生まれた疑問の一つを選び、実際に観察できる方法を考えてみます。

Experiment 001 — 完了

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?