ロープとアリバイによるパフォーマンスの向上を示すケーススタディまたは参照
回転位置埋め込み(ロープ):
-
ケーススタディ1:論文「ロフォーマー:変圧器モデルの回転位置埋め込み」で、著者は、ロープが言語モデリングなどの長いシーケンスタスクのパフォーマンスを大幅に改善することを実証しました。余分な計算リソースを必要とせずに、ロープが長いシーケンスをよりよく一般化する能力により、従来の埋め込みよりも効率的な選択になりました。
-
パフォーマンスゲイン:従来の位置エンコーディングを使用したモデルと比較して、512トークンよりも長いシーケンスの処理において最大4〜6%の精度を提供しました。
Alibi(線形バイアスを伴う注意):
-
ケーススタディ2: 「Alibi:効率的な長距離シーケンスモデリングの線形バイアスを伴う注意」では、注意メカニズムに線形バイアスを導入することで、位置エンコードに依存せずにモデルがシーケンスを効率的に処理することができました。 Alibiはメモリのオーバーヘッドを減らし、機械の翻訳や要約などのタスクのモデルのスケーラビリティを改善しました。
-
パフォーマンスのゲイン: Alibiは、長期シーケンスベンチマークのモデルパフォーマンスを維持または改善しながら、トレーニング時間の最大8%の速度とメモリ使用量の大幅な削減を実証しました。
これらの進歩は、ロープやアリバイなどの近代的な位置埋め込み技術が、従来の方法の制限に対処するだけでなく、特に長い入力を扱う場合、大規模な言語モデルのスケーラビリティと効率をどのように強化するかを示しています。
より低い精度の力を活用します
LLMは、その重量を表す広大なマトリックスとベクトルで構成されています。これらの重みは通常、float32、bfloat16、またはfloat16精度に保存されます。メモリ要件は次のように推定できます。
- float32精度:必要なメモリ= 4 * x gb、xはモデルパラメーターの数(数十億)です。
- bfloat16/float16精度:メモリが必要= 2 * x gb。
BFLOAT16精度におけるメモリ使用の例:
- GPT-3: 1750億パラメーター、約350 GB VRAM。
-
ブルーム: 1760億パラメーター、〜352 GB VRAM。
- llama-2-70b: 700億パラメーター、〜140 GB VRAM。
- FALCON-40B: 400億パラメーター、〜80 GB VRAM。
- MPT-30B: 300億パラメーター、〜60 GB VRAM。
-
スターコダー: 155億パラメーター、〜31 GB VRAM。
NVIDIA A100 GPUの最大80 GB VRAMがあることを考えると、より大きなモデルでは、効率的に動作するためにテンソル並列性またはパイプライン並列性が必要です。
実用的な例
8 x 80GB A100ノードにブルームをロードする:
!PIPインストールトランスは、BitsandBytesを最適化します
#トランスフォーマーからAutomodelforcausallmをインポートします
#model = automodelforcausallm.from_pretrained( "BigScience/Bloom"、device_map = "auto"))
Transformers Import Automodelfelcausallm、Autotokenizer、Pipelineから
トーチをインポートします
モデル= automodelforcausallm.from_pretrained( "bigcode/octocoder"、torch_dtype = torch.bfloat16、device_map = "auto"、pad_token_id = 0)
tokenizer = autotokenizer.from_pretrained( "BigCode/OctoCoder")
Pipe = Pipeline( "Text-Generation"、Model = Model、Tokenizer = Tokenizer)
PROMP = "質問:バイトをギガバイトに変換する関数をPythonに記述してください。\ n \ nanswer:"
result = pipe(prompt、max_new_tokens = 60)[0] ["generated_text"] [len(prompt):]
結果
def bytes_to_giga_bytes(バイト):
バイトを返す / 1024 /1024 /1024
bytes_to_giga_bytes(torch.cuda.max_memory_allocated())
model.to( "cpu")
デルパイプ
delモデル
GCをインポートします
トーチをインポートします
def flush():
gc.collect()
torch.cuda.empty_cache()
torch.cuda.reset_peak_memory_stats()
フラッシュ()
さまざまな量子化技術がありますが、ここでは詳細に説明しませんが、一般に、すべての量子化技術は次のように機能します。
- すべての重みをターゲット精度まで量子化します。
- 量子化された重みをロードし、BFLOAT16精度のベクトルの入力シーケンスを渡します。
- 重量をBFLOAT16に動的に非定量化して、BFLOAT16精度の入力ベクトルを使用して計算を実行します。
- 入力を計算した後、重みをターゲット精度にもう一度定量化します。
一言で言えば、これは、Inputs-Weight MatrixMultiplicationsを意味し、Inputsを使用して、重量マトリックスを使用して出力を使用します。
y = x ∗ wはy = x ∗ dequantize(w); Quantize(w)に変更されます。入力がネットワークグラフを介して実行されると、すべての重量マトリックスに対して、非Quantizationと再引用が順番に実行されます。
#!pipインストールbitsandbytes
Model = automodelforcausallm.from_pretrained( "bigcode/octocoder"、load_in_8bit = true、low_cpu_mem_usage = true、pad_token_id = 0)
Pipe = Pipeline( "Text-Generation"、Model = Model、Tokenizer = Tokenizer)
result = pipe(prompt、max_new_tokens = 60)[0] ["generated_text"] [len(prompt):]
結果
bytes_to_giga_bytes(torch.cuda.max_memory_allocated())
model.cpu()
delモデル
デルパイプ
フラッシュ()
Model = automodelforcausallm.from_pretrained( "bigcode/octocoder"、load_in_4bit = true、low_cpu_mem_usage = true、pad_token_id = 0)
Pipe = Pipeline( "Text-Generation"、Model = Model、Tokenizer = Tokenizer)
result = pipe(prompt、max_new_tokens = 60)[0] ["generated_text"] [len(prompt):]
結果
bytes_to_giga_bytes(torch.cuda.max_memory_allocated())
model.cpu()
delモデル
デルパイプ
model.cpu()
delモデル
デルパイプ
フラッシュ()
Model = automodelforcausallm.from_pretrained( "bigcode/octocoder"、load_in_4bit = true、low_cpu_mem_usage = true、pad_token_id = 0)
Pipe = Pipeline( "Text-Generation"、Model = Model、Tokenizer = Tokenizer)
result = pipe(prompt、max_new_tokens = 60)[0] ["generated_text"] [len(prompt):]
結果
bytes_to_giga_bytes(torch.cuda.max_memory_allocated())
model.cpu()
delモデル
デルパイプ
フラッシュ()
フラッシュ注意メカニズム
フラッシュの注意は、メモリ効率を高め、より良いGPUメモリの利用を活用することにより、注意メカニズムを最適化します。このアプローチでは、
-
メモリフットプリントの削減:注意計算をより効率的に処理することにより、メモリオーバーヘッドを大幅に最小限に抑えます。
-
より高いパフォーマンス:推論中の速度の大幅な改善。
System_prompt = "" "以下は、さまざまな人々とAIのテクニカルアシスタントの間の一連の対話です。
アシスタントは、親切で、礼儀正しく、正直で、洗練され、感情的に認識し、謙虚であるが知識が豊富であることを試みます。
アシスタントはコードの質問を喜んで手伝い、必要なものを正確に理解するために最善を尽くします。
また、虚偽または誤解を招く情報を提供しないようにしようとします。また、正しい答えについて完全に確信が持てない場合は警告します。
とはいえ、アシスタントは実際にその最善を尽くしており、有用であるという邪魔をしすぎないようにしません。
StarCoderモデルは、Stack(v1.2)から80のプログラミング言語でトレーニングされた一連の15.5bパラメーターモデルです(オプトアウトリクエストを除く)。
このモデルはマルチクエリの注意を使用し、中程度の目標を使用してトレーニングされ、8,192トークンのコンテキストウィンドウを使用して、重度に重複したデータを1兆個用にしました。
-----
質問:2つのリストを取得し、各入力リストから交互の要素があるリストを返す関数を書きます。
回答:確かに。これがそれを行う関数です。
def alternating(list1、list2):
結果= []
範囲のiの場合(len(list1)):
results.append(list1 [i])
results.append(list2 [i])
結果を返します
質問:この機能のテストケースをいくつか書くことはできますか?
回答:確かに、ここにいくつかのテストがあります。
assert alternating([10、20、30]、[1、2、3])== [10、1、20、2、30、3]
assert alternating([true、false]、[4、5])== [true、4、false、5]
Assert Alternating([]、[])== []
質問:リストの長さが不均一になったときにすべての入力要素を返すように機能を変更します。長いリストの要素は最後にあるはずです。
回答:ここに修正された関数があります。
def alternating(list1、list2):
結果= []
範囲のi(min(len(list1)、len(list2))):
results.append(list1 [i])
results.append(list2 [i])
Len(list1)> len(list2)の場合:
results.extend(list1 [i 1:])
それ以外:
results.extend(list2 [i 1:])
結果を返します
-----
"" "
long_prompt = 10 * System_promptプロンプト
Model = automodelforcausallm.from_pretrained( "bigcode/octocoder"、torch_dtype = torch.bfloat16、device_map = "auto")
tokenizer = autotokenizer.from_pretrained( "BigCode/OctoCoder")
Pipe = Pipeline( "Text-Generation"、Model = Model、Tokenizer = Tokenizer)
インポート時間
start_time = time.time()
result = pipe(long_prompt、max_new_tokens = 60)[0] ["generated_text"] [len(long_prompt):]
print(f "{time.time() - start_time}秒で生成されます。")
結果
bytes_to_giga_bytes(torch.cuda.max_memory_allocated())
出力:

フラッシュ()
model = model.to_bettertransformer()
start_time = time.time()
result = pipe(long_prompt、max_new_tokens = 60)[0] ["generated_text"] [len(long_prompt):]
print(f "{time.time() - start_time}秒で生成されます。")
結果
bytes_to_giga_bytes(torch.cuda.max_memory_allocated())
フラッシュ()
出力:

LLMアーキテクチャの背後にある科学
これまでのところ、以下を含む計算効率とメモリ効率を改善するための戦略を調査しました。
- より低い精度形式にウェイトをキャストします。
- より効率的なバージョンの自己関節アルゴリズムを実装します。
ここで、大規模な言語モデル(LLMS)のアーキテクチャを変更して、次のような長いテキスト入力を必要とするタスクに最適化する方法に注意を向けています。
- 検索された高級質問応答、
- 要約、
- チャットアプリケーション。
特に、チャットインタラクションでは、LLMが長いテキスト入力を処理するだけでなく、CHATGPTが達成するものと同様に、ユーザーとモデルの間の動的な前後の対話を効率的に処理する必要があります。
トレーニング後のLLMの基本的なアーキテクチャを修正することは困難であるため、適切に考慮された設計上の決定を前もって行うことが不可欠です。 LLMアーキテクチャの2つの主要なコンポーネントは、多くの場合、大きな入力シーケンスのパフォーマンスボトルネックになります。
これらのコンポーネントをより深く掘り下げましょう。
LLMSの位置埋め込みの改善
自己関節メカニズムは、テキストシーケンス内の各トークンを他のトークンに関連付けます。たとえば、入力シーケンス「Hello」、「I」、「Love」、「You」のSoftMax(QKT)マトリックスは次のように表示できます。
|
こんにちは |
私 |
愛 |
あなた |
こんにちは |
0.2 |
0.4 |
0.3 |
0.1 |
私 |
0.1 |
0.5 |
0.2 |
0.2 |
愛 |
0.05 |
0.3 |
0.65 |
0.0 |
あなた |
0.15 |
0.25 |
0.35 |
0.25 |
各単語トークンには、他のトークンにどれだけ参加するかを示す確率分布があります。たとえば、「愛」という言葉は、0.05の確率で「Hello」、0.3の「I」、それ自体が0.65の「I」に注意しています。
しかし、位置の埋め込みがなければ、LLMはトークンの相対的な位置を理解するのに苦労しており、「Hello I Love You」のようなシーケンスを「You Love I Hello」と区別するのが難しくなります。 QKT計算は、位置距離を考慮せずにトークンを関連付け、それぞれを等距離として扱います。
これを解決するために、位置エンコーディングが導入され、モデルがトークンの順序を理解するのに役立つ数値キューを提供します。
従来の位置埋め込み
元の注意が必要なのは、紙のすべてで、正弦波位置埋め込みが提案され、各ベクトルはその位置の正弦波機能として定義されます。これらの埋め込みは、次のように入力シーケンスベクトルに追加されます。
Bertなどの一部のモデルは、トレーニング中に学習された学習位置埋め込みを導入しました。
絶対的な位置埋め込みによる課題
正弦波および学習された位置埋め込みは絶対的であり、ユニークな位置をコードします。しかし、Huang et al。また、絶対的な埋め込みは、長いシーケンスのパフォーマンスを妨げる可能性があります。重要な問題は次のとおりです。
-
長い入力制限:絶対埋め込みは、相対距離ではなく固定位置に焦点を合わせているため、長いシーケンスを処理するときにパフォーマンスが低下します。
-
固定トレーニングの長さ:学習した埋め込みは、モデルを最大トレーニング長に結び付け、より長い入力に一般化する能力を制限します。
進歩:相対的な位置埋め込み
これらの課題に対処するために、相対的な位置埋め込みは牽引力を獲得しました。 2つの注目すべき方法は次のとおりです。
- 回転位置埋め込み(ロープ)
- alibi(線形バイアスを伴う注意)
どちらの方法でも、QKT計算を変更して、文の順序を自己関節メカニズムに直接組み込み、モデルが長いテキスト入力を処理する方法を改善します。
回転位置埋め込み(ロープ)は、クエリとキーベクターをそれぞれ角度で回転させ、位置を示すことにより位置情報をエンコードします。
ここでは、回転マトリックスであり、トレーニングの最大入力長に基づいて事前に定義されています。
これらのアプローチにより、LLMは相対距離に焦点を合わせ、より長いシーケンスの一般化を改善し、効率的なタスク固有の最適化を促進することができます。
input_ids = tokenizer(prompt、return_tensors = "pt")["input_ids"]。to( "cuda"))
_の範囲(5):
next_logits = model(input_ids)["logits"] [:, -1:]
next_token_id = torch.argmax(next_logits、dim = -1)
input_ids = torch.cat([input_ids、next_token_id]、dim = -1)
print( "input_ids"、input_ids.shape)
generated_text = tokenizer.batch_decode(input_ids [:、-5:])
generated_text

past_key_values = none#past_key_valuesはキー値キャッシュです
generated_tokens = []
next_token_id = tokenizer(prompt、return_tensors = "pt")["input_ids"]。
_の範囲(5):
next_logits、past_key_values = model(next_token_id、past_key_values = past_key_values、use_cache = true).to_tuple()
next_logits = next_logits [:, -1:]
next_token_id = torch.argmax(next_logits、dim = -1)
print( "input_ids"、next_token_id.shape)
print( "key-valueキャッシュの長さ"、len(past_key_values [0] [0]))
generated_tokens.append(next_token_id.item())
generated_text = tokenizer.batch_decode(generated_tokens)
generated_text

config = model.config
2 * 16_000 * config.n_layer * config.n_head * config.n_embd // config.n_head
出力
7864320000
結論
長いテキスト入力と動的チャットアプリケーションのLLMアーキテクチャの最適化は、実際の適用性を向上させる上で極めて重要です。広範な入力コンテキストを管理し、計算効率を維持し、意味のある会話の相互作用を提供するという課題は、建築レベルで革新的なソリューションを必要とします。回転位置埋め込み(ロープ)、アリバイ、フラッシュの注意などの技術は、位置埋め込みや自己触媒などの微調整中心部品の変革の可能性を示しています。
フィールドが前進するにつれて、計算効果とエンジニアリングの独創性を混合することの中心は、次のブレークスルーの波を促進します。これらの手順を理解して実現することにより、設計者はLLMの総制御に取り組むことができ、それらが見事に公平ではなく、あまりにも適応性があり、応答性が高く、異なる現実世界のアプリケーションで一般的であることを保証できます。
キーテイクアウト
- ロープやアリバイなどのテクニックにより、パフォーマンスを犠牲にすることなく、より長いテキストを処理するLLMSの能力が向上します。
- フラッシュの注意やスライドウィンドウの注意などのイノベーションは、メモリの使用量を減らし、現実世界のアプリケーションに大きなモデルを実用的にします。
- 長いテキスト入力のLLMを最適化すると、拡張された会話と複雑なタスクのコンテキストと一貫性を維持する能力が向上します。
- LLMは、要約、検索、マルチターンダイアログなどのタスクをサポートし、スケーラビリティと応答性を向上させるために進化しています。
- モデルの精度を低下させると、精度を維持しながら計算効率が向上し、より広範な採用が可能になります。
- 建築設計とリソースの最適化のバランスをとることで、LLMは多様で成長するユースケースに依然として効果的になります。
よくある質問
Q1。 1。LLMSとは何ですか?なぜ重要なのですか? A.大規模な言語モデル(LLMS)は、それを取得して人間のようなコンテンツを作成するために概説されているAIモデルです。これらは、質問への返信から想像力豊かな作曲まで、さまざまなビジネスに柔軟な装置になるまで、幅広い割り当てを実行する能力のために重要です。
Q2。ロープとアリバイはどのようにLLMSを改善しますか? A.ロープ(ロータリー位置エンコーディング)とAlibi(線形バイアスを伴う注意)は、長いコンテキストを処理する能力を改善し、一貫性を失うことなく拡張テキストの効率的な処理を確保することによりLLMSを強化します。
Q3。 Flashの注意とは何ですか?また、メモリ使用量を最適化する方法は何ですか? A.フラッシュの注意は、注意をより効率的に計算し、メモリの消費を大幅に削減し、大規模なモデルの処理をスピードアップするアルゴリズムです。
Q4。 LLMSにとって量子化が重要なのはなぜですか? A.量子化により、重みを示す精度(32ビットから8ビットまで)が低下します。これにより、計算の必需品とメモリの利用が低下し、維持されていることで、より小さなガジェットの配置を強化します。
Q5。 LLMSをさらにスケーリングするためにどのような課題が残っていますか? A.主要な課題には、計算コストとメモリコストの管理、バイアスや誤用などの倫理的懸念への対処、モデルが多様なタスクや言語全体で効果的に一般化できるようにすることが含まれます。
Q6。長いテキスト入力を効果的に処理するためにLLMを最適化するにはどうすればよいですか? A.長いテキスト入力のLLMSの最適化には、コンテキストウィンドウの拡張、メモリメカニズム、効率的なトークン処理などの手法が含まれ、拡張会話やドキュメント分析中に一貫性とパフォーマンスを維持します。