RNN と LSTM 入門
この primer はスキップしてよい。Transformer だけ読みたいなら、 次の primer に直接飛んでも構わない。だが Transformer の前に何があり、 Transformer が具体的にどんな痛みを解いたのかを理解することは、 「Transformer がなぜそれほど鋭い断絶だったか」を最もきれいに把握する方法だ。 短い 3 トピック:RNN、トークンを 1 個ずつ処理する基本的な 再帰型ネット;LSTM / GRU、長距離依存を扱うためのゲート付き派生; そしてなぜ Transformer がそれらを全部殺したか —— 並列化、本当の長距離記憶、encoder-decoder の情報ボトルネックの終わり。
RNN —— トークンを 1 個ずつ
系列を通じて運ばれる固定長の「記憶」。
テキスト primer §4 では Transformer 以前の景色に RNN 系を並べた。ここでは中を開けて みる。基本の RNN(Recurrent Neural Network、再帰型ニューラル ネットワーク)は、可変長入力を扱う最も単純なネット:系列を左から右へ歩き、各ステップ で新しいトークンを「今までに見た全ての記憶」と合わせる。
レシピは 1 行の更新規則、各タイムステップに 1 回適用:
h_t = tanh(W_h · h_{t−1} + W_x · x_t + b)
h_t はステップ t での隠れ状態 —— 系列のここまでをすべて 要約した固定長ベクトル。x_t は新しいトークンの埋め込み。W_h が前の隠れ状態を再利用し、W_x が新しい入力を射影し、tanh が両方を絞り込む。重要なのは、W_h、W_x、b はすべてのタイムステップで同一であること —— これが「時間を跨ぐパラメータ共有」で、1 セットの重みであらゆる長さの系列を処理できる。
最後に出力 1 つだけ欲しい(感情分類、次トークン予測)タスクでは、最終の隠れ状態を読んで射影する:
順方向に 1 回走る: h_0 = tanh( 0 + W_x · x_0 + b ) ← "The" h_1 = tanh( W_h · h_0 + W_x · x_1 + b ) ← "dog" h_2 = tanh( W_h · h_1 + W_x · x_2 + b ) ← "runs" h_3 = tanh( W_h · h_2 + W_x · x_3 + b ) ← "fast" 答えを読む: y = W_o · h_3 + b_o ← 予測
RNN が正しく解けていること:
- 可変長。同じ重みで、ループを必要な回数だけ回す。5 トークンの文も 5000 トークンの文書もまったく同じパラメータを使う。
- 順序は構造上尊重される。トークン
x_tはt以降の隠れ状態にしか影響できない;再帰が厳格な左→右の読み方を強制する。 - パラメータが少ない。各「役割」に行列 1 つ(
W_h、W_x、W_o)、どこでもそれを使い回す。言語向けに訓練された RNN は合計数百万パラメータで済むことも。
RNN がうまくいかないこと:
- 逐次。
h_4ができるまでh_5は計算できない。 1 サンプル内で時間を跨いだ並列化ができないので、GPU には拷問だ。 - 時間にわたる勾配消失 / 爆発。
∂L/∂h_0を計算するには、 チェーン全体を逆向きに歩き、毎ステップW_hを掛ける必要がある。‖W_h‖ < 1なら勾配は 0 へ、‖W_h‖ > 1なら NaN へ。 誤差逆伝播 primer §3 で扱った失敗モードと同じ。 - 有限容量の記憶。隠れ状態は固定長ベクトル。500 トークンの段落の意味を 1024 個の浮動小数点に詰め込むのは損失圧縮;古い情報は新しい情報で上書きされる。
最初の弱点が GPU 殺し。2 つ目と 3 つ目のせいで、小さな RNN ですら数十トークンを 超えると苦しむ。LSTM と GRU(§2)は勾配問題を正面から殴り、Transformer (次の primer)は再帰そのものを捨てて 3 つを一気に解く。
LSTM & GRU —— ゲート付き記憶
学習可能なゲートが制御する、ハイウェイ上を流れる独立した cell state。
ふつうの RNN の最大の弱点は §1 で扱った「時間にわたる勾配」問題 —— 20 ステップ 戻る頃には W_h を 20 回掛けている。信号は塵か NaN になる。 Hochreiter と Schmidhuber(1997)が巧妙な構造的修正を提案した:独立した cell state c_t をタイムラインに沿ってほぼ無傷で流し、各ステップで何を捨て、何を加え、 何を晒すかを学習可能なゲートに決めさせる。これが LSTM(Long Short-Term Memory)だ。
1 タイムステップの完全な更新 —— 見た目より怖くない:
Forget ゲート: f_t = σ(W_f · [h_{t-1}, x_t] + b_f)
Input ゲート: i_t = σ(W_i · [h_{t-1}, x_t] + b_i)
候補: ĉ_t = tanh(W_c · [h_{t-1}, x_t] + b_c)
セル更新: c_t = f_t · c_{t-1} + i_t · ĉ_t
Output ゲート: o_t = σ(W_o · [h_{t-1}, x_t] + b_o)
隠れ状態: h_t = o_t · tanh(c_t)各ゲートは sigmoid(値は [0, 1])で、制御対象に要素ごとに掛かる。各行を文として読む:
- Forget(忘れる) —— 「古い cell state の、この割合を残す」。
f = 1なら全部残す、f = 0なら消し去る。 - Input + 候補 —— 「これだけ(i)この内容(ĉ)を cell に書く」。
i = 0なら何も書かない;候補そのものは tanh で囲った 「加える新情報」の塊。 - Output(出力) —— 「(更新後の)cell state の、この割合を新しい 隠れ状態 h_t として晒す」。隠れ状態は次タイムステップのゲートにも、LSTM の上の 層にも流れていく。
これが勾配消失を解く理由は繊細で美しい。cell state の更新を見る:c_t = f_t · c_{t-1} + i_t · ĉ_t。c_t の c_{t-1} に関する微分はちょうど f_t。 ネットワークが特定の cell 次元で「複数ステップにわたり f_t ≈ 1」を学べば、 勾配はそのステップ群を通じてほぼ減衰せずに流れる —— 1 を 20 回掛けても 1。 普通の RNN ではどの逆ステップでも文脈に関わらず W_h を掛けていた。 LSTM は「いつ忘れるか自分で選ぶ」つまみをネットワークに与える;普通の RNN にはない。
GRU(Gated Recurrent Unit、2014)は人気のある単純化版: ゲートが 2 つ(reset と update)だけ、独立した cell state なし。LSTM より約 25% パラメータが少なく、わずかに高速、実用では精度に区別がつかないことも多い。 フレームワークにバインドがある方を使えばよい。
LSTM / GRU が普通の RNN に対して得たもの:
- 長距離依存が現実的に。100、500、ときに 1000 トークン文脈も訓練可能。 forget ゲートが 1 付近に留まれば、cell state は遠距離にわたり情報を保持できる。
- 訓練が安定。長系列で NaN になりにくい。普通の RNN は色々な技 (勾配クリッピング、慎重な初期化)を必要としたが、LSTM はほぼ素直に動く。
解決していないもの:
- 依然逐次。ステップ
tのゲート値はh_{t-1}に依存、それはh_{t-2}に依存、と続く。 GPU は今もこれを嫌う。 - 記憶は依然有限。cell state は固定長 —— 文脈窓を大きくしても、 同じ数の浮動小数点に多くの情報が押し込まれるだけ。
- n トークン処理は依然 O(n) 逐次操作。1024 次元の隠れ状態を持つ LSTM は 1 ステップは速いが、各ステップが次を塞ぐ。
2014 から 2017 年まで、LSTM は系列モデリングの主流だった —— ニューラル機械翻訳、 言語モデル、音声認識。2016 年の Google 翻訳の書き直しは深層 LSTM。ELMo(2018)、 最初に広く使われた文脈化埋め込み、は双方向 LSTM。そしてアテンションがすべてを引き継いだ。
なぜ Transformer がすべてを殺したか
Transformer が一気にもたらし、LSTM では届かなかった 3 つの構造的勝利。
2017 年頃から、LSTM はランキングから徐々に姿を消した。2020 年には、主要アーキテクチャ として LSTM を使う最近の NLP 論文を見つけるのは難しい。Transformer(Vaswani et al.、 2017)は LSTM をあまりに完全に置き換えたので、3 年の間に分野全体が再装備した。 なぜか? 3 つの性質 —— それぞれが §1 と §2 で扱った RNN 系の具体的な弱点への 直接的な応答だ。
1. 並列性。
RNN のタイムステップ t は t − 1 が終わるまで開始できない。 隠れ状態は順番に計算するしかない、それだけ。現代の GPU には数千の並列コアがあり、 その上で LSTM を回すとほぼすべてが遊んでいる。バッチ並列(複数系列を並列に) があっても、系列内の作業は逐次。
Transformer の self-attention 層は対照的に、各位置の出力を並列に計算する。 位置 1、位置 5、位置 5000 が同じ瞬間に処理される。バッチ 64 × 系列長 2048 で Transformer を 1 回前向きすると GPU は完全に埋まる;同じバッチで LSTM を回すと、 バッチ次元で GPU を埋めたとしても 1 系列あたり 2048 倍遅い。これがスケールにおいて Transformer が LSTM を食う最大の理由だ。
2. 本当の長距離記憶。
LSTM の巧妙な forget ゲートがあっても、トークン 1 からの情報がトークン 1000 に 影響するには 999 ステップのゲート演算を通る必要がある。ゲートはそれを通すこともできる (理論上は毎ステップ forget ≈ 1 でよい)が、実際にはネットワークが残すべき各次元でその振る舞いを学習する必要があり、難しい最適化問題だ。本物の LSTM は 距離に対して滑らかに劣化する。
Transformer では、位置 1 と位置 1000 はアテンションによって直接結ばれている。 モデルは両者の query と key を掛け、類似度を得、softmax を通して重みづける。 位置 1 から位置 1000 への寄与は 999 の中間ゲートを通らず、1 本のアテンション辺を通る。 任意の 2 トークン間の「実効経路長」は O(1)、O(n) ではない。
3. 情報ボトルネックがない。
encoder-decoder タスク(翻訳、要約)では、RNN encoder が原文系列を読み、最終隠れ状態 を作る。その単一の固定長ベクトルが decoder に渡され、decoder はそこから出力系列全体を 生成する。200 語の段落を翻訳する場合、その段落の意味全体が数千次元のベクトルに収まり、 decoder が単語ごとにそれを展開する必要がある。Bahdanau et al.(2014)はこれを ボトルネックと認識し、decoder が最後の 1 つではなくすべての encoder 隠れ状態を見れる ようにアテンション機構を提案した。これ自体が翻訳品質に巨大な向上をもたらした —— と同時に、「再帰こそが間違った原語ではないか?」という伏線を植えた。
Vaswani 2017 の答えは「そうだ」。RNN を捨てる。アテンションを encoder と decoder の 各層で使う。すると各出力位置はあらゆる入力位置に直接注目できる —— ボトルネックなし、薄れる記憶なし、逐次の詰まりなし。
Transformer がこの 3 勝に払う対価:
- 系列長に対する 2 乗のメモリ / 計算量。n トークン間のペアワイズ アテンションは n² エントリ。n = 1024 なら問題なし、n = 1,000,000 なら破滅的。2020 年以降の ML システム研究の半分は「効率的アテンション」 (FlashAttention、スパース、線形、スライディング窓、ring attention)で 2 乗の天井を 崩そうとしている。
- パラメータ数が増える。Transformer は各層に独立の Q、K、V 投影と FFN サブ層が必要。中規模の Transformer でも LSTM 時代のパラメータ数を遥かに超える。 一部は良いこと(容量増)、一部は無駄。
- 順序を明示的に注入する必要がある。アテンション自体は順序不変なので、 Transformer には位置エンコーディングが必要 —— テキスト primer §2 で簡単に触れた、 次の primer で詳述する。
私たちが気にかける種類の系列(テキスト、コード、音声フレーム、キロトークン規模の トークン化された何か)では、勝利が代償を大きく上回る。それが過去 7 年の中身だ。
RNN が戻りつつある場所も一言:極めて長い系列(DNA、数時間の音声など)では、 アテンションの n² コストが現実的でなくなる。Mamba(2023)や他の状態空間モデル、 RWKV(2023)は、現代の訓練技法とともに RNN 風の再帰を復活させ —— 極端な長さでは逆に Transformer に勝つ。だが 2026 年の LLM の典型的な 4k–128k コンテキスト窓では、Transformer の 3 勝が依然として主旋律だ。
これが歴史的文脈だ。次の primer は Transformer 自体をブロック単位、サブ層単位で ほどく —— そして同じアーキテクチャがどう 3 つの性質を同時に届けるかを見ることになる。