パフォーマンスを維持しながら、大規模な教師モデルから小規模な生徒モデルに知識を蒸留します。
このガイドでは、Qwen2 を使用したデータ拡張と知識蒸留について、命令データの準備から生徒モデルのトレーニングとデプロイまでを説明します。
ワークフロー
-
必要な形式でトレーニングデータセットを準備します。
-
Qwen2-1.5B-Instruct-Exp または Qwen2-7B-Instruct-Exp を使用して、意味的に類似した命令を生成し、汎化性能を向上させます。
-
Qwen2-1.5B-Instruct-Refine または Qwen2-7B-Instruct-Refine を使用して、拡張されたものを含む命令を洗練し、よりリッチな出力を得ます。
-
Qwen2-72B-Instruct を使用して、命令データセットに対する教師モデルの応答を生成します。
-
完成した命令と応答のデータセットで、本番用の小規模な生徒モデルをファインチューニングします。
前提条件
以下の前提条件を満たしてください:
-
PAI (Platform for AI) (DLC および EAS) の従量課金を有効化し、デフォルトのワークスペースを作成済みであること。詳細については、「PAI の有効化とデフォルトワークスペースの作成」をご参照ください。
-
トレーニングデータとモデルファイルを保存するための OSS バケットを作成済みであること。バケットの作成方法の詳細については、「コンソールクイックスタート」をご参照ください。
命令データの準備
データ準備戦略とデータ形式の要件に従って、命令データを準備します:
データ準備戦略
知識蒸留の結果を向上させるために、以下の戦略に従ってください:
-
少なくとも数百のデータポイントを準備します。データが多いほど、モデルのパフォーマンスが向上します。
-
タスクシナリオ、入出力の長さ、言語にわたって、広くバランスの取れたディストリビューションを確保します。
-
ルールベースのメソッドを使用して、異常データをクリーンアップおよびフィルター処理します。少量でもファインチューニングの結果を低下させる可能性があります。
データ形式の要件
トレーニングデータセットは、instruction という 1 つのフィールドを持つ JSON ファイルである必要があります。例:
[
{
"instruction": "2008年の金融危機の際、金融市場を安定させるために政府が講じた主要な措置は何ですか?"
},
{
"instruction": "気候変動が悪化する中、持続可能な開発を促進するために政府が講じた重要な行動は何ですか?"
},
{
"instruction": "2001年のITバブル崩壊時、経済回復を支援するために政府が講じた主要な措置は何ですか?"
}
]
オプション: 命令の拡張
命令拡張は、ユーザー提供の命令データセットを拡張して、多様性とカバー率を高めます。
-
たとえば、次の入力が与えられた場合:
魚香肉絲 (ユーシャンロースー) の作り方は? GRE 試験の準備方法は? 友人に誤解されたらどうすればいい? -
モデルは次のようなものを出力します:
麻婆豆腐の作り方を教えて。 TOEFL 試験の準備に関する詳細なガイドを提供して。 仕事で挫折した場合、どのように考え方を調整しますか?
命令の多様性が高いほど、生徒モデルの汎化性能が向上します。PAI は、Qwen2 に基づく 2 つのプロプライエタリな拡張モデル、Qwen2-1.5B-Instruct-Exp と Qwen2-7B-Instruct-Exp を提供しています。どちらかを EAS (Elastic Algorithm Service) サービスとしてデプロイします:
モデルサービスのデプロイ
命令拡張モデルを EAS オンラインサービスとしてデプロイします。
-
モデルギャラリーページに移動します。
-
PAI コンソールにログインします。
-
左上隅で、ご利用のリージョンを選択します。
-
左側のナビゲーションウィンドウで、[ワークスペース] を選択し、ご利用のワークスペース名をクリックします。
-
左側のナビゲーションウィンドウで、 を選択します。
-
-
[モデルギャラリー] ページで、Qwen2-1.5B-Instruct-Exp または Qwen2-7B-Instruct-Exp を検索し、[デプロイ] をクリックします。
-
[デプロイ] パネルで、[モデルサービス情報] と [リソースデプロイメント情報] のデフォルト値を確認します。必要に応じて変更し、[デプロイ] をクリックします。
-
[課金に関する通知] ダイアログボックスで、[OK] をクリックします。
システムは [Deployment タスク] ページを開きます。[ステータス] が [実行中] と表示されると、デプロイメントが成功します。
モデルサービスの呼び出し
デプロイ後、API を使用して推論を実行します。詳細については、「大規模言語モデルのデプロイ」をご参照ください。クライアントリクエストの例:
-
サービスのエンドポイントとトークンを取得します。
-
[サービス詳細] ページで、[基本情報] をクリックし、次に [エンドポイント情報を表示] をクリックします。
-
[エンドポイント情報] ダイアログボックスで、エンドポイントとトークンを見つけ、ローカルに保存します。
-
-
次の Python スクリプトを作成して実行します:
import argparse import json import requests from typing import List def post_http_request(prompt: str, system_prompt: str, host: str, authorization: str, max_new_tokens: int, temperature: float, top_k: int, top_p: float) -> requests.Response: headers = { "User-Agent": "Test Client", "Authorization": f"{authorization}" } pload = { "prompt": prompt, "system_prompt": system_prompt, "top_k": top_k, "top_p": top_p, "temperature": temperature, "max_new_tokens": max_new_tokens, "do_sample": True, "eos_token_id": 151645 } response = requests.post(host, headers=headers, json=pload) return response def get_response(response: requests.Response) -> List[str]: data = json.loads(response.content) output = data["response"] return output if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--top-k", type=int, default=50) parser.add_argument("--top-p", type=float, default=0.95) parser.add_argument("--max-new-tokens", type=int, default=2048) parser.add_argument("--temperature", type=float, default=1) parser.add_argument("--prompt", type=str, default="Sing me a song.") args = parser.parse_args() prompt = args.prompt top_k = args.top_k top_p = args.top_p temperature = args.temperature max_new_tokens = args.max_new_tokens host = "EAS HOST" authorization = "EAS TOKEN" print(f" --- input: {prompt}\n", flush=True) system_prompt = "You are an instruction creator. Your goal is to create a new instruction inspired by the [given instruction]." response = post_http_request( prompt, system_prompt, host, authorization, max_new_tokens, temperature, top_k, top_p) output = get_response(response) print(f" --- output: {output}\n", flush=True)パラメーター:
-
host: サービスのエンドポイント。
-
authorization: サービスのトークン。
-
バッチ拡張
EAS API を使用して、JSON データセットから命令をバッチ拡張します。次の Python スクリプトを作成して実行します:
import requests
import json
import random
from tqdm import tqdm
from typing import List
input_file_path = "input.json" # 入力ファイル名
with open(input_file_path) as fp:
data = json.load(fp)
total_size = 10 # 拡張後の目標サンプル総数
pbar = tqdm(total=total_size)
while len(data) < total_size:
prompt = random.sample(data, 1)[0]["instruction"]
system_prompt = "You are an instruction creator. Your goal is to create a new instruction inspired by the [given instruction]."
top_k = 50
top_p = 0.95
temperature = 1
max_new_tokens = 2048
host = "EAS HOST"
authorization = "EAS TOKEN"
response = post_http_request(
prompt, system_prompt,
host, authorization,
max_new_tokens, temperature, top_k, top_p)
output = get_response(response)
temp = {
"instruction": output
}
data.append(temp)
pbar.update(1)
pbar.close()
output_file_path = "output.json" # 出力ファイル名
with open(output_file_path, 'w') as f:
json.dump(data, f, ensure_ascii=False)
パラメーター:
-
host: サービスのエンドポイント。
-
authorization: サービスのトークン。
-
file_path: ご利用のデータセットファイルのローカルパスに置き換えてください。
-
post_http_requestおよびget_response関数は、モデルサービスの呼び出しの Python スクリプトで定義されているものと一致します。
または、PAI-Designer の [LLM-Instruction Expansion (DLC)] コンポーネントを使用して、コードなしで実行することもできます。詳細については、「カスタムパイプライン」をご参照ください。
PAI-Designer のワークフローで、[OSS データの読み取り] ノードを追加し、[LLM-Instruction Expansion (DLC)] ノードに接続します。[LLM-Instruction Expansion (DLC)] ノードを選択し、右側の [フィールド設定] パネルで次のパラメーターを設定します:
-
OSS RAM Role: 権限付与を完了します。
-
Target Process Field: 処理するフィールドの名前を入力します (必須)。
-
Model Name: モデルを選択します。例:
qwen2-1.5b-instruct-exp。 -
Output OSS Directory: 出力パスを指定します。
オプション: 命令の最適化
命令の最適化は、命令をより詳細で構造化されたプロンプトに洗練させ、よりリッチな LLM の応答を引き出します。
-
たとえば、命令最適化モデルに次の入力が与えられた場合:
魚香肉絲 (ユーシャンロースー) の作り方は? GRE 試験の準備方法は? 友人に誤解されたらどうすればいい? -
モデルは次のようなものを出力します:
魚香肉絲の本格的な四川風レシピを詳しく教えてください。野菜、豚肉、調味料の具体的な材料リストと、ステップバイステップの調理手順を含めてください。また、一緒に提供するのに適した副菜や主食も推奨してください。 GRE の登録、必要書類、学習戦略、推奨される参考書を網羅した包括的なガイドを提供してください。また、準備に役立つ効果的な練習問題や模擬試験も提案してください。 友人に誤解されたときに冷静かつ合理的に対処し、効果的にコミュニケーションをとって解決するための詳細なガイドを提供してください。例えば、自分の考えや感情を表現する方法、誤解をエスカレートさせない方法、練習のための具体的な対話シナリオや状況など、実践的なアドバイスを含めてください。
より詳細な命令は、より良い LLM の出力を生み出します。PAI は、Qwen2 に基づく 2 つのプロプライエタリな最適化モデル、Qwen2-1.5B-Instruct-Refine と Qwen2-7B-Instruct-Refine を提供しています。どちらかを EAS サービスとしてデプロイします:
モデルサービスのデプロイ
-
モデルギャラリーページに移動します。
-
PAI コンソールにログインします。
-
左上隅で、ご利用のリージョンを選択します。
-
左側のナビゲーションウィンドウで、[ワークスペース] を選択し、ご利用のワークスペース名をクリックします。
-
左側のナビゲーションウィンドウで、 を選択します。
-
-
[モデルギャラリー] ページで、Qwen2-1.5B-Instruct-Refine または Qwen2-7B-Instruct-Refine を検索し、[デプロイ] をクリックします。
-
[デプロイ] パネルで、[モデルサービス情報] と [リソースデプロイメント情報] のデフォルト値を確認します。必要に応じて変更し、[デプロイ] をクリックします。
-
[課金に関する通知] ダイアログボックスで、[OK] をクリックします。
[デプロイメントタスク] ページが開きます。[ステータス] が [実行中] と表示されたら、デプロイは成功です。
モデルサービスの呼び出し
デプロイ後、API を使用して推論を実行します。詳細については、「大規模言語モデルのデプロイ」をご参照ください。クライアントリクエストの例:
-
サービスのエンドポイントとトークンを取得します。
-
[サービス詳細] ページで、[基本情報] をクリックし、次に [エンドポイント情報を表示] をクリックします。
-
[エンドポイント情報] ダイアログボックスで、エンドポイントとトークンを見つけ、ローカルに保存します。
-
-
次の Python スクリプトを作成して実行します:
import argparse import json import requests from typing import List def post_http_request(prompt: str, system_prompt: str, host: str, authorization: str, max_new_tokens: int, temperature: float, top_k: int, top_p: float) -> requests.Response: headers = { "User-Agent": "Test Client", "Authorization": f"{authorization}" } pload = { "prompt": prompt, "system_prompt": system_prompt, "top_k": top_k, "top_p": top_p, "temperature": temperature, "max_new_tokens": max_new_tokens, "do_sample": True, "eos_token_id": 151645 } response = requests.post(host, headers=headers, json=pload) return response def get_response(response: requests.Response) -> List[str]: data = json.loads(response.content) output = data["response"] return output if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--top-k", type=int, default=2) parser.add_argument("--top-p", type=float, default=0.95) parser.add_argument("--max-new-tokens", type=int, default=256) parser.add_argument("--temperature", type=float, default=0.5) parser.add_argument("--prompt", type=str, default="Sing me a song.") args = parser.parse_args() prompt = args.prompt top_k = args.top_k top_p = args.top_p temperature = args.temperature max_new_tokens = args.max_new_tokens host = "EAS HOST" authorization = "EAS TOKEN" print(f" --- input: {prompt}\n", flush=True) system_prompt = "Optimize this instruction to make it more detailed and specific." response = post_http_request( prompt, system_prompt, host, authorization, max_new_tokens, temperature, top_k, top_p) output = get_response(response) print(f" --- output: {output}\n", flush=True)パラメーター:
-
host: サービスのエンドポイント。
-
authorization: サービスのトークン。
-
バッチ最適化
EAS API を使用して、JSON データセットから命令をバッチ最適化します。次の Python スクリプトを作成して実行します:
import requests
import json
import random
from tqdm import tqdm
from typing import List
input_file_path = "input.json" # 入力ファイル名
with open(input_file_path) as fp:
data = json.load(fp)
pbar = tqdm(total=len(data))
new_data = []
for d in data:
prompt = d["instruction"]
system_prompt = "Optimize the following instruction."
top_k = 50
top_p = 0.95
temperature = 1
max_new_tokens = 2048
host = "EAS HOST"
authorization = "EAS TOKEN"
response = post_http_request(
prompt, system_prompt,
host, authorization,
max_new_tokens, temperature, top_k, top_p)
output = get_response(response)
temp = {
"instruction": output
}
new_data.append(temp)
pbar.update(1)
pbar.close()
output_file_path = "output.json" # 出力ファイル名
with open(output_file_path, 'w') as f:
json.dump(new_data, f, ensure_ascii=False)
パラメーター:
-
host: サービスのエンドポイント。
-
authorization: サービスのトークン。
-
file_path: ご利用のデータセットファイルのローカルパスに置き換えてください。
-
post_http_requestおよびget_response関数は、モデルサービスの呼び出しの Python スクリプトで定義されているものと一致します。
または、PAI-Designer の [LLM-Instruction Optimization (DLC)] コンポーネントを使用して、コードなしで実行することもできます。詳細については、「カスタムパイプライン」をご参照ください。
PAI-Designer のワークフローで、[OSS データの読み取り] ノードを [LLM-Instruction Optimization (DLC)] ノードに接続します。右側の [フィールド設定] パネルで、次の設定を完了します:
-
OSS RAM Role: 権限付与を完了します。
-
Target Process Field: 処理するフィールドの名前を入力します。
-
Model Name:
qwen2-1.5b-instruct-refineを選択します。 -
Output OSS Directory: 出力パスを指定します。
教師モデルによる応答の生成
モデルサービスのデプロイ
教師 LLM をデプロイして、最適化された命令データセットに対する応答を生成します:
-
モデルギャラリーページに移動します。
-
PAI コンソールにログインします。
-
左上隅で、ご利用のリージョンを選択します。
-
左側のナビゲーションウィンドウで、[ワークスペース] を選択し、ご利用のワークスペース名をクリックします。
-
左側のナビゲーションウィンドウで、 を選択します。
-
-
[モデルギャラリー] ページで、Qwen2-72B-Instruct を検索し、[デプロイ] をクリックします。
-
[デプロイ] パネルで、[モデルサービス情報] と [リソースデプロイメント情報] のデフォルト値を確認します。必要に応じて変更し、[デプロイ] をクリックします。
-
[課金に関する通知] ダイアログボックスで、[OK] をクリックします。
[デプロイメントタスク] ページが開きます。[ステータス] が [実行中] と表示されたら、デプロイは成功です。
モデルサービスの呼び出し
デプロイ後、API を使用して推論を実行します。詳細については、「大規模言語モデルのデプロイ」をご参照ください。クライアントリクエストの例:
-
サービスのエンドポイントとトークンを取得します。
-
[サービス詳細] ページで、[基本情報] をクリックし、次に [エンドポイント情報を表示] をクリックします。
-
[エンドポイント情報] ダイアログボックスで、エンドポイントとトークンを見つけ、ローカルに保存します。
-
-
次の Python スクリプトを作成して実行します:
import argparse import json import requests from typing import List def post_http_request(prompt: str, system_prompt: str, host: str, authorization: str, max_new_tokens: int, temperature: float, top_k: int, top_p: float) -> requests.Response: headers = { "User-Agent": "Test Client", "Authorization": f"{authorization}" } pload = { "prompt": prompt, "system_prompt": system_prompt, "top_k": top_k, "top_p": top_p, "temperature": temperature, "max_new_tokens": max_new_tokens, "do_sample": True, } response = requests.post(host, headers=headers, json=pload) return response def get_response(response: requests.Response) -> List[str]: data = json.loads(response.content) output = data["response"] return output if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--top-k", type=int, default=50) parser.add_argument("--top-p", type=float, default=0.95) parser.add_argument("--max-new-tokens", type=int, default=2048) parser.add_argument("--temperature", type=float, default=0.5) parser.add_argument("--prompt", type=str) parser.add_argument("--system_prompt", type=str) args = parser.parse_args() prompt = args.prompt system_prompt = args.system_prompt top_k = args.top_k top_p = args.top_p temperature = args.temperature max_new_tokens = args.max_new_tokens host = "EAS HOST" authorization = "EAS TOKEN" print(f" --- input: {prompt}\n", flush=True) response = post_http_request( prompt, system_prompt, host, authorization, max_new_tokens, temperature, top_k, top_p) output = get_response(response) print(f" --- output: {output}\n", flush=True)パラメーター:
-
host: サービスのエンドポイント。
-
authorization: サービスのトークン。
-
教師モデルによる命令のバッチアノテーション
教師モデル API を使用して、JSON データセットから命令をバッチアノテーションします。次の Python スクリプトを作成して実行します:
import json
from tqdm import tqdm
import requests
from typing import List
input_file_path = "input.json" # 入力ファイル名
with open(input_file_path) as fp:
data = json.load(fp)
pbar = tqdm(total=len(data))
new_data = []
for d in data:
system_prompt = "You are a helpful assistant."
prompt = d["instruction"]
print(prompt)
top_k = 50
top_p = 0.95
temperature = 0.5
max_new_tokens = 2048
host = "EAS HOST"
authorization = "EAS TOKEN"
response = post_http_request(
prompt, system_prompt,
host, authorization,
max_new_tokens, temperature, top_k, top_p)
output = get_response(response)
temp = {
"instruction": prompt,
"output": output
}
new_data.append(temp)
pbar.update(1)
pbar.close()
output_file_path = "output.json" # 出力ファイル名
with open(output_file_path, 'w') as f:
json.dump(new_data, f, ensure_ascii=False)
パラメーター:
-
host: サービスのエンドポイント。
-
authorization: サービスのトークン。
-
file_path: ご利用のデータセットファイルのローカルパスに置き換えてください。
-
post_http_requestおよびget_response関数は、モデルサービスの呼び出しのスクリプトで定義されているものと一致します。
生徒モデルのトレーニング
モデルのトレーニング
モデルギャラリーで、教師が生成したデータセットを使用して生徒モデルをトレーニングします。この例では Qwen2-7B-Instruct を使用します:
-
モデルギャラリーページに移動します。
-
PAI コンソールにログインします。
-
左上隅で、ご利用のリージョンを選択します。
-
左側のナビゲーションウィンドウで、[ワークスペース] を選択し、ご利用のワークスペース名をクリックします。
-
左側のナビゲーションウィンドウで、 を選択します。
-
-
[モデルギャラリー] ページで、Qwen2-7B-Instruct カードを検索してクリックし、詳細ページを開きます。
-
「モデル詳細」ページで、右上隅の[ファインチューニング]をクリックします。
-
[ファインチューニング] パネルで、これらの主要なパラメーターを設定します。他のパラメーターはデフォルト値のままにします。
パラメーター
説明
デフォルト値
データセット設定
訓練データセット
ドロップダウンから [OSS ファイルまたはディレクトリ] を選択し、データセットの OSS パスを選択します:
-
をクリックし、ご利用の OSS バケットを選択します。 -
[ファイルをアップロード] をクリックします。データセットファイルを OSS ディレクトリにアップロードします。
-
[OK] をクリックします。
なし
トレーニング出力設定
model
をクリックし、ご利用の OSS ストレージディレクトリを選択します。なし
tensorboard
をクリックし、ご利用の OSS ストレージディレクトリを選択します。なし
コンピューティングリソース設定
ジョブリソース
リソース仕様を選択します。システムが適切なオプションを推奨します。
なし
ハイパーパラメーター設定
learning_rate
学習率。型: Float。
5e-5
num_train_epochs
トレーニングのエポック数。型: INT。
1
per_device_train_batch_size
GPU ごとのイテレーションあたりのトレーニングサンプル数。型: INT。
1
seq_length
テキストシーケンスの長さ。型: INT。
128
lora_dim
LoRA のディメンション。型: INT。lora_dim > 0 の場合、LoRA/QLoRA 軽量トレーニングを使用します。
32
lora_alpha
LoRA の重み。型: INT。lora_dim > 0 で、LoRA/QLoRA 軽量トレーニングが使用されている場合にのみ有効です。
32
load_in_4bit
モデルを 4 ビットモードでロードするかどうか。型: bool。有効な値:
-
true
-
false
lora_dim > 0、load_in_4bit が true、かつ load_in_8bit が false の場合、4 ビット QLoRA 軽量トレーニングを使用します。
true
load_in_8bit
モデルを 8 ビットモードでロードするかどうか。型: bool。有効な値:
-
true
-
false
lora_dim > 0、load_in_4bit が false、かつ load_in_8bit が true の場合、8 ビット QLoRA 軽量トレーニングを使用します。
false
gradient_accumulation_steps
勾配累積ステップ数。型: INT。
8
apply_chat_template
トレーニングデータをデフォルトのチャットテンプレートと組み合わせるかどうか。型: bool。有効な値:
-
true
-
false
Qwen2 シリーズモデルの場合、フォーマットは次のとおりです:
-
質問:
<|im_end|>\n<|im_start|>user\n + instruction + <|im_end|>\n -
回答:
<|im_start|>assistant\n + output + <|im_end|>\n
true
system_prompt
トレーニング用のシステムプロンプト。型: String。
You are a helpful assistant
-
-
パラメーターを設定した後、[トレーニング] をクリックします。
-
[課金に関する通知] ダイアログボックスで、[OK] をクリックします。
トレーニングタスクページが開きます。
モデルサービスのデプロイ
トレーニング後、モデルを EAS サービスとしてデプロイします。
-
トレーニングタスクページで、右側の [デプロイ] をクリックします。
-
デプロイパネルで、システムは [モデルサービス情報] と [リソースデプロイメント情報] のデフォルト値を設定します。必要に応じて変更し、[デプロイ] をクリックします。
-
[課金に関する通知] ダイアログボックスで、[OK] をクリックします。
[デプロイメントタスク] ページが開きます。[ステータス] が [実行中] と表示されたら、デプロイは成功です。
モデルサービスの呼び出し
デプロイ後、API を使用して推論を行います。詳細については、「大規模言語モデルのデプロイ」をご参照ください。