1 ポイント 投稿者 GN⁺ 2023-07-25 | 1件のコメント | WhatsAppで共有
  • 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件のコメント

 
GN⁺ 2023-07-25
Hacker News の意見
  • 著者が提案しているのは最終出力のソフトマックスではなく、アテンション内部のソフトマックスの分母に 1 を足すこと
    アテンションのソフトマックスはキー/クエリのマッチングを確率のように見せ、0/1 の参照ではなく連続値の重みでキー・バリュー参照を行えるようにする
    分母に 1 を足すと重みの合計は 1 より小さくなり、本当の確率ベクトルではなくなるが、モデルが高い重みを学習すればほぼ確率ベクトルのように振る舞い、すべて低い重みを出して「何も確信しない」を選ぶこともできる
    実際に良いかどうかは、この方式で LLM を学習してみるしかない。ただ、大きな差はない気がする。確信度の低いアテンションノードは、ソフトマックス前のスコアをすでに似た値にしてほぼ一様分布を作れ、その場合は複数ベクトルの平均になって統計的に 0 に近づく可能性が高い
    また Transformer には V 行列やアテンション後のフィードフォワード層のように、オプトアウトを実装できる学習済み重みがすでに多い。それでも、記事の非学術的なトーンと根本のアイデアをいじってみようという姿勢は良いし、完全には納得していないが、こういう記事はもっと読みたい

    • 私の理解では、著者はこの変更によって 大きな値が消え、Transformer の出力をより少ないビットでエンコードできるため、ネットワークのメモリ要求が下がると言っているようだ
      大規模モデルの実行ではメモリがボトルネックなので、本当ならかなり大きな意味がある
    • 著者が提案した概念モデルのほうが気に入っている
      元はこの関数を ghostmax と呼びたかったというくだりのように、x に 0 値の項目が 1 つ余分にあり、exp(0)=1 なので、V 行列にも結果を弱める 0 ベクトルがあると見なせる
      「重みの合計が 1 未満なので、たまに何も選ばない」というより、選択肢の集合を考えるたびに 何もしない という選択肢も強制的に一緒に考慮している、と見るほうがよい
      「ハンマーしかなければ何でも釘に見える」と「ハンマーしかなくても釘は打ち、釘でないものは無視する」の違いだ
      たとえば音声テキストシステムで、最初に人が言語を指定し、その言語の音声を入れるとかなり良い書き起こしを返すのに、1 段階目の言語選択を間違えると意味不明な結果になるのは不便だ。英語の文字起こし器なら、フランス語の音声が入ったときに、まず「これは英語ではない」と言うべきで、そのほうが人間のやり方に近い
    • 良いか確かめるには、同一のモデルを 2 つ大きなデータセットで学習すればよい
      片方はアテンションモジュールのソフトマックス分母に +1 を入れ、もう片方は入れない。性能が似ていることを示し、+1 モデルでは発散が減ってより効果的に量子化できることを示す必要がある
    • 「確信度が低ければソフトマックス前のスコアを似たものにすればよい」という点には同意しにくい
      ニューラルネットワークは恒等関数をうまくモデル化できず残差接続が必要になるように、低エントロピー変換を暗黙に学習することにもかなり弱いと思う
      表現力は増やさなくても、勾配降下で到達しにくい針探しのような変換をモデルに焼き込む効果があるかもしれない。実際どれだけ有用かは分からない
    • この手法は数年前から知られていて PyTorch にも入っている
      広く使われていないのは、人々が試してみて実際にはあまりうまく動かなかったからだ。原文が「8 年以上見過ごされていたバグ」と呼ぶのは、クリックベイトに近い
  • 何か見落としているのかもしれないが、コメント欄がなぜこんな大事のように捉えているのかよく分からない。このトリックは実際に何度も見たことがある
    たとえば古い Google のリポジトリにもこうしたコードがある: https://github.com/google/flaxformer/blob/ee62754ebe5a5eeb11...

    • その通り。数年前、私たちの昔のモデルでもこれを使っていた。細部は正確には覚えていないが、ほとんど効果はなかった気がする
      安定性にはまったく効かないと思う。スケールを大きくするときのソフトマックス安定化には Q/K layernorm のようなトリックのほうがよい: https://arxiv.org/pdf/2302.05442.pdf
    • 人気モデルが今でもこのミスをしているなら、依然として注目に値する
      認知を広げるためにブログ記事や論文を書くことにも十分価値がある。良いアイデアが何度も独立に発見されるのは珍しくない
    • 重要なのは、人々が 量子化、つまり int8 / GGML / GPTQ 方式でこれを試したかどうかだ
      分母が大きくなることで分布が平坦になるのが、より良い量子化挙動につながるかどうかは、+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...

    • ドキュメントはかなり良くない。「指定すると dim=1 で key と value シーケンスに 0 の新しいバッチを追加する」程度にしか書かれていない
      意味をほんの短くでも説明していない。今書いた 2 文目を足すだけでも、ずっと有用になるはずだ
    • デフォルト値が false のオプションだ。ということは、人々はすでに試してみて、普通は役に立たないという意味だろうか?
    • よく見つけた。原文の著者が見てくれるといい
    • https://en.wikipedia.org/wiki/Multiple_discovery
  • AIやこのアルゴリズムの話ではないが、小さな誤りをいくら指摘しても誤りだと納得してもらえないことがある
    2011年に自分のプロジェクトでredditランキングアルゴリズムをコピーしようとしてソースコードを見たところ、負の合計投票の投稿に対してまったく筋の通らない動作をしていた
    単純な式で項が入れ替わっており、正負の符号も誤って適用されているように見えた。そこでブログに書いてredditに投稿したが、reddit社員を含む多くの人が私の完全な間違いで、アルゴリズムは意図どおり動いていると言った
    以前にも同じ点に気づいて指摘した人たちがいたが、みな間違っていると言われたそうだ
    結局ブログ記事を「自分より賢い人たちがredditアルゴリズムに誤りはないと言っており、ただ自分の変形のほうが自分には理にかなって見える」と修正した
    ところが3年後の2014年、redditのソースコードに、私やそれ以前の人たちがずっと提案していたまさにその修正がコミットされた: https://github.com/reddit-archive/reddit/commit/50d35de04b92...
    オープンソースでは多くの目がバグを見つけられるが、時にはバグを見つけたと誰も納得させられないこともある。もちろんredditは2017年にコードを閉じてしまった
    結局、自分のアプリにはもともとコピーしようとしていたランキング機能も、投票機能も入れなかった

    • 2008年ごろYahooでインターンとしてOAuth 1.0 URL生成の社内ツールを作ったときにも似たことがあった
      クエリパラメータに多くの値をエンコードする必要があり、特定のパラメータは実質的に二重にエンコードされる必要があったので、自分のツールもそうしていた。ところが実装エンジニアは私のツールが間違っていると言い張り、インターンという立場を持ち出し、OAuth仕様まで持ち出して自分の実装が正しく、私の読み方が間違っていると無理に解釈していた
      結局Eran Hammer-Lahavを呼んで確認してもらってようやく私が正しいという結論になり、そのエンジニアもそこで初めて、もちろんそれが正しいと認めた。数日にわたる人格攻撃についての認知や謝罪は一切なかった
      よりシニアだからといって常に正しいわけではない、という重要な教訓を得たし、今ではたいてい自分のほうがシニアの立場だが、毎日それを忘れないようにしている
    • FAANGで働いているが、こういうことがどれほど頻繁に起こるのか知って本当に驚いた
      「コードベースのあちこちにログを入れて一歩ずつ推論していく人」になるだけでも、長く影響力のあるキャリアを築ける。ごく単純なレベルでやるだけでも、古い問題への驚くような修正が見つかることがよくあった
      ただし政治的な面倒もたくさん付いてくる。人々の最初の反応は否定で、その後はさらに悪くなる。「ああ、直せばいいね」と見る人は1〜2人しかおらず、誰かが「並行性/メモリ管理/その他もろもろへの懸念が足りない」と体裁よく包んで、上司の上司のさらに上司までCCに入れたメールを送ってくる
      そういうときは静かに待ち、対抗したり不満を言ったりしないほうがいい。何も起こらず、リーダーシップも問いたださないのに同僚たちが問い始めたら、別のチームに移る計画を立てたほうがよい
    • たった今コードを見たが、ただただ明白に間違っている。相当もどかしかっただろう
    • ここ数か月のことを思えば、reddit社員とのやり取りがそういう流れになったのも驚きではない
  • 外れ値特徴と量子化についての興味深い議論がある: https://timdettmers.com/2022/08/17/llm-int8-and-emergent-fea...
    外れ値は値の刈り込みに使われ、Transformerはおよそ67億パラメータ付近で外れ値特徴の扱い方に「相転移」を経験するように見える。これによりアブレーション研究が複雑になる可能性がある
    Tim Dettmersと話してみる材料がいろいろありそうだ

  • 著者は実際の問題点を突き、簡単な解決策を示している。私の奇人判定基準はすべて通過している。
    「なぜ誰もこれを思いつかなかったのか?」については、著者が機械学習の外側の仕事で ソフトマックス関数 に非常に慣れており、この問題を調べていた人たちは「ソフトマックスに関係する何か」までは絞り込めていても、ソフトマックス自体を十分深く理解していなかった可能性がある、という説明はもっともらしい。
    ただし元記事の著者がこのコメントを見るなら、「外れ値フィードバックループを 99.44% の確率で解決するだろう」という主張について、もう少し詳しく書いてほしい。今のところ、外れ値がソフトマックスとどう関係しうるのかについての説明はその一文しかない。

    • 調べてみると、すでに誰かが考えていた。具体的には Google で、このアイデアは少なくとも 2021年11月 から flaxformer に入っていた。
      https://github.com/google/flaxformer/blame/ee62754ebe5a5eeb1...
      コメントには「0 のような追加の仮想ロジットを持つソフトマックス関数。以前に学習済みの一部モデルとの互換性のためのもの。これは分母に 1 を加えるのと同じ。アテンション文脈では何も見ないことを可能にする」とある。
      この記事とまったく同じ修正ソフトマックスを作っている。なぜ公には無視されてきたのかは、時間がたてば分かるだろう。効果があまりなかったのかもしれないし、単に埋もれたのかもしれないし、Google が強く推さなかったのかもしれない。
    • いちばん重要な検証が抜けている。つまり 結果 だ。
      実際に試したのではなく、ただ動くだろうと考えただけだ。ソフトマックスへのこれほど単純な変更なら検証に長くはかからないはずで、公開前に試していないのはかなり気まずい。
    • 「なぜ誰も思いつかなかったのか? 著者が機械学習の外でソフトマックスに深く慣れていたからだ」という説明は疑わしい。
      ソフトマックスは機械学習コミュニティの中で非常によく理解されている。ごく一般的なテクニックだし、こうした性質もよく知られている。誰も思いつかなかった可能性は低そうだ。
      それでも、現在のソフトマックスの慣行が偶然選ばれ、著者がその欠点を的確に突いた可能性はある。
    • 問題の効果が微妙だからかもしれない。
      診断が正しいとしても、全精度の LLM は意味のないトークンに大きなアテンション重みを与え、無害なアテンション出力を作ることでこの問題を回避できるかもしれない。
      この問題は重みを量子化するときにだけ重要で、最近の最先端 LLM 開発の目標が必ずしも量子化性能とは限らない。
    • 「99.44% の確信」は、ソフトマックスの 較正の悪い確率 をからかった冗談として読んだ。
      ソフトマックスは 99.9% の確信や 0.1% の確信は得意だが、中間はあまり出ない、ということだ。
  • HN で学界に文句を言うのが流行っているのは分かるが、このブログ記事は良い議論をしていない。
    全体の 1/4、たぶん 1/8 より短くしても要点は伝えられたはずなのに、砕けた表現と学術出版への薄く覆い隠した不満で包んである。
    その結果、ここでの議論も記事の結果やアイデアではなく、学術出版 vs ブログ、形式的な文章 vs 非形式的な文章についてのコメント 200 件になっている。
    HN のトップページにブログ記事を載せたいなら良い文体かもしれない。だが、アイデアの長所と短所を検討して議論させたいのなら、あまり向いていない。

    • 結局、私たちが 注意経済 にたどり着く根本的な理由はそこにある。
      人はあらゆることに使える注意が限られている一方で、注意を得たいという能力と必要は無限にある。Michael Goldhaber が言っていたことだ。
      これが情報爆発の種になる。ゆで卵の作り方動画が 60億本あることや、自転車小屋めいたコメント 200 件のようなものだ。
      これを防ぐために Google、Facebook、HN のような場所でコメント・リンク・ニュースフィードの順位付けをするが、順位付け対象の大半がナンセンスなので、結局は別のナンセンスの層になるだけだ。
      Goldhaber が 30〜40年前に注意について述べたことを反映した情報システムは、いまだに設計できていない。
    • 「HN のトップページに載る」とあざ笑うが、「非公式に観察した何かを議論する」と言い換えれば、その見下しは力を失う。
      目的は情報を与えると同時に楽しませることかもしれない。多くの人は核心の周辺にある緩い議論を楽しむし、著者も学術論文の臨床的で形式ばったトーンよりそれを好むのかもしれない。
    • 参考までに、PyTorch の Multihead Attention API にこの問題の選択的な回避策があると誰かが指摘していた。
      それでも少し腹立たしいことに、それを見るには話題から外れた不平コメント 200 件を読み飛ばさなければならなかった。
  • 似たような実験をしてみたが、私の設定では役に立たなかった。
    バグのようなものがなかったと断言はしないが、現在位置へのアテンション がこの問題をある程度解決しているように思える。出力すべきでないときは、単に現在位置の値を出力するというわけだ。
    正確には、ソフトマックスの分母に 1 を足したのではなく、QK の前に学習されたパラメータである attention sink を付け、ソフトマックスの後でそれを取り除くことで、V と掛けるときに和が 1 にならないようにした。
    現在位置を見る変形と見ない変形、学習パラメータの代わりに位置ごとにフィードフォワードネットワークで sink を生成する変形も試した。私の設定ではどちらも大きな違いを生まなかったが、ほかにも変な要素がいろいろ混ざっていたので、もう一度試す価値はあるかもしれない。

    • 役に立たなかったというとき、何を測定したのか気になる。
      この記事の文脈では、タスク性能と 外れ値重みの個数と大きさ の両方が重要に見える。
    • 彼はこれが飛び抜けた外れ値を直すと売り込んでいる。君の変形には、そもそもそういう外れ値があったのか?
  • 結果が見えない。理論を補強する数字があれば、ずっと強く説得力があっただろう。
    小さなデータで既存の言語モデルをファインチューニングして動くかどうか確認するのは、それほど難しくない。
    ただ、より良いアテンションの式がありうるという点には同感だ。2020年の論文 https://arxiv.org/abs/2005.09561 は、私が学習した Transformer モデルの一つで大いに役立った。一般的な言語モデルではなく、特殊な マルチモーダルグラフ問題 だった。
    この論文は正規化アテンションを提案しており、私の理解が間違っていなければ、量子化の問題にも役立つかもしれない。

  • このやり方は、ダミートークンが一般化する前にはよく使われていた。私はこのアイデアをXLNetの論文で初めて見た。
    PyTorchには2019/2020年ごろから入っていたと思うし、もっと古い参考文献も誰かが見つけられるはずだ。
    元記事の大げさな態度には驚いた。特に、Transformer研究者の大半が理解している内容についてならなおさらだ。返信で「研究はこうあるべきだ」という立場が多いのにも驚く。これは研究がなぜこういうふうには進まないのかを示す例に近く、査読は多くの面で有益であり、そのうちの一つは自分で恥をかく事態を減らしてくれることだ。

  • 彼は傲慢なわけではない。人はくだけていて率直で、自己卑下的なトーンを好むものだが、それは傲慢さの反対だ。
    曖昧な自己卑下を本気の主張として読んでいるように見える。
    なぜ重要だと思って共有したのかを要約すると、これは制約のあるハードウェアでChatGPTのぼんやりした模倣を動かそうとするときに重要になる、かなりニッチな問題だ。だから大規模な研究チームが重要視していなかった可能性は十分ある。彼らは3090でLLMを動かそうとしているわけではないのだから。

  • 「傲慢だ」という評は変だ。
    文章は口語的で、自己卑下的で、ユーモラスなトーンだ。長所短所はわからないが、推論は完全に追うことができた。傲慢とはほど遠い。
    「自分で恥をかく事態を減らす」という言い方は、間違っていたり最初の発見でなかったりすると恥ずかしい、という前提を含んでいる。それこそ傲慢なのではないか?