前書き
この記事はClaudeの協力を多大に受けて書きました。半日くらい内容の正しさを検証したり文章を整えたりと格闘したので、ある程度理解しているつもりですが、理屈が間違っている可能性もあります。論文として似た内容のことを主張しているものは今のところ見つけられていません。
Claudeもこの内容で実装およびトイタスクでの学習ができていると言っているのですが、まだコードまで確認はできていないです。
また、LoRAの性質を使ってさらに削減ができるようですが、長くなりそうだったのでまずはこの段階で切っています。
本編
古典 RNN を素朴な RTRL で学習するときの計算量は、状態の要素数を として空間計算量
・時間計算量
とされます。本稿では、 Gated DeltaNetを LoRA で学習する設定を考察します。
結論として、 1 層の GDN では、 (
は LoRA のランク、
は 残差ブロックでの次元 (
d_model) 、 はキー次元)として空間計算量が
、時間計算量が
となると考えられます。
0. 前提・記号
Gated DeltaNetはブロック1個は以下のようになっています。

1 サンプルについて考え、バッチ次元は省略します。
各種記号を以下のように定義します。実際の値はQwen3.5-0.8Bを使う場合の値となります。
| 記号 | 意味 | 実際の値 |
|---|---|---|
| |
時刻(トークン位置) | |
| |
残差ストリームの次元(d_model) | 1024 |
| |
GDN のヘッド数 | 16 |
| |
ヘッドあたりのキー次元・値次元 | 128, 128 |
| |
短い因果畳み込みのカーネル長 | 4 |
| |
LoRA のランク | 8 |
| |
LoRA のスケール |
2 |
| |
1 層あたりの状態の要素数 | 262,144 |
| |
学習層への入力(凍結した下位層の出力に、凍結した RMSNorm を掛けたもの)。学習対象のパラメータにも、この層の状態にも依存しない | |
| |
LoRA の対象となる射影の名前。 |
|
| |
射影 |
|
| |
凍結した事前学習重み | |
| |
LoRA 因子(学習対象) | |
| |
全 LoRA 因子を並べたベクトル | |
LoRA を付けるのは、ブロック内の次の 7 個の線形射影です。学習するパラメータは LoRA の因子だけで、事前学習済みの重みはすべて凍結します。
| 射影 |
役割 | 状態に寄与するか | 入力 |
出力 |
|---|---|---|---|---|
| |
元の in_proj_qkv のうち query の部分。状態の読み出しにだけ使う |
しない | |
|
| |
同じく key の部分。状態の更新に使う | する | |
|
| |
同じく value の部分。状態の更新に使う | する | |
|
| |
ゲート |
する | |
|
| |
ゲート |
する | |
|
| |
出力側のゲート用の射影 | しない | |
|
| out | GDN の出力射影 | しない | |
|
ヘッド の状態は
です。全ヘッドの状態を、ヘッド
、行
(キー次元)、列
(値次元)の順に 1 本に並べたベクトルを
とし、その添字を
と書きます。
1. 背景
GDN の基本式
LoRA や前処理を省いた GDN では、ヘッド ごとに、各時刻に入力から、キー
、値
、クエリ
、減衰ゲート
、書き込み強度
、出力ゲート
が作られます。状態
(キーから値への連想記憶)は次のように更新され、層の出力
が決まります。
に掛かる係数
は、入力から作られ、
に依存しません(遷移は状態に対して線形です)。Qwen3.5 では、
を次のように作ります。
1 層の GDN(Qwen3.5)
射影()は、LoRA を含めて次のようになります。
基本式の各量は、この から作られます。
:
に、短い因果畳み込み(直近
時刻分。チャネルごとに独立で、チャネルどうしは混ざりません)と silu を適用します。
はさらに L2 正規化します。これで
になります。
:それぞれ
、
だけから決まります。
:
をヘッドごとに
個ずつに分けたものです。
これらは、入力窓 と
だけから決まり、状態には依存しません。畳み込みのバッファ(過去
時刻の射影)も
と
の関数なので、状態に加える必要はなく、過去の
を
個保持しておけば足ります。
RTRL
状態更新を と書き、時刻
の損失を
、全時刻の損失の和を
と書きます。各量を次のように
定義します。
連鎖律から次の式が成り立ちます。
(1)(2) は近似を含まない恒等式なので、得られる勾配は BPTT と厳密に一致します。
素朴な RTRL の計算量
状態に寄与するパラメータ(0 節の表で「する」の の LoRA 因子)の数を
とします。状態に寄与しないパラメータは、感度が不要です。構造を使わずに
を密に持つ RTRL(以下、素朴な RTRL)では、1 ステップあたりのコストは次のようになります。
- 空間計算量:
を保持するので、
です。
- 時間計算量:
は
の行列積なので、
です。
古典 RNN (状態の要素数
、
)では、
なので、空間計算量は
、時間計算量は
です。
- 空間計算量が大きい理由。
の各要素は 1 ステップで
のすべての要素に影響し、その影響は
を通してさらに広がります。そのため
は一般に密行列で、
個の要素をすべて持つ必要があります。
- 時間計算量が大きい理由。
は密な
行列です。
では、
の 1 要素あたり
回の積和が必要になります。
2. 空間計算量
GDN では、 の大部分が常に 0 です。ここでは、実際に持つべき部分と、そのサイズを示します。
感度を考えるパラメータは、各射影 の LoRA 因子
です(
は
射影の
、
は
射影の
を指します)。
の行は、射影の出力チャネルに対応します。たとえば
の行は、ヘッド
の
の第
成分を表す 1 つの添字
で指定し、その行は
個の要素
を持ちます。
状態の要素 ごとに、
に影響しうるパラメータの感度だけを考えます。因子ごとに、どのパラメータの感度を持つかと、その要素数は次のとおりです(実際の数値は
、fp32、1 層・1 サンプルの場合です)。
| 因子 | 状態要素 |
要素数 | 実際の要素数 | メモリ | 参考:素朴な RTRL の要素数 |
|---|---|---|---|---|---|
| |
行 |
|
|
8 MiB | |
| |
行 |
|
|
8 MiB | |
| |
行 |
|
|
1 GiB | |
| |
|
|
|
8 GiB | |
| 合計 |
|
|
33 GiB | |
例として (
)を少し動かしたとき、その影響が届く範囲を確かめます。
- 射影の出力。
は、実効重み
の行
だけを変えます。
は入力
に掛かる行列で、状態には掛かりません。したがって、変わるのは、射影の出力
(畳み込みと silu を通す前の値)のチャネル
だけです(どの時刻でも同じです)。
- 畳み込みと silu。 畳み込みはチャネルごとに独立なので、変化はチャネル
に留まります。変わるのは
の第
成分
だけで、ほかの成分
(
)や、
は変わりません。
- 状態への書き込み。
が状態に入るのは、書き込み項
だけです。この項の第
列は
なので、
が変わると、書き込み項の第
列だけが変わります(
。
は第
成分だけが 1 の単位ベクトル)。
- 時間発展。 変わった第
列は、次のステップで
により変換されます。しかし、
は列どうしを混ぜないので、変化は第
列の中に留まります。
ほかの因子も同様です。
:
は、ヘッドごとに 1 つのスカラーで、そのヘッドの状態
の全要素に作用します。そのため、
と
だけが、
の全要素に効きます。ヘッド間は混ざりません。
:L2 正規化と
が行
(キー次元)を混ぜるので、
は、どの
でもヘッド
の全要素に効きます。
:
は、
の全出力チャネルに効きます。
よって空間計算量は、保持する感度の総要素数、つまり表の合計行の で決まり、
です。ほかに、過去
個の
(
)と状態
(
)も保持しますが、
に比べて小さい量です。
3. 時間計算量
時間計算量を決めるのは、(1) 式の です。
の各列(パラメータ
ごとの、長さ
のベクトル)は状態と同じ空間のベクトルで、これに
を掛けることは、その列を状態とみなして、順伝播の状態更新(の線形部分)を 1 回行うことと同じです。したがって、GDN の順伝播が速いのと同じ仕組みで、
も速く計算できます。
状態更新の線形部分は です。
と書き込み項は状態に依存しない(1 節)ので、
はこの操作を
の行列として書いたものそのものです。
- 2 節のとおり、左から掛けるだけなので、
の各列(長さ
)が独立に
で変換されます。
は単位行列からランク 1 を引いた形なので、長さ
のベクトル
に対して
と、内積 を 1 回計算すれば済みます。1 列あたり
、つまり 1 要素あたり
です。
保持する 個の要素それぞれに、1 要素あたり
でこの更新を行うので、
は
です(直接項
の足し込みと、勾配への縮約
も
です)。よって、1 ステップあたりの時間計算量は、
に、通常の 1 ステップの順伝播・逆伝播を加えたものになります。


























