0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[LLMのFinetuningのための基礎] transformersのAutoClassesの基本を理解する 2

Posted at

はじめに

今回は [LLMのFinetuningのための基礎] transformersのAutoClassesの基本を理解する 2 と題しまして、transformersのAutoModelに関して学習したことをまとめました。

今回メインで使用する教材はTransformersのAutoClassesのAPI referenceです。

以下、現段階でのアウトプットの記事のイメージ図です。

「AutoClassの基本的内容を抑えた記事を書いたあとにどのようなことを書くのかはまだ検討中です」と前回は述べていましたが、よく考えるとTrainerも必要だと思い立ったため前回から追加しています。

LLM事前知識・datasetsの基本の理解・AutoTokenizer・AutoConfigの基本を理解するについては下記記事に記載されています。よろしければ是非一読お願いいたします。

おことわり

本記事はあくまでもLLM初学者である私の学習のアウトプットなので不正確・不十分な説明の可能性もあるため参考にされる場合は十分にご注意ください。

目次

1. AutoModelとは
2. Modelのインスタンス化
3. AutoModelForxxx
4. Modelの使い方
5. おわりに

AutoModelとは

AutoModelはAutoClassesの主要な3つのコンポーネントのAutoConfigAutoTokenizerAutoModelの内の1つです。

AutoModelを使用することで指定したMODEL ID もしくは ローカルパス先の設定に関連するモデルのアーキテクチャを読込み、インスタンス化することが可能です。

Modelのインスタンス化

AutoModelのreferenceを見てみましょう。

AutoModelに用意されている関数としてはfrom_config()from_pretrained()の2つが用意されています。
ここではこの2つの違いについて見ています。

AutoModel.from_config()

from_config()のreferenceを見てみます。

この関数は主に configを引数として受け取る ことが分かります。(attn_implementationも受け取りますが基本的にはデフォルトの値を取ることが多いようです。)
ここでのconfigは前回紹介したPretrainedConfigであることに注意してください。

実際に動かしてみます。

from transformers import AutoConfig, AutoModel

config = AutoConfig.from_pretrained("google-bert/bert-base-cased")
model = AutoModel.from_config(config)

上記を実行すると正常にModelをインスタンス化できます。
しかし注意点としてこのfrom_config()ではconfigファイルから関連するModel Classのみをロードしています。

つまるところ、モデルの重みはロードしていません。

今回の場合はBertModelクラスのみをインスタンス化しています。

ここで既に鋭い方はお気づきかと思いますが、from_pretrained()を使用するとモデルの重みも同時にロードしてインスタンス化できます。

AutoModel.from_pretrained()

from_pretrained()のreferenceを見てみます。

from_pretrained()にはかなり多くの引数が用意されていることが分かります。

ここでは重要性と覚えやすさの観点から、最初に抑えておくべきだと筆者が個人的に考えた3つ掲載します。

pretrained_model_name_or_path

必須の引数です。
AutoTokenizerと同じでMODEL IDローカルの保存先Pathを指定します。

AutoModel.from_pretrained()はそこにある(もしくはロードした)config.jsonから関連するModel Classを特定しインスタンス化します。

config

PretrainedConfigを引数として受け取ります。
例えば一例として、Finetuningなどで作成したデフォルトとは異なるアーキテクチャを持つモデルを使用・ロードしたい場合に、その設定をしたPretrainedConfigを渡します。

from_tf

bool型を引数として受け取ります。
Trueにすることで、TensorFlowで学習されたモデルの重みをPyTorchで活用したいといった場合に使用可能です。

上記3つ以外にも**kwargs(output_attentionsなど)revisiontrust_remote_codeなども重要ですが、先ずは触ってみ動かしてみたいといった初学者にとってはあまり重要ではない可能性が高いため割愛しています。

これらを確認したい場合はreferenceを見たり、実際に動かしてみて挙動の違いをご確認ください。

実際にコードで動作確認してみます。

from transformers import AutoModel

# 先ほどとは違ってconfigを事前に読み込まない。
# config = AutoConfig.from_pretrained("google-bert/bert-base-cased")

model = AutoModel.from_pretrained("google-bert/bert-base-cased")

上記のコードを実行すると正常にモデルがロードされたことが確認できると思います。

また、model.safetensorsというファイルがconfig.jsonとは別でロードされたことも確認できたかと思います。

スクリーンショット 2025-05-11 212115.png

このsafetensorsはHugging Faceが開発したテンソルを安全・高速に保存・読み込む形式です。

今回の場合はここにモデルの重みやバイアスといった情報が格納されており、先ほどみたfrom_config()では重みなどを読み込んでいないというのがご理解いただけたかと思います。

safetensorsについてより詳しく学ぶために以下2つの記事をご紹介させていただきます。

AutoModelForxxx

ここまではAutoModelについて学習し、まとめてきました。

ですが待ってください。AutoModelにはAutoConfigAutoTokenizerとは違い、AutoModelForSequenceClassificationのようなAutoModelForxxxといったコンポーネントが沢山存在しています。

この部分は私の学習時に一番混乱した部分であり、ネットの記事やSNSを見てみても他のAutoClassesと比べて困惑している方が多くいた印象です。

ここではAutoModelAutoModelForxxxの違いについて見ていきます。

AutoModelとAutoModelForxxx

この混乱を解く為に私たちが理解すべきはHugging Faceのモデル構造についてです。

幸いなことにこの部分について詳しくまとめてくれている記事が既にあります。私はこの記事を参考にまとめていきます。


まず、HugginFaceのモデルは基本的にはモデルのベースとなる部分(Body)と特定のタスクに合わせて作成されたヘッド部分(Head)に分かれます。

スクリーンショット 2025-05-11 221355.png

AutoModelではHeadを持たない状態でModelをロードします。
一方でAutoModelForxxではHead付きでModelをロードします。

スクリーンショット 2025-05-11 222312.png

AutoModelForxxxでは既に特定のタスクに特化したHeadを持った状態でModelをロードできるため、比較的簡単に使用することが可能です。

一方でAutoModelはHeadを持っていないため出力して返すのは、テキストから抽出した特徴量です。
これを例えば機械学習に回したり、個人のカスタムHeadを通して固有のタスクに合わせることが可能で柔軟です。
しかしこれらはかなり高度なテクニックなため私たち初学者にとっては扱えるようになるためにより多くの経験が必要になるものかと思われます。

実際にロードしてみる

実際にロードしてみます。
ここでは説明のためにあえて先ほどまでと同様のモデル、google-bert/bert-base-casedを使用しています。

また、SequenceClassificationを使いnum_labelsを2として2値分類タスクを想定してみます。

from transformers import AutoModelForSequenceClassification

model = AutoModelForSequenceClassification.from_pretrained(
            "google-bert/bert-base-cased"
            num_labels=2
            )

Modelがロードされたあとに次の様な文面が出てくることが確認できます。

スクリーンショット 2025-05-11 224111.png

Some weights of BertForSequenceClassification were not initialized from the model checkpoint at google-bert/bert-base-cased and are newly initialized: ['classifier.bias', 'classifier.weight']
You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.

これは先ほどロードしたモデル(google-bert/bert-base-cased)は元々このタスク(SequenceClassification)のトレーニングを行っておらず、Headのバイアスと重みの情報(classifier.biasとclassifier.weight)を所有していないため適当な値で初期化したことを知らせています。

AutoModelForxxx.from_pretrained()でロードすると、指定したModelが事前にそのタスクで訓練されていたかに関わらずにHeadを追加してインスタンス化することに注意が必要です。

試しにSequenceClassificationで訓練されたモデル、distilbert/distilbert-base-uncased-finetuned-sst-2-englishで試してみます。
先ほどの様な文面は表示されないはずです。

from transformers import AutoModelForSequenceClassification

model = AutoModelForSequenceClassification.from_pretrained(
    "distilbert/distilbert-base-uncased-finetuned-sst-2-english",
    num_labels=2
    )

スクリーンショット 2025-05-11 225049.png

先ほどの様な文面が出てこないことを確認できました!

注意
Headの重みとバイアスがランダムな値で初期化された文面は出てきませんでしたが、このまま自分のタスクで使用できるわけではありません(正確には使用できるが精度は非常に悪い)。

これは元々訓練されたドメイン知識に偏っているためです。
例えば医療関連のドメインで学習されたModelを使用して医療とは無関連のドメインでタスクを遂行させることはできません。

Modelの使い方

ここまでで、from_config()from_pretrained()を使用してModelクラスのインスタンス化の方法とAutoModelAutoModelForxxxの違いについて見ていきました。

ここからはインスタンス化されたModelの使い方について見ていきます。

基本的にfrom_pretrained()などでインスタンス化されたモデルたちはPreTrainedModel(PyTorch)TFPreTrainedModel(TensorFlow)FlaxPreTrainedModel(JAX/Flax)をベースクラスとしてもつ派生クラスです。

そしてこれら3つのベースクラスはそれぞれtorch.nn.Moduletf.keras.Modelflax.linen.Moduleを継承しています。(これはソースコードを見ても分かります。)

これらはそれぞれの順伝播メソッド(torch.nn.Moduleであればforward()、TensorFlowのモデルであればcall()、Flaxのモデルであれば__call__())を実装することが期待されており、BartModelを見てみても、それらが実装され__call__で呼び出せることが分かります。

したがって先ほどまででインタスタンス化したModelクラスはmodel(xxx)の形式で使用することができます。

基本的な使い方

これらModelクラスがどのような引数を受け取るのかをBartModelを例にとって見てみます。

input_idsattention_maskdecoder_input_idsなどいくつか引数を取ることが確認できますが、まず最初の一歩目としてはinput_idsを渡すことを覚えておきます。

これはModelが予測するために必要な最低限の引数だからです。

実際に動かしてみます。

from transformers import AutoTokenizer, AutoModel
import torch

tokenizer = AutoTokenizer.from_pretrained("facebook/bart-base")
model = AutoModel.from_pretrained("facebook/bart-base")

# return_tensorsはpt(Pytorch)
inputs = tokenizer("Hello, my dog is cute", return_tensors="pt")

# inputsは{'input_ids': tensor([[    0, 31414,     6,   127,  2335,    16, 11962,     2]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1]])}
# **を付けることで辞書をアンパッキングして引数に入れる。
outputs = model(**inputs)

正常に動いてoutputsには値が入っていることが確認できます。

このoutputsオブジェクトには、モデルの様々な出力が含まれています。例えば、モデルの最終層の隠れ状態(各入力トークンに対応する特徴量ベクトル) を取得したい場合は、次のようにします。

last_hidden_state = outputs.last_hidden_state

この last_hidden_state は、後続のタスク(例えば、この特徴量を使って別の分類器で分類するなど)に利用できます。

おわりに

今回はAutoModelについて学習していきました。

これで前回までと合わせて、datasetsの基本AutoClassesの基本を学習終えました。
次回は本シリーズの最後であり、Trainerの基本について学習していきます。

datasetsAutoClassesTrainerの基本を学び終えると簡単なLLMのFinetuningはご自身で行うことができるようになるかつネット上のFinetuningに関する記事(Kaggleなどのコンペ記事やコードなど)をより鮮明に見て、理解することができるようになるはずです。

何か間違いなどありましたらご指摘お願いいたします。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?