このソリューションは、大規模言語モデル (LLM) ベースの意図認識技術を活用しています。大量のデータから複雑な言語パターンとユーザーの動作を学習し、より正確なユーザー意図認識と、より自然で流動的な対話体験を可能にします。Qwen1.5 大規模言語モデルを基盤とするこのソリューションは、LLMベースの意図認識ソリューションの完全な開発プロセスについて説明します。
背景情報
意図認識とは
AIエージェントは、自然言語で表現されたユーザーのニーズを理解します。その後、対応する操作を実行したり、関連情報を提供したりします。この機能は、インテリジェント対話システムの重要な部分です。LLMベースの意図認識技術は広く注目を集め、現在では広く利用されています。
意図認識技術の典型的なシナリオ
スマート音声アシスタントでは、ユーザーは簡単な音声コマンドを使用して対話します。例えば、ユーザーが音声アシスタントに「音楽を聴きたい」と伝えた場合、システムはユーザーの音楽再生の意図を正確に識別し、対応する操作を実行する必要があります。
スマートカスタマーサービスでは、さまざまなカスタマーサービスリクエストを処理することが課題となります。システムは、それらを返品、交換、苦情などの異なる処理フローに迅速かつ正確に分類する必要があります。例えば、Eコマースプラットフォームでは、ユーザーが「受け取った商品に欠陥があるので返品したい」と言うかもしれません。ここで、LLMベースの意図認識システムは、ユーザーの意図を「返品」として迅速に捉え、返品プロセスを自動的にトリガーし、その後の操作をユーザーに案内する必要があります。
利用プロセス
LLMベースの意図認識ソリューションの利用プロセスは次のとおりです。
データ形式要件とデータ準備戦略を参照して、特定のビジネスシナリオ向けのトレーニングデータセットを準備できます。または、データ準備戦略を参照してビジネスデータを準備し、iTAGを使用して生データにアノテーションを付けます。ラベリング結果をエクスポートし、PAI-QuickStartがサポートするデータ形式に変換して、その後のモデルトレーニングに利用します。
QuickStartでは、Qwen1.5-1.8B-Chat モデルに基づいてモデルをトレーニングできます。モデルトレーニングが完了したら、モデルをオフラインで評価します。
モデル評価結果がお客様の期待を満たしている場合、トレーニング済みモデルをQuickStartを通じてEASオンラインサービスとしてデプロイできます。
前提条件
開始する前に、次の準備を完了してください。
PAI (DLC, EAS) の従量課金を有効にし、デフォルトワークスペースを作成します。詳細については、「PAIを有効にしてデフォルトワークスペースを作成する」をご参照ください。
トレーニングデータとトレーニング済みモデルファイルを保存するためのOSSバケットを作成します。詳細については、「コンソールクイックスタート」をご参照ください。
トレーニングデータの準備
次のいずれかの方法でトレーニングデータを準備します。
方法2: データ準備戦略とiTAGプラットフォームを使用したデータアノテーションを参照します。この方法は、大規模なデータシナリオに適用され、アノテーション効率を大幅に向上させます。
データ準備戦略
トレーニング効果と安定性を向上させるために、次の戦略を使用してデータを準備します。
単一意図認識シナリオの場合、各意図のアノテーション数が50~100以上であることを確認します。モデルのファインチューニングが効果的でない場合は、アノテーションデータの量を増やすことを検討できます。また、各意図のアノテーションデータの量がバランスが取れていることを確認します。1つの意図にアノテーションデータが多すぎる状況は避けてください。
複数意図認識またはマルチターン対話シナリオの場合、推奨されるアノテーションデータ量は、単一意図認識シナリオのデータ量の少なくとも20%です。さらに、複数意図認識またはマルチターン対話シナリオに含まれる意図は、単一意図認識シナリオに登場している必要があります。
意図の説明は、幅広い質問とシナリオをカバーしている必要があります。
データ形式要件
トレーニングデータ形式はJSON形式ファイルです。これには`instruction`と`output`の2つのフィールドが含まれます。`instruction`フィールドは入力命令に対応し、`output`フィールドはモデルが予測した意図とその関連主要パラメーターに対応します。以下は、異なる意図認識シナリオにおけるトレーニングデータの例です。
単一意図認識シナリオの場合、特定のビジネスシナリオに対応するビジネスデータを準備できます。このデータは、大規模言語モデル (LLM) のファインチューニングトレーニングに使用されます。以下は、スマートホームシナリオにおけるシングルターン対話のトレーニングデータの例です。
[ { "instruction": "I want to listen to music", "output": "play_music()" }, { "instruction": "It is too loud. Lower the volume.", "output": "volume_down()" }, { "instruction": "I do not want to listen anymore. Stop the music.", "output": "music_exit()" }, { "instruction": "I want to visit Hangzhou. Check the weather forecast for me.", "output": "weather_search(Hangzhou)" } ]複数意図認識またはマルチターン対話シナリオの場合、ユーザーの意図は複数の対話ラウンドにわたって表現されることがあります。この場合、マルチターン対話データを準備し、マルチターンユーザー入力にアノテーションを付けることができます。例えば、音声アシスタントのマルチターン対話フローを次に示します。
User: I want to listen to music. Assistant: What type of music? User: Play some *** music. Assistant: play_music(***)対応するマルチターン対話トレーニングデータ形式は次のとおりです。
[ { "instruction": "I want to listen to music. Play some *** music.", "output": "play_music(***)" } ]
マルチターン対話モデルのトレーニングは、トレーニング期間を大幅に増加させ、実際のアプリケーションではマルチターン対話意図認識シナリオの数が限られています。シングルターン対話意図認識が実際のビジネス要件を満たせない場合にのみ、マルチターン対話モデルのトレーニングを検討する必要があります。このソリューションでは、シングルターン対話を例として、利用プロセス全体を説明します。
iTAGプラットフォームを使用したデータアノテーション
また、次の手順を参照して、PAI-iTAGプラットフォームを使用してデータにアノテーションを付け、特定の要件を満たすトレーニングデータセットを生成することもできます。
iTAGアノテーション用のデータをPAIデータセットに登録できます。
データ準備戦略を参照して、マニフェスト形式のデータファイルを準備できます。例:
{"data":{"instruction": "I want to listen to music"}} {"data":{"instruction": "It is too loud. Lower the volume."}} {"data":{"instruction": "I do not want to listen anymore. Stop the music."}} {"data":{"instruction": "I want to visit Hangzhou. Check the weather forecast for me."}}「AI アセット管理 > データセット」ページを開きます。対象のワークスペースを選択し、[データセットを開く] をクリックします。
Create Dataset をクリックします。以下の主要なパラメーターを設定します。その他のパラメーター設定の詳細については、「データセットの作成と管理」をご参照ください。
パラメーター
説明
Storage Type
「Alibaba Cloud Object Storage Service (OSS)」を選択します。
Import Format
[File] を選択してください。
OSS Path
既存のOSSディレクトリを選択します。準備したマニフェストファイルを次のようにアップロードします。
ボタンをクリックし、Select OSS file ダイアログボックスで Upload File をクリックします。[Browse Local Files] または [Drag and Drop File to Upload] をクリックし、プロンプトに従ってマニフェストファイルをアップロードします。
「データ準備 > iTAG」ページに移動します。Go to Management Page をクリックし、Template Management タブに切り替えます。
Create Template をクリックします。Custom Template > Basic Templates を選択し、Edit をクリックします。パラメーターを構成した後、Save Template Name をクリックします。主要なパラメーターは次のとおりです。構成の詳細については、「テンプレート管理」をご参照ください。
設定
説明
基本テンプレート キャンバスエリア
Text を選択し、**[コンテンツカードの生成]** をクリックします。

テキストエリアをクリックします。表示される Import Dataset ダイアログボックスで、既存のデータセットを選択します。その後、右側の 基本テンプレート設定 エリアで、Dataset Field Name > 命令 を選択します。
基本テンプレート 回答エリア
Input Field を選択し、Generate Title Card をクリックします。その後、Title を output に変更します。

左側のナビゲーションウィンドウで、 を選択し、右側の Task Management タブで Create Task をクリックします。Create Labeling Task ページで関連するパラメーターを設定した後、Create をクリックします。主な構成設定を以下に説明します。他のパラメーター設定の詳細については、「ラベリングタスクの作成」をご参照ください。
パラメーター
説明
Input data set
前のステップで作成したデータセットを選択します。
説明入力データは、使用するテンプレートに対応している必要があります。
Template Type
「Custom Template」を選択し、既存のテンプレートのドロップダウンリストから作成済みテンプレートを選択します。
アノテーションタスクが作成されたら、データにアノテーションを付けることができます。詳細については、「アノテーションタスクの処理」をご参照ください。

データアノテーションが完了したら、アノテーション結果をOSSディレクトリにエクスポートできます。詳細については、「アノテーション結果データのエクスポート」をご参照ください。
このソリューションでは、出力マニフェストファイルの内容の例を次に示します。データ形式の説明については、「アノテーションデータ形式の概要」をご参照ください。
{"data":{"instruction":"I want to listen to music","_itag_index":""},"label-1947839552568066048-system":{"fixedFlag":0,"results":[{"MarkResultId":"1947839554911772672","MarkTitle":"Basic Template","MarkResult":"{\"tabId\":\"CommonExtensions\",\"annotations\":[{\"id\":null,\"labels\":{\"output\":\"play_music()\"},\"exif\":null}],\"type\":\"CommonExtensions\",\"version\":\"v2\"}","QuestionId":"CommonExtensions","ResultType":"OPEN_GROUP","Progress":null,"Version":"1753236185165","MarkTime":"Wed Jul 23 10:03:05 CST 2025","UserMarkResultId":null,"IsNeedVoteJudge":false}],"abandonFlag":0},"label-1947839552568066048":{"results":[{"MarkResultId":"1947839554911772672","MarkTitle":"Basic Template","MarkResult":"{\"tabId\":\"CommonExtensions\",\"annotations\":[{\"id\":null,\"labels\":{\"output\":\"play_music()\"},\"exif\":null}],\"type\":\"CommonExtensions\",\"version\":\"v2\"}","QuestionId":"CommonExtensions","ResultType":"OPEN_GROUP","Progress":null,"Version":"1753236185165","MarkTime":"Wed Jul 23 10:03:05 CST 2025","UserMarkResultId":"1947839763671740416","IsNeedVoteJudge":false}]},"abandonFlag":0,"abandonRemark":null} {"data":{"instruction":"It is too loud. Lower the volume.","_itag_index":""},"label-1947839552568066048-system":{"fixedFlag":0,"results":[{"MarkResultId":"1947839554891464704","MarkTitle":"Basic Template","MarkResult":"{\"tabId\":\"CommonExtensions\",\"annotations\":[{\"id\":null,\"labels\":{\"output\":\"volume_down()\"},\"exif\":null}],\"type\":\"CommonExtensions\",\"version\":\"v2\"}","QuestionId":"CommonExtensions","ResultType":"OPEN_GROUP","Progress":null,"Version":"1753236198979","MarkTime":"Wed Jul 23 10:03:19 CST 2025","UserMarkResultId":null,"IsNeedVoteJudge":false}],"abandonFlag":0},"label-1947839552568066048":{"results":[{"MarkResultId":"1947839554891464704","MarkTitle":"Basic Template","MarkResult":"{\"tabId\":\"CommonExtensions\",\"annotations\":[{\"id\":null,\"labels\":{\"output\":\"volume_down()\"},\"exif\":null}],\"type\":\"CommonExtensions\",\"version\":\"v2\"}","QuestionId":"CommonExtensions","ResultType":"OPEN_GROUP","Progress":null,"Version":"1753236198979","MarkTime":"Wed Jul 23 10:03:19 CST 2025","UserMarkResultId":"1947839868520656896","IsNeedVoteJudge":false}]},"abandonFlag":0,"abandonRemark":null} {"data":{"instruction":"I do not want to listen anymore. Stop the music.","_itag_index":""},"label-1947839552568066048-system":{"fixedFlag":0,"results":[{"MarkResultId":"1947839554992373760","MarkTitle":"Basic Template","MarkResult":"{\"tabId\":\"CommonExtensions\",\"annotations\":[{\"id\":null,\"labels\":{\"output\":\"music_exit()\"},\"exif\":null}],\"type\":\"CommonExtensions\",\"version\":\"v2\"}","QuestionId":"CommonExtensions","ResultType":"OPEN_GROUP","Progress":null,"Version":"1753236212152","MarkTime":"Wed Jul 23 10:03:32 CST 2025","UserMarkResultId":null,"IsNeedVoteJudge":false}],"abandonFlag":0},"label-1947839552568066048":{"results":[{"MarkResultId":"1947839554992373760","MarkTitle":"Basic Template","MarkResult":"{\"tabId\":\"CommonExtensions\",\"annotations\":[{\"id\":null,\"labels\":{\"output\":\"music_exit()\"},\"exif\":null}],\"type\":\"CommonExtensions\",\"version\":\"v2\"}","QuestionId":"CommonExtensions","ResultType":"OPEN_GROUP","Progress":null,"Version":"1753236212152","MarkTime":"Wed Jul 23 10:03:32 CST 2025","UserMarkResultId":"1947839936657285120","IsNeedVoteJudge":false}]},"abandonFlag":0,"abandonRemark":null} {"data":{"instruction":"I want to visit Hangzhou. Check the weather forecast for me.","_itag_index":""},"label-1947839552568066048-system":{"fixedFlag":0,"results":[{"MarkResultId":"1947839554971426816","MarkTitle":"Basic Template","MarkResult":"{\"tabId\":\"CommonExtensions\",\"annotations\":[{\"id\":null,\"labels\":{\"output\":\"weather_search(Hangzhou)\"},\"exif\":null}],\"type\":\"CommonExtensions\",\"version\":\"v2\"}","QuestionId":"CommonExtensions","ResultType":"OPEN_GROUP","Progress":null,"Version":"1753236218730","MarkTime":"Wed Jul 23 10:03:39 CST 2025","UserMarkResultId":null,"IsNeedVoteJudge":false}],"abandonFlag":0},"label-1947839552568066048":{"results":[{"MarkResultId":"1947839554971426816","MarkTitle":"Basic Template","MarkResult":"{\"tabId\":\"CommonExtensions\",\"annotations\":[{\"id\":null,\"labels\":{\"output\":\"weather_search(Hangzhou)\"},\"exif\":null}],\"type\":\"CommonExtensions\",\"version\":\"v2\"}","QuestionId":"CommonExtensions","ResultType":"OPEN_GROUP","Progress":null,"Version":"1753236218730","MarkTime":"Wed Jul 23 10:03:39 CST 2025","UserMarkResultId":"1947839975890939904","IsNeedVoteJudge":false}]},"abandonFlag":0,"abandonRemark":null}ターミナルで、次のPythonスクリプトを使用して、生成されたマニフェスト形式のアノテーション済みデータ結果ファイルをQuickStartに適したトレーニングデータ形式に変換できます。
import json # Input and output file paths input_file_path = 'test_json.manifest' output_file_path = 'train.json' converted_data = [] with open(input_file_path, 'r', encoding='utf-8') as file: for line in file: try: # Parse JSON data for each line data = json.loads(line) # Extract instruction instruction = data['data']['instruction'] # Iterate through all keys starting with "label-" for key in data.keys(): if key.startswith('label-'): # Extract MarkResult and parse its content mark_result_str = data[key]['results'][0]['MarkResult'] mark_result = json.loads(mark_result_str) # Parse MarkResult string as JSON # Extract labels["output"] from annotations output = mark_result['annotations'][0]['labels']['output'] # Build new data structure converted_data.append({ 'instruction': instruction, 'output': output }) break except Exception as e: print(f"Error processing line: {line.strip()}. Error: {e}") # Write converted data to output file with open(output_file_path, 'w', encoding='utf-8') as outfile: json.dump(converted_data, outfile, ensure_ascii=False, indent=4) print(f"Conversion completed. Output saved to {output_file_path}")出力はJSON形式ファイルです。
モデルのオフラインでのトレーニングと評価
モデルのトレーニング
QuickStartは、AIオープンソースコミュニティから優れた事前学習済みモデルを収集しています。QuickStartでは、コードを記述することなく、トレーニングからデプロイ、推論までの全プロセスを完了でき、モデル開発を大幅に簡素化します。
このソリューションでは、Qwen1.5-1.8B-Chat モデルを例として、QuickStartで準備したトレーニングデータを使用してモデルをトレーニングする方法を説明します。手順は次のとおりです。
-
モデルギャラリーページに移動します。
-
PAIコンソールにログインします。
-
左上隅でリージョンを選択します。
-
左側のナビゲーションウィンドウで、**[ワークスペース]** を選択し、対象ワークスペースの名前をクリックして入ります。
-
左側のナビゲーションウィンドウで、[クイックスタート] > [モデルギャラリー] を選択します。
-
QuickStartページで、右側のモデルリストから **Qwen1.5-1.8B-Chat** モデルカードを検索してクリックし、モデル詳細ページに移動します。
モデルの詳細ページで、右上隅にある Train をクリックします。次に、Train 構成パネルで、以下の主要なパラメーターを構成し、他のパラメーターにはデフォルト構成を使用します。
パラメーター
説明
Training Mode
全パラメーターファインチューニング: より多くのリソースを必要とし、トレーニングに時間がかかりますが、一般的に優れた結果が得られます。
説明パラメーターの少ないモデルは、全パラメーターファインチューニングをサポートしています。必要に応じてこのオプションを選択してください。
QLoRA: 軽量ファインチューニングを示します。全パラメーターファインチューニングと比較して、必要なリソースが少なく、トレーニング時間が短縮されますが、一般的に結果はわずかに劣ります。
LoRA: QLoRAと同じです。
Dataset configuration
Training dataset
準備したトレーニングデータセットを次のように選択します。
ドロップダウンリストで、OSS file or directory を選択します。
ボタンをクリックし、既存のOSSディレクトリを選択します。「Select OSS File」ダイアログボックスで、Upload File をクリックし、準備済みの学習用データセットファイルをドラッグ アンド ドロップして、OK をクリックします。
Output Configuration
Model output path
トレーニング出力構成ファイルとモデルファイルを保存するOSSディレクトリを選択します。
Tensorboard出力パス
Hyperparameter Configuration
ハイパーパラメーターの詳細な説明については、「表1. 全ハイパーパラメーターの説明」をご参照ください。
次の戦略を使用してハイパーパラメーターを設定します。異なるトレーニング方法の推奨主要ハイパーパラメーター構成については、「表2. 推奨ハイパーパラメーター構成」をご参照ください。
トレーニング方法に基づいてハイパーパラメーターを設定します。
Global batch size = number of cards × per_device_train_batch_size × gradient_accumulation_stepsトレーニング性能を最大化するには、カード数と`per_device_train_batch_size`を増やすことを優先します。
通常、グローバルバッチサイズは64~256に設定します。トレーニングデータ量が少ない場合は、必要に応じて減らしてください。
必要に応じてシーケンス長 (`seq_length`) を調整します。例えば、データセットの最大シーケンス長が50の場合、シーケンス長を64 (通常は2のべき乗) に設定します。
トレーニング損失の減少が遅すぎる、または収束しない場合は、学習率 (`learning_rate`) を上げてください。また、トレーニングデータの品質も確認してください。
まず、Fine-tune ボタンをクリックし、次に OK を Billing Notification ダイアログボックスでクリックします。
システムは自動的にトレーニングジョブ詳細ページにリダイレクトされます。トレーニングジョブが正常に開始されると、このページでトレーニングジョブステータスとトレーニングログを表示できます。

モデルのオフラインでの評価
モデルトレーニングが完了したら、ターミナルでPythonスクリプトを使用してモデル性能を評価できます。
評価データファイル`testdata.json`を準備します。例:
[ { "instruction": "Who sings the song 'Ten Years'?", "output": "music_query_player(Ten Years)" }, { "instruction": "What is the weather like in Hangzhou today?", "output": "weather_search(Hangzhou)" } ]ターミナルで、次のPythonスクリプトを使用してモデルをオフラインで評価できます。
#encoding=utf-8 from transformers import AutoModelForCausalLM, AutoTokenizer import json from tqdm import tqdm device = "cuda" # the device to load the model onto # Modify model path model_name = '/mnt/workspace/model/qwen14b-lora-3e4-256-train/' print(model_name) model = AutoModelForCausalLM.from_pretrained( model_name, torch_dtype="auto", device_map="auto" ) tokenizer = AutoTokenizer.from_pretrained(model_name) count = 0 ecount = 0 # Modify training data path test_data = json.load(open('/mnt/workspace/data/testdata.json')) system_prompt = 'You are an intent recognition expert. You can detect user intents and return the corresponding function calls and parameters.' for i in tqdm(test_data[:]): prompt = '<|im_start|>system\n' + system_prompt + '<|im_end|>\n<|im_start|>user\n' + i['instruction'] + '<|im_end|>\n<|im_start|>assistant\n' gold = i['output'] gold = gold.split(';')[0] if ';' in gold else gold model_inputs = tokenizer([prompt], return_tensors="pt").to(device) generated_ids = model.generate( model_inputs.input_ids, max_new_tokens=64, pad_token_id=tokenizer.eos_token_id, eos_token_id=tokenizer.eos_token_id, do_sample=False ) generated_ids = [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] pred = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0] if gold.split('(')[0] == pred.split('(')[0]: count += 1 gold_list = set(gold.strip()[:-1].split('(')[1].split(',')) pred_list = set(pred.strip()[:-1].split('(')[1].split(',')) if gold_list == pred_list: ecount += 1 else: pass print("Intent recognition accuracy:", count/len(test_data)) print("Parameter recognition accuracy:", ecount/len(test_data))説明コード実行結果がプロンプトメッセージ
Using low_cpu_mem_usage=True or a device_map requires Accelerate: pip install accelerateを返す場合、プロンプトに従ってpip install accelerateを実行して依存関係ライブラリをインストールしてください。
モデルサービスのデプロイと呼び出し
モデルサービスのデプロイ
モデル評価結果が期待を満たしている場合、次の手順を使用してトレーニング済みモデルをEASオンラインサービスとしてデプロイできます。
「Task details」ページで、右上隅のDeployをクリックします。システムが基本情報およびリソース情報を事前に設定します。Deployment MethodとしてvLLM Accelerated Deploymentを選択します。必要に応じて、これらの設定を変更できます。パラメーター設定を完了したら、Deployボタンをクリックします。
Billing Notification ダイアログボックスで、OK をクリックします。
自動的にデプロイタスクページにリダイレクトされます。Status が Running になると、サービスデプロイは成功です。
モデルサービスの呼び出し
次のAPI呼び出し例は、クライアントを介してリクエスト呼び出しを開始する方法を示しています。
サービスエンドポイントとトークンを取得できます。
[Service details] ページの [Basic Information] セクションで、[View Endpoint Information] をクリックします。

[Invocation Information] ダイアログボックスで、サービス エンドポイントとトークンを取得し、ローカルに保存します。
**vLLM高速デプロイ** を例として、呼び出しコードは次のとおりです。このコードをターミナルで実行してサービスを呼び出すことができます。
from openai import OpenAI ##### API Configuration ##### openai_api_key = "<EAS_SERVICE_TOKEN>" openai_api_base = "<EAS_SERVICE_URL>/v1/" client = OpenAI( api_key=openai_api_key, base_url=openai_api_base, ) models = client.models.list() model = models.data[0].id print(model) def main(): stream = True chat_completion = client.chat.completions.create( messages=[ { "role": "system", "content": [ { "type": "text", "text": "You are an intent recognition expert who can identify the intent from user questions and return the corresponding intent and parameters.", } ], }, { "role": "user", "content": [ { "type": "text", "text": "I want to listen to music", } ], } ], model=model, max_completion_tokens=2048, stream=stream, ) if stream: for chunk in chat_completion: print(chunk.choices[0].delta.content, end="") else: result = chat_completion.choices[0].message.content print(result) if __name__ == "__main__": main()ここで:
<EAS_SERVICE_URL>: 取得したサービスエンドポイントに設定します。
<EAS_SERVICE_TOKEN>: 取得したサービストークンに設定します。
参考資料
iTAG利用プロセスとアノテーションデータ形式要件の詳細については、「iTAG」をご参照ください。
EAS製品の詳細については、「Elastic Algorithm Service (EAS)」をご参照ください。
QuickStart機能を使用すると、Llama-3、Qwen1.5、Stable Diffusion V1.5などのシリーズモデルを含む、より多くのシナリオのデプロイとファインチューニングジョブを簡単に完了できます。詳細については、「モデルギャラリー利用事例のまとめ」をご参照ください。