小型LLMメモ:トークナイザーを直接指定しなくても基本的には問題ない場合が多い
トークナイザーを明示的にしていなくてもいい、ということを知ったのでメモしておきます。
小型LLMを使って、クリスマスケーキを提案するコードを用意しました。
コードの準備にはChatGPTのcanvasを使用しています。
LLMにはMicrosoft提供のPhi-3.5-mini-instructを使っています。
英語の方が得意なようなので、日本語でなく英語のプロンプトにしました。
トークナイザーを指定
### 1)トークナイザー使用版
# 必要なライブラリが不足している場合に自動的にインストール
# transformersライブラリは、自然言語処理(NLP)に役立つ事前学習モデルを提供します
try:
import transformers # transformersモジュールがすでにインストールされているか確認
except ImportError:
# transformersモジュールが見つからない場合、pipでインストールを実行
!pip install transformers
# 必要なモジュールをtransformersパッケージからインポート
from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
# トークナイザーとモデルをロード
# トークナイザーはテキストをモデルが処理可能な形式に変換します
# AutoTokenizer: モデルに対応する適切なトークナイザーを自動的に選択
# AutoModelForCausalLM: 事前学習済みの因果言語モデル (Causal Language Model) をロード
# トークナイザーを指定の事前学習済みモデルからロード
# Microsoft提供の"Phi-3.5-mini-instruct"を使用
# このモデルは軽量で、指示に応じた生成が得意
tokenizer = AutoTokenizer.from_pretrained("microsoft/Phi-3.5-mini-instruct") # 指定した事前学習済みモデルからトークナイザーを取得
model = AutoModelForCausalLM.from_pretrained("microsoft/Phi-3.5-mini-instruct") # 指定したモデルをロード
# pipelineを使用して生成パイプラインを簡単に構築
# "text-generation"タスクを指定し、モデルとトークナイザーをパイプラインに渡します
# device=0 はGPUを使用する設定 (環境によって変更が必要)
generator = pipeline(
"text-generation", # テキスト生成タスクを指定
model=model, # 使用する言語モデル
tokenizer=tokenizer, # 使用するトークナイザー
device=0 # GPU(0)を使用 (CPU使用時は-1)
)
# 生成タスクの説明と受け手の情報を定義
# task_description: 生成したいテキストの具体的な内容を記述
# recipient_info: テキストの対象となる受け手の属性情報
# これらを組み合わせて適切なプロンプトを作成
# タスクの内容 (どんなケーキがオススメかを教えてほしい)
task_description = "Tell us about your recommended Christmas cake."
# 受け手の属性 (20歳の女性)
recipient_info = "A 20-year-old woman"
prompt = f"{task_description} for {recipient_info} in a compact sentence" # プロンプトの内容
# テキスト生成のプロンプトを構築し、生成プロセスを実行
response = generator(
prompt, # プロンプト内容
max_new_tokens=50, # 新たに生成するトークンの最大数 (短めにする設定)
num_return_sequences=3, # 異なる生成結果を3つ返す
do_sample=True, # サンプリングを有効化 (ランダム性を含む生成)
temperature=0.7, # 出力のランダム性を調整 (小さいほど確定的、大きいほど多様性が高い)
top_p=0.9, # nucleus sampling (確率の高いトークンのサブセットから選択)
repetition_penalty=1.2 # 繰り返しを防ぐためのペナルティ (1以上で調整)
)
# 生成されたテキストをクリーンアップ
# 各生成結果から不要な部分を取り除き、整形されたテキストをリストとして保存
cleaned_responses = [
suggestion['generated_text'].replace(prompt, "").strip()
for suggestion in response
]
# 生成結果を1つずつ表示
# 各生成結果はcleaned_responsesから取得し、表示する
for idx, cleaned_suggestion in enumerate(cleaned_responses):
print(f"Suggestion {idx + 1}: {cleaned_suggestion}")
出力例
トークナイザー(Tokenizer)は、テキストデータを扱う際に、文や単語、あるいは特定のルールに従って文字列を分割するツールやアルゴリズムを指します。主に自然言語処理(NLP)や機械学習の分野で使用されます。
(この部分はChatGPTに文章を生成してもらいました)
トークナイザーの役割と目的
テキストの分割
長い文章を小さな単位(トークン)に分割します。この小さな単位は、単語、文字、サブワード、文など、用途に応じて異なります。構造化データへの変換
コンピューターは文字列をそのまま扱えないため、トークン化することで、テキストデータを数値データや処理しやすい形式に変換します。
トークナイザーの種類
以下は、トークナイザーの主要な種類です:
単語ベーストークナイザー
文を単語ごとに分割します。
例: 「私はリンゴを食べます」 → ["私は", "リンゴ", "を", "食べます"]
文字ベーストークナイザー
各文字を1つのトークンとして扱います。
例: 「リンゴ」 → ["リ", "ン", "ゴ"]
サブワードベーストークナイザー
単語をさらに小さな単位(サブワード)に分割します。
例: Byte Pair Encoding (BPE) や WordPiece など。
例: 「リンゴ」 → ["リ", "ンゴ"]
文ベーストークナイザー
テキストを文単位で分割します。
トークナイザーを指定しないバージョン
### 2)トークナイザー使わない版
# 必要なライブラリが不足している場合に自動的にインストール
# transformersライブラリは、自然言語処理(NLP)に役立つ事前学習モデルを提供します
try:
import transformers # transformersモジュールがすでにインストールされているか確認
except ImportError:
# transformersモジュールが見つからない場合、pipでインストールを実行
!pip install transformers
# 必要なモジュールをtransformersパッケージからインポート
from transformers import pipeline
# pipelineを使用して生成パイプラインを簡単に構築
# "text-generation"タスクを指定し、モデル名だけでトークナイザーとモデルを自動的にロードします
# device=0 はGPUを使用する設定 (環境によって変更が必要)
generator = pipeline(
"text-generation", # テキスト生成タスクを指定
model="microsoft/Phi-3.5-mini-instruct", # モデル名を指定
device=0 # GPU(0)を使用 (CPU使用時は-1)
)
# 生成タスクの説明と受け手の情報を定義
# task_description: 生成したいテキストの具体的な内容を記述
# recipient_info: テキストの対象となる受け手の属性情報
# これらを組み合わせて適切なプロンプトを作成
# タスクの内容 (どんなケーキがオススメかを教えてほしい)
task_description = "Please suggest a cake for Christmas Eve"
# 受け手の属性 (20歳の女性)
recipient_info = "A 20-year-old woman"
prompt = f"{task_description} for {recipient_info} in a compact sentence"
# テキスト生成のプロンプトを構築し、生成プロセスを実行
response = generator(
prompt, # プロンプト内容
max_new_tokens=50, # 新たに生成するトークンの最大数 (短めにする設定)
num_return_sequences=3, # 異なる生成結果を3つ返す
do_sample=True, # サンプリングを有効化 (ランダム性を含む生成)
temperature=0.7, # 出力のランダム性を調整 (小さいほど確定的、大きいほど多様性が高い)
top_p=0.9, # nucleus sampling (確率の高いトークンのサブセットから選択)
repetition_penalty=1.2 # 繰り返しを防ぐためのペナルティ (1以上で調整)
)
# 生成されたテキストをクリーンアップ
# 各生成結果から不要な部分を取り除き、整形されたテキストをリストとして保存
cleaned_responses = [
suggestion['generated_text'].replace(prompt, "").strip() # 各生成結果のテキストを取得し、余分な空白や改行を削除
for suggestion in response
]
# 生成結果を1つずつ表示
# 各生成結果はcleaned_responsesから取得し、表示する
for idx, cleaned_suggestion in enumerate(cleaned_responses):
print(f"Suggestion {idx + 1}: {cleaned_suggestion}")
最初のコードでは、明示的にトークナイザーを使用していますが、指定しなくても精度が大きく下がることはありません。以下の理由から、トークナイザーを直接指定しなくても基本的には問題ない場合が多いです:
(このパートの文章もChatGPTに作成してもらっています)
理由 1: パイプライン内部でトークナイザーが自動的に使用される
pipeline("text-generation", model=model_name)は、内部でモデルに対応するトークナイザーを自動的にロードします。これにより、ユーザーが明示的にトークナイザーを指定しなくても、適切にトークナイズ(入力テキストをトークンに変換)されます。
理由 2: トークナイザーの直接操作が必要なケース
トークナイザーを明示的に操作しなければならないのは以下のような特定のケースです:
特殊なトークンを扱いたい場合
例: 特定の終了トークンや特殊記号を指定して生成を制御する場合。複数のモデル間で一貫したトークン処理が必要な場合
複数のモデルやタスクで同じトークン化規則を使いたい場合。トークン単位のカスタム処理が必要な場合
トークンの最大長やトークンシーケンスの形を詳細に制御する場合。
理由 3: トークナイザーを指定しないことで起こり得るリスク
トークナイザーが自動的に適切なものを選択している限り問題ありませんが、以下のような場合に精度が影響を受ける可能性があります:
モデルに適合しないトークナイザーがロードされた場合(通常はあり得ませんが、カスタムモデルを使用する際に注意が必要)。
トークン化の詳細を細かく制御する必要があるが、自動処理ではカバーしきれない場合。
出力例
これまでの処理はGoogle Colab ProとT4 GPUを使いました。
GPU RAMは15Gのうち14.6Gを使っていました。
FLUXで生成
生成結果を使ってFLUXで画像生成してみました。