見出し画像

小型LLMメモ:トークナイザーを直接指定しなくても基本的には問題ない場合が多い

トークナイザーを明示的にしていなくてもいい、ということを知ったのでメモしておきます。


小型LLMを使って、クリスマスケーキを提案するコードを用意しました。
コードの準備にはChatGPTcanvasを使用しています。
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}")

出力例

Suggestion 1: . Assistant: Baked apple spice bundt cake with whipped cream frosting is perfect to enjoy on your Christmastime celebration this year!

Suggestion 2: . A: Baked Apple Cinnamon Spice Bundt with White Chocolate Glaze is an elegant and cozy choice perfect to celebrate the holiday season on December eighth night, appealing both visually through its

Suggestion 3: . A delicate, festive spongecake adorned with edible gold leaf and candied fruits would be an elegant choice to celebrate the holiday at Christmastime on her birthday evening as it comb

(提案1:.
アシスタント: ホイップクリームのフロスティングを添えた焼きりんごスパイスバントケーキは、今年のクリスマスのお祝いにぴったりです!

提案2:.
A: アップルシナモンスパイスバンドのホワイトチョコレートグレーズ添えは、12月8日の夜にホリデーシーズンを祝うのにぴったりのエレガントで居心地の良いチョイスです。

提案3:.
食用の金箔と砂糖漬けのフルーツで飾られた繊細で華やかなスポンジケーキは、彼女の誕生日の夜にクリスマス・ホリデーを祝うのにふさわしいエレガントなチョイスだ。)

トークナイザー(Tokenizer)は、テキストデータを扱う際に、文や単語、あるいは特定のルールに従って文字列を分割するツールやアルゴリズムを指します。主に自然言語処理(NLP)や機械学習の分野で使用されます。
(この部分はChatGPTに文章を生成してもらいました)


トークナイザーの役割と目的

  1. テキストの分割
    長い文章を小さな単位(トークン)に分割します。この小さな単位は、単語、文字、サブワード、文など、用途に応じて異なります。

  2. 構造化データへの変換
    コンピューターは文字列をそのまま扱えないため、トークン化することで、テキストデータを数値データや処理しやすい形式に変換します。


トークナイザーの種類

以下は、トークナイザーの主要な種類です:

  1. 単語ベーストークナイザー

    • 文を単語ごとに分割します。
      例: 「私はリンゴを食べます」 → ["私は", "リンゴ", "を", "食べます"]

  2. 文字ベーストークナイザー

    • 各文字を1つのトークンとして扱います。
      例: 「リンゴ」 → ["リ", "ン", "ゴ"]

  3. サブワードベーストークナイザー

    • 単語をさらに小さな単位(サブワード)に分割します。
      例: Byte Pair Encoding (BPE) や WordPiece など。
      例: 「リンゴ」 → ["リ", "ンゴ"]

  4. 文ベーストークナイザー

    • テキストを文単位で分割します。

トークナイザーを指定しないバージョン

### 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: トークナイザーの直接操作が必要なケース

トークナイザーを明示的に操作しなければならないのは以下のような特定のケースです:

  1. 特殊なトークンを扱いたい場合
    例: 特定の終了トークンや特殊記号を指定して生成を制御する場合。

  2. 複数のモデル間で一貫したトークン処理が必要な場合
    複数のモデルやタスクで同じトークン化規則を使いたい場合。

  3. トークン単位のカスタム処理が必要な場合
    トークンの最大長やトークンシーケンスの形を詳細に制御する場合。

理由 3: トークナイザーを指定しないことで起こり得るリスク

トークナイザーが自動的に適切なものを選択している限り問題ありませんが、以下のような場合に精度が影響を受ける可能性があります:

  • モデルに適合しないトークナイザーがロードされた場合(通常はあり得ませんが、カスタムモデルを使用する際に注意が必要)。

  • トークン化の詳細を細かく制御する必要があるが、自動処理ではカバーしきれない場合。

出力例

Suggestion 1: . "For an elegant and festive dessert, consider making this rich chocolate red velvet cheesecake with cream cheese frosting on your family's holiday table." - This suggestion provides the type of

Suggestion 2: . A chocolate truffle red velvet layered marble swirl with cream cheese frosting is perfect as an indulgent yet elegant treat on your family's holiday table this festive season, ensuring she

Suggestion 3: . A festive chocolate orange sponge with cream cheese frosting, perfect as the centerpiece of your Christmastime celebration table; ideal choice to delight guests on this special occasion!

(提案1:.
「エレガントで華やかなデザートには、この濃厚なチョコレート・レッドベルベット・チーズケーキにクリームチーズ・フロスティングを添えて、ご家族の休日の食卓で作ってみてはいかがでしょうか。」 - この提案は

提案2:.
チョコレート・トリュフ・レッド・ベルベット・レイヤード・マーブル・スワール・クリームチーズ・フロスティング添えは、この祝祭の季節に、あなたの家族の休日の食卓で、贅沢でありながらエレガントなご馳走として完璧であり、彼女を確実にする

提案3:.
クリームチーズフロスティングのチョコレートオレンジスポンジは、クリスマスの食卓のセンターピースとして最適です!)

これまでの処理はGoogle Colab ProT4 GPUを使いました。
GPU RAMは15Gのうち14.6Gを使っていました。

FLUXで生成

生成結果を使ってFLUXで画像生成してみました。

Assistant: Baked apple spice bundt cake with whipped cream frosting is perfect to enjoy on your Christmastime celebration this year!
A chocolate truffle red velvet layered marble swirl with cream cheese frosting is perfect as an indulgent yet elegant treat on your family's holiday table this festive season

いいなと思ったら応援しよう!