{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "#!/usr/bin/env python\n", "# -*- coding: utf-8 -*-\n", "\n", "\"\"\"\n", "Sample script to finetune ModernBERT-Ja-130M on Japanese MT-bench (0~10 discrete scores).\n", "\"\"\"\n", "\n", "import os\n", "import gc\n", "import re\n", "import glob\n", "import json\n", "import random\n", "import pickle\n", "import numpy as np\n", "import pandas as pd\n", "from typing import Dict, Any\n", "\n", "from matplotlib import pyplot as plt\n", "\n", "import torch\n", "from torch import nn\n", "from datasets import Dataset, DatasetDict\n", "\n", "\n", "\n", "from transformers import (\n", " AutoTokenizer,\n", " AutoConfig,\n", " ModernBertForSequenceClassification,\n", " DataCollatorWithPadding,\n", " Trainer,\n", " TrainingArguments,\n", ")\n", "\n", "from transformers.modeling_outputs import SequenceClassifierOutput\n", "\n", "\n", "\n", "\n", "os.environ[\"CUDA_VISIBLE_DEVICES\"] = \"0\"\n", "\n", "# -------------------------------------------------------\n", "# 1. パラメータ設定(適宜変更)\n", "# -------------------------------------------------------\n", "CSV_FILE_PATH = r\"/media/kurogane/kioxia1/dataset/sss/pixiv/JMTB_1_rescore_float.csv\" # Japanese MT benchのCSVファイルパスを指定\n", "MODEL_NAME = \"sbintuitions/modernbert-ja-130m\" # ModernBERT-Ja-130M\n", "NUM_LABELS = 1 # 0~10の11クラス分類とする\n", "SEED = 42\n", "\n", "\n", "BASE_PROMPT = \"AIアシスタントがユーザーの質問に対して提供した回答の質を、公平な立場で評価してください。評価の際は、回答の有用性、関連性、正確性、深さ、創造性、詳細さを考慮してください。評価の前に短い説明を提供し、できるだけ客観的に評価してください。期待される言語は日本語です。日本語以外の言語での回答は、特に要求されない限り減点対象となります。全く日本語を使用しない場合、最低評価となります。ただし、Pythonのスクリプトや計算結果のみを提供する場合、日本語は必須ではありません。評価を0から1.0の範囲で小数点第一位までの数値で示し、floatで記載してください。例:\\\"0.5\\\"。\"\n", "\n", "# -------------------------------------------------------\n", "# 2. CSV読み込み & データ前処理\n", "# -------------------------------------------------------\n", "def load_jmtb_data(csv_path: str) -> pd.DataFrame:\n", " \"\"\"\n", " CSVを読み込んでDataFrameを返す。\n", " CSVの列名例:\n", " ['model_name', 'question_id', 'category', 'question', 'answer', 'judge', 'user_prompt',\n", " 'judgment', 'score', 'turn', 'tstamp', 'sub_category']\n", " \"\"\"\n", " df = pd.read_csv(csv_path)\n", " return df\n", "\n", "\n", "def build_input_text(row: pd.Series, df: pd.DataFrame) -> str:\n", " \"\"\"\n", " turn=1 の場合は「ターン1のみ」のテキストを構築。\n", " turn=2 の場合は「ターン1のQ&A + ターン2のQ&A」を一つに連結したテキストを構築。\n", " \"\"\"\n", " turn = row[\"turn\"]\n", " if turn == 1:\n", " # シングルターン\n", " # text = (\n", " # f\"{BASE_PROMPT}\\n\\n\",\n", " # f\"{row['question']}\",\n", " # f\"{row['answer']}\",\n", " # )\n", " text = f\"{BASE_PROMPT}{row['question']}{row['answer']}\"\n", " else:\n", " # 2ターン目のscore行なので、同じquestion_idのturn=1を探す\n", " qid = row[\"question_id\"]\n", " # 同じquestion_id & turn=1の行を検索\n", " df_turn1 = df[(df[\"question_id\"] == qid) & (df[\"turn\"] == 1)]\n", " if len(df_turn1) > 0:\n", " # 1行だけのはずだが、複数ある場合はiloc[0]\n", " r1 = df_turn1.iloc[0]\n", " # text = (\n", " # f\"{BASE_PROMPT}\\n\\n\",\n", " # f\"{r1['question']}\\n\\n{row['question']}\",\n", " # f\"{row['answer']}\",\n", " # )\n", " text = f\"{BASE_PROMPT}{r1['question']}\\n\\n{row['question']}{row['answer']}\"\n", " else:\n", " # turn=1が見当たらない不備データの場合 -> 仕方ないのでターン2だけ\n", " # text = (\n", " # f\"{BASE_PROMPT}\\n\\n\",\n", " # f\"{row['question']}\",\n", " # f\"{row['answer']}\",\n", " # )\n", " text = f\"{BASE_PROMPT}{row['question']}{row['answer']}\"\n", " return text\n", "\n", "\n", "def create_dataset_from_df(df: pd.DataFrame) -> Dataset:\n", " \"\"\"\n", " pandas DataFrame から [input_text, label] を作り、Hugging Face Datasets の Dataset を返す。\n", " - label は score (0~10) をそのまま格納。\n", " \"\"\"\n", " # 新しい列 input_text と label を作成\n", " # 参照しやすいようにデータフレームをコピー\n", " df2 = df.copy()\n", "\n", " # テキスト列を作成\n", " df2[\"input_text\"] = df2.apply(lambda row: build_input_text(row, df2), axis=1)\n", " # スコアを整数化(既にintなら不要)\n", " df2[\"label\"] = df2[\"score\"].astype(float)\n", "\n", " # 必要な列のみ残す\n", " used_cols = [\"input_text\", \"label\"]\n", " df2 = df2[used_cols]\n", "\n", " # Pandas -> Huggingface Dataset\n", " dataset = Dataset.from_pandas(df2, preserve_index=False)\n", " return dataset\n", "\n", "\n", "# -------------------------------------------------------\n", "# 3. データセットの分割: train/valid/test\n", "# -------------------------------------------------------\n", "def split_dataset(\n", " dataset: Dataset,\n", " split_ratio=(0.8, 0.1, 0.1),\n", " seed=SEED\n", ") -> DatasetDict:\n", " \"\"\"\n", " Dataset を train/dev/test に分割 (ランダム).\n", " デフォルトは 8:1:1\n", " \"\"\"\n", " train_ratio, valid_ratio, test_ratio = split_ratio\n", " # assert sum(split_ratio) == 1.0\n", " n_samples = len(dataset)\n", "\n", " # まず shuffle\n", " dataset = dataset.shuffle(seed=seed)\n", "\n", " train_end = int(n_samples * train_ratio)\n", " valid_end = int(n_samples * (train_ratio + valid_ratio))\n", "\n", " train_dataset = dataset.select(range(0, train_end))\n", " valid_dataset = dataset.select(range(train_end, valid_end))\n", " test_dataset = dataset.select(range(valid_end, n_samples))\n", "\n", " return DatasetDict({\n", " \"train\": train_dataset,\n", " \"validation\": valid_dataset,\n", " \"test\": test_dataset\n", " })\n", "\n", "\n", "# -------------------------------------------------------\n", "# 4. トークナイズ関数\n", "# -------------------------------------------------------\n", "def tokenize_function(examples, tokenizer, max_length=None):\n", " \"\"\"\n", " 文章をトークナイズ。max_lengthは適宜設定(Noneの場合は基本無制限、FlashAttention2でpadding無視)\n", " \"\"\"\n", " return tokenizer(\n", " examples[\"input_text\"],\n", " truncation=(max_length is not None),\n", " max_length=max_length,\n", " )\n", "\n", "\n", "# -------------------------------------------------------\n", "# 5. 評価指標: 分類タスク (単純にAccuracyを例示)\n", "# 必要に応じて MAE, F1, MSE などを追加実装してください。\n", "# -------------------------------------------------------\n", "def compute_metrics_regression(eval_pred):\n", " logits, labels = eval_pred\n", " # logits: shape (batch_size, 1)\n", " predictions = logits.reshape(-1)\n", " mae = mean_absolute_error(labels, predictions)\n", " mse = mean_squared_error(labels, predictions)\n", " return {\n", " \"mae\": mae,\n", " \"mse\": mse\n", " }\n", "\n", "class ModernBertForScoring(ModernBertForSequenceClassification):\n", " \"\"\"\n", " ModernBertForSequenceClassificationを継承し、\n", " 出力層にシグモイドをかけて 0~1 の範囲にマッピングするカスタムクラス。\n", " \"\"\"\n", "\n", " def __init__(self, config):\n", " super().__init__(config)\n", " # num_labels=1 + 回帰タスク想定なので、classification_head は linear + activation とする\n", " # 既存の self.classifier を再利用しつつ、最後にシグモイドを追加するイメージ\n", " self.sigmoid = nn.Sigmoid()\n", " # もし self.classifier が 1 出力以外になっている場合は要調整\n", " # (ModernBertForSequenceClassification の場合は config.num_labels に応じた Linear が作られる想定)\n", "\n", " def forward(\n", " self,\n", " input_ids=None,\n", " attention_mask=None,\n", " token_type_ids=None,\n", " labels=None,\n", " **kwargs,\n", " ):\n", " # 親クラス(ModernBertForSequenceClassification)の forward を実行\n", " # ただし 親クラスは [loss, logits] を返す実装なので、それを受け取り再加工する\n", " outputs = super().forward(\n", " input_ids=input_ids,\n", " attention_mask=attention_mask,\n", " token_type_ids=token_type_ids,\n", " labels=None, # ここでは一旦親の loss 計算を無効化し、自前でやる\n", " **kwargs,\n", " )\n", "\n", " # 親から返される logits は shape = (batch_size, num_labels=1) のはず\n", " logits = outputs.logits # => [B,1]\n", "\n", " # ここでシグモイドをかけて 0~1 に収まるようにする\n", " preds = self.sigmoid(logits) # => [B,1], range(0,1)\n", "\n", " loss = None\n", " if labels is not None:\n", " labels = labels.view(-1, 1).float()\n", " loss_fct = nn.MSELoss()\n", " loss = loss_fct(preds, labels)\n", " \n", " # hidden_states / attentions が None の場合も型的に問題なく格納できる\n", " return SequenceClassifierOutput(\n", " loss=loss,\n", " logits=preds, # シグモイド後の出力 (shape=[B,1])\n", " hidden_states=outputs.hidden_states,\n", " attentions=outputs.attentions,\n", " )\n", "\n", "\n", "from sklearn.metrics import mean_absolute_error, mean_squared_error\n", "\n", "def compute_metrics_regression(eval_pred):\n", " logits, labels = eval_pred\n", " # logits: [batch_size, 1], labels: [batch_size]\n", " preds = logits.reshape(-1)\n", " mse = mean_squared_error(labels, preds)\n", " mae = mean_absolute_error(labels, preds)\n", " return {\n", " \"mse\": mse,\n", " \"mae\": mae\n", " }\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[Info] Loading CSV from: /media/kurogane/kioxia1/dataset/sss/pixiv/JMTB_1_rescore_float.csv\n", "[Info] CSV loaded: 6480 rows.\n", "[Info] Built dataset with columns: ['input_text', 'label']\n", "DatasetDict({\n", " train: Dataset({\n", " features: ['input_text', 'label'],\n", " num_rows: 5184\n", " })\n", " validation: Dataset({\n", " features: ['input_text', 'label'],\n", " num_rows: 648\n", " })\n", " test: Dataset({\n", " features: ['input_text', 'label'],\n", " num_rows: 648\n", " })\n", "})\n", "[Info] Loading tokenizer for sbintuitions/modernbert-ja-130m\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "851e20ba48b845b995288997e95a58c5", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Map: 0%| | 0/5184 [00:00\n", " \n", " \n", " [2592/2592 18:44, Epoch 32/32]\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
EpochTraining LossValidation LossMseMae
10.1210000.0507170.0507170.172666
20.0891000.0413920.0413920.158076
30.0789000.0295730.0295730.121381
40.1049000.0648990.0648990.209115
50.0505000.0299660.0299660.131566
60.0245000.0687390.0687390.215073
70.0176000.0326280.0326280.140590
80.0115000.0240800.0240800.107284
90.0096000.0235500.0235500.106661
100.0089000.0196720.0196720.098421
110.0079000.0208090.0208090.108778
120.0050000.0187930.0187930.098439
130.0036000.0176990.0176990.098569
140.0029000.0202240.0202240.100133
150.0034000.0172070.0172070.096104
160.0012000.0177200.0177200.095289
170.0015000.0179830.0179830.096090
180.0008000.0177090.0177090.095045
190.0009000.0174560.0174560.094618
200.0003000.0174870.0174870.095387
210.0002000.0174180.0174180.094866
220.0001000.0173750.0173750.095027
230.0001000.0171700.0171700.095647
240.0001000.0173440.0173440.095632
250.0000000.0171270.0171270.095365
260.0000000.0171530.0171530.095548
270.0000000.0172620.0172620.095495
280.0000000.0172040.0172040.095659
290.0000000.0173180.0173180.095501
300.0000000.0172860.0172860.095896
310.0000000.0173630.0173630.095974
320.0000000.0172500.0172500.095597

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "[Info] Evaluating on test set ...\n" ] }, { "data": { "text/html": [ "\n", "

\n", " \n", " \n", " [81/81 00:01]\n", "
\n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Test set metrics: {'eval_loss': 0.022432124242186546, 'eval_mse': 0.022432127967476845, 'eval_mae': 0.10348472744226456, 'eval_runtime': 1.4185, 'eval_samples_per_second': 456.805, 'eval_steps_per_second': 57.101, 'epoch': 32.0}\n", "[Info] Done. Saving final model ...\n", "[Info] Finished.\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjUAAAGwCAYAAABRgJRuAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAACQu0lEQVR4nO3deXxTVfr48U+SJuneAqUthZaCIIusslRARceO4DooIi4zMMjgqFRH6sp8FRydmaIigwsj6gyoP2VgXEfFYQZQcBRwKSCyiIJIEWjL1r1N0uT+/ri9t0mbtEn3Js/79coraXLuzUmw16fPec45BkVRFIQQQgghOjlje3dACCGEEKIlSFAjhBBCiKAgQY0QQgghgoIENUIIIYQIChLUCCGEECIoSFAjhBBCiKAgQY0QQgghgkJYe3egrbhcLo4dO0ZMTAwGg6G9uyNESFIUhdLSUlJSUjAaO8ffVHLtEKJ9BXLdCJmg5tixY6SmprZ3N4QQwJEjR+jVq1d7d8Mvcu0QomPw57oRMkFNTEwMoH4psbGx7dwbIUJTSUkJqamp+u9jZyDXDiHaVyDXjZAJarS0cWxsrFyYhGhnnWkYR64dQnQM/lw3OsegthBCCCFEIySoEUIIIURQkKBGCCGEEEEhZGpqRMfndDpxOBzt3Q3RDGazGZPJ1N7dECFMriOdT0teNySoEe1OURTy8/MpKipq766IFhAfH09ycnKnKgYWnZ9cRzq3lrpuSFAj2p12IUpMTCQyMlL+Z9hJKYpCRUUFhYWFAPTo0aOdeyRCiVxHOqeWvm5IUCPaldPp1C9E3bp1a+/uiGaKiIgAoLCwkMTERBmKEm1CriOdW0teN6RQWLQrbew7MjKynXsiWor2byl1DaKtyHWk82up64YENaJDkFRx8JB/S9Fe5L+9zqul/u0kqBFCCCFEUJCgRgghhBBBQYIaITqol19+mfj4+PbuhhCikwvkWvLII48wYsSIVu1Pa5KgpoOqtDvbuwtCCH+5XFB2Ak7sb++eCBHSJKjpgP79zXGGPPIf3vjqSHt3RYg2tWzZMtLT0wkPDycjI4MvvvjCZ9s9e/YwdepU0tPTMRgMLF26tF6bnJwcxowZQ0xMDImJiUyZMoX9+1sh8LAVw+J+sGwsVNta/vxCCL9IUNMB7ThShNOlsD2vqL270uYURaHCXt0uN0VRAuqry+UiJyeHPn36EBERwfDhw3nzzTdxuVz06tWL559/3qP9jh07MBqNHD58GIAlS5YwdOhQoqKiSE1N5Y477qCsrKxJ35uWMl6xYgVpaWlER0dzxx134HQ6eeKJJ0hOTiYxMZE//elPHsf504dPP/2UCy64gIiICFJTU7nrrrsoLy9vUj8bsmbNGrKzs1m4cCHbt29n+PDhTJo0SV+Uq66Kigr69u3LokWLSE5O9tpm8+bNzJ07l23btrF+/XocDgeXXnppy/ffGgeGmstpxemWPbdoErmWNO1a4q1vjz76KL169cJqtTJixAjWrVunv26328nKyqJHjx6Eh4fTu3dvcnJyAPXf4JFHHiEtLQ2r1UpKSgp33XVXi/TLF1l8rwMqt1UDUFZzH0oqHU4GL/hPu7z33kcnEWnx/1ciJyeH1157jeXLl9O/f38++eQTfvnLX/Kf//yHG2+8kVWrVnH77bfr7V9//XUmTJhA7969ATAajTzzzDP06dOHH374gTvuuIP777+fv/71r03q/8GDB/n3v//NunXrOHjwINdddx0//PADZ599Nps3b2bLli3ccsstZGZmkpGR4VcfDh48yOTJk/njH//IihUrOHHiBFlZWWRlZbFy5com9dOXJUuWMGfOHGbNmgXA8uXLWbt2LStWrODBBx+s137MmDGMGTMGwOvrgMfFF9TagsTERHJzc7nwwgtbrvNGI0R0hYqTUHkaYmU15fYm15KmX0vcPf300zz11FO88MILjBw5khUrVnD11VezZ88e+vfvzzPPPMN7773HP//5T9LS0jhy5AhHjqijDG+99RZ/+ctfWL16Neeccw75+fl8/fXXze5TQySo6YAqauppykMwqOksbDYbf/7zn9mwYQPjxo0DoG/fvnz66ae88MIL3H///Tz11FPk5eWRlpaGy+Vi9erVPPTQQ/o57r77bv1xeno6f/zjH7ntttuafCFyuVysWLGCmJgYBg8ezMUXX8z+/fv58MMPMRqNDBgwgMcff5yPP/5YD2oa60NOTg4333yz3k67iE2cOJHnn3+e8PDwJvW1LrvdTm5uLvPnz9efMxqNZGZmsnXr1hZ5D4Di4mIAunbt6rONzWbDZqsdQiopKfHv5JE1QU3FqWb1UYSWjngtcbd48WIeeOABbrjhBgD9GrJ06VKWLVtGXl4e/fv35/zzz8dgMOiB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2lo1kqkRfrrooou4++6727sbQUOCmlZUWWdlYH/UzdTI8JMQnUiEZGqEaE8S1LSiiiYMP8k6NUJ0YrIAnxDtSoKaVuQ+jTvQdWoiLerCXSE3pVtRwF7ePrcA9wlyuVzk5OTQp08fIiIiGD58OG+++SYul4tevXrx/PPPe7TfsWMHRqORw4cPA7BkyRKGDh1KVFQUqamp3HHHHZSVlTXpa3vkkUcYMWIEK1asIC0tjejoaO644w6cTidPPPEEycnJJCYm8qc//cntq1Z45JFHSEtLw2q1kpKSwl133aW/brPZuPfee+nZsydRUVFkZGTU239J1CGFwh1HJ7qWaM6cOcOMGTPo0qULkZGRXHbZZXz//ff664cPH+aqq66iS5cuREVFcc455/Dhhx/qx9588810796diIgI+vfvz8qVK1vkq+xMmrSi8LJly/SddIcPH86zzz7L2LFjvbZ96aWXePXVV9m9ezcAo0aN4s9//rNHe0VRWLhwIS+99BJFRUVMmDCB559/Xt/aHOD06dPceeedvP/++xiNRqZOncrTTz9NdHR0Uz5Cm6h0uA8/BbZOTWKMlR9PVYTeNgmOCvhzSvu89++PgcW/TUcBcnJyeO2111i+fDn9+/fnk08+4Ze//CX/+c9/uPHGG1m1ahW333673v71119nwoQJ+oqeRqORZ555hj59+vDDDz9wxx13cP/99/PXv/61Sd0/ePAg//73v1m3bh0HDx7kuuuu44cffuDss89m8+bNbNmyhVtuuYXMzEwyMjJ46623+Mtf/sLq1as555xzyM/P5+uvv9bPl5WVxd69e1m9ejUpKSm88847TJ48mW+++cbjd1O40QuF/dvrTbSiTnQt0fz617/m+++/57333iM2NpYHHniAyy+/nL1792I2m5k7dy52u51PPvmEqKgo9u7dq/8/8OGHH2bv3r38+9//JiEhgQMHDlBZWdnSn6zDCzioWbNmDdnZ2SxfvpyMjAyWLl3KpEmT2L9/P4mJifXab9q0iRtvvJHx48cTHh7O448/zqWXXsqePXvo2bMnAE888QTPPPMMr7zyCn369OHhhx9m0qRJ7N27V9+C/Oabb+b48eOsX78eh8PBrFmzuPXWW1m1alUzv4LW4z6UZHe6sFe7sIQ1nBzTMjWJseH8eKqiXo2N6BhsNht//vOf2bBhA+PGjQOgb9++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oU+fPkRERDB8+HDefPNNoDa9u3btWoYNG0Z4eDjnnXceu3fv9jjHW2+9xTnnnIPVaiU9PZ2nnnrK43WbzcYDDzxAamoqVquVfv368fe//92jTW5uLqNHjyYyMpLx48ezf/9+/bWvv/6aiy++mJiYGGJjYxk1ahRfffVVK30jQgh/yLVDNFuLb5EpQt4f//hHZeDAgcq6deuUgwcPKitXrlSsVquyadMmfWffQYMGKf/973+VXbt2KVdeeaWSnp6u2O12RVEU5auvvlKMRqPy6KOPKvv371dWrlypREREeOx8e/311yupqanK22+/rRw8eFDZsGGDsnr1akVRancPzsjIUDZt2qTs2bNHueCCC5Tx48frx59zzjnKL3/5S2Xfvn3Kd999p/zzn/9Udu7c2abfkxDCk1w7RHNJUCNaVFVVlRIZGals2bLF4/nZs2crN954o37R0C4iiqIop06dUiIiIpQ1a9YoiqIoN910k/Lzn//c4/j77rtPGTx4sKIoirJ//34FUNavX++1D9p7bNiwQX9u7dq1CqBUVlYqiqIoMTExyssvv9z8DyyEaBFy7RAtQYafRIs6cOAAFRUV/PznPyc6Olq/vfrqqxw8eFBvN27cOP1x165dGTBgAPv27QNg3759TJgwweO8EyZM4Pvvv8fpdLJz505MJhMTJ05ssC/Dhg3TH/fo0QOAwsJCALKzs/nNb35DZmYmixYt8uibEKLtybVDtAQJakSLKisrA2Dt2rXs3LlTv+3du1cfG2+uiIgIv9qZzWb9scFgANQxe4BHHnmEPXv2cMUVV/DRRx8xePBg3nnnnRbpnxAicHLtEC1BghrRogYPHozVaiUvL49+/fp53FJTU/V227Zt0x+fOXOG7777jkGDBgEwaNAgPvvsM4/zfvbZZ5x99tmYTCaGDh2Ky+Vi8+bNzerr2Wefzbx58/jvf//Ltddey8qVK5t1PiFE08m1Q7SEsPbugAguMTEx3HvvvcybNw+Xy8X5559PcXExn332GbGxsfTu3RuARx99lG7dupGUlMT//d//kZCQwJQpUwC45557GDNmDI899hjTp09n69atPPfcc/z1r38FID09nZkzZ3LLLbfwzDPPMHz4cA4fPkxhYSHXX399o32srKzkvvvu47rrrqNPnz789NNPfPnll0ydOrXVvhchRMPk2iFaRHsX9Yjg43K5lKVLlyoDBgxQzGaz0r17d2XSpEnK5s2b9UK8999/XznnnHMUi8WijB07Vvn66689zvHmm28qgwcPVsxms5KWlqY8+eSTHq9XVlYq8+bNU3r06KFYLBalX79+yooVKxRFqS32O3PmjN5+x44dCqAcOnRIsdlsyg033KCkpqYqFotFSUlJUbKysvRCQCFE+5Brh2gug6IoSnsGVSK0bNq0iYsvvpgzZ84QHx/f3t0RQnQScu0Q/pCaGiGEEEIEBQlqhBBCCBEUZPhJCCGEEEFBMjVCCCGECAoS1AghhBAiKEhQI4QQQoigIEGNEEIIIYKCBDVCCCGECAoS1AghhBAiKEhQI4QQQoigIEGNEEIIIYLC/wf8Df3ckddGgAAAAABJRU5ErkJggg==", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# -------------------------------------------------------\n", "# 6. 実行メイン\n", "# -------------------------------------------------------\n", "\n", "6\n", "# 学習関連ハイパーパラメータ\n", "TRAIN_EPOCHS = 32\n", "TRAIN_BATCH_SIZE = 64\n", "EVAL_BATCH_SIZE = 8\n", "LEARNING_RATE = 4e-5\n", "\n", "\n", "SAVE_DIR = \"./modernbert_jamt_finetune_ckpt_{:0=2}\".format(len(glob.glob(\"./modernbert_jamt_finetune_ckpt_*\")))\n", "SPLIT_RATIO = (0.8, 0.1, 0.1) # train:valid:test = 8:1:1\n", "\n", "\n", "os.environ[\"TOKENIZERS_PARALLELISM\"] = \"false\"\n", "random.seed(SEED)\n", "np.random.seed(SEED)\n", "torch.manual_seed(SEED)\n", "\n", "print(f\"[Info] Loading CSV from: {CSV_FILE_PATH}\")\n", "df = load_jmtb_data(CSV_FILE_PATH)\n", "print(f\"[Info] CSV loaded: {len(df)} rows.\")\n", "\n", "# Dataset化\n", "dataset_all = create_dataset_from_df(df)\n", "print(\"[Info] Built dataset with columns:\", dataset_all.column_names)\n", "\n", "# train/dev/test split\n", "dataset_dict = split_dataset(dataset_all, split_ratio=SPLIT_RATIO, seed=SEED)\n", "\n", "# 変数をpickle形式で保存する\n", "with open(\"./dataset_dict_float.pkl\", \"wb\") as file:\n", " pickle.dump(dataset_dict, file)\n", "# # pickle形式で保存された変数を読み込む\n", "# with open(\"./dataset_dict_float.pkl\", \"rb\") as file:\n", "# dataset_dict = pickle.load(file)\n", "\n", "\n", "# dataset_dict = DatasetDict.load_from_disk(\"./jmtb_dataset_splits\")\n", "\n", "print(dataset_dict)\n", "\n", "# トークナイザ準備\n", "print(f\"[Info] Loading tokenizer for {MODEL_NAME}\")\n", "tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)\n", "\n", "def tokenize_fn(examples):\n", " return tokenize_function(examples, tokenizer, max_length=None)\n", "\n", "dataset_dict = dataset_dict.map(tokenize_fn, batched=True)\n", "\n", "# モデルConfigとモデル本体\n", "# num_labels=11クラス分類 (score=0..10)\n", "config = AutoConfig.from_pretrained(\n", " MODEL_NAME,\n", " num_labels=1,\n", " problem_type=\"single_label_regression\"\n", ")\n", "# 注意: AutoConfig で problem_type 指定しても、上書きするのは親クラスの forward.\n", "# ここでは主に「情報として入れておく」ため\n", "\n", "tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)\n", "\n", "model = ModernBertForScoring.from_pretrained(\n", " MODEL_NAME,\n", " config=config\n", ")\n", "\n", "\n", "\n", "# 学習データと評価データへ正しく入力されるようにcollator準備\n", "data_collator = DataCollatorWithPadding(tokenizer=tokenizer)\n", "\n", "# Trainer用の引数設定\n", "training_args = TrainingArguments(\n", " output_dir=SAVE_DIR,\n", " num_train_epochs=TRAIN_EPOCHS,\n", " learning_rate=LEARNING_RATE,\n", " per_device_train_batch_size=TRAIN_BATCH_SIZE,\n", " per_device_eval_batch_size=EVAL_BATCH_SIZE,\n", " evaluation_strategy=\"epoch\",\n", " save_strategy=\"epoch\",\n", " logging_strategy=\"epoch\",\n", " load_best_model_at_end=True,\n", " bf16=True, # Ampere以降のGPUでMixed Precision(BF16)学習\n", " bf16_full_eval=True,\n", " report_to=\"none\", # レポート先をOFF(W&Bなど使わない場合)\n", " seed=SEED,\n", " warmup_ratio=0.1,\n", " lr_scheduler_type=\"cosine\",\n", " weight_decay=0.01,\n", " # logging_dir=SAVE_DIR,\n", ")\n", "\n", "# Trainer生成\n", "trainer = Trainer(\n", " model=model,\n", " args=training_args,\n", " train_dataset=dataset_dict[\"train\"],\n", " eval_dataset=dataset_dict[\"validation\"],\n", " tokenizer=tokenizer,\n", " data_collator=data_collator,\n", " compute_metrics=compute_metrics_regression, #compute_metrics_classification,\n", ")\n", "\n", "print(\"[Info] Starting training ...\")\n", "trainer.train()\n", "\n", "# 学習完了後、テストセットで評価\n", "print(\"[Info] Evaluating on test set ...\")\n", "metrics_test = trainer.evaluate(dataset_dict[\"test\"])\n", "print(\"Test set metrics:\", metrics_test)\n", "\n", "# 終了処理\n", "print(\"[Info] Done. Saving final model ...\")\n", "trainer.save_model(SAVE_DIR)\n", "print(\"[Info] Finished.\")\n", "\n", "\n", "\n", "# ロスなどの結果を別途保存\n", "dir_checkpoints = glob.glob(os.path.join(SAVE_DIR, \"checkpoint-*\", \"trainer_state.json\"))\n", "def atoi(text):\n", " return int(text) if text.isdigit() else text\n", "\n", "def natural_keys(text):\n", " return [ atoi(c) for c in re.split(r'(\\d+)', text) ]\n", "\n", "dir_checkpoints = sorted(dir_checkpoints,key=natural_keys)\n", "\n", "l_data_eval_mae = []\n", "l_data_eval_mse = []\n", "l_data_eval_loss = []\n", "l_data_loss = []\n", "for i_checkpoint in dir_checkpoints:\n", " with open(i_checkpoint, \"r\", encoding=\"utf-8\") as reader:\n", " data_check = json.load(reader)\n", " l_data_eval_mae.append(data_check[\"log_history\"][-1][\"eval_mae\"])\n", " l_data_eval_mse.append(data_check[\"log_history\"][-1][\"eval_mse\"])\n", " l_data_eval_loss.append(data_check[\"log_history\"][-1][\"eval_loss\"])\n", " l_data_loss.append(data_check[\"log_history\"][-2][\"loss\"])\n", "\n", "d_logs = {\n", " \"eval_mae\": l_data_eval_mae,\n", " \"eval_mse\": l_data_eval_mse,\n", " \"eval_loss\": l_data_eval_loss,\n", " \"loss\": l_data_loss,\n", "}\n", "\n", "with open(os.path.join(SAVE_DIR, \"log_epochs.json\"), \"w\", encoding=\"utf-8\") as writer:\n", " json.dump(d_logs, writer, indent=4, ensure_ascii=False)\n", "\n", "# 可視化\n", "fig, ax = plt.subplots(ncols=2)\n", "\n", "ax[0].plot(l_data_eval_mae, label=\"eval_mae\")\n", "ax[0].plot(l_data_eval_mse, label=\"eval_mse\")\n", "ax[1].plot(l_data_eval_loss, label=\"eval_loss\")\n", "ax[1].plot(l_data_loss, label=\"loss\")\n", "\n", "ax[0].set_xlabel(\"epochs\")\n", "ax[1].set_xlabel(\"epochs\")\n", "\n", "ax[0].legend()\n", "ax[1].legend()\n", "\n", "plt.savefig(os.path.join(SAVE_DIR, \"log_epochs.png\"))\n", "plt.show()" ] } ], "metadata": { "kernelspec": { "display_name": "vllmtest", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.4" } }, "nbformat": 4, "nbformat_minor": 2 }