次の方法で共有


チュートリアル: Phi-4 サイドカー拡張機能を使用して App Service でチャットボットを実行する (Express.js)

このチュートリアルでは、Azure App Service の Phi-4 サイドカー拡張機能と統合された Express.jsベースのチャットボット アプリケーションをデプロイする方法について説明します。 この手順に従って、スケーラブルな Web アプリを設定し、会話機能を強化するための AI を利用したサイドカーを追加し、チャットボットの機能をテストする方法について説明します。

独自の小さな言語モデル (SLM) をホストすると、いくつかの利点があります。

  • データを完全に制御できます。 機密情報は外部サービスに公開されません。これは、厳しいコンプライアンス要件を持つ業界にとって重要です。
  • セルフホステッド モデルは、特定のユース ケースまたはドメイン固有の要件を満たすように微調整できます。
  • ネットワーク待ち時間を最小限に抑え、応答時間を短縮し、ユーザー エクスペリエンスを向上させます。
  • リソースの割り当てを完全に制御し、アプリケーションの最適なパフォーマンスを確保します。

[前提条件]

サンプル アプリケーションをデプロイする

  1. ブラウザーで、 サンプル アプリケーション リポジトリに移動します。

  2. リポジトリから新しい Codespace を開始します。

  3. Azure アカウントでログインします。

    az login
    
  4. Codespace でターミナルを開き、次のコマンドを実行します。

    cd use_sidecar_extension/expressapp
    az webapp up --sku P3MV3
    

このスタートアップ コマンドは、Express.js アプリケーションを Azure App Service にデプロイするための一般的なセットアップです。 詳細については、「 Node.js Web アプリを Azure にデプロイする」を参照してください。

Phi-4 サイドカー拡張機能を追加する

このセクションでは、Azure App Service でホストされている ASP.NET Core アプリケーションに Phi-4 サイドカー拡張機能を追加します。

  1. Azure portal に移動し、アプリの管理ページに移動します。
  2. 左側のメニューで、[ デプロイ>展開センター] を選択します。
  3. [ コンテナー ] タブで、[ 追加>サイドカー拡張機能] を選択します。
  4. サイドカー拡張機能オプションで、[ AI: phi-4-q4-gguf (Experimental)]\(AI: phi-4-q4-gguf (試験段階)\) を選択します。
  5. サイドカー拡張機能の名前を指定します。
  6. [保存] をクリックして変更を適用します。
  7. サイドカー拡張機能がデプロイされるまで数分待ちます。 [状態] 列に [実行中] が表示されるまで、[最新の情報に更新] を選択し続けます。

この Phi-4 サイドカー拡張機能は、でチャット完了応答に応答できる http://localhost:11434/v1/chat/completionsチャット完了 API を使用します。 API を操作する方法の詳細については、次を参照してください。

チャットボットをテストする

  1. アプリの管理ページの左側のメニューで、[ 概要] を選択します。

  2. [ 既定のドメイン] で、ブラウザーで Web アプリを開く URL を選択します。

  3. チャットボット アプリケーションが実行され、ユーザー入力に応答していることを確認します。

    ブラウザーで実行されているファッション アシスタント アプリを示すスクリーンショット。

サンプル アプリケーションのしくみ

サンプル アプリケーションでは、Express.jsベースのサービスを SLM サイドカー拡張機能と統合する方法を示します。 SLMService クラスは、SLM API に要求を送信し、ストリーミングされた応答を処理するためのロジックをカプセル化します。 この統合により、アプリケーションは会話型応答を動的に生成できます。

use_sidecar_extension/expressapp/src/services/slm_service.jsを見ると、次のことがわかります。

  • サービスは、SLM エンドポイント http://127.0.0.1:11434/v1/chat/completionsに POST 要求を送信します。

    this.apiUrl = 'http://127.0.0.1:11434/v1/chat/completions';
    
  • POST ペイロードには、選択した製品とユーザー クエリから構築されたシステム メッセージとプロンプトが含まれます。

    const requestPayload = {
      messages: [
        { role: 'system', content: 'You are a helpful assistant.' },
        { role: 'user', content: prompt }
      ],
      stream: true,
      cache_prompt: false,
      n_predict: 2048 // Increased token limit to allow longer responses
    };
    
  • POST 要求は、応答を 1 行ずつストリームします。 各行が解析され、生成されたコンテンツ (またはトークン) が抽出されます。

    // Set up Server-Sent Events headers
    res.setHeader('Content-Type', 'text/event-stream');
    res.setHeader('Cache-Control', 'no-cache');
    res.setHeader('Connection', 'keep-alive');
    res.flushHeaders();
    
    const response = await axios.post(this.apiUrl, requestPayload, {
      headers: { 'Content-Type': 'application/json' },
      responseType: 'stream'
    });
    
    response.data.on('data', (chunk) => {
      const lines = chunk.toString().split('\n').filter(line => line.trim() !== '');
    
      for (const line of lines) {
        let parsedLine = line;
        if (line.startsWith('data: ')) {
          parsedLine = line.replace('data: ', '').trim();
        }
    
        if (parsedLine === '[DONE]') {
          return;
        }
    
        try {
          const jsonObj = JSON.parse(parsedLine);
          if (jsonObj.choices && jsonObj.choices.length > 0) {
            const delta = jsonObj.choices[0].delta || {};
            const content = delta.content;
    
            if (content) {
              // Use non-breaking space to preserve formatting
              const formattedToken = content.replace(/ /g, '\u00A0');
              res.write(`data: ${formattedToken}\n\n`);
            }
          }
        } catch (parseError) {
          console.warn(`Failed to parse JSON from line: ${parsedLine}`);
        }
      }
    });
    

よく寄せられる質問


価格レベルは SLM サイドカーのパフォーマンスにどのように影響しますか?

AI モデルではかなりのリソースが消費されるため、特定のモデルを実行するのに十分な vCPU とメモリを提供する価格レベルを選択します。 このため、組み込みの AI サイドカー拡張機能は、アプリが適切な価格レベルにある場合にのみ表示されます。 独自の SLM サイドカー コンテナーを構築する場合、App Service の価格レベルは CPU 専用レベルであるため、CPU 最適化モデルも使用する必要があります。

たとえば、 Hugging Face のコンテキスト長が 4K の Phi-3 ミニ モデル は、限られたリソースで実行するように設計されており、多くの一般的なシナリオに対して強力な数学と論理的な推論を提供します。 また、CPU 最適化バージョンも付属しています。 App Service では、すべての Premium レベルでモデルをテストし、 P2mv3 レベル以上で優れたパフォーマンスが得られたことがわかりました。 要件で許可されている場合は、下位レベルで実行できます。


自分の SLM サイドカーを使用する方法

サンプル リポジトリには、サイドカーとして使用できるサンプル SLM コンテナーが含まれています。 Dockerfile で指定されているように、ポート 8000 でリッスンする FastAPI アプリケーションを実行します。 アプリケーションでは、ONNX Runtime を使用して Phi-3 モデルを読み込み、HTTP POST データをモデルに転送し、モデルからクライアントに応答をストリームします。 詳細については、「model_api.py」を参照してください。

サイドカー イメージを自分でビルドするには、Docker Desktop をマシンにローカルにインストールする必要があります。

  1. リポジトリをローカルにクローンします。

    git clone https://github.com/Azure-Samples/ai-slm-in-app-service-sidecar
    cd ai-slm-in-app-service-sidecar
    
  2. Phi-3 イメージのソース ディレクトリに変更し、 Huggingface CLI を使用してモデルをローカルにダウンロードします。

    cd bring_your_own_slm/src/phi-3-sidecar
    huggingface-cli download microsoft/Phi-3-mini-4k-instruct-onnx --local-dir ./Phi-3-mini-4k-instruct-onnx
    

    Dockerfile は、./Phi-3-mini-4k-instruct-onnx からモデルをコピーするように構成されています。

  3. Docker イメージをビルドします。 例えば次が挙げられます。

    docker build --tag phi-3 .
    
  4. Docker CLI を使用して、最初のイメージを Azure コンテナー レジストリにプッシュして、ビルドされたイメージを Azure Container Registry にアップロードします。

  5. [Deployment Center>Containers (new) タブで、Add>Custom コンテナーを選択し、次のように新しいコンテナーを構成します。

    • 名前: phi-3
    • イメージ ソース: Azure Container Registry
    • レジストリ: あなたのレジストリ
    • 画像: アップロードされたイメージ
    • タグ: 目的の画像タグ
    • ポート: 8000
  6. を選択してを適用します。

このカスタム サイドカー コンテナーと対話するサンプル アプリケーションについては、 bring_your_own_slm/src/webapp を参照してください。

次のステップ

チュートリアル: Azure App Service で Linux アプリのサイドカー コンテナーを構成する