すべてのプロダクト
Search
ドキュメントセンター

Platform For AI:LLM ベースの意図認識ソリューションを開発する

最終更新日:Sep 28, 2025

このソリューションは、大規模言語モデル (LLM) の意図認識技術を活用して、大量のデータから複雑な言語パターンとユーザーの行動パターンを学習します。これにより、ユーザーの意図をより正確に認識し、よりスムーズで自然な対話体験を提供できます。このトピックでは、Qwen1.5 大規模言語モデルを使用した LLM ベースの意図認識ソリューションの完全な開発プロセスについて説明します。

背景情報

意図認識とは

AI エージェントは、自然言語で記述されたユーザーの要件を解釈して、適切な操作を実行したり、関連情報を提供したりします。これらのエージェントは、インテリジェントな対話システムに不可欠なコンポーネントとなっています。LLM ベースの意図認識技術は、業界で大きな注目を集め、広く応用されています。

意図認識技術の典型的なシナリオ

  • インテリジェント音声アシスタントのシナリオでは、ユーザーは簡単な音声コマンドを使用して音声アシスタントと対話します。たとえば、ユーザーが音声アシスタントに「音楽を聴きたい」と言うと、システムはユーザーの要件が音楽を再生することであると正確に認識し、関連する操作を実行する必要があります。

  • インテリジェントカスタマーサービスのシナリオでは、さまざまな顧客サービスリクエストを処理し、それらを返品、交換、苦情などのさまざまなプロセスに迅速に分類することが課題となります。たとえば、ユーザーが e コマースプラットフォームの顧客サービスシステムに「不良品を受け取ったので返品したい」と言う場合があります。この場合、LLM ベースの意図認識システムは、ユーザーの意図が「商品を返品する」ことであると迅速に把握し、返品プロセスをトリガーして、ユーザーを後続の操作に誘導する必要があります。

作業プロセス

以下の図は、LLM ベースの意図認識ソリューションの作業プロセスを示しています。

image
  1. トレーニングデータを準備する

    特定のビジネスシナリオに合わせて、データ形式の要件とデータ準備戦略に基づいてトレーニングデータセットを準備する必要があります。また、データ準備戦略に基づいてビジネスデータを準備し、iTAG を使用して生データにラベルを付けることもできます。次に、ラベリング結果をエクスポートし、Platform for AI (PAI) の QuickStart でサポートされているデータ形式に変換して、後続のモデルトレーニングに備える必要があります。

  2. モデルのトレーニングとオフライン評価を実行する

    QuickStart では、Qwen1.5-1.8B-Chat モデルをトレーニングできます。モデルをトレーニングした後、オフライン評価を実行する必要があります。

  3. モデルサービスをデプロイして呼び出す

    モデルの評価結果が期待どおりであれば、QuickStart を使用して、トレーニング済みのモデルを Elastic Algorithm Service (EAS) にオンラインサービスとしてデプロイできます。

前提条件

このトピックで説明する操作を実行する前に、次の準備が完了していることを確認してください。

  • PAI の Deep Learning Containers (DLC) と EAS が従量課金ベースでアクティブ化され、デフォルトのワークスペースが作成されていること。詳細については、「PAI をアクティブ化し、デフォルトのワークスペースを作成する」をご参照ください。

  • トレーニングデータとモデルトレーニングから得られたモデルファイルを保存するために、Object Storage Service (OSS) バケットが作成されていること。バケットの作成方法については、「クイックスタート」をご参照ください。

トレーニングデータの準備

次のいずれかの方法でトレーニングデータを準備できます。

データ準備戦略

トレーニングの効果と安定性を向上させるために、次の戦略に基づいてデータを準備できます。

  • 単一意図認識シナリオでは、各タイプの意図に対して少なくとも 50 から 100 のデータレコードにラベルが付けられていることを確認してください。ファインチューニング後のモデルのパフォーマンスが期待どおりでない場合は、ラベル付けされたデータレコードの数を増やすことができます。さらに、各タイプの意図に対してラベル付けされたデータレコードの量が均衡していることを確認する必要があります。

  • 複数意図認識シナリオまたは複数ラウンドのチャットシナリオでは、ラベル付けされたデータレコードの量が単一意図認識シナリオの量の 20% を超えることを推奨します。また、複数意図認識または複数ラウンドのチャットシナリオに関与する意図は、単一意図認識シナリオで発生したものでなければなりません。

  • 意図の説明は、できるだけ多くの言い回しやシナリオをカバーする必要があります。

データ形式の要件

トレーニングデータは、instruction と output フィールドを含む JSON ファイルに保存する必要があります。output フィールドは、モデルによって予測された意図と関連パラメーターに対応します。次のサンプルコードは、さまざまな意図認識シナリオにおけるトレーニングデータの例を示しています。

  • 単一意図認識シナリオでは、特定のビジネスシナリオのビジネスデータを準備して LLM をファインチューニングする必要があります。次のサンプルコードは、スマートホームシナリオの単一ラウンドチャットの例を示しています。

    [
        {
            "instruction": "I want to listen to music",
            "output": "play_music()"
        },
        {
            "instruction": "Too loud, turn the sound down",
            "output": "volume_down()"
        },
        {
            "instruction": "I do not want to listen to this, turn it off",
            "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 kind of music?
    User: Play *** music.
    Assistant: play_music(***)

    複数ラウンドチャットのトレーニングデータは次の形式です。

    [
        {
            "instruction": "I want to listen to music. Play *** music.",
            "output": "play_music(***)"
        }
    ]

複数ラウンドチャットのモデルトレーニングのシーケンス長は大幅に長くなり、複数ラウンドチャットを使用する意図認識シナリオの数は限られています。単一ラウンドチャットモードがビジネス要件を満たせない場合にのみ、複数ラウンドチャットモードをモデルトレーニングに使用することをお勧めします。次のセクションでは、単一ラウンドチャットモードの例を使用して、完全なプロセスを説明します。

iTAG を使用したデータラベリング

次の手順を実行することで、PAI の iTAG でデータにラベルを付けて、特定の要件を満たすトレーニングデータセットを生成できます。

  1. iTAG ラベリングに使用するデータを PAI データセットに登録します。

    1. マニフェスト形式でデータファイルを準備します。詳細については、「データ準備戦略」をご参照ください。例:

      {"data":{"instruction": "I want to listen to music"}}
      {"data":{"instruction": "Too loud, turn the sound down"}}
      {"data":{"instruction": "I do not want to listen to this, turn it off"}}
      {"data":{"instruction": "I want to visit Hangzhou. Check the weather forecast for me"}}
    2. AI アセット管理 > データセット ページに移動し、対象のワークスペースを選択して、[データセットに入る] をクリックします。

    3. [データセットの作成] をクリックし、次の表で説明する主要なパラメーターを設定します。その他のパラメーターについては、「データセットの作成と管理」をご参照ください。

      パラメーター

      説明

      ストレージタイプ

      OSS を選択します。

      インポート形式

      ファイルを選択します。

      OSS パス

      作成した OSS ディレクトリを選択し、次の手順で準備したマニフェストファイルをアップロードします。

      1. image ボタンをクリックし、[OSS ファイルの選択] ダイアログボックスで [ファイルのアップロード] をクリックします。

      2. [ローカルファイルの表示] または [ファイルをドラッグアンドドロップ] をクリックして、プロンプトに従ってマニフェストファイルをアップロードします。

  2. データ準備 > iTAG ページに移動し、[管理ページへ移動] をクリックし、[テンプレート管理] タブに切り替えます。

  3. [テンプレートの作成] をクリックし、[カスタムテンプレート] > [基本テンプレート] を選択し、[編集] をクリックします。パラメーターを設定した後、[テンプレートの保存] をクリックします。次の表に、主要なパラメーターを示します。その他のパラメーターについては、「テンプレートの管理」をご参照ください。

    構成

    説明

    基本テンプレートキャンバス

    1. [テキスト] を選択し、[コンテンツカードの生成] をクリックします。image

    2. テキストエリアをクリックします。[データのインポート] ダイアログボックスで、既存のデータセットを選択します。[基本テンプレートの構成] セクションで、[データセットフィールド] > [instruction] を選択します。

    基本テンプレートの回答

    [入力フィールド] を選択し、[タイトルカードの生成] をクリックします。次に、[タイトル][output] に変更します。image

  4. 左側のナビゲーションウィンドウで、[管理ハブ] > [タスク管理] を選択します。[タスク管理] タブで、[タスクの作成] をクリックします。[ラベリングジョブの作成] ページで、パラメーターを設定し、[作成] をクリックします。次の表に、主要なパラメーターを示します。その他のパラメーターについては、「ラベリングジョブの作成」をご参照ください。

    パラメーター

    説明

    入力データセット

    ステップ 1 で作成したデータセットを選択します。

    説明

    データがテンプレートと一致している必要があることに注意してください。

    テンプレートタイプ

    [カスタムテンプレート] を選択し、ドロップダウンリストから既存のテンプレートを選択します。

  5. ラベリングジョブを作成した後、データにラベルを付けます。詳細については、「ラベリングジョブの処理」をご参照ください。image

  6. データにラベルを付けた後、ラベリング結果を 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":"Too loud, turn the sound down","_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 to this, turn it off","_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}
  7. ターミナルで、次の Python スクリプトを使用して、マニフェスト形式のラベリング結果ファイルを QuickStart に適したトレーニングデータ形式に変換します。

    import json
    
    # 入力ファイルパスと出力ファイルパス
    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:
                # 各行の JSON データを解析
                data = json.loads(line)
             
                # instruction を抽出
                instruction = data['data']['instruction']
              
                # "label-" で始まるすべてのキーを反復処理
                for key in data.keys():
                    if key.startswith('label-'):
                        # MarkResult を抽出し、その内容を解析
                        mark_result_str = data[key]['results'][0]['MarkResult']
                        mark_result = json.loads(mark_result_str)  # MarkResult 文字列を JSON として解析
                   
                        # アノテーションから labels["output"] を抽出
                        output = mark_result['annotations'][0]['labels']['output']
                     
                        # 新しいデータ構造を構築
                        converted_data.append({
                            'instruction': instruction,
                            'output': output
                        })
                        break
              
            except Exception as e:
                print(f"Error processing line: {line.strip()}. Error: {e}")
    
    # 変換されたデータを出力ファイルに書き込む
    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) コミュニティから高品質の事前学習済みモデルを統合しています。これにより、コードを記述することなく、モデルのトレーニング、デプロイ、推論までの完全なプロセスを実装できます。これにより、モデル開発プロセスが大幅に簡素化されます。

この例では、Qwen1.5-1.8B-Chat モデルを使用して、準備されたトレーニングデータを使用して QuickStart でモデルをトレーニングする方法を説明します。モデルをトレーニングするには、次の手順を実行します。

  1. モデルギャラリーページに移動します。

    1. PAI コンソールにログインします。

    2. 左上隅でリージョンを選択します。

    3. 左側のナビゲーションウィンドウで、[ワークスペース管理] を選択し、目的のワークスペースの名前をクリックします。

    4. 左側のナビゲーションウィンドウで、[クイックスタート] > [モデルギャラリー] を選択します。

  2. モデルギャラリーページのモデルリストで、Qwen1.5-1.8B-Chat モデルを検索してクリックします。

  3. モデル詳細ページの右上隅にある [トレーニング] をクリックします。[トレーニング] パネルで、次の表で説明する主要なパラメーターを設定します。他のパラメーターはデフォルト設定を使用します。

    パラメーター

    説明

    トレーニングモード

    • フルパラメーターファインチューニング: このモードはより多くのリソースを必要とし、トレーニング時間が長くなりますが、良好なトレーニング結果が得られます。

      説明

      パラメーター数が少ないモデルは、フルパラメーターファインチューニングをサポートします。必要に応じてフルパラメーターファインチューニングを選択してください。

    • QLoRA: これは軽量のファインチューニングモードです。フルパラメーターファインチューニングと比較して、Quantized Low-Rank Adaptation (QLoRA) は必要なリソースが少なく、トレーニング時間も短いですが、トレーニング結果はそれほど良くありません。

    • LoRA: このモードは QLoRA に似ています。

    データセット構成

    トレーニングデータセット

    準備されたトレーニングデータセットを選択するには、次の手順を実行します。

    1. ドロップダウンリストで [OSS ファイルまたはディレクトリ] を選択します。

    2. image ボタンをクリックして OSS ディレクトリを選択します。

    3. [OSS ファイルの選択] ダイアログボックスで、[ファイルのアップロード] をクリックし、準備したトレーニングデータセットファイルを空白の領域にドラッグして、[OK] をクリックします。

    出力構成

    ModelOutput パス

    出力構成ファイルとモデルファイルを保存する OSS ディレクトリを選択します。

    TensorboardOutput パス

    ハイパーパラメーター

    ハイパーパラメーターの詳細については、「表 1. 完全なハイパーパラメーター」をご参照ください。

    次の構成戦略に基づいてハイパーパラメーターを設定することをお勧めします。推奨されるハイパーパラメーター構成については、「表 2. 推奨されるハイパーパラメーター構成」をご参照ください。

    • さまざまなトレーニング方法に基づいてハイパーパラメーターを設定します。

    • グローバルバッチサイズ = GPU 数 × per_device_train_batch_size × gradient_accumulation_steps

      • トレーニングパフォーマンスを最大化するには、まず GPU の数を増やし、per_device_train_batch_size をより高い値に設定します。

      • ほとんどの場合、グローバルバッチサイズは 64 から 256 の範囲です。トレーニングデータが少ない場合は、グローバルバッチサイズを適切に減らすことができます。

    • 必要に応じて seq_length パラメーターを設定する必要があります。たとえば、データセット内のテキストシーケンスの最大長が 50 の場合、このパラメーターを 64 (2 のべき乗) に設定できます。

    • トレーニング損失の減少が遅すぎるか、収束しない場合は、learning_rate パラメーターで指定された学習率を上げることをお勧めします。また、トレーニングデータの品質が保証されているかどうかも確認する必要があります。

    表 1. 完全なハイパーパラメーター

    ハイパーパラメーター

    タイプ

    説明

    デフォルト値

    learning_rate

    FLOAT

    モデルトレーニングの学習率。

    5e-5

    num_train_epochs

    INT

    エポック数。

    1

    per_device_train_batch_size

    INT

    1 回のトレーニング反復で各 GPU が処理するデータ量。

    1

    seq_length

    INT

    テキストシーケンスの長さ。

    128

    lora_dim

    INT

    Low-Rank Adaptation (LoRA) または QLoRA トレーニングで使用される低ランク行列の内部次元。このパラメーターを 0 より大きい値に設定します。

    32

    lora_alpha

    INT

    LoRA または QLoRA の重み。このパラメーターは、lora_dim パラメーターを 0 より大きい値に設定した場合にのみ有効になります。

    32

    load_in_4bit

    BOOL

    モデルを 4 ビット量子化でロードするかどうかを指定します。このパラメーターは、lora_dim パラメーターを 0 より大きい値に設定し、load_in_4bit パラメーターを true に、load_in_8bit パラメーターを false に設定した場合にのみ有効になります。

    false

    load_in_8bit

    BOOL

    モデルを 8 ビット量子化でロードするかどうかを指定します。このパラメーターは、lora_dim パラメーターを 0 より大きい値に設定し、load_in_4bit パラメーターを false に、load_in_8bit パラメーターを true に設定した場合にのみ有効になります。

    false

    gradient_accumulation_steps

    INT

    勾配累積ステップ数。

    8

    apply_chat_template

    BOOL

    アルゴリズムがトレーニングデータをデフォルトのチャットテンプレートと組み合わせるかどうかを指定します。Qwen1.5 モデルは次の形式を使用します。

    • 質問: <|im_start|>user\n + instruction + <|im_end|>\n

    • 回答: <|im_start|>assistant\n + output + <|im_end|>\n

    true

    system_prompt

    STRING

    モデルトレーニングのデフォルトのシステムプロンプト。このパラメーターは、apply_chat_template パラメーターを true に設定した場合にのみ有効になります。Qwen1.5 モデルのトレーニング中にカスタムシステムプロンプトを設定して、LLM に特定のロールを割り当てることができます。アルゴリズムはトレーニングデータを自動的に拡張します。実行の詳細に注意を払う必要はありません。たとえば、system_prompt を「あなたは意図認識の専門家です。ユーザーの質問に基づいて意図を認識し、対応する意図とパラメーターを返すことができます。」に設定します。この場合、次のトレーニングサンプルが提供されます。

    [
        {
            "instruction": "I want to listen to music",
            "output": "play_music()"
        }
    ]

    トレーニングデータは次の形式です。

    <|im_start|>system\nYou are an intent recognition expert. You can recognize an intent based on user questions and return the corresponding intent and parameters<|im_end|>\n<|im_start|>user\nI want to listen to music<|im_end|>\n<|im_start|>assistant\nplay_music()<|im_end|>\n

    You are a helpful assistant

    表 2. 推奨されるハイパーパラメーター構成

    パラメーター

    フルパラメーターファインチューニング

    LoRA/QLoRA

    learning_rate

    5e-6 および 5e-5

    3e-4

    グローバルバッチサイズ

    256

    256

    seq_length

    256

    256

    num_train_epochs

    3

    5

    lora_dim

    0

    64

    lora_alpha

    0

    16

    load_in_4bit

    False

    True/False

    load_in_8bit

    False

    True/False

  4. [トレーニング] をクリックします。[請求通知] メッセージで、[OK] をクリックします。

    システムは自動的にトレーニングジョブの詳細ページに移動します。トレーニングジョブが実行された後、トレーニングジョブのステータスとトレーニングログを表示できます。image

モデルのオフライン評価

モデルをトレーニングした後、Python スクリプトを使用してターミナルでモデルを評価できます。

  1. 評価データファイル 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)"
        }
    ]
  2. ターミナルで、次の Python スクリプトを使用してモデルをオフラインで評価します。

    #encoding=utf-8
    from transformers import AutoModelForCausalLM, AutoTokenizer
    import json
    from tqdm import tqdm
    
    device = "cuda" # モデルをロードするデバイス
    
    # モデルのパスを変更します。
    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
    
    
    # トレーニングデータが保存されているパスを変更します。
    test_data = json.load(open('/mnt/workspace/data/testdata.json'))
    system_prompt = 'You are an intent recognition expert. You can recognize an intent based on user questions and return the corresponding function invocation 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 のオンラインサービスとしてデプロイできます。

  1. [タスク詳細] ページの右上隅にある [デプロイ] をクリックします。システムは基本情報とリソース情報を自動的に設定します。[デプロイメント方法] で、[VLLM 加速デプロイメント] を選択します。必要に応じてパラメーターを変更できます。パラメーターを設定した後、[デプロイ] をクリックします。

  2. [請求通知] メッセージで、[OK] をクリックします。

    システムは自動的にデプロイタスクページに移動します。[ステータス][実行中] の場合、サービスは正常にデプロイされています。

モデルサービスの呼び出し

次の例は、クライアントを使用して API を呼び出す方法を示しています。

  1. モデルサービスのエンドポイントとトークンを取得します。

    1. [サービス詳細] ページの [基本情報] セクションで、[呼び出し情報の表示] をクリックします。image

    2. [呼び出し情報] ダイアログボックスで、モデルサービスのエンドポイントとトークンを表示し、オンプレミスのマシンに保存します。

  2. 次の例は、vLLM 加速デプロイメント方法を使用してサービスを呼び出す方法を示しています。ターミナルでこのコードを実行してサービスを呼び出すことができます。

    from openai import OpenAI
    
    ##### API設定 #####
    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": "あなたは意図認識のエキスパートです。ユーザーの質問に基づいて意図を認識し、対応する意図とパラメーターを返すことができます。",
                        }
                    ],
                },
                {
                    "role": "user",
                    "content": [
                        {
                            "type": "text",
                            "text": "音楽を聴きたいです",
                        }
                    ],
                }
            ],
            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」をご参照ください。

  • PAI の QuickStart を使用して、Llama-3、Qwen1.5、Stable Diffusion V1.5 モデルなど、さまざまなシナリオでモデルをトレーニングおよびデプロイできます。詳細については、「シナリオ別の実践」をご参照ください。