[LLM] 3Blue1BrownのLLM解説

3Blue1Brown は有名なYoutubeチャンネル
https://www.youtube.com/@3blue1brown

制作者:Grant Sanderson(グラント・サンダーソン)
内容:数学・AI・物理などの抽象的な概念を超美しいアニメーションで可視化する教育チャンネル
名前の意味:制作者の目の色(片方が青3つ、もう片方が茶1つ)に由来しています

■高品質なアニメーション
使用しているツールは Manim(Mathematical Animation Engine)
自作のPythonライブラリで、数学アニメーション専用。
現在はオープンソース化され、教育・AI研究の可視化に広く使われています。
👉 Manim公式

OpenAIやDeepMindのエンジニアも「彼の動画で理解した」と発言

### 3Blue1BrownのLLM解説
1. LLMとは「次の単語を予測する関数」
LLM(大規模言語モデル)は、あるテキストの直後に続く単語を予測する確率分布関数と考えられる。
ただし「最も確率の高い単語」を常に選ぶわけではなく、ランダム性を持たせて応答を自然にするよう設計されることがある。
モデルは、与えられた文脈(プロンプト+生成済みテキスト)をすべて使って次の単語を決定する。

2. Transformer/Attention の利用
3Blue1Brown の解説では、LLM内部で Transformer(Attention 機構) が使われている点を詳細に描写します。
– Embed(埋め込み)段階:単語を高次元ベクトルに変換
– Attention:各単語ベクトルが他の単語ベクトルに注目して情報を交換
– Feed Forward ネットワーク(MLP):Attention 後のベクトルを各位置で独立変換
– これらの処理を複数層重ねることで、文脈の情報が多段階で取り込まれていく

3. 事実の記憶(Knowledge / Facts の “格納”)
3Blue1Brown は “LLM がどうやって事実(知識)を内部に持つか” という観点に触れています。特に “How might LLMs store facts” という章で詳述。
– モデルの MLP(多層パーセプトロン)層 に、事実情報がある程度蓄えられている可能性を指摘
– 例示:入力「Michael Jordan plays the sport of ___」に対して “basketball” を予測できるのは、内部で “Michael Jordan → basketball” という対応を何らかのベクトル操作で実現しているから、という説明
3blue1brown.com
+1
– この観点から、「Attention は文脈処理/結合、MLP は知識格納の役割を持つ」という分担感が描かれています

4. モデルの規模と訓練の難しさ
3Blue1Brown では、LLM の巨大さ・計算コストにも触れています。
3blue1brown.com
何十億〜何千億というパラメータ(重み)を持つ
それらを最適化するための学習には膨大なデータと計算資源が必要
人間が株ごとパラメータを設定するわけではなく、勾配法 + 損失関数 によって徐々に学ばれる

5. 応答の確率的性・多様性
3Blue1Brown は「同じプロンプトでも違う応答が返る」点にも言及します。
3blue1brown.com
モデルは確率分布を使って次の単語を選ぶので、必ずしも最頻出語を返すわけではない
少し確率が下がる語を選ぶことで、応答が自然・人間らしくなる

[LLM] Hugging Face の「Transformers」入門

### Hugging Faceとは
AIモデル(特にLLM)を「共有・利用・学習」できるオープンソースのAIプラットフォームです。
– GitHubのように世界中の研究者・企業がモデルを公開
– 代表ライブラリが「transformers」
– 無料で多くのモデルをダウンロードして使える

### transformers ライブラリの目的
transformers は 最先端のNLPモデルを簡単に使うためのPythonライブラリ。
代表的な利用例:
– 文章生成(GPT, LLaMA)
– 翻訳(Marian, T5)
– 要約(BART)
– 感情分析(BERT)
– 質問応答(DistilBERT)

### 基本の3構成
1️⃣ Tokenizer(トークナイザー)
→ テキストを数値化(単語 → トークンID)
2️⃣ Model(モデル)
→ トークン列を処理して出力を返す
3️⃣ Pipeline(パイプライン)
→ Tokenizer と Model をまとめて簡単に使える便利関数

実際のコード例

from transformers import pipeline
# 感情分析のパイプラインをロード
classifier = pipeline("sentiment-analysis")
# テキストを入力
result = classifier("I love Hugging Face!")
print(result)
# [{'label': 'POSITIVE', 'score': 0.9998}]

モデルを指定したコード

from transformers import AutoTokenizer, AutoModelForCausalLM

model_name = "gpt2"

tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)

input_text = "Hello, my name is"
inputs = tokenizer(input_text, return_tensors="pt")

outputs = model.generate(**inputs, max_length=20)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))

主なpipeline
感情分析 pipeline(“sentiment-analysis”) 映画レビューなど
翻訳 pipeline(“translation”, model=”Helsinki-NLP/opus-mt-en-jp”) 英→日翻訳
要約 pipeline(“summarization”) ニュース要約
文章生成 pipeline(“text-generation”, model=”gpt2″) GPT風応答
質問応答 pipeline(“question-answering”) QAボット

注意点
– モデルサイズが大きい場合、ダウンロードに時間がかかる
– GPUがあると高速(CUDA対応)
– オフライン実行も可能(cache_dirを指定)

[LLM] Attention is All You Need

Attention is All You Need

従来の機械翻訳(Seq2Seq)はこうでした:
🧩 RNN(LSTMなど)で入力文を順に読み、隠れ状態にエンコード
🧩 その状態をデコーダーが順に展開して出力を生成
→ つまり「時系列処理(順番に読む)」が前提。
しかしRNNは並列化できず、長文では文脈を忘れやすいという弱点がありました。

Transformerの発想
「全部並列で読んで、Attention(注意機構)で関係性だけを学習すればいい」
つまり:
時系列構造をやめて「全単語を同時に見て」
単語間の関係を Attention で表現する
→ これがタイトルの “Attention is All You Need” の意味です。

構成は「エンコーダ」と「デコーダ」の2ブロック:
ブロック 役割 構成
Encoder 入力文の意味を圧縮・表現 Self-Attention + Feed Forward
Decoder その表現をもとに出力文を生成 Masked Self-Attention + Cross-Attention + Feed Forward

名前 役割
Q (Query) 注目する視点(どの単語に注目したいか)
K (Key) 単語の特徴(注目される側)
V (Value) 実際に取り出す情報

🎭 Multi-Head Attentionとは?
「1つの視点では足りない」ので、
複数の異なるQ, K, V空間(ヘッド) を並列で使い、
さまざまな関係(文法的・意味的など)を学びます。

Feed Forward Network(FFN)
Self-Attentionの出力(各単語)を、
個別に2層のMLP(全結合層)で変換します。
これにより非線形変換が入り、表現力が上がります。

[LLM] コンテキスト長、推論速度、埋め込み

① コンテキスト長(Context Length)とは?

「モデルが一度に理解・処理できる情報量」 のことです。つまり、「LLMが一度の会話・文書入力で覚えておける最大トークン数(単語や記号のかたまり)」を指す。

🧩 たとえば:
GPT-4 Turbo:128,000トークン(=日本語でおよそ8〜10万文字)
Gemini 1.5 Pro:100万トークン(=本一冊レベル)
小型モデル(LLaMA 3 8Bなど):通常4,000〜8,000トークン

短いコンテキスト長(例:4,000トークン)
→「一度に短文しか読めないAI」
→ 小説1章を超えると前の内容を忘れてしまう。

長いコンテキスト長(例:100万トークン)
→「本1冊をまるごと読んで要約できるAI」
→ ドキュメント全体を把握して、前後の関係を理解できる。

長いコンテキスト長を持つモデルほど、
「文脈を途切れずに理解」できる

### 推論速度(Inference Speed)とは?
AIが応答を返すまでの速さ のこと
同じ質問をしても、モデルの設計や規模によって速度は大きく異なる

Flash系 (例: Gemini Flash, GPT-4o-mini) 軽量スポーツカー 速い 🚀
Pro系 (例: GPT-4, Gemini Pro) 高性能SUV やや遅いが高精度
巨大モデル (例: Mixtral, LLaMA 70B) 重トラック 高精度だが遅い 🐢

速度は主に以下の3要素で決まります。
モデルサイズ(パラメータ数が多いほど遅い)
ハードウェア(GPU or CPU)
並列化や量子化(最適化で速くなる)

チャットボットやQA → 高速モデル(Flash系)
高精度な分析や生成 → Pro系モデル
リアルタイム処理が必要な場面 → 推論速度重視

埋め込み(Embedding)とは?

これは、LLMの「意味を数値に変換する技術」です。
テキストを単なる文字列ではなく、
AIが「意味的な距離」で比較できるようにします。

🔍 たとえば:
テキスト 埋め込み後のベクトル(例)
「りんご」 [0.12, -0.87, 0.44, …]
「みかん」 [0.10, -0.80, 0.46, …]
「車」 [-0.55, 0.92, -0.33, …]

このとき、「りんご」と「みかん」はベクトルが近い

[LLM] オープンモデルとクローズドモデル

「オープンモデル」は中身が公開されていて自由に使える
「クローズドモデル」は中身が非公開で、企業のサーバー経由でしか使えないモデル

### オープンモデル(Open Model)
モデルの中身(重み・コード)が公開されている
研究者・開発者が自由にダウンロードして、改良・再学習できる
オフラインでも動かせる(ローカル環境で実行可能)

代表例
LLaMA 3(Meta社)
Mistral / Mixtral
Falcon
Gemma(Googleのオープン版)
Japanese StableLM(日本語特化)

### クローズドモデル(Closed Model)
■特徴
モデルの中身(重み)は非公開
提供企業(OpenAI, Googleなど)のAPIを通じて利用する
モデルの更新や最適化は提供企業が行う

■代表例
GPTシリーズ(OpenAI)
Claude(Anthropic)
Gemini(Google)
Command R+(Cohere)

超軽量モデル
$ pip3 install accelerate

from transformers import pipeline

# 軽量モデル(日本語対応)
pipe = pipeline(
    "text-generation",
    model="cyberagent/open-calm-1b",  # 約1Bの日本語モデル
)

prompt = "オープンモデルとクローズドモデルの違いを教えてください。"
result = pipe(prompt, max_new_tokens=150)
print(result[0]['generated_text'])

モデルを動かすにはGPUがないとキツそう…

LLMで、GPT系、LLaMA系、Claude、Geminiの違い

1. GPT系
特徴:
汎用性が非常に高く、最も実用化が進んでいる。
**RLHF(人間のフィードバックで学習)**により自然で安全な応答。
GPT-4oは音声・画像・動画も理解するフル・マルチモーダルモデル。
APIやChatGPT経由で商用利用が容易。
用途:
チャットボット、コード生成、文章校正、マルチモーダルアプリなど。

2. LLaMA系(Meta)
代表モデル:LLaMA-2, LLaMA-3, CodeLLaMA
特徴:
**完全オープンモデル(研究・商用利用OK)**として人気。
Hugging Face や Ollama などで簡単にローカル実行できる。
学習データは透明性が高く、再現性や拡張性に優れる。
企業や研究者が 独自ファインチューニングしやすい。

用途:
独自アシスタント、社内LLM開発、RAG(検索拡張生成)など。

3. Claude(Anthropic)
代表モデル:Claude 3 系列(Opus, Sonnet, Haiku)
特徴:
Anthropicは「Constitutional AI(憲法型AI)」という理念を採用。
→ 倫理的原則をあらかじめモデルに教え込み、安全性を確保。
**非常に長いコンテキスト(100k〜200kトークン以上)**を扱える。
文章理解力が高く、長文要約や複雑な推論に強い。
用途:
法務、ドキュメント要約、思考型タスク、知識ワークなど。

4. Gemini(Google DeepMind)
代表モデル:Gemini 1.0 → 1.5 Pro / Flash
特徴:
マルチモーダル統合設計が最初から前提(画像・音声・動画対応)。
高速モデル「Flash」など、応答速度と効率にも力を入れている。
Google 検索や Workspace などと密接に連携。
数学的推論・コード生成能力も非常に強い。

用途:
Google製品内のアシスタント、教育、研究、マルチモーダル処理。

import os
from openai import OpenAI
import google.generativeai as genai
import time
from dotenv import load_dotenv
load_dotenv()

# === APIキー設定 ===
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
genai.configure(api_key=os.getenv("GOOGLE_API_KEY"))

prompt = "GPTとGeminiの違いを簡潔に説明してください。"

# === GPT呼び出し ===
def call_gpt(prompt):
    start = time.time()
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}],
    )
    latency = time.time() - start
    return {
        "model": "gpt-4o-mini",
        "text": response.choices[0].message.content.strip(),
        "latency": latency,
    }

# === Gemini呼び出し ===
def call_gemini(prompt, model="models/gemini-2.5-flash"):
    start = time.time()
    model_obj = genai.GenerativeModel(model)
    response = model_obj.generate_content(prompt)
    latency = time.time() - start
    return {
        "model": model,
        "text": response.text.strip(),
        "latency": latency,
    }

# === 実行 ===
if __name__ == "__main__":
    print("=== GPT ===")
    gpt_out = call_gpt(prompt)
    print(f"model: {gpt_out['model']} latency(s): {gpt_out['latency']:.2f}")
    print("text:", gpt_out["text"], "\n")

    print("=== Gemini Flash ===")
    gemini_flash_out = call_gemini(prompt, "models/gemini-2.5-flash")
    print(f"model: {gemini_flash_out['model']} latency(s): {gemini_flash_out['latency']:.2f}")
    print("text:", gemini_flash_out["text"], "\n")

    print("=== Gemini Pro ===")
    gemini_pro_out = call_gemini(prompt, "models/gemini-2.5-pro")
    print(f"model: {gemini_pro_out['model']} latency(s): {gemini_pro_out['latency']:.2f}")
    print("text:", gemini_pro_out["text"])

$ python3 compare.py
=== GPT ===
model: gpt-4o-mini latency(s): 6.15
text: GPTとGeminiは、AI言語モデルですが、設計や機能にいくつかの違いがあります。

1. **開発者**:
– GPT(Generative Pre-trained Transformer)は、OpenAIによって開発されました。
– Geminiは、Google DeepMindによって開発されています。

2. **アプローチ**:
– GPTは大規模なテキストデータを用いて事前に学習し、生成タスクに強みを持っています。
– Geminiは、より多様なデータソースを統合し、より広範な知識や能力を持つことを目指しています。

3. **用途**:
– GPTは主に会話、文章生成、質問応答などに利用されます。
– Geminiは、同様の機能を持ちながら、強化学習やマルチモーダル処理などの高度な機能を取り入れることが期待されています。

これらの違いにより、各モデルは異なるニーズや用途に応じて使われることがあります。

=== Gemini Flash ===
WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
E0000 00:00:1760237589.456894 56153 alts_credentials.cc:93] ALTS creds ignored. Not running on GCP and untrusted ALTS is not enabled.
model: models/gemini-2.5-flash latency(s): 8.99
text: GPTとGeminiの最も大きな違いは、**「開発元」**と**「マルチモーダル能力への注力度」**です。

* **GPT(OpenAI製)**
* 主にテキストベースの処理に強みを持つ大規模言語モデルです。自然な会話、文章生成、要約、翻訳などが得意です。元々はテキスト中心で進化してきました。

* **Gemini(Google製)**
* テキストだけでなく、画像、音声、動画といった**複数の情報形式(マルチモーダル)を最初から統合的に理解し、生成すること**に特に注力して開発されています。

どちらも非常に高性能なAIですが、Geminiはより多様な種類の情報を横断的に扱えるように設計されている点が特徴と言えます。

=== Gemini Pro ===
model: models/gemini-2.5-pro latency(s): 13.69
text: はい、承知いたしました。GPTとGeminiの違いを簡潔に説明します。

一番大きな違いは、AIの**「生まれと育ち(設計思想)」**です。

### GPT (OpenAI製) – 「テキストが得意な専門家」

* もともと**テキスト(文章)を極めるために開発**され、後から画像などを認識する能力が追加されました。
* 例えるなら「国語をマスターした人が、後から美術を学んだ」イメージです。
* **得意なこと:** 創造的な文章作成、自然な会話、要約など、言語に関するタスク全般。

### Gemini (Google製) – 「生まれながらのマルチタレント」

* 最初から**テキスト、画像、音声、動画などを同時に扱える**ように設計されています(ネイティブ・マルチモーダル)。
* 例えるなら「国語も美術も音楽も、最初から一緒に学んできた」イメージです。
* **得意なこと:** 画像を見ながら質問に答える、図やグラフを読み解くなど、複数の情報を組み合わせた複雑なタスク。

### まとめ

| | GPT (GPT-4など) | Gemini |
| :— | :— | :— |
| **開発元** | OpenAI | Google |
| **特徴** | テキスト中心に発展 | 最初からマルチモーダル |
| **強み** | **文章生成**や**対話の自然さ** | **画像や音声を含む複合的な質問** |
| **搭載例** | ChatGPT, Microsoft Copilot | Gemini (旧Bard), Google検索 |

どちらも非常に高性能ですが、**文章作成ならGPT**、**画像や音声も絡めた分析ならGemini**といったように、現時点では得意な分野が少し異なります。

—-
このコードで示している「差」の解説

モデル選択(モデル名)

GPT 側は gpt-4o のように「オムニモーダル」かつ会話最適化を想定。
OpenAI
+1

Gemini は flash(低遅延・低コスト向け)と pro(精度重視)などプロファイルがある点を示している。
blog.google
+1

マルチモーダル入力

両者とも画像や音声を扱えるが、実装のインターフェースや得意分野(音声・動画の理解、あるいは空間・映像処理)に差がある。Geminiは特にマルチモーダル統合を重視している。
blog.google
+1

レイテンシとコスト(コード内の time.sleep は擬似)

Gemini の Flash 系は「高速・効率化」をうたっており、高頻度・低遅延なユースケースに向く。OpenAIも GPT-4o で高速化・低コスト化の改善を進めている(モデルと提供形態で差がある)。
blog.google
+1

用途の違い(選び方)

「対話の自然さ・汎用性」と「広いエコシステム連携(Googleサービス)」、さらに「長文コンテキストや特殊なマルチモーダル処理」などで判断する。具体的な要件(コンテキスト長、マルチモーダル比重、レイテンシ、運用コスト、データポリシー)で選ぶのが実務的。
OpenAI
+1

補足(実務でのチェックリスト)

API の利用規約/データ利用方針を必ず確認(トレーニングへの利用、保存、削除ポリシー)。
G2 Learn Hub

日本語・専門分野での品質比較はケースバイケース。ベンチマーク(自分のデータで)を取るのが確実。
labelyourdata.com

大きなコンテキスト(100kトークン以上など)を扱う必要がある場合は、各モデルの「最大コンテキスト長」を確認。

[Dify] Zepプラグインによる長期メモリ活用

■Zepプラグインの主なブロック
1. Initialize Session
新しいセッション(ユーザーごとの会話コンテキスト)を作成
例:ユーザーが初めてチャットを開始するときに使用

2. Get Session Memory
既存セッションの過去の会話や記憶を取得
例:直近の会話履歴や保存しておいたメモを LLM に渡したいとき

3. Add Message to Session
新しいメッセージをセッションに追加(保存)

LLMの学習方法(事前学習、FineTuning, RLHF)

LLMの学習方法は大きく分けて3つある

1. 事前学習(Pre-training)
目的:
「言語の基礎的な知識」を身につける段階
文法・語彙・一般常識・文脈の理解などを、膨大なテキストから学ぶ

方法:
教師なし学習(Self-supervised learning)
入力文の一部を隠して、隠された部分を予測する(=マスク言語モデル、例:BERT)
次の単語を予測する(=自己回帰モデル、例:GPT系列)

データ:
インターネット上のテキスト(Webページ、書籍、Wikipediaなど)
数百億〜数兆トークン規模

2. ファインチューニング(Fine-tuning)
目的:
事前学習で得た「言語の基礎力」を、特定の目的や用途に合わせて調整

方法:
教師あり学習(Supervised fine-tuning)
入力と正解(出力)のペアを与える。
例:「質問 → 回答」「命令 → 応答」
少量の高品質データで調整。

3.人間のフィードバックによる強化学習(RLHF: Reinforcement Learning from Human Feedback)
目的:
モデルの出力を「人間にとって好ましい形」にする。
(=有用で、正確で、安全で、自然な応答にする)

① SFTモデル(ファインチューニング済)を使って、複数の応答候補を生成。
② 人間の評価者が「どの回答が良いか」を順位付け。
**③ 報酬モデル(Reward Model)**を学習。
→ 「この応答が好ましい」と判断するスコア関数を作る。
**④ 強化学習(PPOなど)**でモデルを更新し、報酬が高い出力を出すように最適化。

### Pretraining

import torch
import torch.nn as nn
import torch.optim as optim

text = "I love AI . AI loves people ."
vocab = list(set(text.split()))
word2idx = {w:i for i,w in enumerate(vocab)}
idx2word = {i:w for w,i in word2idx.items()}

def make_data(text):
    words = text.split()
    X, Y = [], []
    for i in range(len(words)-2):
        X.append([word2idx[words[i]], word2idx[words[i+1]]])
        Y.append(word2idx[words[i+2]])
    return torch.tensor(X), torch.tensor(Y)


X, Y = make_data(text)

class TinyLM(nn.Module):
    def __init__(self, vocab_size, hidden_size=8):
        super().__init__()
        self.emb = nn.Embedding(vocab_size, hidden_size)
        self.fc = nn.Linear(hidden_size*2, vocab_size)

    def forward(self, x):
        x = self.emb(x).view(x.size(0), -1)
        return self.fc(x)

model = TinyLM(len(vocab))
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.01)

for epoch in range(200):
    output = model(X)
    loss = criterion(output, Y)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

test = torch.tensor([[word2idx["I"], word2idx["love"]]])
pred = torch.argmax(model(test), dim=1)
print("Predicted next word:", idx2word[pred.item()])

### Fine tuning

train_data = [
    ("Hello", "Hi there!"),
    ("How are you?", "I'm fine, thank you."),
    ("Bye", "Goodbye!")
]

from transformers import AutoTokenizer, AutoModelForCausalLM, Trainer, TrainingArguments

tokenizer = AutoTokenizer.from_pretrained("gpt2")
model = AutoModelForCausalLM.from_pretrained("gpt2")

# データを整形
inputs = [tokenizer(f"User: {q}\nAI:", return_tensors="pt") for q, _ in train_data]
labels = [tokenizer(a, return_tensors="pt")["input_ids"] for _, a in train_data]

# 学習っぽいループ
for i, (inp, lab) in enumerate(zip(inputs, labels)):
    out = model(**inp, labels=lab)
    loss = out.loss
    loss.backward()
print("Fine-tuning step complete ✅")

### RLHF

import random

# モデルの応答候補
responses = ["Sure, here’s an example.", "I don’t know.", "You’re stupid."]

# 人間が選んだランキング(良い順)
human_ranking = {"Sure, here’s an example.": 1, "I don’t know.": 0, "You’re stupid.": -1}

# 報酬モデル(スコア関数)を模擬
def reward(response):
    return human_ranking[response]

# 強化学習っぽい更新(高報酬応答を強化)
policy = {r: 0.0 for r in responses}
for _ in range(10):
    r = random.choice(responses)
    policy[r] += reward(r) * 0.1

print("Learned policy:", policy)

[LLM] トランスフォーマー構造の概要とAttentionの考え方

## 1. トランスフォーマーとは?
トランスフォーマーは2017年に登場した自然言語処理のニューラルネットワーク構造
RNNやCNNと違って系列データの処理を並列化できるのが最大の特徴
– 入力: 文章(単語やトークンに分けたもの)
– 出力: 文章の予測や分類など
– 主な構成:
1. エンコーダ: 入力を内部表現に変換
2. デコーダ: 内部表現から出力を生成
LLM(ChatGPTなど)は、基本的にデコーダ中心のトランスフォーマを使っている

## Attentionの考え方
Attentionは「文章の中でどの単語に注目すべきかを学習する仕組み」
文章: 「猫がネズミを追いかける」
「追いかける」を予測するとき、
「猫」が主語だから重要
「ネズミ」も目的語として重要
他の単語(「が」や「を」)はそれほど重要ではない
これを 数値化して重み付け するのが Attention の仕組み

## Self-Attentionの仕組み
トランスフォーマーでは 各単語が文章の他の単語を参照して特徴を作る
これを Self-Attention と呼ぶ

Query (Q):注目するための質問
Key (K):候補の特徴
Value (V):候補の情報

Query と Key の内積 → 「どれくらい注目すべきか」を示すスコア
Softmax で正規化 → 重みを 0〜1 に
Value に重みをかけて足し合わせ → 注目した情報の合成

## Multi-Head Attention
Attention は 1種類の見方だけでなく、複数の異なる視点で注目することができます。
これを Multi-Head Attention と呼ぶ

例:
1つ目のヘッド:主語と動詞の関係に注目
2つ目のヘッド:目的語と動詞の関係に注目
これにより、文脈を多面的に理解できる

なるほど~