Attention は 1 項ぶんずれていた
(evanmiller.org)- Transformer 内部の attention softmax は、head が「何もしない」を選べないようにしており、量子化や低メモリ環境へのデプロイを難しくしている可能性がある
- 問題の手がかりは LLM に現れる 外れ値 weight/activation であり、Qualcomm AI Research の論文は外れ値 activation の 97% 以上が空白や句読点の位置から生じると分析している
- 従来の softmax は、すべての入力が非常に大きな負の値でも各項に 1/k の重みを与えるが、
softmax_1は分母に 1 を加えることで attention 出力を 0 に近づけられるようにする softmax_1は相対比を保ちながら総和を 0 と 1 の間に制限し、正の導関数によって 0 ではない gradient も残る- この変更は既存モデルにそのまま差し込めるパッチではなく、再学習 が必要であり、LLaMA のようなモデルでは zero prefix token 方式で素早い実験が可能かもしれない
量子化を難しくする外れ値
- Transformer モデルには、ほかの値より 桁違いに大きい weight と activation が現れ、これらの値はモデルの動作に重要だとみられている
- このような外れ値は一般的な scale-and-bias 整数量子化で性能低下を引き起こし、大規模モデルを Mac Mini や Raspberry Pi のような RAM が限られた環境で動かしにくくする
- RAM 使用量を減らせれば、クラウド環境でもエッジ環境でも、より大きなモデルやより多くの機能を扱える余地が生まれる
- Qualcomm AI Research の Quantizable Transformers: Removing Outliers by Helping Attention Heads Do Nothing は、外れ値を attention mechanism の softmax と結び付けている
- LLM の外れ値 activation の 97% 以上 が whitespace と punctuation の位置で発生すると分析している
- clipped softmax には zero gradient の問題があり、gated attention は数百万個の新しいパラメータを追加する
Transformer における softmax の役割
- Transformer の入力 embedding は、単語を表現する浮動小数点ベクトルである
- Meta の LLaMA 2 は長さ 3,204 の embedding vector を使っており、half-precision 基準では単語 1 つの表現に 6KB 超が必要になる
- vocabulary は通常 30,000〜50,000 項目を持つ
- Transformer は入力ベクトルを同じサイズの出力ベクトルに変換し、最終出力ベクトルは現在のトークンの次に来るトークンの予測に使われる
- residual connection は、attention が元の単語情報に文脈情報を加える形で機能する
- たとえば
pupilが学生なのか、目の瞳孔なのかを見分ける文脈情報を追加する
- たとえば
- 最後の段階では、出力ベクトルを vocabulary 長のベクトルに変換してから softmax を適用し、次トークンの確率のように扱う
- 実際の実装では softmax 出力の確率をそのまま信じるのではなく、sampling mechanism を使う
- 出力段階の softmax は vocabulary 全体に gradient を与える役割があるため、妥当な選択とみなされている
内部 attention softmax の限界
- 内部 attention の中核となる式は次のとおり
[ \textrm{Attention}(Q, K, V) = \textrm{softmax}\left(\frac{QK^T}{\sqrt{d}}\right)V ]
- decoder-only model では、(Q)、(K)、(V) は同じ入力シーケンスから始まるが、それぞれ異なる形で projection される
- (QK^T) は token embedding vector 間の相関を見つけ、各行に softmax を適用して (V) matrix の value vector を混合する重みとして使う
- multi-head attention は、この処理を各 layer の複数の head で並列に行う
- embedding vector を複数の segment に分割し、各 head が output vector の一つの segment に情報を追加する
- 問題は、softmax が各 attention head に必ず annotation を作らせる点にある
- head に追加すべき情報がなくても、softmax は何らかの選択を作ってしまう
- specialized head ほど「pass」が必要になる可能性が高いが、従来の softmax には abstention がない
提案: softmax_1 と QuietAttention
- 提案されている変更は、softmax の分母に 1 を足すこと である
[ (\textrm{softmax}_1(x))_i = \frac{\exp(x_i)}{1+\sum_j \exp(x_j)} ]
- 従来の softmax では、すべての (x) の値が非常に大きな負の値に向かっても、各項は (1/k) に収束する
[ \lim_{x_1 \to -\infty} \ldots \lim_{x_k \to -\infty} (\textrm{softmax}(x))_i = \frac{1}{k} \gt 0 ]
softmax_1では、同じ条件で各項は 0 に収束する
[ \lim_{x_1 \to -\infty} \ldots \lim_{x_k \to -\infty} (\textrm{softmax}_1(x))_i = 0 ]
- この違いによって、attention head は情報を追加しないという選択ができるようになる
- 提案されている attention の式は次のとおり
[ \textrm{QuietAttention}(Q, K, V) := \textrm{softmax}_1 \left(\frac{QK^T}{\sqrt{d}}\right)V ]
softmax_1 の性質と実験条件
softmax_1は全体の値を少し縮小するが、attention の後に normalization があるため、その縮小は補正できる- 出力ベクトルの相対比は従来の softmax と同じである
[ \frac{(\textrm{softmax}_1(x))_i}{(\textrm{softmax}_1(x))_j} = \frac{(\textrm{softmax}(x))_i}{(\textrm{softmax}(x))_j} = \frac{\exp(x_i)}{\exp(x_j)} \quad \forall \ i, j ]
- 導関数は正で 0 ではない gradient を保ち、総和は 0 と 1 の間にあるため出力が制御範囲を外れない
- この問題は numerical precision ではなく 数学的な問題 として扱われており、precision を増やすだけでは解決しない
- 実験のアイデアは、すべての入力 context の先頭に zero vector を付け、positional encoding を含めて bias が加わらないよう保証する方法である
- zero がそのまま通れば、その後の各 softmax denominator に 1 を加える効果を持つ
- fixed embedding と special prefix token を使う LLaMA 系モデルなら可能かもしれない
- これは既存モデルにそのまま適用する実験ではなく、モデルの 再学習 が必要である
- 確認したい指標は、weight kurtosis と activation infinity norm の変化である
1件のコメント
Hacker News の意見
著者が提案しているのは最終出力のソフトマックスではなく、アテンション内部のソフトマックスの分母に 1 を足すこと
アテンションのソフトマックスはキー/クエリのマッチングを確率のように見せ、0/1 の参照ではなく連続値の重みでキー・バリュー参照を行えるようにする
分母に 1 を足すと重みの合計は 1 より小さくなり、本当の確率ベクトルではなくなるが、モデルが高い重みを学習すればほぼ確率ベクトルのように振る舞い、すべて低い重みを出して「何も確信しない」を選ぶこともできる
実際に良いかどうかは、この方式で LLM を学習してみるしかない。ただ、大きな差はない気がする。確信度の低いアテンションノードは、ソフトマックス前のスコアをすでに似た値にしてほぼ一様分布を作れ、その場合は複数ベクトルの平均になって統計的に 0 に近づく可能性が高い
また Transformer には V 行列やアテンション後のフィードフォワード層のように、オプトアウトを実装できる学習済み重みがすでに多い。それでも、記事の非学術的なトーンと根本のアイデアをいじってみようという姿勢は良いし、完全には納得していないが、こういう記事はもっと読みたい
大規模モデルの実行ではメモリがボトルネックなので、本当ならかなり大きな意味がある
元はこの関数を ghostmax と呼びたかったというくだりのように、x に 0 値の項目が 1 つ余分にあり、
exp(0)=1なので、V 行列にも結果を弱める 0 ベクトルがあると見なせる「重みの合計が 1 未満なので、たまに何も選ばない」というより、選択肢の集合を考えるたびに 何もしない という選択肢も強制的に一緒に考慮している、と見るほうがよい
「ハンマーしかなければ何でも釘に見える」と「ハンマーしかなくても釘は打ち、釘でないものは無視する」の違いだ
たとえば音声テキストシステムで、最初に人が言語を指定し、その言語の音声を入れるとかなり良い書き起こしを返すのに、1 段階目の言語選択を間違えると意味不明な結果になるのは不便だ。英語の文字起こし器なら、フランス語の音声が入ったときに、まず「これは英語ではない」と言うべきで、そのほうが人間のやり方に近い
片方はアテンションモジュールのソフトマックス分母に +1 を入れ、もう片方は入れない。性能が似ていることを示し、+1 モデルでは発散が減ってより効果的に量子化できることを示す必要がある
ニューラルネットワークは恒等関数をうまくモデル化できず残差接続が必要になるように、低エントロピー変換を暗黙に学習することにもかなり弱いと思う
表現力は増やさなくても、勾配降下で到達しにくい針探しのような変換をモデルに焼き込む効果があるかもしれない。実際どれだけ有用かは分からない
広く使われていないのは、人々が試してみて実際にはあまりうまく動かなかったからだ。原文が「8 年以上見過ごされていたバグ」と呼ぶのは、クリックベイトに近い
何か見落としているのかもしれないが、コメント欄がなぜこんな大事のように捉えているのかよく分からない。このトリックは実際に何度も見たことがある
たとえば古い Google のリポジトリにもこうしたコードがある: https://github.com/google/flaxformer/blob/ee62754ebe5a5eeb11...
安定性にはまったく効かないと思う。スケールを大きくするときのソフトマックス安定化には Q/K layernorm のようなトリックのほうがよい: https://arxiv.org/pdf/2302.05442.pdf
認知を広げるためにブログ記事や論文を書くことにも十分価値がある。良いアイデアが何度も独立に発見されるのは珍しくない
分母が大きくなることで分布が平坦になるのが、より良い量子化挙動につながるかどうかは、+1 を入れた場合と入れない場合を直接比較しないと分からない。原文はこの利点が大きい可能性があると見ている
技術的にはソフトマックスは提示された式そのままではなく、
exp(x_i-max(x))として実装し、その値を分母で合計する。私が何か見落としているのかもしれないまた残差接続は、ネットワークが恒等関数を学べないために使われるが、0 は学習できる。だから
f(x): x+g(x)ではg:x ~> 0、つまりほぼ 0 になればよいf(x): x+g(x)は勾配も流れやすくする「発見された」このトリックは PyTorch のマルチヘッドアテンションの標準実装の一部で、名前は
add_zero_attentionだロジットに 0 を追加するので
e^0=1となり、分母に 1 が生じる: https://pytorch.org/docs/stable/generated/torch.nn.Multihead...意味をほんの短くでも説明していない。今書いた 2 文目を足すだけでも、ずっと有用になるはずだ
AIやこのアルゴリズムの話ではないが、小さな誤りをいくら指摘しても誤りだと納得してもらえないことがある
2011年に自分のプロジェクトでredditランキングアルゴリズムをコピーしようとしてソースコードを見たところ、負の合計投票の投稿に対してまったく筋の通らない動作をしていた
単純な式で項が入れ替わっており、正負の符号も誤って適用されているように見えた。そこでブログに書いてredditに投稿したが、reddit社員を含む多くの人が私の完全な間違いで、アルゴリズムは意図どおり動いていると言った
以前にも同じ点に気づいて指摘した人たちがいたが、みな間違っていると言われたそうだ
結局ブログ記事を「自分より賢い人たちがredditアルゴリズムに誤りはないと言っており、ただ自分の変形のほうが自分には理にかなって見える」と修正した
ところが3年後の2014年、redditのソースコードに、私やそれ以前の人たちがずっと提案していたまさにその修正がコミットされた: https://github.com/reddit-archive/reddit/commit/50d35de04b92...
オープンソースでは多くの目がバグを見つけられるが、時にはバグを見つけたと誰も納得させられないこともある。もちろんredditは2017年にコードを閉じてしまった
結局、自分のアプリにはもともとコピーしようとしていたランキング機能も、投票機能も入れなかった
クエリパラメータに多くの値をエンコードする必要があり、特定のパラメータは実質的に二重にエンコードされる必要があったので、自分のツールもそうしていた。ところが実装エンジニアは私のツールが間違っていると言い張り、インターンという立場を持ち出し、OAuth仕様まで持ち出して自分の実装が正しく、私の読み方が間違っていると無理に解釈していた
結局Eran Hammer-Lahavを呼んで確認してもらってようやく私が正しいという結論になり、そのエンジニアもそこで初めて、もちろんそれが正しいと認めた。数日にわたる人格攻撃についての認知や謝罪は一切なかった
よりシニアだからといって常に正しいわけではない、という重要な教訓を得たし、今ではたいてい自分のほうがシニアの立場だが、毎日それを忘れないようにしている
「コードベースのあちこちにログを入れて一歩ずつ推論していく人」になるだけでも、長く影響力のあるキャリアを築ける。ごく単純なレベルでやるだけでも、古い問題への驚くような修正が見つかることがよくあった
ただし政治的な面倒もたくさん付いてくる。人々の最初の反応は否定で、その後はさらに悪くなる。「ああ、直せばいいね」と見る人は1〜2人しかおらず、誰かが「並行性/メモリ管理/その他もろもろへの懸念が足りない」と体裁よく包んで、上司の上司のさらに上司までCCに入れたメールを送ってくる
そういうときは静かに待ち、対抗したり不満を言ったりしないほうがいい。何も起こらず、リーダーシップも問いたださないのに同僚たちが問い始めたら、別のチームに移る計画を立てたほうがよい
外れ値特徴と量子化についての興味深い議論がある: https://timdettmers.com/2022/08/17/llm-int8-and-emergent-fea...
外れ値は値の刈り込みに使われ、Transformerはおよそ67億パラメータ付近で外れ値特徴の扱い方に「相転移」を経験するように見える。これによりアブレーション研究が複雑になる可能性がある
Tim Dettmersと話してみる材料がいろいろありそうだ
著者は実際の問題点を突き、簡単な解決策を示している。私の奇人判定基準はすべて通過している。
「なぜ誰もこれを思いつかなかったのか?」については、著者が機械学習の外側の仕事で ソフトマックス関数 に非常に慣れており、この問題を調べていた人たちは「ソフトマックスに関係する何か」までは絞り込めていても、ソフトマックス自体を十分深く理解していなかった可能性がある、という説明はもっともらしい。
ただし元記事の著者がこのコメントを見るなら、「外れ値フィードバックループを 99.44% の確率で解決するだろう」という主張について、もう少し詳しく書いてほしい。今のところ、外れ値がソフトマックスとどう関係しうるのかについての説明はその一文しかない。
https://github.com/google/flaxformer/blame/ee62754ebe5a5eeb1...
コメントには「0 のような追加の仮想ロジットを持つソフトマックス関数。以前に学習済みの一部モデルとの互換性のためのもの。これは分母に 1 を加えるのと同じ。アテンション文脈では何も見ないことを可能にする」とある。
この記事とまったく同じ修正ソフトマックスを作っている。なぜ公には無視されてきたのかは、時間がたてば分かるだろう。効果があまりなかったのかもしれないし、単に埋もれたのかもしれないし、Google が強く推さなかったのかもしれない。
実際に試したのではなく、ただ動くだろうと考えただけだ。ソフトマックスへのこれほど単純な変更なら検証に長くはかからないはずで、公開前に試していないのはかなり気まずい。
ソフトマックスは機械学習コミュニティの中で非常によく理解されている。ごく一般的なテクニックだし、こうした性質もよく知られている。誰も思いつかなかった可能性は低そうだ。
それでも、現在のソフトマックスの慣行が偶然選ばれ、著者がその欠点を的確に突いた可能性はある。
診断が正しいとしても、全精度の LLM は意味のないトークンに大きなアテンション重みを与え、無害なアテンション出力を作ることでこの問題を回避できるかもしれない。
この問題は重みを量子化するときにだけ重要で、最近の最先端 LLM 開発の目標が必ずしも量子化性能とは限らない。
ソフトマックスは 99.9% の確信や 0.1% の確信は得意だが、中間はあまり出ない、ということだ。
HN で学界に文句を言うのが流行っているのは分かるが、このブログ記事は良い議論をしていない。
全体の 1/4、たぶん 1/8 より短くしても要点は伝えられたはずなのに、砕けた表現と学術出版への薄く覆い隠した不満で包んである。
その結果、ここでの議論も記事の結果やアイデアではなく、学術出版 vs ブログ、形式的な文章 vs 非形式的な文章についてのコメント 200 件になっている。
HN のトップページにブログ記事を載せたいなら良い文体かもしれない。だが、アイデアの長所と短所を検討して議論させたいのなら、あまり向いていない。
人はあらゆることに使える注意が限られている一方で、注意を得たいという能力と必要は無限にある。Michael Goldhaber が言っていたことだ。
これが情報爆発の種になる。ゆで卵の作り方動画が 60億本あることや、自転車小屋めいたコメント 200 件のようなものだ。
これを防ぐために Google、Facebook、HN のような場所でコメント・リンク・ニュースフィードの順位付けをするが、順位付け対象の大半がナンセンスなので、結局は別のナンセンスの層になるだけだ。
Goldhaber が 30〜40年前に注意について述べたことを反映した情報システムは、いまだに設計できていない。
目的は情報を与えると同時に楽しませることかもしれない。多くの人は核心の周辺にある緩い議論を楽しむし、著者も学術論文の臨床的で形式ばったトーンよりそれを好むのかもしれない。
それでも少し腹立たしいことに、それを見るには話題から外れた不平コメント 200 件を読み飛ばさなければならなかった。
似たような実験をしてみたが、私の設定では役に立たなかった。
バグのようなものがなかったと断言はしないが、現在位置へのアテンション がこの問題をある程度解決しているように思える。出力すべきでないときは、単に現在位置の値を出力するというわけだ。
正確には、ソフトマックスの分母に 1 を足したのではなく、QK の前に学習されたパラメータである attention sink を付け、ソフトマックスの後でそれを取り除くことで、V と掛けるときに和が 1 にならないようにした。
現在位置を見る変形と見ない変形、学習パラメータの代わりに位置ごとにフィードフォワードネットワークで sink を生成する変形も試した。私の設定ではどちらも大きな違いを生まなかったが、ほかにも変な要素がいろいろ混ざっていたので、もう一度試す価値はあるかもしれない。
この記事の文脈では、タスク性能と 外れ値重みの個数と大きさ の両方が重要に見える。
結果が見えない。理論を補強する数字があれば、ずっと強く説得力があっただろう。
小さなデータで既存の言語モデルをファインチューニングして動くかどうか確認するのは、それほど難しくない。
ただ、より良いアテンションの式がありうるという点には同感だ。2020年の論文 https://arxiv.org/abs/2005.09561 は、私が学習した Transformer モデルの一つで大いに役立った。一般的な言語モデルではなく、特殊な マルチモーダルグラフ問題 だった。
この論文は正規化アテンションを提案しており、私の理解が間違っていなければ、量子化の問題にも役立つかもしれない。
このやり方は、ダミートークンが一般化する前にはよく使われていた。私はこのアイデアをXLNetの論文で初めて見た。
PyTorchには2019/2020年ごろから入っていたと思うし、もっと古い参考文献も誰かが見つけられるはずだ。
元記事の大げさな態度には驚いた。特に、Transformer研究者の大半が理解している内容についてならなおさらだ。返信で「研究はこうあるべきだ」という立場が多いのにも驚く。これは研究がなぜこういうふうには進まないのかを示す例に近く、査読は多くの面で有益であり、そのうちの一つは自分で恥をかく事態を減らしてくれることだ。
彼は傲慢なわけではない。人はくだけていて率直で、自己卑下的なトーンを好むものだが、それは傲慢さの反対だ。
曖昧な自己卑下を本気の主張として読んでいるように見える。
なぜ重要だと思って共有したのかを要約すると、これは制約のあるハードウェアでChatGPTのぼんやりした模倣を動かそうとするときに重要になる、かなりニッチな問題だ。だから大規模な研究チームが重要視していなかった可能性は十分ある。彼らは3090でLLMを動かそうとしているわけではないのだから。
「傲慢だ」という評は変だ。
文章は口語的で、自己卑下的で、ユーモラスなトーンだ。長所短所はわからないが、推論は完全に追うことができた。傲慢とはほど遠い。
「自分で恥をかく事態を減らす」という言い方は、間違っていたり最初の発見でなかったりすると恥ずかしい、という前提を含んでいる。それこそ傲慢なのではないか?