Hanah

Hanah

Qwenの使用

参照文献: Qwen-blog
Qwen 全体架构:

framework
其中:

  • tokenizerはテキストを語彙リスト内の数値に変換します。
  • 数値はembeddingを通じて一対一のベクトルを得ます。
  • attention_maskは左側、右側、双方向などを見えるように設定するためのものです。
  • 各種下流タスク、Casualseqclsなどは、基本的に基礎モデルmodelの後に対応するLinear層が接続され、損失関数が異なります。

まず、github から transformer リポジトリをダウンロードし、transformer_213 と名付けます(私は 2.13 日付でダウンロードしたため)。このステップはパッケージと混同しないためのものです。

run_demo.ipynb を定義して qwen2 を詳しく理解します。

from transformers_213.src.transformers.models.qwen2 import Qwen2Config, Qwen2Model
import torch

def run_qwen2():
    qwen2config = Qwen2Config(
        vocab_size=151936,
        hidden_size=4096//2,
        num_hidden_layers=32//2,
        num_attention_heads=32,
        intermediate_size=2048//2
    )
    qwen2model = Qwen2Model(qwen2config)
    input_ids = torch.randint(0, qwen2config.vocab_size, (4, 30))
    res = qwen2model(input_ids)
    print(res)

if __name__ == "__main__":
    run_qwen2()

1 Qwen2Config#

Qwen2Config にはいくつかのカスタムハイパーパラメータが含まれています。例えば、vocab_sizehidden_sizenum_hidden_layersnum_attention_headsなど。dictのように内部のハイパーパラメータを呼び出すことができます:config.pad_token_id

1.1 Qwen2Model#

1.1.1 初期化#

  • モデルの 2 つの属性を設定しました:padding_idx(パディングトークンのインデックスを指定するため)、vocab_size(語彙のサイズ)
  • モデルの埋め込み層、デコーダ層、正規化層を初期化しました
  • 埋め込み層(nn.Embedding):モデルは埋め込み層を使用して入力トークンを密なベクトル表現にマッピングします。
  • デコーダ層(nn.ModuleList()):モデルには複数のデコーダ層が含まれており、これらの層はQwen2DecoderLayerによって定義されています
  • 正規化層Qwen2RMSNorm:正規化層は Root Mean Square Layer Normalization を使用しています
  • gradient_checkpointを使用するかどうかを設定し、主にメモリを節約するために使用されます
  • post_init()を呼び出して、いくつかの初期化と準備チェックのコードを完了します
class Qwen2Model(Qwen2PreTrainedModel):
    def __init__(self, config: Qwen2Config):
        super().__init__(config)
        self.padding_idx = config.pad_token_id
        self.vocab_size = config.vocab_size

        self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx)
        self.layers = nn.ModuleList(
            [Qwen2DecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
        )
        self.norm = Qwen2RMSNorm(config.hidden_size, eps=config.rms_norm_eps)

        self.gradient_checkpointing = False
        # 重みを初期化し、最終処理を適用
        self.post_init()

post_init関数について:
主にパラメータの初期化と、初期化された勾配チェックポイントの役割を果たします

def post_init(self):
    """
    各Transformerモデルの初期化の最後に実行されるメソッドで、モデルの
    モジュールが適切に初期化されている必要があるコードを実行します(重みの初期化など)。
    """
    self.init_weights()
    self._backward_compatibility_gradient_checkpointing()

1.1.2 フォワード#

ここではコアの主幹について説明します:

inputs_embeds = self.embed_tokens(input_ids)
# embed positions
hidden_states = inputs_embeds

for idx, decoder_layer in enumerate(self.layers):
    # すべてのhidden_statesをタプルとして保存
    if output_hidden_states:
        all_hidden_states += (hidden_states,)
    # hsを各デコーダ層に送信
    layer_outputs = decoder_layer(
        hidden_states,
        attention_mask=attention_mask,
        position_ids=position_ids,
        past_key_value=past_key_value,
        output_attentions=output_attentions,
        use_cache=use_cache,
    )
    # 前のデコーダー出力のhsを取得し、次の層に渡す
    # 最初のものだけ、2番目はキャッシュの一種で、次の層に入ります
    hidden_states = layer_outputs[0]
    
# 最後の層出力後のhidden_statesを正規化  
hidden_states = self.norm(hidden_states)
    
# 最後の層のhidden_statesを追加
if output_hidden_states:
    all_hidden_states += (hidden_states,)
  • output_hidden_statesを保存する場合、最初はinput_idsに対してembを行い、次にn-1層のdecoder_layerの出力hsを保存し、最後の層のlayerの出力hsを正規化後のhsに加えます。
  • 最後はBaseModelOutputWithPastの形式で出力されます。

続く。。。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。