【自作LLMをまた少し改良】文章に多様性が無い問題を解決!Nucleus Samplingで10%→100%へ【SNN-LLM v3】
はじめに
こんにちは、日本語向けのSNN製LLM開発を試行錯誤しています、ろーるです!
まずちょっとした嬉しい報告ですが、先日、スマホのクロムの新しいタブを開いたら、おすすめ(Google Discover)に自分の記事が出てきてびっくりしましたw
思わずスクショまでしましたw

あと、最近少しずつLikeをつけて下さる方や訪問して下さる方が増えてきて嬉しい限りです!😊ありがとうございます!
今回は私が作っているSNN-LLM(スパイキングニューラルネットワーク製の大規模言語モデル)のv3アップデートを報告します。前回のv2で11次元ハイパーキューブトポロジーを導入しましたが、今回は多様性問題を根本解決しました。
因みにv3で達成した成果は以下3つです!
- 🔧 単語単位学習(MeCab使用)
- 🎯 Nucleus Samplingで多様性1/10 → 10/10達成!
- ⚖️ 品質83.5%を維持しつつ多様性100%
この記事で出てくる用語解説
| 用語 | 意味 |
|---|---|
| SNN(スパイキングニューラルネットワーク) | 脳みその神経細胞を真似したAI |
| Nucleus Sampling | AIの選択の方法を工夫する技術 |
| Temperature | AIの選択のランダム度。高ければバラつき、低いと同じのばかり |
| MeCab | 日本語を単語に分ける道具 |
今回解決した「多様性が無い問題」について
症状
同じプロンプトを入れると、毎回同じ出力が出てくる...
プロンプト: 人工知能
1回目: 人工知能はが人間のを社会に変革もたらしている。
2回目: 人工知能はが人間のを社会に変革もたらしている。
3回目: 人工知能はが人間のを社会に変革もたらしている。
...(10回とも同じ)
多様性: 1/10 (10%) 😭
試したけど効果なかったもの
| アプローチ | 結果 |
|---|---|
| コーパス拡大(覚えさせる文章を23行→10,000行に) | 1/20(悪化!) |
| Dropoutを25%に(ノイズを入れる) | 1/20(効果なし) |
| Temperatureを上げる(低確率の選択も選ばれやすくする) | 1/10(変化なし) |
コーパスやアーキテクチャの問題ではなかった...
解決策:Nucleus Sampling(次の単語の選択確率を変えた!)
私の今のLLMモデルは次の単語を選ぶとき、確率で選んでます。
従来の確率分布:
「は」: 80% ← ほぼこれが当たる
「が」: 10%
「も」: 5%
「を」: 3%
「に」: 2%
80%もあると、ほぼ毎回「は」が選ばれてた。
今回実装したNucleus Sampling(核サンプリング):
「確率の高い単語だけで選ぶ!でも1つだけでなく、合計で90%になるまで選択肢を入れる!」
「は」: 80% ← 入れる
「が」: 10% ← まだ90%に達してないから入れる
------------ ここで90%超えたのでこれ以上の選択肢は入れない ------------
「も」: 5% ← 入れない
「を」: 3% ← 入れない
「に」: 2% ← 入れない
こうして、「は」と「が」だけでくじ引き!
新しい確率:
「は」: 89%
「が」: 11%
たまに「が」も選ばれるようになった!🎉
Nucleus (Top-p) Samplingの実装
通常のサンプリング:
probs = softmax(logits / temperature)
next_token = np.random.choice(vocab, p=probs)
問題: 確率が極端に偏っていると、ほぼ同じトークンが選ばれ続ける
Nucleus Sampling:
# 確率の高い順にソート
sorted_probs = sort(probs, descending=True)
# 累積確率がpに達するまでの候補だけ残す
cutoff = find_index_where(cumsum(sorted_probs) > p)
candidates = sorted_probs[:cutoff]
# 候補の中からサンプリング
next_token = sample(candidates)
実装コード
@njit(cache=True)
def nucleus_sampling(logits, p=0.9, temperature=1.0):
scaled_logits = logits / temperature
probs = softmax(scaled_logits)
# 確率順にソート
sorted_indices = np.argsort(probs)[::-1]
sorted_probs = probs[sorted_indices]
# 累積確率がpを超えるまで
cumsum = np.cumsum(sorted_probs)
cutoff_idx = 1
for i in range(len(cumsum)):
if cumsum[i] > p:
cutoff_idx = i + 1
break
# 再正規化してサンプリング
selected = sorted_probs[:cutoff_idx]
selected = selected / sum(selected)
# ランダム選択
r = np.random.random()
for i in range(len(cumsum)):
if r < cumsum[i]:
return sorted_indices[i]
return sorted_indices[0]
結果
多様性の劇的改善
| 手法 | Temp | 多様性 | 品質 |
|---|---|---|---|
| 従来(標準sampling) | 0.9 | 1/10 ❌ | 85 |
| Nucleus (p=0.9) | 1.2 | 10/10 ✅ | 75 |
| Nucleus (p=0.9) | 0.8 | 10/10 ✅ | 83.5 🏆 |
生成サンプル
Before(従来手法)
1: 人工知能はが人間のを社会に変革もたらしている。
2: 人工知能はが人間のを社会に変革もたらしている。
3: 人工知能はが人間のを社会に変革もたらしている。
(全部同じ...)
After(Nucleus Sampling)
1: 人工知能は抽象とてもを生み出している。
2: 人工知能は堅牢なをシステム構築する。
3: 人工知能は人間の能力をと超えている。
4: 人工知能は飛躍的には新しいアルゴリズムを生み出している。
5: 人工知能は人間の能力を超えとている。
(10個すべて違う!)
パラメータ探索
Temperature
T=0.7 → 多様性: 10/10, 品質: 80.5
T=0.8 → 多様性: 10/10, 品質: 83.5 ← 最適!
T=0.9 → 多様性: 10/10, 品質: 78.0
T=1.0 → 多様性: 10/10, 品質: 78.0
T=1.2 → 多様性: 10/10, 品質: 75.0
発見: 低めの温度(0.8)で品質維持、Nucleus Samplingで多様性確保
Top-p
p=0.70 → 多様性: 10/10, 品質: 80.5
p=0.80 → 多様性: 9/10, 品質: 81.0
p=0.85 → 多様性: 8/10, 品質: 77.0
p=0.90 → 多様性: 10/10, 品質: 78.0 ← 安定
p=0.95 → 多様性: 10/10, 品質: 80.0
技術詳細:ハイブリッド読み出し
現在のアーキテクチャ
logits = W_spike @ h + W_membrane @ m + bias
-
h: スパイク(0 or 1の離散値) -
m: 膜電位(連続値)
なぜ両方使うのか
| 読み出し方法 | 問題 |
|---|---|
| スパイクのみ | 「発火寸前」の情報が失われる |
| 膜電位のみ | 離散的な発火タイミング情報が失われる |
| 両方(Hybrid) | より豊かな情報で判断可能 ✅ |
v1-v3の進化
| バージョン | トークン化 | 主な成果 |
|---|---|---|
| v1 | 文字 | 1000x RAM削減、PPL 1.39 |
| v2 | 文字 | 11D Hypercube、PPL 81.92 |
| v3 | 単語 | 多様性 10/10、Nucleus Sampling |
残課題
- 文法エラー: 「をと」「てもを」などの不自然な表現
- ドメイン限定: AI/脳科学の語彙のみ(359語)
- PPL未計測: 今回は多様性重視で評価
論文
Zenodo Working Paper v3:
現状のまとめ等
🎯 Nucleus SamplingがSNNの多様性問題を解決!
- サンプリング手法の変更だけで1/10 → 10/10
- Temperature 0.8 + top-p 0.9が最適
- アーキテクチャ変更なしで効果あり
GeminiやチャットGPT等の様々な国の言語で、汎用的な会話ができるAIの凄さを益々痛感しています・・・(^_^;)
私は汎用的に使えるAIの開発と言うより、性能を短時間で上げる方法や、同じ性能を保ったまま省電力化や小容量化ができる方法がないかを研究していきたいと思います!😊
次は文法品質の改善に取り組みます!
Discussion