HUOXIU

LLaMA 3 コアテクノロジーの「大規模モデル初心者」向け解説

編集者注:この記事は、LLaMA 3の中核技術である、事前正規化のためのRMSNorm、SwiGLU活性化関数、回転エンコーディング(RoPE)、バイトペアエンコーディング(BPE)アルゴリズムについて、読者に深く理解してもらうことを目的としています。RMSNormは、モデルがテキスト内の重要なポイントを識別することを可能にし、SwiGLU活性化関数は「魔法のペン」のように機能し、生成されたテキストをより焦点を絞った分かりやすいものにします。RoPEは、シーケンス内の単語の位置をモデルが柔軟に処理できるようにし、BPEアルゴリズムは、モデルの長文処理能力を効果的に強化します。

開発環境の設定とプロジェクトロジックの整理から、各コンポーネントの導入と構築、そしてモデルコンポーネントの統合まで、この記事ではテキストデータのセグメンテーションから埋め込みの作成、アテンションメカニズムからマルチヘッドアテンションの実装まで、プロセス全体をステップバイステップで解説します。Pythonプログラミング、ニューラルネットワーク、そしてTransformerアーキテクチャに関する基本的な知識があれば、このガイドに従ってLLaMA 3が入力からどのように出力を生成するかを観察し、入力に基づいて一貫性と意味のあるテキストを生成する様子を目の当たりにすることができます。

著者は、完全なコードサンプルと詳細なガイダンスドキュメントを提供しており、GPUは不要で17GBのRAMのみですぐに始めることができます。理論的な理解を深めたい場合でも、実践的なスキルを向上させたい場合でも、この記事は非常に貴重なリソースとなります。

著者 | ファリード・カーン

編纂者:岳陽

LLaMA 3[1]は、Mistral[2]に次ぐ最も有望なオープンソースモデルの一つであり、様々なタスクに対応できる強力な能力を備えています。以前、私はLLaMAアーキテクチャに基づいて、230万以上のパラメータを持つ大規模言語モデル(LLM)をゼロから構築する方法を詳しく説明した記事を公開しました。LLaMA-3がリリースされたので、このモデルをよりシンプルな方法で再構築します。

このブログ投稿では GPU を使用する必要はありませんが、サイズが 15 GB を超える複数のファイルを読み込むため、少なくとも 17 GB の RAM が必要です。

練習を容易にするために、私はこのブログから1行ずつコピーして貼り付けるという面倒なプロセスを回避し、すべての操作コードと詳細な手順を含むノートブックファイルを含むコードリポジトリをGitHub [3] に作成しました。

230万以上のパラメータを持つ大規模言語モデル(LLM)をゼロから構築する方法を学びたいですか?このガイド[4]を参考に、大規模モデルをゼロから構築する旅に出かけましょう。

目次

01 前提条件の概要

02 LLaMA 2とLLaMA 3の違い

03 LLaMA 3アーキテクチャの探究

  • RMSNormを使用した事前正規化
  • SwiGLU活性化関数
  • 回転エンコーディング(RoPE)
  • バイトペアエンコーディング(BPE)アルゴリズム

04 開発環境を構成する

05. プロジェクトの組織ロジックを明確にする

06. 入力データに対して単語分割を実行します。

07 各トークンの埋め込みを作成する

08. RMSNormを使った正規化

09. 主要な要素 (クエリ、キー、値) に注意してください。

10 RoPEの実装

11 自己注意を実装する

12 マルチヘッドアテンションの実装

13. SwiGLU活性化関数を実装する

14. 上記のモデルコンポーネントを統合する

15. 証人モデルが入力に基づいて出力を生成する方法。

01 前提条件の概要

この記事はオブジェクト指向プログラミング(OOP)については扱いません。Pythonの基本的な構文を理解していれば十分です。ただし、このブログ記事をスムーズに読むには、ニューラルネットワークとTransformerのアーキテクチャの基礎的な理解が不可欠です。この2点が、この記事を学習するための必須条件です。

02 LLaMA 2とLLaMA 3の違い

技術的な詳細に入る前に、LLaMA 3のアーキテクチャはLLaMA 2と全く同じであることを理解しておくことが重要です。そのため、LLaMA 3の技術的な詳細をまだ調べていない方でも、このブログ記事を読んでいただければ全く問題ありません。また、LLaMA 2のアーキテクチャに馴染みのない方もご安心ください。興味のあるすべての読者の皆様がこの記事からメリットを得られるよう、技術的な詳細の概要を説明します。

LLaMA 2 と LLaMA 3 に関する重要なポイントは次のとおりです。

03 LLaMA 3アーキテクチャの探究

コードを書き始める前に、LLaMA 3アーキテクチャを理解することが不可欠です。読者がこの概念をより明確に理解できるように、オリジナルのTransformerアーキテクチャとLLaMA 2/3、およびMistralの類似点と相違点を視覚的に示した比較表を掲載しています。

ラジェシュ・カヴァディキより

それでは、LLaMA 3 のコア要素のいくつかの詳細を見ていきましょう。

3.1 RMSNormを用いた前正規化

LLaMA 2 のアプローチに従って、LLaMA 3 は RMSNorm と呼ばれる手法を採用して、各 Transformer サブレイヤーの入力データを正規化します。

大きな試験の準備をしていて、分厚い教科書が手元にあると想像してみてください。教科書は複数の章に分かれています。各章はそれぞれ異なるトピックを扱っていますが、全体のテーマを理解する上で特に重要な章もあります。教科書全体を読む前に、各章の重要性を評価してみることにしました。すべての章に同じ時間をかけるのではなく、核となる章にエネルギーを集中させたいのです。

ChatGPTのような大規模言語モデル(LLM)と同様に、 RMSnormを事前正規化に使用することは、各章の重要度に応じて「重み付け」するようなものです。本のテーマを理解する上で重要な章には高い「重み付け」が与えられ、それほど重要でない章には低い「重み付け」が与えられます。

そのため、教材を深く理解する前に、各章の重要度に基づいて学習計画を調整します。重要度の高い章には、より多くの時間と労力を割き、その中核となる概念を包括的かつ深く理解できるようにします。

「二乗平均平方根レイヤー正規化」(https://arxiv.org/abs/1910.07467)

同様に、RMSNormを事前正規化に用いることで、大規模言語モデル(LLM)が文脈とその意味を理解する上でテキストのどの部分がより重要かを特定するのに役立ちます。RMSNormは、重要な要素に高い重みを、そうでない要素に低い重みを割り当てることで、文脈を正確に解釈するために最も必要な部分にモデルが注意を集中するように導きます。このトピックに興味のある読者は、RMSNormの具体的な実装について、こちら[5]で詳しく知ることができます。

3.2 SwiGLU活性化関数

LLaMA は PaLM モデルからインスピレーションを得て、SwiGLU アクティベーション関数を導入しています。

あなたが教師で、生徒に複雑なトピックを説明しようとしているところを想像してみてください。大きなホワイトボードに要点を書き、説明を分かりやすくするために図を描いています。しかし、時には手書きが汚かったり、図が完璧でなかったりするかもしれません。これは、生徒が教材を理解するのを著しく困難にする可能性があります。

それぞれの重要度に応じて、文字の大きさとスタイルを自動調整する「魔法のペン」を持っていると想像してみてください。重要なポイントは大きくはっきりと書き、より目立たせます。重要度の低いポイントは小さく書きますが、それでも読みやすいように書きます。

SwiGLUは、ChatGPTのような大規模言語モデル(LLM)において「魔法のペン」のような役割を果たします。テキストを生成する前に、SwiGLUは文脈との関連性に基づいて各単語またはフレーズの重要度を調整します。「魔法のペン」が文章を書く際にフォントサイズとスタイルを調整するように、SwiGLUも各単語またはフレーズの重要度を調整します。

「SwiGLU: GLUバリアントによるTransformerの改良」(https://kikaben.com/swiglu-2020/)

このように、大規模言語モデルはテキストを生成する際に重要な部分を強調表示し、それらの内容がテキスト全体の理解にさらに貢献するようにすることができます。このように、SwiGLUは大規模言語モデルがより明確で理解しやすいテキストを生成するのを支援します。これはまるで「魔法のペン」がホワイトボード上で生徒にとってより明確な内容を作成するのを支援するのと同様です。SwiGLUの詳細については、関連論文[6]を参照してください。

3.3 回転エンコーディング(RoPE)

Rotary Embeddings (RoPE) は、LLaMA 3 で使用される位置埋め込み方法です。

教室でグループディスカッションを企画し、生徒に座席を割り当てる必要があると想像してみてください。従来の方法では、生徒は固定席に座り、列と行に座席を配置します。しかし、状況によっては、生徒がより自由に動き回り、交流できるような、より柔軟な座席配置を設計したい場合があります。

RoPEは、特別な座席配置のようなもので、各生徒が他の生徒との相対的な位置関係を維持しながら、回転したり姿勢を変えたりすることができます。生徒は固定された場所に縛られることなく、円を描くように動くことができるため、よりスムーズな交流が可能になります。

このシナリオでは、各生徒はテキストシーケンス内の単語またはトークンを表し、その位置はシーケンス内の位置に対応します。RoPEでは、生徒が回転したり位置を変更したりできるのと同様に、テキストシーケンス内の単語の位置埋め込みも、相対的な位置に基づいて動的に調整できます。

そのため、 RoPEはテキスト処理の過程で、位置エンコーディングを単純に固定された静的な要素とみなすのではなく、回転の概念を巧みに取り入れることで、表現をより柔軟で多様なものにし、テキストシーケンス内の単語間の変化する関係をより正確に把握できるようにします。この柔軟性により、ChatGPTなどのモデルは、自然で流暢、かつ論理的に一貫したテキストコンテンツをより深く理解・生成する能力が高まります。これは、教室で動的な座席配置を採用することで、よりインタラクティブな議論を促進できるのと同じです。その背後にある数学的原理を理解するには、RoPEの関連論文[7]を参照してください。

3.4 バイトペアエンコーディング(BPE)アルゴリズム

LLaMA 3はOpenAIが提供するtiktokenライブラリのバイトペアエンコーディング(BPE)を使用していますが、LLaMA 2のBPEセグメンテーションメカニズムはsentencepieceライブラリに基づいています。両者には微妙な違いはあるものの、現時点での主な課題はBPEが実際に何であるかを理解することです。

簡単な例から始めましょう。「ab」、「bc」、「bcd」、「cde」という単語を含むテキストコーパスがあるとします。コーパス内のすべての単語を個々の文字からなる語彙に分解すると、{「a」、「b」、「c」、「d」、「e」}となります。

次に、テキストコーパス内の各文字の出現頻度を計算します。この例では、統計は{"a": 1, "b": 3, "c": 3, "d": 2, "e": 1}となります。

  1. 次に、コアステージであるマージプロセスに移ります。語彙が所定のサイズに達するまで、以下の手順を繰り返します。まず、最も頻繁に出現する連続文字の組み合わせを特定します。この例では、最も頻繁に出現するペアは「bc」で、頻度は2です。次に、このペアをマージして新しいサブワード単位「bc」を生成します。マージ後、文字頻度は{"a": 1, "b": 2, "c": 2, "d": 2, "e": 1, "bc": 2}に更新されます。次に、新しいサブワード単位「bc」を語彙に追加し、{"a", "b", "c", "d", "e", "bc"}に拡張します。
  2. このプロセスが繰り返されます。次に頻出する単語ペアは「cd」です。これは統合されて新しいサブワードユニット「cd」が生成され、それに応じて頻度が更新されます。更新されたシーケンスは{"a": 1, "b": 2, "c": 1, "d": 1, "e": 1, "bc": 2, "cd": 2}です。次に、「cd」が語彙に追加され、{"a", "b", "c", "d", "e", "bc", "cd"}になります。
  3. このプロセスを続けると、次に頻出する単語ペアは「de」であり、これはサブワードユニット「de」に統合され、その頻度は{「a」: 1、「b」: 2、「c」: 1、「d」: 1、「e」: 0、「bc」: 2、「cd」: 1、「de」: 1}に更新されます。次に、「de」が語彙に追加され、{「a」、「b」、「c」、「d」、「e」、「bc」、「cd」、「de」}に更新されます。
  4. 次に、「ab」が最も頻出する単語ペアであることがわかったので、これをサブワードユニット「ab」に統合し、頻度を{"a": 0, "b": 1, "c": 1, "d": 1, "e": 0, "bc": 2, "cd": 1, "de": 1, "ab": 1}に更新しました。その後、「ab」を語彙に追加し、{"a", "b", "c", "d", "e", "bc", "cd", "de", "ab"}に拡張しました。
  5. 次に、「bcd」が次に頻出する単語ペアとなり、サブワード単位「bcd」に統合され、頻度は{"a": 0, "b": 0, "c": 0, "d": 0, "e": 0, "bc": 1, "cd": 0, "de": 1, "ab": 1, "bcd": 1}に更新されます。その後、「bcd」が語彙に追加され、{"a", "b", "c", "d", "e", "bc", "cd", "de", "ab", "bcd"}にアップグレードされます。
  6. 最後に、最も頻出する単語ペアは「cde」で、これはサブワード単位「cde」に統合され、頻度は{"a": 0, "b": 0, "c": 0, "d": 0, "e": 0, "bc": 1, "cd": 0, "de": 0, "ab": 1, "bcd": 1, "cde": 1}に更新されます。その後、「cde」が語彙に追加され、語彙は{"a", "b", "c", "d", "e", "bc", "cd", "de", "ab", "bcd", "cde"}になります。

この手法は、大規模言語モデル(LLM)の性能を大幅に向上させ、一般的でない単語や語彙に含まれない単語を効果的に処理できます。TikToken BPEとSentencepiece BPEの主な違いは、TikToken BPEは既知の完全な単語を盲目的に分割しないことです。例えば、「hugging」が語彙に既に存在する場合、そのまま残り、["hug", "ging"]のように分割されることはありません。

04 環境設定

いくつかのPythonライブラリを使用します。「モジュールが見つかりません」というエラーを防ぐため、以下のコマンドを実行して事前にこれらのライブラリをインストールすることをお勧めします。

必要なライブラリをインストールしたら、次は関連ファイルをダウンロードします。llama-3-8Bモデルのアーキテクチャを再現するため、HuggingFaceプラットフォームにアカウントを登録する必要があります。また、llama-3は制限付きモデルであるため、コンテンツにアクセスする前に利用規約に同意する必要があります。

具体的な手順は以下のとおりです。

  • HuggingFaceアカウントを登録するにはここ[8]をクリックしてください
  • llama-3-8Bの利用規約に同意するにはここ[9]をクリックしてください。

上記の2つの手順を完了すると、必要なファイルがダウンロードされます。ダウンロードには2つの方法があります。

  • 手動ダウンロード(オプション1:手動):このリンク[10]からllama-3–8BのHuggingFaceディレクトリにアクセスし、次の3つのファイルを1つずつ手動でダウンロードします。

LLaMA-3 構成ファイルのダウンロード

  • プログラミングによるダウンロード(オプション2:コーディング):事前にインストールしたhugging_faceライブラリを使用すれば、必要なファイルはすべてワンクリックでダウンロードできます。ただし、その前に、現在の作業環境でHFトークンを使用してHuggingFace Hubにログインする必要があります。新しいトークンを作成するか、このリンク[11]から直接取得することができます。

このコードユニットを実行すると、トークンの入力を求められます。ログインに問題が発生した場合は、もう一度お試しください。その際、「token as git credential」オプションのチェックを外してください。その後は、簡単なPythonスクリプトを実行するだけで、llama-3-8Bアーキテクチャの3つのメインファイルを正常にダウンロードできます。

必要なファイルをすべてダウンロードしたら、このブログで使用する Python ライブラリをインポートする必要があります。

次に、ダウンロードした各ファイルの具体的な目的を理解する必要があります。

05. プロジェクトの組織ロジックを明確にする

私たちの目標はllama-3を正確に再現することなので、入力テキストに関わらず意味のある出力が得られるはずです。例えば、「太陽の色は何ですか?」という質問を入力した場合、期待される答えは当然「白」です。しかし、これを実現するには通常、大規模なデータセットを用いて大規模言語モデル(LLM)を学習する必要があり、これは多くの場合非常に多くの計算量を必要とするため、現実的ではありません。

しかし、Metaはllama-3アーキテクチャファイル(より正確には、事前学習済みモデルの重み)を一般公開しています。これは私たちがダウンロードしたファイルなので、モデルを自分で学習させたり、アーキテクチャを再現するために大規模なデータセットを収集したりする必要はありません。準備はすべて整ったので、あとはこれらのコンポーネントを適切な場所で正しく使用するだけです。

それでは、これらのドキュメントを 1 つずつ調べて、それぞれの重要な役割を見てみましょう。

`tokenizer.model` — 前述の通り、LLaMA-3はTikTokライブラリのバイトペアエンコーディング(BPE)トークン化技術を使用しています。この技術は、LLaMA-2で使用されたデータセットの7倍にあたる15兆トークンを含む大規模なデータセットで学習されました。それでは、このファイルを読み込んで、その秘密を探ってみましょう。

` length属性は語彙全体のサイズ、具体的にはトレーニングデータ内の異なる(一意の)文字の総数を表しますtokenizer_model自体は辞書型のデータ構造です。

ランダムに10個の項目を選択して表示すると、これらはすべてBPEアルゴリズムを用いて慎重に構築された文字列であることがわかります。これは、前述の例と非常によく似ています。ここで、辞書のキーはBPEアルゴリズムの学習プロセスにおけるバイトシーケンスを表し、辞書の値は出現頻度によって決定されるマージランクを反映しています。

ファイルsolidated.00.pthには重要な詳細が含まれています。それは、Llama-3-8Bモデルがトレーニング中に学習したすべてのパラメータ(モデル重みとも呼ばれます)が格納されているということです。これらのパラメータは、トークンのエンコード方法、アテンション重みの計算方法、フィードフォワードニューラルネットワーク変換の実行方法、そして最終的な出力の正規化方法など、モデルの動作の詳細を明らかにします。

Transformerアーキテクチャに精通している方であれば、クエリ行列やキー行列といった概念は容易に理解できるでしょう。後ほど、これらのモデルレイヤー/重みを用いて、Llama-3アーキテクチャ内でこれらの行列を構築する方法を説明します。

params.json — このファイルには、次のようなさまざまなパラメータの特定の値が記録された多くの情報が含まれています。

これらの値は、Llama-3アーキテクチャを段階的に再現するのに役立ちます。これらの値は、アテンションヘッドの数や埋め込みベクトルの次元など、モデルアーキテクチャの主要なパラメータを詳細に記録します。

ここで、後続の手順で使用するために、これらのデータ値を適切に保存しましょう。

トークナイザーモデルキーの重みを含むアーキテクチャモデル、そして詳細な設定パラメータが揃ったので、最後のステップを除いてすべて準備完了です。さあ、最も基本的な部分から始めて、独自のLlama-3モデルを構築してみましょう!

06. 入力データに対して単語分割を実行します。

このステップの主なタスクは、入力テキスト情報をトークン形式に変換することです。このステップの鍵となるのは、まず一連の特殊なトークンを生成することです。これらの特殊なトークンは、ナビゲーションマーカーのように、単語分割後のテキストに埋め込まれます。これにより、単語分割器は特定の条件や指示を認識して処理することができ、プロセス全体にとって不可欠な要素となります。

次に、入力テキスト内の様々な種類の部分文字列を識別するための様々なパターンを定義し、テキスト分割ルールを策定します。具体的な手順を見てみましょう。

このツールは、入力テキストから単語、短縮形、数字(最大3桁) 、および空白文字以外の文字で構成される文字列を抽出できます。ニーズに合わせてカスタマイズできます。

TikTokenのBPEアルゴリズムを使用して、3つのパラメータ( t0okenizer_modeltokenize_breakerspecial_tokens )を受け入れるシンプルなトークン化関数を作成する必要があります。この関数は、入力テキストを必要に応じてエンコードまたはデコードします。

エンコード関数が正しく動作することを確認するために、まず「Hello World」をテストテキストとして入力します。関数はまずテキストをエンコードし、数値列に変換します。次に、これらの数値を元のテキストにデコードし、最終的に「hello world!」を取得します。このプロセスにより、関数が正しく動作することが証明されます。それでは、入力コンテンツの単語分割を始めましょう。

特殊な用語を使用して、入力テキスト「生命、宇宙、そして万物についての究極の問いに対する答えは何か」のエンコードを開始します (翻訳者注: これは<|begin_of_text|>です)。

07 各トークンの埋め込みを作成する

入力ベクトルの長さを確認すると、その長さは次のようになります。

現在、入力ベクトルの次元は(17x1)です。次のステップは、分割された各単語を対応する埋め込み表現に変換することです。これにより、元の(17x1)トークンは(17x4096)次元の埋め込み行列に拡張されます。つまり、各トークンは長さ4096の埋め込みベクトルを持つことになります。

注意すべき点は、これらの埋め込みベクトルが正規化されていないことです。正規化を行わないと、深刻な悪影響が生じる可能性があります。次のセクションでは、入力ベクトルの正規化処理について説明します。

08. RMSNormを使った正規化

入力ベクトルが正規化されていることを確認するために、前述の RMSnorm 式を使用して処理します。

「二乗平均平方根レイヤー正規化」(https://arxiv.org/abs/1910.07467)

正規化されていない埋め込みベクトルを正規化するために、layer_0 の注目重みを使用します。layer_0 を選択した理由は、LLaMA-3 Transformer アーキテクチャの最初の層を扱っているためです。

ベクトルを正規化するだけで他の操作は実行しないため、ベクトルの次元は変化しません。

09. 主要な要素 (クエリ、キー、値) に注意してください。

まず、モデルからクエリ、キー、値、および出力ベクトルを読み込みます。

ベクトル次元からわかるように、ダウンロードしたモデルの重みは、複数のアテンションヘッドを同時に処理できる並列処理または並列学習を使用しているため、単一のアテンションヘッド向けに設計されたものではありません。しかし、これらの行列を分解することで、単一のアテンションヘッドにのみ適用できるようになりました。

ここで、 32 LLama-3 のアテンション ヘッドの数、 128はクエリ ベクトルの次元、 4096はトークン埋め込みの次元を表します。

最初のレイヤーの最初のアテンションヘッドのクエリ重みマトリックスは、次のように取得できます。

各トークンに対応するクエリ ベクトルを計算するには、トークンの埋め込みベクトルにクエリの重みを掛ける必要があります。

クエリ ベクトル自体はプロンプト テキスト内の特定の位置を識別できないため、RoPE テクノロジを使用してこれらのベクトルがその位置を認識できるようにします。

10 RoPEの実装

クエリベクトルを 2 つのグループに分割し、各グループの回転角度を調整して区別します。

これは、サイズ[17x64x2]のベクトルを処理することを意味します。基本的には、各プロンプト語に含まれる128単位(長さ128)のクエリ情報を64個のペアに分割します。各クエリペアは、m*θの角度で回転します。ここで、mはシーケンス内のトークンの位置です。

ベクトルの回転演算を実行するには、複素数のドット積を使用します。

セグメンテーションプロセスが完了したら、次にセグメント化されたデータに対して頻度計算を実行します。

これで、各トークンのクエリ部分に対応する複素数値が割り当てられました。次に、これらのクエリを複素数に変換し、シーケンス内のそれぞれの位置に基づいてドット積演算を使用して回転を実行します。

回転したベクトルを取得した後、以前の複素数を実数として再解釈することで、元々ペア形式で表現されていたクエリ ベクトルを復元できます。

次に、回転されたデータをマージして、[17x128]の形状を持つ新しい回転クエリベクトルを取得します。ここで、17はトークンの総数、128はクエリベクトルの次元を表します。

キーベクトルはクエリベクトルと同様に処理されますが、キーベクトルも128次元であることに注意してください。キーベクトルの重みは計算量を最小限に抑えるために4つのアテンションヘッド間で共有されるため、重みの数はクエリベクトルの4分の1になります。クエリベクトルと同様に、キーベクトルも位置情報を組み込むために回転処理が行われ、これによりモデルによる配列位置の理解が向上します。

これで、各トークンの回転されたクエリとキーが取得されました。どちらも [17x128] です。

11 自己注意を実装する

クエリ行列とキー行列を乗算することで、各トークンと他のトークンとの関連度に対応するスコア(類似度スコア)のセットが得られます。具体的には、これらのスコアは各トークンのクエリベクトルとキーベクトルの関係を表します。

[17x17] この図形は注目スコア (qk_per_token) を表します。17 という数字はキューテキストに含まれるトークンの数を示します。

クエリキースコアをマスクする必要があります(注:これは、アテンションウェイトを計算する際に、クエリマトリックスとキーマトリックス間の一致スコアまたは関連スコアを指します)。モデルのトレーニング中、モデルが予測に過去の情報のみを使用するようにするため、将来のトークンのクエリキースコアをマスクします。この戦略により、推論中に将来のすべてのトークンのクエリキースコアがゼロに設定されます。

次に、各トークンのクエリベクトルとキーベクトルに対してマスキング操作を実行する必要があります。次に、ソフトマックス関数を適用して、得られたスコアを確率値に変換します。これにより、モデルの語彙から最も可能性の高いトークンまたはトークンシーケンスを選択できるようになり、モデルの予測がより理解しやすくなり、言語生成や分類などのアプリケーションに適したものになります。

自己注意機構は値行列で完結します。同様に、計算リソースを節約するために、値行列の重みは4つの注意ヘッドごとに共有されます。最終的に、値重み行列は[8x128x4096]の形状になります。

クエリ行列やキー行列と同様に、特定の方法を通じて第 1 層と第 1 アテンション ヘッドの値行列を取得できます。

価値行列の重みを用いて各トークンの注目度を計算し、最終的に[17x128]の形状の行列を得ます。ここで、17はプロンプトテキストに含まれるトークンの総数、128は単一トークンの価値ベクトルの次元です。

最終的なアテンション マトリックスを取得するには、次の乗算演算を実行するだけです。

これで、第 1 層と第 1 注意ヘッドの注意値、つまり実際には自己注意値を取得しました。

12 マルチヘッドアテンションの実装

上記の計算手順は、ループ処理を通じて第 1 層のすべてのアテンション ヘッドに対して繰り返されます。

これで、第1層の32個のアテンションヘッドすべてに対するQKVアテンション行列が計算されました。次に、これらのアテンションスコアを[17x4096]の大きな行列に統合します。

レイヤー 0 のアテンション (Transformer モデル全体のシーケンスの理解と処理のプロセスの最初のステップである可能性があります) では、最後のステップは、重み行列を使用して積み重ねられた QKV 行列を乗算することです。

これで、注目メカニズムによって処理された埋め込み値が得られ、これらの変更が元のトークン埋め込みに追加されるはずです。

次に、埋め込まれた値の変化を正規化し、それをフィードフォワードニューラルネットワークに送り込んでさらに処理します。

13. SwiGLU活性化関数を実装する

先ほど紹介した SwiGLU 活性化関数についてある程度理解できたので、ここで先ほど説明した式を適用します。

SwiGLU: GLUバリアントによるTransformerの改良 (https://kikaben.com/swiglu-2020/)

14. 上記のモデルコンポーネントを統合する

すべての準備ができたので、コードをマージしてさらに 31 個のモデル レイヤーを構築する必要があります。

15. 証人モデルがテキスト入力に基づいて出力を生成する仕組み

これで、モデルが次のトークンを予測するための基礎となる最終的な埋め込み表現が得られました。この埋め込みの構造は通常のトークン埋め込みと一致しており、[17x4096]、つまり17個のトークンで構成され、各トークンの埋め込みベクトルの次元は4096です。

次に、取得した埋め込み表現を特定のトークン値に変換し直し、抽象表現からテキスト コンテンツへのデコード プロセスを完了します。

後続のコンテンツを予測する際には、前のトークンの埋め込み表現を基に、最も可能性の高い次のトークン値を推測します。

トークン ID の文字列を読み取り可能なテキストに変換するには、トークン ID を特定の文字または単語にマッピングするデコード プロセスを実行する必要があります。

したがって、入力は「生命、宇宙、そして万物についての究極の問いに対する答えは」であり、モデル出力は「42」となり、これが正解です。

読者の皆様は、様々なプロンプトテキストをぜひ試してみてください。変更が必要なのは、この2行のコードだけです。それ以外は変更ありません。

読んでいただきありがとうございます!このブログを楽しんで、新しいことを学んでいただけたら嬉しいです!

ファリード・カーン

データサイエンスの修士号を取得し、AIについて執筆しています

https://www.linkedin.com/in/fareed-khan-dev/

終わり

参考文献

[1]https://llama.meta.com/llama3/

[2]https://mistral.ai/

[3]https://github.com/FareedKhan-dev/Building-llama3-from-scratch

[4]https://levelup.gitconnected.com/building-a-million-parameter-llm-from-scratch-using-python-f612398f06c2

[5]https://github.com/bzhangGo/rmsnorm/blob/master/rmsnorm_torch.py

[6]https://arxiv.org/pdf/2002.05202v1.pdf

[7]https://arxiv.org/pdf/2104.09864v4.pdf

[8]https://huggingface.co/join?next=%2Fmeta-llama%2FMeta-Llama-3-8B

[9]https://huggingface.co/meta-llama/Meta-Llama-3-8B

[10]https://huggingface.co/meta-llama/Meta-Llama-3-8B/tree/main/original

[11]https://huggingface.co/settings/tokens

オリジナルリンク:

https://levelup.gitconnected.com/building-llama-3-from-scratch-with-python-e0cf4dbbc306