BigBirdのブロック疎な注意機構の理解
Understanding BigBird's sparse attention mechanism.
イントロダクション
トランスフォーマーベースのモデルは、多くの自然言語処理タスクにおいて非常に有用であることが示されています。ただし、トランスフォーマーベースのモデルの主な制限は、O(n^2) の時間とメモリの複雑さ(ここで n はシーケンスの長さです)です。したがって、長いシーケンス n > 512 に対してトランスフォーマーベースのモデルを適用するのは計算上非常に高コストです。最近のいくつかの論文では、Longformer
、Performer
、Reformer
、Clustered attention
などが、完全な注意行列を近似することでこの問題を解決しようとしています。これらのモデルについて詳しく知りたい場合は、🤗の最近のブログ記事をチェックしてください。
BigBird
(論文で紹介)は、この問題に対処するための最近のモデルの1つです。 BigBird
は通常の注意(つまり、BERTの注意)ではなく、ブロックスパースな注意を使用し、BERTよりも低い計算コストで長さ 4096 のシーケンスを処理することができます。 BigBird
は、長いドキュメントの要約、長いコンテキストを持つ質問応答など、非常に長いシーケンスを含むさまざまなタスクでSOTAを達成しています。
BigBird RoBERTa-like モデルは現在、🤗Transformersで利用できます。この記事の目的は、読者に 詳細な BigBird の実装の理解を提供し、🤗Transformers を使用して BigBird を簡単に利用できるようにすることです。ただし、さらに詳しく説明する前に、重要なことを忘れないようにしてください。 BigBird
の注意は BERT
の完全な注意の近似であり、したがって BERT
の完全な注意よりも 優れた ものではなく、むしろ効率的であることを目指しています。単純に言えば、∞ の計算と ∞ の時間がある場合、ブロックスパースな注意よりも BERT
の注意が優先されます(この記事で説明します)。
長いシーケンスで作業する際になぜより多くの計算が必要か疑問に思う場合は、このブログ記事が適しています!
標準の BERT
のような注意を使用する場合に持つかもしれない主な質問のいくつかは次のとおりです:
- すべてのトークンは本当に他のすべてのトークンに注意を払う必要がありますか?
- 重要なトークンにのみ注意を払う理由は何ですか?
- どのトークンが重要かを決める方法はありますか?
- 非常に効率的な方法でわずかなトークンに注意を払うにはどうすればよいですか?
このブログ記事では、これらの質問に答えようとします。
どのトークンに注意を払うべきですか?
「BigBirdはHuggingFaceで抽出型質問応答のために利用可能です」という文を考えながら、注意がどのように機能するかの実際的な例を示します。 BERT
のような注意では、すべての単語が単純に他のすべてのトークンに注意を払います。数学的に言えば、各クエリトークン query-token ∈ { BigBird , is , now , available , in , HuggingFace , for , extractive , question , answering } は、キートークンのリスト key-tokens = [ BigBird , is , now , available , in , HuggingFace , for , extractive , question , answering ] に対して注意を払います。
疑問符のトークンが実際に関連するキートークンを考えるために、いくつかの擬似コードを書いて考えましょう。クエリされるトークンはavailable
とし、関連するキートークンの適切なリストを作成します。
>>> # 以下の文を例として考えましょう
>>> example = ['BigBird', 'is', 'now', 'available', 'in', 'HuggingFace', 'for', 'extractive', 'question', 'answering']
>>> # さらに、'available'の表現を理解しようとしていると仮定しましょう
>>> query_token = 'available'
>>> # 空の`set`を初期化し、このセクションで進めるにつれて興味のあるトークンを追加していきます。
>>> key_tokens = [] # => 現在、'available'のトークンは参照するものがありません
近くのトークンは重要です。なぜなら、文章(単語の連続)では、現在の単語は隣接する過去および未来のトークンに高く依存しているからです。この直感は、sliding attention
の概念のアイデアです。
>>> # `window_size = 3`を考慮して、'available'の左側のトークンと右側のトークンを1つずつ考慮します
>>> # 左側のトークン:'now';右側のトークン:'in'
>>> sliding_tokens = ["now", "available", "in"]
>>> # 上記のトークンでコレクションを更新します
>>> key_tokens.append(sliding_tokens)
長距離依存:一部のタスクでは、トークン間の長距離の関係を捉えることが重要です。たとえば、質問応答では、モデルは文脈の各トークンを全ての質問と比較する必要があります。これにより、モデルは正しい回答に必要な文脈の一部を特定することができます。もし文脈のほとんどのトークンが他の文脈のトークンにのみ参照し、質問に参照しない場合、モデルは重要な文脈トークンと重要でない文脈トークンを区別することが難しくなります。
さて、BigBird
は、計算効率を保ちながら長期的な注意依存関係を可能にする2つの方法を提案しています。
- グローバルトークン:すべてのトークンに参照され、すべてのトークンが参照するいくつかのトークンを導入します。例:「HuggingFaceは簡単なNLPのための素晴らしいライブラリを構築しています」。ここで、’building’はグローバルトークンと定義され、モデルはいくつかのタスク(これら2つのトークンは2つの極端にある)で「NLP」と「HuggingFace」の関係を知る必要があります。ここで、’building’が他のすべてのトークンにグローバルに参照することで、モデルはおそらく「NLP」と「HuggingFace」を関連付けるのに役立つでしょう。
>>> # 最初と最後のトークンを`global`と仮定しましょう
>>> global_tokens = ["BigBird", "answering"]
>>> # グローバルトークンをキートークンのコレクションに追加します
>>> key_tokens.append(global_tokens)
- ランダムトークン:ランダムにいくつかのトークンを選択し、それらが他のトークンに情報を伝達して、さらに他のトークンに情報を伝達できるようにします。これにより、情報がトークン間を移動するコストを削減できます。
>>> # 今、例の文から`r`個のトークンをランダムに選べます
>>> # `r=1`として'is'を選びましょう
>>> random_tokens = ["is"] # 注意:完全にランダムに選ばれるので、他の何かになる可能性もあります。
>>> # ランダムトークンをコレクションに追加します
>>> key_tokens.append(random_tokens)
>>> # `key_tokens`リストに含まれるトークンを見てみましょう
>>> key_tokens
{'now', 'is', 'in', 'answering', 'available', 'BigBird'}
# これにより、クエリトークンはシーケンス全体ではなく、これらのトークンのサブセットにのみ参照します
この方法により、クエリトークンは全ての可能なトークンのサブセットにのみ参照し、完全な注意を近似する良い近似値を得ることができます。同じアプローチは他のすべてのクエリトークンに対しても使用されます。ただし、ここでのポイントは、BERT
の完全な注意をできるだけ効率的に近似することです。BERTの場合と同様に、各クエリトークンがすべてのキートークンに参照するようにすることは、現代のハードウェア(GPUなど)上での行列積のシーケンスとして非常に効果的に計算できます。ただし、スライド、グローバル、ランダムな注意の組み合わせは、効率的に実装するのが難しい疎行列の乗算を意味するように見えます。BigBird
の主要な貢献の1つは、スライド、グローバル、ランダムな注意を効果的に計算するためのblock sparse
注意メカニズムの提案です。詳しく見てみましょう!
グラフを使用したグローバル、スライディング、ランダムキーの必要性の理解
まず、グラフを使用してグローバル
、スライディング
、ランダム
のアテンションをより良く理解し、これら3つのアテンションメカニズムの組み合わせが標準的なBert-like
アテンションの非常に良い近似値を提供するかを理解しましょう。
上記の図は、それぞれグラフとして表されるグローバル
(左)、スライディング
(中央)、ランダム
(右)の接続を示しています。各ノードはトークンに対応し、各線はアテンションスコアを表します。2つのトークン間に接続がない場合、アテンションスコアは0とみなされます。
BigBirdブロックスパースアテンションは、スライディング、グローバル、およびランダム接続(合計10つの接続)の組み合わせであり、左のgif
に示されています。一方、通常のアテンションのグラフ(右)はすべての15つの接続を持っています(注:合計6つのノードが存在します)。通常のアテンションは、すべてのトークンがグローバルに1つのトークンにアテンションを集中すると考えることができます。
通常のアテンション:モデルは、各トークンが他のすべてのトークンに対して問い合わせられ、他のすべてのトークンにアテンションを集中するため、1つの層で1つのトークンから別のトークンへの情報の転送が直接行えます。上記の図に示されているのと似た例を考えてみましょう。モデルが「going」と「now」を関連付ける必要がある場合、両トークンを直接結ぶ接続があるため、単一の層で簡単に行うことができます。
ブロックスパースアテンション:モデルが2つのノード(またはトークン)間で情報を共有する必要がある場合、一部のトークンのパスを通じて情報が他の複数のノードを経由して移動する必要があります。なぜなら、すべてのノードが単一の層で直接接続されていないからです。例えば、「going」と「now」を関連付ける必要がある場合、スライディングアテンションのみが存在する場合、これら2つのトークンの間で情報のフローは次のパスで定義されます:going -> am -> i -> now
(つまり、2つの他のトークンを経由して移動する必要があります)。したがって、シーケンスのすべての情報を捉えるためには、複数の層が必要になる場合があります。通常のアテンションは、これを単一の層で捉えることができます。極端な場合では、入力トークンと同じ数の層が必要になる可能性があります。ただし、いくつかのグローバルトークンを導入すると、情報はより短いパスを通じて移動できるようになります:going -> i -> now
(これは短いです)。さらに、ランダムな接続を導入すると、次のように移動できます:going -> am -> now
。ランダムな接続とグローバルな接続の助けを借りて、情報は非常に迅速に(わずか数層で)次のトークンに移動できます。
もし、多くのグローバルトークンがある場合は、情報が移動するための複数の短いパスが存在するため、ランダムな接続は必要ありません。これは、後のセクションで説明するBigBirdのバリアントであるETCを使用する場合にnum_random_tokens = 0
を保持する理由です。
1 {}^1 1 これらのグラフでは、アテンション行列が対称であると仮定しています。つまり、グラフではトークンAがトークンBにアテンションを集中する場合、トークンBもトークンAにアテンションを集中します。次のセクションに示されているアテンション行列の図からもわかるように、この仮定はBigBirdのほとんどのトークンに対して成り立っています。
original_full
はBERT
のアテンションを、block_sparse
はBigBird
のアテンションを表しています。何がblock_size
なのか気になりますか?後のセクションでそれについて説明します。今のところ、単純化のために1と考えてください。
BigBirdブロック疎な注意
BigBirdブロック疎な注意は、私たちが上記で議論したことの効率的な実装です。各トークンは、他のすべてのトークンに注意を払う代わりに、いくつかのグローバルトークン、スライディングトークン、およびランダムトークンに注意を払っています。著者は複数のクエリコンポーネントごとに注意行列をハードコードしました。また、GPUとTPUでのトレーニング/推論を高速化するためのクールなトリックを使用しました。
注:上部には2つの追加の文があります。お気づきのように、すべてのトークンが両方の文で位置を1つずつ切り替えています。これがスライディング注意の実装方法です。 q[i]
が k[i,0:3]
と乗算されると、q[i]
のスライディング注意スコアが得られます(ここで i
はシーケンス内の要素のインデックスです)。
実際の block_sparse
注意の実装はこちらで見つけることができます。これは今は非常に怖い 😨😨 かもしれません。しかし、この記事はコードの理解を容易にするためにあなたの生活を確実に楽にします。
グローバル注意
グローバル注意では、各クエリは単純にシーケンス内の他のすべてのトークンに注意を払い、他のすべてのトークンから注意を受けます。上の図では、Vasudev
(1番目のトークン)とthem
(最後のトークン)をグローバルとして仮定します。これらのトークンは他のすべてのトークン(青いボックス)と直接接続されていることがわかります。
# 疑似コード
Q -> クエリ行列(seq_length、head_dim)
K -> キー行列(seq_length、head_dim)
# 1番目のトークンと最後のトークンは他のすべてのトークンに注意を払う
Q[0] x [K[0], K[1], K[2], ......, K[n-1]]
Q[n-1] x [K[0], K[1], K[2], ......, K[n-1]]
# 1番目のトークンと最後のトークンは他のすべてのトークンから注意を受ける
K[0] x [Q[0], Q[1], Q[2], ......, Q[n-1]]
K[n-1] x [Q[0], Q[1], Q[2], ......, Q[n-1]]
スライディング注意
キートークンのシーケンスは2回コピーされ、1つのコピーでは各要素が右にシフトされ、もう1つのコピーでは左にシフトされます。これでクエリシーケンスベクトルをこれらの3つのシーケンスベクトルで乗算すると、すべてのスライディングトークンをカバーすることができます。計算量は単純にO(3xn) = O(n)
です。上の図を参照してください。オレンジのボックスはスライディング注意を表しています。図の上部には3つのシーケンスがあり、そのうちの2つが1つのトークンずつシフトされていることがわかります(1つは左に、もう1つは右に)。
# やりたいこと
Q[i] x [K[i-1], K[i], K[i+1]] (ただし i = 1:-1)
# コードでの効率的な実装(内積の乗算を仮定 👇)
[Q[0], Q[1], Q[2], ......, Q[n-2], Q[n-1]] x [K[1], K[2], K[3], ......, K[n-1], K[0]]
[Q[0], Q[1], Q[2], ......, Q[n-1]] x [K[n-1], K[0], K[1], ......, K[n-2]]
[Q[0], Q[1], Q[2], ......, Q[n-1]] x [K[0], K[1], K[2], ......, K[n-1]]
# 各シーケンスは `window_size = 3` を保つために 3 つのシーケンスのみと乗算されます。
# 一部の計算が抜けているかもしれません。これはあくまで大まかなアイデアです。
ランダム注意
ランダムな注意は、各クエリトークンがいくつかのランダムなトークンにも注意を払うことを保証します。実際の実装では、モデルはいくつかのトークンをランダムに選び、その注意スコアを計算します。
# r1、r2、rはいくつかのランダムなインデックスです。注意:r1、r2、r3は各行ごとに異なる 👇
Q[1] x [Q[r1], Q[r2], ......, Q[r]]
.
.
.
Q[n-2] x [Q[r1], Q[r2], ......, Q[r]]
# 0番目と(n-1)番目のトークンはすでにグローバルなので除外します
注意:現在の実装では、シーケンスをブロックにさらに分割し、各表記はトークンではなくブロックに対して定義されています。次のセクションで詳しく説明しましょう。
実装
復習:通常のBERTアテンションでは、トークンのシーケンスであるX = x 1 , x 2 , . . . . , x n X = x_1, x_2, .…, x_n X = x 1 , x 2 , . . . . , x n は、密な層を介してQ、K、V Q,K,V Q , K , V に射影され、アテンションスコアZ Z Z がZ = S o f t m a x ( Q K T ) Z=Softmax(QK^T) Z = S o f t m a x ( Q K T ) として計算されます。BigBirdブロック疎なアテンションの場合、同じアルゴリズムが使用されますが、一部の選択されたクエリとキーベクトルのみを使用します。
BigBirdブロック疎なアテンションの実装方法を見てみましょう。まず、b、r、s、g b, r, s, g b , r , s , g がそれぞれblock_size
、num_random_blocks
、num_sliding_blocks
、num_global_blocks
を表すものとします。視覚的には、big birdのブロック疎なアテンションのコンポーネントをb = 4、r = 1、g = 2、s = 3、d = 5 b=4, r=1, g=2, s=3, d=5 b = 4 , r = 1 , g = 2 , s = 3 , d = 5 として次のように示すことができます:
q 1 、q 2 、q 3 のアテンションスコア:n − 2 、q n − 1 、q n {q}_{1}, {q}_{2}, {q}_{3:n-2}, {q}_{n-1}, {q}_{n} q 1 、q 2 、q 3 : n − 2 、q n − 1 、q n は、以下に説明するようにそれぞれ個別に計算されます:
q 1 のアテンションスコア \mathbf{q}_{1} q 1 のアテンションスコアは a 1 a_1 a 1 で表され、ここで a 1 = S o f t m a x ( q 1 ∗ K T ) a_1=Softmax(q_1 * K^T) a 1 = S o f t m a x ( q 1 ∗ K T ) です。これは、1番目のブロックのすべてのトークンとシーケンス内の他のトークンとの間のアテンションスコアにすぎません。
q 1 q_1 q 1 は1番目のブロックを表し、g i g_i g i は i i i 番目のブロックを表します。単純に、q 1 q_1 q 1 と g g g (すべてのキー) の間で通常のアテンション操作を行っています。
2番目のブロックのトークンのアテンションスコアを計算するために、最初の3つのブロック、最後のブロック、そして5番目のブロックを収集します。その後、a 2 = S o f t m a x ( q 2 ∗ c o n c a t ( k 1 , k 2 , k 3 , k 5 , k 7 ) a_2 = Softmax(q_2 * concat(k_1, k_2, k_3, k_5, k_7) a 2 = S o f t m a x ( q 2 ∗ c o n c a t ( k 1 , k 2 , k 3 , k 5 , k 7 ) を計算できます。
トークンは g、r、s g, r, s g , r , s で表していますが、それはその性質を明示するためのものです(つまり、グローバル、ランダム、スライディングトークンを表示しています)。それ以外の場合は、k k k のみです。
q 3 : n − 2 {q}_{3:n-2} q 3 : n − 2 のアテンションスコアを計算するために、グローバル、スライディング、ランダムなキーを収集し、q 3 : n − 2 {q}_{3:n-2} q 3 : n − 2 と収集したキーの間で通常のアテンション操作を行います。スライディングキーは、スライディングアテンションセクションで前述した特殊なシフトトリックを使用して収集されます。
前から最後のブロックのトークンの注意スコアを計算するために(つまり、 q n − 1 {q}_{n-1} q n − 1 )は、最初のブロック、最後の3つのブロック、および3番目のブロックを収集しています。次に、以下の式を適用できます: a n − 1 = S o f t m a x ( q n − 1 ∗ c o n c a t ( k 1 , k 3 , k 5 , k 6 , k 7 ) ) {a}_{n-1} = Softmax({q}_{n-1} * concat(k_1, k_3, k_5, k_6, k_7)) a n − 1 = S o f t m a x ( q n − 1 ∗ c o n c a t ( k 1 , k 3 , k 5 , k 6 , k 7 ) ) 。これは、q 2 q_2 q 2 に対して行ったことと非常に似ています。
q n \mathbf{q}_{n} q n の注意スコアは、a n a_n a n で表され、a n = S o f t m a x ( q n ∗ K T ) a_n=Softmax(q_n * K^T) a n = S o f t m a x ( q n ∗ K T ) であり、これは最後のブロック内のすべてのトークンとシーケンス内の他のすべてのトークンの間の注意スコアにすぎません。これは、q 1 q_1 q 1 に対して行ったことと非常に似ています。
上記の行列を組み合わせて最終的な注意行列を取得しましょう。この注意行列は、すべてのトークンの表現を取得するために使用できます。
青 -> グローバルブロック
、赤 -> ランダムブロック
、オレンジ -> スライディングブロック
この注意行列は、単にイラストです。フォワードパス中には白
ブロックを保存していませんが、上記で説明した各部分ごとに直接各分離されたコンポーネントごとに重み付け値行列(つまり、各トークンの表現)を計算しています。
これで、ブロック疎な注意の最も難しい部分、つまり実装について説明しました。実際のコードを理解するための背景がより良くなったことを願っています。コードの各部分を上記のコンポーネントの1つに接続することができますので、自由に探求してください。
時間とメモリの複雑さ
BERTの注意とBigBirdのブロック疎な注意の時間と空間の複雑さの比較。
計算を見るために、このスニペットを展開してください
BigBirdの時間の複雑さ = O(w x n + r x n + g x n)
BERTの時間の複雑さ = O(n^2)
仮定:
w = 3 x 64
r = 3 x 64
g = 2 x 64
seqlen = 512の場合
=> **BERTの時間の複雑さ = 512^2**
seqlen = 1024の場合
=> BERTの時間の複雑さ = (2 x 512)^2
=> **BERTの時間の複雑さ = 4 x 512^2**
=> BigBirdの時間の複雑さ = (8 x 64) x (2 x 512)
=> **BigBirdの時間の複雑さ = 2 x 512^2**
seqlen = 4096の場合
=> BERTの時間の複雑さ = (8 x 512)^2
=> **BERTの時間の複雑さ = 64 x 512^2**
=> BigBirdの計算 = (8 x 64) x (8 x 512)
=> BigBirdの計算 = 8 x (512 x 512)
=> **BigBirdの時間の複雑さ = 8 x 512^2**
ITC vs ETC
BigBirdモデルは2つの異なる戦略、ITC(内部トランスフォーマー構築)とETC(拡張トランスフォーマー構築)を使用してトレーニングすることができます。ITCは、上記で説明したものです。ETCでは、いくつかの追加トークンをグローバルに設定することで、すべてのトークンとの間で注意を受けたり、注意を払ったりすることができます。
ITCは、ごく少数のトークンがグローバルであるため、計算量が少なくて済みますが、同時にモデルは十分なグローバル情報をキャプチャできます(ランダムアテンションの助けもあります)。一方、ETCは、コンテキストが正しく質問に関連付けられるためには、質問全体をコンテキストがグローバルに参照できる「質問応答」など、多くのグローバルトークンを必要とするタスクに非常に役立ちます。
注意: Big Birdの論文では、多くのETC実験でランダムブロックの数が0に設定されていることが示されています。これは、上記のグラフセクションでの議論に基づく合理的な判断です。
以下の表は、ITCとETCの要点をまとめたものです。
🤗TransformersでBigBirdを使用する方法
BigBirdModel
は、他の🤗モデルと同様に使用できます。以下にいくつかのコードを見てみましょう:
from transformers import BigBirdModel
# 事前学習済みのBigBirdをロード
model = BigBirdModel.from_pretrained("google/bigbird-roberta-base")
# これにより、デフォルトの設定(attention_type = "block_sparse"、num_random_blocks = 3、block_size = 64)でモデルが初期化されます。
# ただし、これらの引数を任意のチェックポイントで自由に変更することができます。これらの3つの引数は、各クエリトークンが参照するトークンの数を変更するだけです。
model = BigBirdModel.from_pretrained("google/bigbird-roberta-base", num_random_blocks=2, block_size=16)
# attention_typeを`original_full`に設定することで、BigBirdはn^2の計算量を持つ完全な注意に依存するようになります。この方法でBigBirdはBERTに99.9%似ています。
model = BigBirdModel.from_pretrained("google/bigbird-roberta-base", attention_type="original_full")
現時点で、🤗Hubには合計3つのチェックポイントが利用可能です:bigbird-roberta-base
、bigbird-roberta-large
、bigbird-base-trivia-itc
。最初の2つのチェックポイントは、BigBirdForPretraining
をmasked_lm loss
で事前学習したものです。最後のチェックポイントは、trivia-qa
データセット上でBigBirdForQuestionAnswering
のfine-tuning後のチェックポイントに対応しています。
次に、タスクをファインチューニングするために🤗のBigBirdモデルを使用するために書くことができる最小限のコードを見てみましょう(PyTorchトレーナーを使用する場合)。
# 例として、タスクを質問応答にするとしましょう
from transformers import BigBirdForQuestionAnswering, BigBirdTokenizer
import torch
device = torch.device("cpu")
if torch.cuda.is_available():
device = torch.device("cuda")
# 事前学習済みの重みとその上にランダムに初期化されたヘッドを持つBigBirdモデルを初期化します
model = BigBirdForQuestionAnswering.from_pretrained("google/bigbird-roberta-base", block_size=64, num_random_blocks=3)
tokenizer = BigBirdTokenizer.from_pretrained("google/bigbird-roberta-base")
model.to(device)
dataset = "torch.utils.data.DataLoaderオブジェクト"
optimizer = "torch.optimオブジェクト"
epochs = ...
# 非常にシンプルなトレーニングループ
for e in range(epochs):
for batch in dataset:
model.train()
batch = {k: batch[k].to(device) for k in batch}
# 順伝播
output = model(**batch)
# バックプロパゲーション
output["loss"].backward()
optimizer.step()
optimizer.zero_grad()
# 最終的な重みをローカルディレクトリに保存します
model.save_pretrained("<YOUR-WEIGHTS-DIR>")
# 重みを🤗Hubにプッシュします
from huggingface_hub import ModelHubMixin
ModelHubMixin.push_to_hub("<YOUR-WEIGHTS-DIR>", model_id="<YOUR-FINETUNED-ID>")
# 推論にファインチューニングされたモデルを使用します
question = ["How are you doing?", "How is life going?"]
context = ["<some big context having ans-1>", "<some big context having ans-2>"]
batch = tokenizer(question, context, return_tensors="pt")
batch = {k: batch[k].to(device) for k in batch}
model = BigBirdForQuestionAnswering.from_pretrained("<YOUR-FINETUNED-ID>")
model.to(device)
with torch.no_grad():
start_logits, end_logits = model(**batch).to_tuple()
# これでstart_logits、end_logitsを任意の戦略でデコードできます。
# 注意:
# これは非常にシンプルなコードでした(生のPyTorchを使用する場合には)BigBirdの使用方法を示すためだけのものです
# 多くの機能にアクセスするために🤗Trainerを使用することをお勧めします。
Big Birdを使用する際には、次のポイントを念頭に置いておくことが重要です:
- シーケンスの長さはブロックサイズの倍数である必要があります、つまり
seqlen % block_size = 0
です。バッチのシーケンス長さがブロックサイズの倍数でない場合、🤗Transformersは自動的に<pad>
(シーケンス長さよりも大きい最小のブロックサイズの倍数)を追加しますので、心配する必要はありません。 - 現在のところ、HuggingFaceのバージョンはETCをサポートしていませんので、最初と最後のブロックのみがグローバルです。
- 現在の実装では、
num_random_blocks = 0
をサポートしていません。 - シーケンスの長さが1024未満の場合、著者は
attention_type = "original_full"
を設定することを推奨しています。 - 以下の条件を必ず満たす必要があります:
seq_length > global_token + random_tokens + sliding_tokens + buffer_tokens
(ただし、global_tokens = 2 x block_size
、sliding_tokens = 3 x block_size
、random_tokens = num_random_blocks x block_size
、buffer_tokens = num_random_blocks x block_size
)。これを満たさない場合、🤗Transformersは警告と共にattention_type
を自動的にoriginal_full
に切り替えます。 - デコーダーとしてbig birdを使用する場合(または
BigBirdForCasualLM
を使用する場合)、attention_type
はoriginal_full
にする必要があります。しかし、心配する必要はありません、忘れてしまった場合でも、🤗Transformersは自動的にattention_type
をoriginal_full
に切り替えます。
次は何ですか?
@patrickvonplaten氏が、trivia-qa
データセットでBigBirdForQuestionAnswering
を評価する方法についての本当に素晴らしいノートブックを作成しました。そのノートブックを使用して、BigBirdを自由にお試しください。
まもなく、長文要約用のBigBird Pegasusのようなモデルがライブラリに追加される予定です 💥。
エンドノート
ブロックスパースなアテンション行列の元の実装は、こちらで見つけることができます。🤗のバージョンはこちらです。
We will continue to update VoAGI; if you have any questions or suggestions, please contact us!
Was this article helpful?
93 out of 132 found this helpful
Related articles