Fragments of verbose memory

冗長な記憶の断片 - Web技術のメモをほぼ毎日更新

Feb 23, 2026 - 日記

セマンティックエントロピー入門: LLMが「自信なさげ」な回答を数値化する仕組み

セマンティックエントロピー入門: LLMが「自信なさげ」な回答を数値化する仕組み cover image

「GPT-4に質問したら、なんか自信なさそうな回答が返ってきた」——そんな経験はありませんか?

実は、LLMの「自信のなさ」は数値化できます。それを可能にするのが セマンティックエントロピー(Semantic Entropy)という技術です。

本記事では、Oxford大学の研究論文 (Nature 2024年掲載)をベースに、セマンティックエントロピーの仕組みと、それを実装したPython ライブラリ Klarity を紹介します。

なぜ「トークン単位の確率」だけでは不十分なのか

LLMは各トークン(単語の断片)を生成する際、確率を計算しています。例えば「東京の首都は」に続く単語として「日本」が90%、「Tokyo」が5%、といった具合です。

この確率を使って「LLMがどれだけ自信を持っているか」を測る方法として、生エントロピー(Raw Entropy)があります。エントロピーは「不確実性の度合い」を示す指標で、値が高いほど「迷っている」ことを意味します。

しかし、生エントロピーには致命的な欠点があります。

問題1: 言い換えを区別できない

次の2つの回答を見てください。

  • 回答A: 「東京は日本の首都です」
  • 回答B: 「日本の首都は東京です」

意味は同じですが、トークン列は異なります。生エントロピーは、この2つを「別の回答」として扱い、不確実性が高いと判断してしまいます。

問題2: 表現のバリエーションに弱い

「2 + 2 = 4」という質問に対して、LLMが以下のように回答したとします。

  • 「4です」(確率50%)
  • 「答えは4です」(確率30%)
  • 「計算結果は4です」(確率20%)

生エントロピーは「3つの異なる回答があるので不確実性が高い」と判断しますが、実際には全て同じ意味です。

セマンティックエントロピーの仕組み

セマンティックエントロピーは、この問題を「意味の同一性」で解決します。

基本アイデア

  1. 複数の回答を生成: 同じ質問に対して、LLMに複数回答えさせる(例: 10回)
  2. 意味でグループ化: 回答を「意味が同じかどうか」でクラスタリング
  3. クラスタ単位でエントロピー計算: トークン単位ではなく、意味のグループ単位で不確実性を測る

具体例

質問: 「フランスの首都は?」

生成された回答(10回):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
1. パリです(確率: 0.3)
2. Paris(確率: 0.2)
3. パリ(確率: 0.15)
4. 首都はパリです(確率: 0.15)
5. ロンドン(確率: 0.05)
6. マルセイユ(確率: 0.05)
7. パリだと思います(確率: 0.05)
8. Parisです(確率: 0.03)
9. パリですね(確率: 0.01)
10. ベルリン(確率: 0.01)

セマンティッククラスタリング後:

クラスタ回答合計確率
クラスタA(パリ)1, 2, 3, 4, 7, 8, 90.89
クラスタB(ロンドン)50.05
クラスタC(マルセイユ)60.05
クラスタD(ベルリン)100.01

セマンティックエントロピー計算:

1
2
3
4
5
6
7
8
9
import numpy as np

# クラスタごとの確率
p = [0.89, 0.05, 0.05, 0.01]

# エントロピー = -Σ(p * log(p))
semantic_entropy = -np.sum([pi * np.log(pi) for pi in p if pi > 0])
print(f"セマンティックエントロピー: {semantic_entropy:.3f}")
# 出力: セマンティックエントロピー: 0.412

この値が低いほど「LLMは自信を持っている」ことを意味します。

生エントロピーとの比較

同じ例で生エントロピーを計算すると、10個の異なるトークン列があるため、エントロピーは約2.3になります(セマンティックエントロピーの5倍以上)。

つまり、生エントロピーは「表現のバリエーション」を「不確実性」と誤認してしまうのです。

Klarity: セマンティックエントロピーを実装したPythonライブラリ

Klarity は、セマンティックエントロピーを簡単に計算できるPythonライブラリです。

主な機能

  • Dual Entropy Analysis: 生エントロピーとセマンティックエントロピーを同時に計算
  • Reasoning Analyzer: DeepSeek-R1等のCoT(Chain-of-Thought)推論の分析
  • VLM Analyzer: Vision-Language Modelのアテンション分析
  • ハルシネーション検出: エントロピーベースで誤情報を検出(精度80%+)

対応フレームワーク

インストール

GitHubから直接インストールするか、PyPIからインストールできます。

1
2
3
4
5
# GitHubから最新版をインストール(推奨)
pip install git+https://github.com/klara-research/klarity.git

# または PyPI から安定版をインストール
pip install klarity

基本的な使い方

以下のコードは、Hugging Face Transformersを使って、質問に対するLLM の不確実性を測定する例です。UncertaintyEstimatorEntropyAnalyzerを組み合わせて、生成時のトークンごとの不確実性を分析します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
from transformers import AutoModelForCausalLM, AutoTokenizer, LogitsProcessorList
from klarity import UncertaintyEstimator
from klarity.core.analyzer import EntropyAnalyzer

# モデルとトークナイザーのロード
model_name = "Qwen/Qwen2.5-0.5B-Instruct"
model = AutoModelForCausalLM.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)

# エントロピーアナライザーの初期化
estimator = UncertaintyEstimator(
    top_k=100,
    analyzer=EntropyAnalyzer(
        min_token_prob=0.01,
        insight_model=model,
        insight_tokenizer=tokenizer
    )
)

uncertainty_processor = estimator.get_logits_processor()

# 質問の準備
prompt = "What is the capital of France?"
inputs = tokenizer(prompt, return_tensors="pt")

# 不確実性分析付きで生成
generation_output = model.generate(
    **inputs,
    max_new_tokens=50,
    temperature=0.7,
    top_p=0.9,
    logits_processor=LogitsProcessorList([uncertainty_processor]),
    return_dict_in_generate=True,
    output_scores=True,
)

# 生成結果の分析
result = estimator.analyze_generation(
    generation_output,
    tokenizer,
    uncertainty_processor
)

generated_text = tokenizer.decode(
    generation_output.sequences[0], 
    skip_special_tokens=True
)

# 結果の表示
print(f"生成テキスト: {generated_text}")
print("\nトークンごとの不確実性分析:")
for idx, metrics in enumerate(result.token_metrics):
    print(f"  Step {idx}: 生エントロピー={metrics.raw_entropy:.4f}, "
          f"セマンティックエントロピー={metrics.semantic_entropy:.4f}")

# 総合的な分析結果
print("\n総合分析:")
print(result.overall_insight)

出力例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
生成テキスト: What is the capital of France? The capital of France is Paris.

トークンごとの不確実性分析:
  Step 0: 生エントロピー=0.8234, セマンティックエントロピー=0.1523
  Step 1: 生エントロピー=0.3421, セマンティックエントロピー=0.0821
  ...

総合分析:
{
    "scores": {
        "overall_uncertainty": 0.25,
        "confidence_score": 0.85,
        "hallucination_risk": 0.15
    },
    ...
}

結果の解釈

Klarityはoverall_insightとして、以下のスコアを返します。

  • overall_uncertainty(0-1): 全体的な不確実性。低いほど安定
  • confidence_score(0-1): 信頼度スコア。高いほど自信あり
  • hallucination_risk(0-1): ハルシネーションリスク。高いほど危険

一般的な目安として、hallucination_riskが0.3を超える場合は、回答の検証を推奨します。

セマンティックエントロピーの限界

セマンティックエントロピーは強力ですが、万能ではありません。

1. クラスタリングの精度に依存

「意味が同じかどうか」の判定には、別のLLM(または埋め込みモデル)を使います。この判定が間違っていると、エントロピー計算も狂います。

2. 計算コストが高い

複数回生成(通常10〜20回)が必要なため、単一回答の生成に比べて10〜20倍の時間がかかります。

3. 短い回答では効果が薄い

「はい」「いいえ」のような短い回答では、クラスタリングの意味が薄れます。

4. 「自信があるが間違っている」ケースは検出できない

LLMが「間違った回答に自信を持っている」場合、セマンティックエントロピーは低くなります。つまり、ハルシネーションを100%検出できるわけではありません。

他の手法との比較

手法仕組みメリットデメリット
セマンティックエントロピー意味ベースのエントロピー言い換えに強い計算コスト高
LLM-as-JudgeGPT-4等で検証高精度API課金、遅い
Cleanlab TLM商用SaaS導入簡単ベンダーロックイン
Semantic Entropy Probes (SEPs)軽量な不確実性定量化高速精度やや低

まとめ

セマンティックエントロピーは、LLMの「自信のなさ」を数値化する強力な手法です。

ポイント:

  • 生エントロピーは「トークン単位」、セマンティックエントロピーは「意味単位」で不確実性を測る
  • 言い換えや表現のバリエーションに強い
  • Klarityを使えば、Pythonで簡単に実装できる
  • 計算コストが高いため、全リクエストに適用するのは現実的ではない

おすすめの使い方:

  • 重要な判断(医療、法律、金融等)でLLMを使う場合の検証
  • RAGシステムの回答品質チェック
  • プロンプトエンジニアリングの効果測定

興味のある方は、ぜひKlarityのGitHubリポジトリをチェックしてみてください。

参考リンク