26. SAMSumプロジェクト始動!ベースラインパフォーマンスを測定しよう

スポンサーリンク

26. SAMSumプロジェクト始動!ベースラインパフォーマンスを測定しよう

Week 3がいよいよ本格的にスタートしました!今回は、実際のプロジェクトに取り組みます。

でも、どんな改善も「どこから始まったか」がわからないと意味がありませんよね。スポーツでも、「記録を更新した!」って言うには、まず以前の記録を知る必要があります。

AIのファインチューニングも同じです。まずベースラインパフォーマンス(出発点の性能)を測定する必要があるんです。

今回は、SAMSumデータセットでLlama 3.2 1B Instructモデルを実行して、その初期ROUGEスコア(要約品質を測る指標)を記録します。この数字が、これから行うすべてのファインチューニング実験のリファレンスポイント、つまり「before(改善前)」のスナップショットになります。

最後には、タスク、メトリック、そして閉じることを目指すパフォーマンスギャップを理解できるようになりますよ!

最初のファインチューニングプロジェクト:対話要約のためのSAMSum

今週は実践的です。ファインチューニングについて学ぶだけでなく、実際に行います。

そして優れた実験と同様に、次のように問うことから始めます:

「ベースラインパフォーマンスは何か?打ち負かそうとしているものは何か?」

SAMSumデータセットとは?

SAMSumデータセットは、人間が書いた要約とペアになった実世界のチャット会話のコレクションです。各例はこんな感じです:

対話:

Amanda: I baked cookies. Do you want some?
Jerry: Sure!
Amanda: I'll bring you tomorrow :-)

要約:

Amanda baked cookies and will bring Jerry some tomorrow.

モデルのタスクは、対話を入力として受け取り、同様のスタイルで簡潔な要約を生成することです。

なぜSAMSumがこのプロジェクトに最適?

SAMSumは次の理由でプロジェクトに最適なんです:

1. 具体的で測定可能
ROUGEメトリックを使用して要約品質を評価できます。数字で改善が見えるんですね。

2. 短く効率的
Colab実験に十分速く実行されます。待ち時間が少なくて済むので、学習に集中できます。

3. 現実的
実際の会話要約ユースケースを反映しています。チャットやカスタマーサポートシナリオで使える技術なんです。

また、数学推論データセットとは異なり、SAMSumは生成品質を測定します。これはPPOやGRPOのような強化学習手法を必要とせずに、ファインチューニングメカニクスを探索するのに最適なんです。

ベースモデルの選択:Llama 3.2 1B Instruct

今週の目標は、最高のパフォーマンスを発揮する数学モデルを構築することではなく、ファインチューニングのメカニクスを学ぶことです。

つまり、小さく、速く、完全に透明なセットアップに焦点を当てます。そうすれば、プロセスのすべてのステップを理解できますからね。

使用するのはLlama 3.2 1B Instruct、MetaのLlama 3ファミリーで最小のオープンウェイトモデルです。

なぜこのモデル?

軽量
プレミアムGPUなしでもGoogle Colabで快適に実行できます。お金の心配がいりません!

指示追従サポート
指示スタイルのプロンプトを理解し応答できます。「こうしてください」と言えば、ちゃんと聞いてくれるんです。

ちょうどいいサイズ
ファインチューニングから測定可能な改善を示すのに十分大きいけど、実験が妥当な時間で終了するのに十分小さい。学習に最適なバランスです。

実際の世界では、モデルの選択はタスク、データスケール、パフォーマンスニーズに依存します。エンタープライズグレードのユースケースには70億、130億、またはフロンティアモデルを選ぶかもしれません。

でもここでは、小さいほど良いです。ワークフローを学んでいるんです。そして、この10億パラメータモデルで行うすべてが、後でより大きなモデルに直接スケールします。

これが「before(改善前)」のモデルになります。週の残りを通じてすべての改善を測定する参照点です!

ベースライン評価の実行

データセットをロードし、クイック評価ループを準備し、精度を測定します。

このセクションには最小限のコードが含まれています。ロジックを示すのに十分な量ですが、初心者にもわかりやすくします。

前提条件:依存関係のインストール

このベースラインのすべては、pipを通じて利用可能なオープンソースライブラリで実行されます:

pip install -q transformers datasets evaluate accelerate peft bitsandbytes

各ライブラリの機能:

  • transformers:Llama 3.2モデル、トークナイザー、生成パイプラインを提供
  • datasets:SAMSumデータのロード、キャッシング、サンプリングを処理
  • evaluate:ROUGEおよびその他のメトリックを計算
  • accelerate:効率的なマルチデバイス推論を可能に
  • peft:LoRA/QLoRAをサポート(次のレッスンで使います)
  • bitsandbytes:4ビット量子化のオプションライブラリ(後で使います)

これらをインストールすれば、ColabまたはローカルEnvironmentで全体のパイプラインを再現できます!

ステップ1:データセット設定

プロジェクトのconfig.yaml内でデータセットを定義します:

dataset:
  name: knkarthick/samsum
  cache_dir: ../data/datasets
  field_map:
    input: dialogue
    output: summary
  type: completion
  splits:
    train: 200
    validation: 200
    test: 200
  seed: 42

これにより再現性が確保され、重要な設定が1か所に保持されます。週を通じてこの設定ファイルを構築していきますよ。

ステップ2:データセットのロードと準備

ヘルパー関数がダウンロード、キャッシング、サンプリングを処理します:

def load_and_prepare_dataset(cfg):
    """
    設定に従ってデータセット分割をロードします。
    """
    cfg_dataset = cfg["dataset"]
    dataset = load_dataset(cfg_dataset["name"])
    val_key = "validation" if "validation" in dataset else "val"

    train = select_subset(dataset["train"], cfg_dataset["splits"]["train"], seed=42)
    val = select_subset(dataset[val_key], cfg_dataset["splits"]["validation"], seed=42)
    test = select_subset(dataset["test"], cfg_dataset["splits"]["test"], seed=42)

    print(f"📊 Loaded {len(train)} train / {len(val)} val / {len(test)} test samples.")
    return train, val, test

この関数は、迅速なベースラインテストのために分割ごとに正確に200サンプルを提供します。

ステップ3:モデルとトークナイザーのロード

量子化とLoRAモードの両方をサポートする統一されたセットアップ関数を使用しますが、ここではシンプルに保ちます:

def setup_model_and_tokenizer(cfg, use_4bit=False, use_lora=False):
    model_name = cfg["base_model"]
    tokenizer = AutoTokenizer.from_pretrained(model_name)
    tokenizer.pad_token = tokenizer.eos_token
    tokenizer.padding_side = "right"

    model = AutoModelForCausalLM.from_pretrained(
        model_name,
        device_map="auto",
        dtype=torch.bfloat16 if torch.cuda.is_available() else torch.float32,
    )

    print("🔹 Using base model only (no LoRA).")
    return model, tokenizer

ステップ4:予測の生成

ロードされたら、各対話を要約するようモデルにプロンプトできます:

def generate_predictions(model, tokenizer, dataset, task_instruction, batch_size=8):
    prompts = []
    for sample in dataset:
        user_prompt = (
            f"{task_instruction}\n\n"
            f"## Dialogue:\n{sample['dialogue']}\n## Summary:"
        )
        messages = [{"role": "user", "content": user_prompt}]
        prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
        prompts.append(prompt)

    pipe = pipeline("text-generation", model=model, tokenizer=tokenizer, do_sample=False)
    preds = []
    for i in tqdm(range(0, len(prompts), batch_size), desc="Generating summaries"):
        batch = prompts[i : i + batch_size]
        outputs = pipe(batch, max_new_tokens=256, return_full_text=False)
        preds.extend([o[0]["generated_text"].strip() for o in outputs])

    return preds

使用した指示:

"You are a helpful assistant who writes concise, factual summaries of conversations.
Summarize the following conversation into a single sentence."

シンプルで明確な指示ですね!

ステップ5:ROUGEスコアの計算

evaluateパッケージを使用して標準的なメトリックを計算します:

def compute_rouge(predictions, samples):
    rouge = evaluate.load("rouge")
    references = [s["summary"] for s in samples]
    return rouge.compute(predictions=predictions, references=references)

ROUGEとは?

ROUGE(Recall-Oriented Understudy for Gisting Evaluation)は、テキスト要約品質を評価するための標準的なメトリックです。

モデルが生成した要約と参照(正解)要約の間にどれだけの重複があるかを比較します。

各スコアの意味:

ROUGE-1
単語レベルの重複を測定します。「どれだけ同じ単語を使っているか」ですね。

ROUGE-2
バイグラム(2語のシーケンス)の重複を測定します。短いフレーズレベルの一貫性と流暢性を捉えます。

ROUGE-L
生成された要約と参照要約の間の最長共通部分列(LCS)に基づいています。モデルが文の構造と順序をどれだけよく保持しているかを反映します。

要約すると:

  • より高いROUGE-1/2:より良い語彙の重複(単語とフレーズの選択)
  • より高いROUGE-L:より良い構造的および意味的アライメント

数字が高いほど、良い要約ということです!

すべてをまとめる

最後に、メイン評価がすべてを調整します:

def evaluate_baseline():
    _, val_data, _ = load_and_prepare_dataset(cfg)
    model, tokenizer = setup_model_and_tokenizer(cfg, use_4bit=False, use_lora=False)

    preds = generate_predictions(
        model=model,
        tokenizer=tokenizer,
        dataset=val_data,
        task_instruction=cfg["task_instruction"],
        batch_size=4,
    )

    scores = compute_rouge(preds, val_data)

    print("\n💾 Results:")
    print(json.dumps(scores, indent=2))
    return scores

ベースライン結果

Llama 3.2 1B Instructモデルは、ファインチューニングなしでどれくらいのパフォーマンスを発揮するでしょうか?

結果はベースラインパフォーマンスを示しています。これが私たちの出発点です!

次のいくつかのレッスンでは、ROUGEスコアを改善するためにモデルをファインチューニングします。このベースラインと比較することで、「どれだけ改善したか」が明確にわかるんです。

要約が実世界で重要な理由

要約は非常に価値のある実世界のLLMアプリケーションです。

例えば、大規模コンタクトセンターシステムでは、顧客との長い会話を自動的に要約する機能が使われています。オペレーターが次に対応するときに、すぐに状況を把握できるんですね。

技術的にもビジネス的にも「良い」要約とは何でしょうか?

技術的に良い要約:
– 重要な情報を漏らさない
– 簡潔で読みやすい
– 元の会話の構造を保持している

ビジネス的に良い要約:
– 時間を節約する
– ミスコミュニケーションを減らす
– 顧客満足度を向上させる

このプロジェクトで学ぶスキルは、すぐに実務で使えるものなんです!

次は何か?

このベースラインは、私たちがどこから始めているかを定義します。ファインチューニング前にモデルがすでに何ができるかです。

これは3つのことを提供します:

1. パフォーマンスの現実
測定可能で再現可能な参照点。「ここからスタート!」ってわかりますよね。

2. ワークフローの検証
データ、推論、評価がすべて正しく配線されています。システムが動いていることの証明です。

3. ベンチマーク基盤
すべてのファインチューニング改善はこれと比較されます。「何%改善した!」って言えるようになります。

次のレッスンでは、フロンティアモデル、OpenAIの4o-miniに切り替えて、同じSAMSumデータセットでどのようにパフォーマンスを発揮するかをテストします。

また、OpenAIのマネージドファインチューニングパイプラインを使用してファインチューニングし、これらのベースラインと結果を比較して、ファインチューニングが実際にどのような利益をもたらすかを見ます。

そこから本当の実験が始まります。楽しみにしていてくださいね!

まとめ

今回は、SAMSumプロジェクトの第一歩として、ベースラインパフォーマンスを測定しました。

重要なポイントを振り返りましょう:

  • SAMSumは会話要約タスクに最適なデータセット
  • Llama 3.2 1B Instructは学習に最適なサイズのモデル
  • ROUGEスコアで要約品質を客観的に測定
  • ベースラインがすべての改善の基準点になる

改善は測定から始まります。出発点がわかって初めて、どれだけ進んだかがわかるんです。

次回からは、いよいよファインチューニングの実践に入ります。ワクワクしますね!

コメント

タイトルとURLをコピーしました