BEACHSIDE BLOG

Azure と GitHub と C# が好きなエンジニアの個人メモ ( ・ㅂ・)و ̑̑

Azure OpenAI の Asynchronous Modified Filter (非同期変更フィルター) で Streaming のレスポンスを劇的改善する

Azure OpenAI でストリーミングのレスポンスを使うと、遅すぎて思ってたのと違うんだが...と思うことありませんか? それを解消する手段の一つが Asynchronous Modified Filter (非同期変更フィルター) です。

Asynchronous Modified Filter (非同期変更フィルター) とは

(前置き) コンテンツフィルターとは

「本家の OpenAI よりレスポンス遅いのなんで」「ストリーミングのレスポンスが本家 OpenAI の API と動きが違ってカックカク」みたいな話を聞きます。その原因として考えられるひとつが、Azure OpenAI Service の機能のひとつ「コンテンツフィルタ―」の影響です。

コンテンツフィルターは Azure OpenAI にデフォルトで備わっている機能で、敵対的なプロンプト (Adversarial Prompting) から守るためのフィルターです。

もう少しかみ砕くと、有害なコンテンツを出力させないようにしたりプロンプトインジェクションやジェイルブレイクから守るためのフィルターです。色々と設定ができますが、詳細を知りたい方は公式ドキュメントが参考になります。

Asynchronous Modified Filter (非同期変更フィルター) とは

コンテンツフィルターのデフォルトの機能だとコンテンツをバッファしてある程度たまったらフィルターします。バッファされた分の文字数がドバっとレスポンスされます。そのため streaming のレスポンスを UI で見るとすごーく微妙に感じます。

Asynchronous Modified Filter は、バッファなしですぐにコンテンツを返します。コンテンツフィルターのチェックは非同期で実行して問題があればちょっと遅れてシグナルを返します。これで本家の OpenAI に近い感じにストリーミングのレスポンスを返すことが可能になります。ずっと Azure OpenAI でデフォルトのコンテンツフィルターを使っていた場合、感動するくらいには変わります (※ 感動するかについては個人差あり)

早くなる理由を書いたのがそのままのデメリットにもなるようなトレードオフもあるので、先ほども紹介したドキュメントの中の "コンテンツストリーミング" のセクション (以下リンク) を確認しましょう。

Asynchronous Modified Filter のコンテンツフィルターをモデル (デプロイ) に適用する

ここからは Asynchronous Modified Filter の適用方法です。

現時点では申請が必要

以下のリンクに「申請ページはこちら」ってところから申請が必要です。

コンテンツフィルターの作成

Azure OpenAI Studio で "コンテンツフィルター" のメニューをクリック → 新規に作成するなら "カスタマイズ済みのフィルターを作成" をクリック。

コンテンツフィルター作成時に、「ストリーミングモード (省略可能) - プレビュー」で、非同期変更フィルター を選択して進めて作成すれば OK です。

モデル (デプロイ) への適用

既存のデプロイに適用するのであれば、Azure OpenAI Studio のメニュー "デプロイ" で対象のデプロイをクリックして "デプロイの編集" をクリックします。

詳細設定オプションの中で、先ほど作成したコンテンツフィルターを選んで保存すれば、あとは普通に使えます。

動作確認

動画取るのめんどかったのでここで載せませんが、通常のコンテンツフィルターでの Streaming のレスポンスを見慣れていた場合、 Asynchronous Modified Filter に変えて初めて Streaming のレスポンスを受け取った私は普通に感動しました。

※ Streaming のレスポンスが早くなると書くと語弊がありそうですが、UI でみるとスムーズに文字が流れるだけなので、トータルのレスポンスが短くなるわけではないです。軽く検証したところ数パーセント早くなる程度でしたので誤差かもくらい) 。 それでも UX は劇的に改善します (と個人的に感じています) 。

実装で気をつけたいポイント

Asynchronous Modified Filter を使ったときに限った話でもないですが、Contents Filter に引っかかったときに正しく処理するよう実装は気を付けましょう。細かい話は以下の公式ドキュメントに書かれています。

自分用に雑に streaming 時に気にすることをざっくりまとめると:

  • HTTP レスポンスステータスコード: 400 返ってきたときにはアウト (プロンプトインジェクションとかでがっつりフィルターに引っかかった場合即400が返るはず)
  • HTTP レスポンスステータスコード: 200 で返ってきたときでも "finish_reason":"content_filter" だったらアウト
    • レスポンスが id が空文字の場合、Prompt annotation message か Annotation message (Contents Filter の結果)。この時に "finish_reason":"content_filter" がくる場合がある。これ時点で streaming は止まる。
    • Streaming のレスポンスで id があるものは Completion token message (Assistant からの回答が入ってるやつ) 。この時はセーフ。

Azure OpenAI Service を監視するための第一歩 (Azure OpenAI Insights)

今回は、Azure workbooks を使って Azure OpenAI の Insights を監視する第一歩の踏み出し方って感じの話です。

監視をするには

Azure では、Azure portal からほとんどのリソースで "Metric" や "Log Analytics" を使って Insights を監視・分析することも可能です。
Azure OpenAI Service のリソースでももちろんリクエスト数やトークンの使用量などを確認したり、状況に応じてアラートをあげることが可能です。

ただ、本番環境で Azure OpenAI Service を利用することを考えると、サービスごとや顧客ごとで model をデプロイしてクオータを制御したりメトリックを監視するようになってくるようになり、慣れていないとどんなダッシュボードを作ろうか悩んだり、考え抜いたダッシュボードを作る手間が発生します。

今回のネタである Azure OpenAI Insights と名付けられた Azure workbook を構成すると、考えたり作る手間をなくして、汎用的かつカスタマイズ性に優れた監視のダッシュボードをサクッと構成できます。

ということでセットアップして、どんなメトリックがみれるかを確認していきます。

Azure OpenAI Insights の workbook をセットアップ

Azure portal で、上部検索バーで「azure workbooks」と入力して "Azure Workbooks" をクリックします。

Azure Workbooks の一覧が表示されるので、"Create" をクリックします。

Grallery が表示されるので、"New" をクリックします。

"Advanced Editor" のアイコンをクリックします。

ここで、一旦ブラウザの別タブを開き、以下の URL を開きます。

右上の方にある "Copy raw file" をクリックしてファイルの内容をコピーします。

さきほどまで開いていた Azure portal を開き、以下の操作をします。

  • Gallery Template が選択されていることを確認する (①)
  • ②の部分を一度すべて空にしてから、コピーした workbook の内容を貼り付ける
  • Apply をクリック (①)

上部の "Save" をクリックします。

Save As のウインドウが表示されるので、監視したいリソースにあった情報を入力して "Apply" をクリックすると、この workbook が保存されます。

これでセットアップは完了です。できた workbook をサクッと見ていきます。

Azure OpenAI Insights を確認する

この workbook を開いたら、まずは上部で Subscription や Azure OpenAI Service のインスタンス、Time range を絞り込むことができます。

そのすぐ下に "Overview", "Monitor", "Insights" の3つのタブがあるのでそれぞれ見ていきます。

Overview タブ

デフォルトで Overview タブが表示されます。リソースグループごとやリージョンごとの概要レベルのグラフが表示されます。ここはみたままで大した内容がないので説明は省きます。

Momitor タブ

Monitor タブを開くとそのすぐ下に、"Overview", "HTTP Requests", "Token-Based Usage" などそれぞれに特化したグラフが用意されています。

それぞれのメトリックが何を意味しているかは、UI 上で親切に説明してくれているのがいい感じです。また、以下のドキュメントでも確認可能です。

また、それぞれのグラフに "Open in Metric Explorer" のボタンがついてるので (下図の矢印)、ボタンをクリックして細かい時間軸で分析が可能です。

Insights タブ

Insights タブは Log Analytics の KQL での集計を利用するため、Azure OpenAI のリソースから diagnostic settings (診断設定) で Log Analytics への送る構成をしておく必要があります。構成方法は以下のドキュメントに書かれています。

あとは、Insights タブをクリックし、Log Analitics workspace を選択したらダッシュボードが見えます。

Insights タブ内で以下3つのタブに分かれています。

  • "Overview": HTTP Request 関連のダッシュボード
  • "By CallerIP": アクセスしてきた Client 側の IP 毎のダッシュボード
  • "All Logs": Request / Response のログ。細かい分析は Logs のアイコンをクリックして KQL でクエリして確認って感じ。

終わりに

ということで Azure OpenAI Insights のセットアップ方法とどんな感じで見れるかの話でした。

Workbook や Metric 自体がカスタマイズ性にも優れているので、ここを出発点に自分にあったダッシュボードにカスタマイズすることも容易ですね。
あとはこれを必要に応じてアラートを構成したり、Azure portal の Dashboard として構成しておけばより実用的に監視が捗ると思っています。

最後に、Azure OpenAI の監視については以下を読んでおくと基本的な知識が身に付くと思います。

Azure OpenAI の Code Interpreter を気軽に試す (2024年2月編)

Code Interpreter とは

Assistants 機能のひとつとして 2024年2月に追加されました。

  • まず Assisntants で既存にある Function calling は、自分で用意した関数のコードを、質問に応じて良しなに実行してくれる機能です。
  • それに対し Code interpreter は、ユーザーの質問に応じて Assistant が動的にコードを生成し実行して、回答を生成してくれる機能です。
    • Code interpriter の利用イメージとして、数学の問題を python のコードを生成して回答したり、データを与えることでグラフを生成してくれたりしますが、具体的な操作は後述します。
    • コードの生成や実行は Azure OpenAI 側で用意されたサンドボックス環境で実行されますので、使えるモジュールや機能に制限があります。
    • チャットで利用したコードやファイルは、他の Azure OpenAI の機能と同様に MS でサービス改善のために利用することはないのでご安心を。

Azure OpenAI での利用

2024年2月8日現在だと利用できるリージョンが少ないですので、とりあえず以下のドキュメントで使えるリージョンを確認しておきましょう。

自分でコードを実装してアプリに組み込むことが可能ですが、Azure OpenAI Studio の Playground でサクッと試すことが可能ですので、まずはここから始めるのが良いです。

Azure OpenAI Studio でのはじめ方

Azure OpenAI Studio (https://oai.azure.com) を開き、左側のメニューで Assistants (Preview) を選びます。

Code Interpreter を使うための準備

利用できないリージョンのリソースを使っていると以下の画面になります。

その場合は、使えるリージョンに Aazure OpenAI のリソースを作りましょう。2024年2月8日現在で日本からだと Australia East が近いです。

また、新しくリソースを作成したら model のデプロイも必要です。利用できる model もリージョンによって若干異なるので注意です。

model のバージョンについては料金が安くなった最新のバージョンを使いましょう。バージョンに関して詳しくは以下のブログで言及しています。

blog.beachside.dev

リソースを作成したら、Azure OpenAI Studio の右上の自分のアイコン付近をクリック → リソースの "Switch" をクリックして Assistants が利用できるリソースへ変更します。

これで、左側のメニュー "Assisntans" から Code interpreter が利用可能となります。

Code Interpreter を試す

あとは Assistants plyground で Assisntant をセットアップしていきます。下の方にある Code interpreter のトグルを ON にして、他の項目は適宜入力して "Save" をクリックすればセットアップです。

保存をすることで Assistant を永続的に保存できるため、後日 "Open" ボタンから再利用することもできるのもいいですね。

OpenAI では長らくある機能なので機能自体に新鮮味はないですが、軽くいじってみましょう。

数学の問題を試す

こんな問題を出してみました。正しい答えがでてますが、ChatGPT のように python のコードは表示されないのか。

ログを見てみましょう。Assistant playground では右側の Logs で API をコールしたログが記録されており、クリックするとその結果をみれたりするので便利です。 ということで Get run steps をクリックしてみます。

以下の json が表示されました。Code interpreter を利用していることが確認できます。

{
  "object": "list",
  "data": [
    {
      "id": "step_gGd9LbQTrZLwRgJ8SDJhlKDm",
      "object": "thread.run.step",
      "created_at": 1707380860,
      "run_id": "run_Z3JoCJAcplU0D1NyFxACrg6y",
      "assistant_id": "asst_HEdZc4jN70am9nWVVKLI03Ng",
      "thread_id": "thread_aO9R4Y831UNG4NTyZGvwMith",
      "type": "message_creation",
      "status": "completed",
      "cancelled_at": null,
      "completed_at": 1707380861,
      "expires_at": null,
      "failed_at": null,
      "last_error": null,
      "step_details": {
        "type": "message_creation",
        "message_creation": {
          "message_id": "msg_QvzJI3BukC4vSAl40HqJsc1m"
        }
      }
    },
    {
      "id": "step_Zq7Aou6UPd0C9dw7UGf52weJ",
      "object": "thread.run.step",
      "created_at": 1707380845,
      "run_id": "run_Z3JoCJAcplU0D1NyFxACrg6y",
      "assistant_id": "asst_HEdZc4jN70am9nWVVKLI03Ng",
      "thread_id": "thread_aO9R4Y831UNG4NTyZGvwMith",
      "type": "tool_calls",
      "status": "completed",
      "cancelled_at": null,
      "completed_at": 1707380860,
      "expires_at": null,
      "failed_at": null,
      "last_error": null,
      "step_details": {
        "type": "tool_calls",
        "tool_calls": [
          {
            "id": "call_6BofWwu80F1aKK9DEv09ZXSP",
            "type": "code_interpreter",
            "code_interpreter": {
              "input": "from sympy import symbols, Eq, solve\r\n\r\n# シンボル定義\r\nx, y = symbols('x y')\r\n\r\n# 方程式の設定\r\neq1 = Eq(x, 0.3*x + 5*y)\r\neq2 = Eq(100*x + 200*y, 1000)\r\n\r\n# 方程式を解く\r\nsolutions = solve((eq1, eq2), (x, y))\r\nsolutions[x]  # レンガ1個の重さを求める",
              "outputs": [
                {
                  "type": "logs",
                  "logs": "7.81250000000000"
                }
              ]
            }
          }
        ]
      }
    },
    {
      "id": "step_e9mJVVS3GZ46549jInuhUCyH",
      "object": "thread.run.step",
      "created_at": 1707380838,
      "run_id": "run_Z3JoCJAcplU0D1NyFxACrg6y",
      "assistant_id": "asst_HEdZc4jN70am9nWVVKLI03Ng",
      "thread_id": "thread_aO9R4Y831UNG4NTyZGvwMith",
      "type": "message_creation",
      "status": "completed",
      "cancelled_at": null,
      "completed_at": 1707380845,
      "expires_at": null,
      "failed_at": null,
      "last_error": null,
      "step_details": {
        "type": "message_creation",
        "message_creation": {
          "message_id": "msg_Wbj9Ww5YDeV5l7Log50KD55j"
        }
      }
    }
  ],
  "first_id": "step_gGd9LbQTrZLwRgJ8SDJhlKDm",
  "last_id": "step_e9mJVVS3GZ46549jInuhUCyH",
  "has_more": false
}

ちなみにコードを表示してとコメントすると、表示してくれます。

他の活用例

よくありそうな例を書いておきます。

  • Assistant set up の Files に分析させたいデータをアップロードして、チャットで指示して分析させたりチャートを作らせたりすることができます。
  • 後述で詳しく書きますが実行環境に pptx や xlsx を生成するモジュールも入っていたので、パワポの資料を作ることもできるはずです (が、試したら生成はしてくれたけど何度やってもファイルが破損してて開けなかった... まぁ OpenAI の方では普通にできるので、きっとどうにかなるでしょう...)

余談: Code Interpreter の実行環境はどうなってるのか

2024年2月8時点の pip list は以下です。つまりこの中にないライブラリを使うことはできないはず。それもどうにかしたければ Code Interpreter を諦めて Open Interpreter でも使う感じですかね。

👉ここをクリックして開くと pip list が表示されます👈

Package                    Version             
-------------------------- --------------------
absl-py                    2.1.0               
affine                     2.4.0               
aiohttp                    3.8.1               
aiosignal                  1.3.1               
analytics-python           1.4.post1           
anyio                      3.7.1               
anytree                    2.8.0               
argcomplete                1.10.3              
argon2-cffi                23.1.0              
argon2-cffi-bindings       21.2.0              
arviz                      0.15.1              
asn1crypto                 1.5.1               
asttokens                  2.4.1               
async-timeout              4.0.3               
attrs                      23.2.0              
audioread                  3.0.1               
Babel                      2.14.0              
backcall                   0.2.0               
backoff                    1.10.0              
backports.zoneinfo         0.2.1               
basemap                    1.3.2               
basemap-data               1.3.2               
bcrypt                     4.1.2               
beautifulsoup4             4.8.2               
bleach                     6.1.0               
blinker                    1.7.0               
blis                       0.7.11              
bokeh                      2.4.0               
branca                     0.7.1               
Brotli                     1.1.0               
cachetools                 5.3.2               
cairocffi                  1.6.1               
CairoSVG                   2.5.2               
camelot-py                 0.10.1              
catalogue                  2.0.10              
certifi                    2019.11.28          
cffi                       1.16.0              
chardet                    4.0.0               
charset-normalizer         2.1.1               
click                      8.1.7               
click-plugins              1.1.1               
cligj                      0.7.2               
cloudpickle                3.0.0               
cmudict                    1.0.18              
comm                       0.2.1               
compressed-rtf             1.0.6               
countryinfo                0.1.2               
cryptography               3.4.8               
cssselect2                 0.7.0               
cycler                     0.12.1              
cymem                      2.0.8               
Cython                     0.29.36             
databricks-sql-connector   0.9.1               
dbus-python                1.2.16              
debugpy                    1.8.0               
decorator                  4.4.2               
defusedxml                 0.7.1               
deprecat                   2.1.1               
dill                       0.3.8               
distro-info                0.23+ubuntu1.1      
dlib                       19.22.1             
dnspython                  2.5.0               
docx2txt                   0.8                 
ebcdic                     1.1.1               
EbookLib                   0.18                
einops                     0.3.2               
email-validator            2.1.0.post1         
entrypoints                0.4                 
et-xmlfile                 1.1.0               
exceptiongroup             1.2.0               
exchange-calendars         3.4                 
executing                  2.0.1               
extract-msg                0.28.7              
Faker                      8.13.2              
fastapi                    0.95.2              
fastjsonschema             2.19.1              
fastprogress               1.0.3               
ffmpeg-python              0.2.0               
ffmpy                      0.3.1               
filelock                   3.13.1              
Fiona                      1.8.20              
flask                      3.0.2               
Flask-CacheBuster          1.0.0               
Flask-Cors                 4.0.0               
Flask-Login                0.6.3               
folium                     0.12.1              
fonttools                  4.48.1              
fpdf                       1.7.2               
frozenlist                 1.4.1               
future                     0.18.3              
fuzzywuzzy                 0.18.0              
gensim                     4.1.0               
geographiclib              1.52                
geopandas                  0.10.2              
geopy                      2.2.0               
gradio                     2.2.15              
graphviz                   0.17                
gTTS                       2.2.3               
h11                        0.14.0              
h2                         4.1.0               
h5netcdf                   1.1.0               
h5py                       3.6.0               
hpack                      4.0.0               
html5lib                   1.1                 
httpcore                   1.0.2               
httptools                  0.6.1               
httpx                      0.26.0              
hypercorn                  0.14.3              
hyperframe                 6.0.1               
idna                       2.8                 
imageio                    2.33.1              
imageio-ffmpeg             0.4.9               
IMAPClient                 2.1.0               
imgkit                     1.2.2               
importlib-metadata         7.0.1               
importlib-resources        6.1.1               
iniconfig                  2.0.0               
ipykernel                  6.29.1              
ipython                    8.12.3              
ipython-genutils           0.2.0               
isodate                    0.6.1               
itsdangerous               2.1.2               
jax                        0.2.28              
jedi                       0.19.1              
Jinja2                     3.1.3               
joblib                     1.3.2               
json5                      0.9.14              
jsonpickle                 3.0.2               
jsonschema                 4.21.1              
jsonschema-specifications  2023.12.1           
jupyter-client             7.4.9               
jupyter-core               5.1.3               
jupyter-server             1.23.5              
jupyterlab                 3.4.8               
jupyterlab-pygments        0.2.2               
jupyterlab-server          2.19.0              
keras                      2.6.0               
kerykeion                  2.1.16              
kiwisolver                 1.4.5               
korean-lunar-calendar      0.3.1               
librosa                    0.8.1               
llvmlite                   0.41.1              
loguru                     0.5.3               
lxml                       5.1.0               
markdown2                  2.4.12              
markdownify                0.9.3               
MarkupSafe                 2.1.5               
matplotlib                 3.4.3               
matplotlib-inline          0.1.6               
matplotlib-venn            0.11.6              
mistune                    3.0.2               
mizani                     0.9.3               
mne                        0.23.4              
monotonic                  1.6                 
moviepy                    1.0.3               
mpmath                     1.3.0               
mtcnn                      0.1.1               
multidict                  6.0.5               
munch                      4.0.0               
murmurhash                 1.0.10              
mutagen                    1.45.1              
nashpy                     0.0.35              
nbclassic                  0.4.5               
nbclient                   0.9.0               
nbconvert                  7.15.0              
nbformat                   5.9.2               
nest-asyncio               1.6.0               
networkx                   2.6.3               
nltk                       3.6.3               
notebook                   6.5.1               
notebook-shim              0.2.3               
numba                      0.58.1              
numexpr                    2.8.6               
numpy                      1.21.2              
numpy-financial            1.0.0               
odfpy                      1.4.1               
olefile                    0.47                
opencv-python              4.5.2.54            
openpyxl                   3.0.10              
opt-einsum                 3.3.0               
orjson                     3.9.13              
oscrypto                   1.3.0               
packaging                  23.2                
pandas                     1.3.2               
pandocfilters              1.5.1               
paramiko                   3.4.0               
parso                      0.8.3               
pathlib-abc                0.1.1               
pathy                      0.11.0              
patsy                      0.5.6               
pdf2image                  1.16.3              
pdfkit                     0.6.1               
pdfminer.six               20191110            
pdfplumber                 0.5.28              
pdfrw                      0.4                 
pexpect                    4.9.0               
pickleshare                0.7.5               
Pillow                     8.3.2               
pip                        20.0.2              
pkgutil-resolve-name       1.3.10              
platformdirs               4.2.0               
plotly                     5.3.0               
plotnine                   0.10.1              
pluggy                     1.4.0               
pooch                      1.8.0               
preshed                    3.0.9               
priority                   2.0.0               
proglog                    0.1.10              
prometheus-client          0.19.0              
prompt-toolkit             3.0.43              
pronouncing                0.2.0               
psutil                     5.9.8               
ptyprocess                 0.7.0               
pure-eval                  0.2.2               
py                         1.11.0              
PyAudio                    0.2.11              
pycountry                  20.7.3              
pycparser                  2.21                
pycryptodome               3.20.0              
pycryptodomex              3.20.0              
pydantic                   1.10.2              
pydot                      1.4.2               
pydub                      0.25.1              
pydyf                      0.8.0               
pygments                   2.17.2              
PyGObject                  3.36.0              
pygraphviz                 1.7                 
PyJWT                      2.8.0               
pylog                      1.1                 
pyluach                    2.2.0               
pymc3                      3.11.5              
PyMuPDF                    1.19.6              
PyNaCl                     1.5.0               
pyOpenSSL                  21.0.0              
pypandoc                   1.6.3               
pyparsing                  3.1.1               
PyPDF2                     1.28.6              
pyphen                     0.14.0              
pyproj                     3.5.0               
pyprover                   0.5.6               
pyshp                      2.1.3               
pyswisseph                 2.10.3.2            
pytesseract                0.3.8               
pytest                     6.2.5               
pyth3                      0.7                 
python-apt                 2.0.1+ubuntu0.20.4.1
python-dateutil            2.8.2               
python-docx                0.8.11              
python-dotenv              1.0.1               
python-multipart           0.0.7               
python-pptx                0.6.21              
pyttsx3                    2.90                
pytz                       2024.1              
PyWavelets                 1.4.1               
pyxlsb                     1.0.8               
PyYAML                     6.0.1               
pyzbar                     0.1.8               
pyzmq                      25.1.2              
qrcode                     7.3                 
rarfile                    4.0                 
rasterio                   1.2.10              
rdflib                     6.0.0               
referencing                0.33.0              
regex                      2023.12.25          
reportlab                  3.6.1               
requests                   2.31.0              
requests-unixsocket        0.2.0               
resampy                    0.4.2               
rpds-py                    0.17.1              
scikit-image               0.18.3              
scikit-learn               1.0                 
scipy                      1.7.1               
seaborn                    0.11.2              
semver                     3.0.2               
Send2Trash                 1.8.2               
sentencepiece              0.1.99              
setuptools                 45.2.0              
shap                       0.39.0              
Shapely                    1.7.1               
six                        1.14.0              
slicer                     0.0.7               
smart-open                 6.4.0               
sniffio                    1.3.0               
snowflake-connector-python 2.7.12              
snuggs                     1.4.7               
sortedcontainers           2.4.0               
SoundFile                  0.10.2              
soupsieve                  2.5                 
spacy                      3.1.6               
spacy-legacy               3.0.12              
SpeechRecognition          3.8.1               
srsly                      2.4.8               
stack-data                 0.6.3               
starlette                  0.27.0              
statsmodels                0.13.1              
svglib                     1.1.0               
svgwrite                   1.4.1               
sympy                      1.8                 
tables                     3.6.1               
tabula                     1.0.5               
tabulate                   0.8.9               
tenacity                   8.2.3               
terminado                  0.18.0              
text-unidecode             1.3                 
textblob                   0.15.3              
textract                   1.6.4               
Theano-PyMC                1.1.2               
thinc                      8.0.17              
threadpoolctl              3.2.0               
thrift                     0.16.0              
tifffile                   2023.7.10           
tinycss2                   1.2.1               
toml                       0.10.2              
tomli                      2.0.1               
toolz                      0.12.1              
torch                      1.10.0              
torchaudio                 0.10.0              
torchtext                  0.6.0               
torchvision                0.11.1              
tornado                    6.4                 
tqdm                       4.64.0              
traitlets                  5.14.1              
trimesh                    3.9.29              
typer                      0.4.2               
typing-extensions          4.5.0               
tzlocal                    5.2                 
ujson                      5.9.0               
unattended-upgrades        0.1                 
urllib3                    1.25.8              
uvicorn                    0.27.0.post1        
uvloop                     0.19.0              
Wand                       0.6.13              
wasabi                     0.10.1              
watchfiles                 0.21.0              
wcwidth                    0.2.13              
weasyprint                 53.3                
webencodings               0.5.1               
websocket-client           1.7.0               
websockets                 10.3                
werkzeug                   3.0.1               
wheel                      0.34.2              
wordcloud                  1.8.1               
wrapt                      1.16.0              
wsproto                    1.2.0               
xarray                     2023.1.0            
xarray-einstats            0.5.1               
xgboost                    1.4.2               
xlrd                       1.2.0               
XlsxWriter                 3.1.9               
xml-python                 0.4.3               
yarl                       1.9.4               
zipp                       3.17.0              
zopfli                     0.2.3               

参考

.NET8 での Azure Functions の開発を始めるための準備 ( C# )

Azure Functions 開発入門として、.NET のバージョンが更新する度に Visula Studio 2022 での恒例の作業のなった Azure Functions のツールセットの更新の方法の話です。

Azure Functions に新しい .NET のバージョンが選べない?!

更新前の状態で Visual Studio 2022 を起動して Azure Functions のプロジェクトを作ろうとすると、.NET8 がない状態とします (去年スクショだけとっておいてよかった←ブログ書くの放置してた💦) 。

新しいバージョンないやん!と困ったときに、Azure Functions のツールセットの更新をすることで解決できる可能性は大です。

Azure Functions でツールセットの更新

Visual Studio 2022 が開いてない状態であれば "コードなしで続行" して起動し、上部のメニューで、"ツール" → "オプション" をクリックします。

"プロジェクトおよびソリューション" の中の "Azure Functions" → "更新の確認" → "ダウンロードしてインストール" をクリックします。画面上ダウンロードしてる雰囲気が出てないですが、 "ダウンロードしてインストール" のボタンが消えると更新完了です。

これで最新の状態なります。プロジェクトを作成すると、今回だと .NET 8 (Isolated) も表示されるようになりました (in-process ではない点注意!)。

isolated は,まだまだ完成度が高いとはいえないのでで、個人的には .NET 8 では in-process が来るのを待ちます。in-process については、公式だと以下のリンクで2024年はじめにはくる予定と書かれています。

.NET on Azure Functions – August 2023 roadmap update - Microsoft Community Hub

あとは、あまり頻度が高くないですが Azure Functions のプロジェクトのテンプレートの更新が来た時も使うので、.NET のバージョンだけでなくプロジェクト作成時のテンプレートが周りの人と違うなーとか古いなーってときにも更新してみるとよいかもしれませんね。

Azure OpenAI のモデルのバージョンの選び方 (2023年12月版)

2023年11月の OpenAI 側のアップデートによって Azure OpenAI のモデルのバージョンと最大トークン数、そして価格が更新され、そのモデルが Azure OpenAI では2023年12月に順次ロールアウトされて利用できるようになりました。

こらから新たに Azure OpenAI Service を試そうとしている方にとって、その更新を把握していないとたくさんのバージョンがあるけどどれを使えばいいのかわからんとなりそうです。

ということで Azure OpenAI 入門としてモデルのバージョンを軽く整理しておきます。

バージョンに関する基礎知識

2023年11月以前は、Azure OpenAI で利用されているモデルのバージョンは 03140613 でした。

2023年11月の OpenAI Dev Day でのアップデートによって、Azure OpenAI では 1106 (または 1106-preview) というバージョンが利用できるようになりました。そこでトークン数の上限も大きく変りました。

ということで、最初に覚えておきたいのは、GPT-4/GPT3.5 のモデルでは以下のことをおさえておくとよいです。

  • 基本的には新しいバージョンが性能良くて単価も安いと考えてよい。ただし、価格を正確に把握したい場合はドキュメント確認しよう。
  • 2023年12月時点では 1106 (または 1106-preview) のバージョンが単価が安く性能もいいので、このバージョンを使いましょう。
  • ただし、リージョンによっては 1106 (または 1106-preview) がまだ使えないので、その時は古いバージョンを選ぶようになります。
  • 価格は基本的に OpenAI に合わせてリリースされるとアナウンスされている。

GPT-4 シリーズ

0613 以前のバージョンではモデル ID で最大トークン数がわかれていました。とりあえず 0613 の GPT-4だと以下。

モデル ID バージョン 概要
gpt-4 0613 最大トークン数 8K
gpt-4-32k 0613 最大トークン数は 32K。価格は 8k のやつの2倍

↑これが古いモデルになります。

そこから2023年11月に 1106 が公開され、入力のトークン数が大きくなりました。
トークン数は大幅に増えたのに、価格はgpt-4 (0613):8Kよりも入力が1/3、出力は1/2になってお安くなりました。16kの価格と比べるとさらに安いということです。

※ API の価格は、OpenAI のと同等になるとアナウンスがあったためその情報に基づいて記載しています。確実な情報は公式ドキュメントを確認しましょう。

ということで以下テーブルが GPT-4シリーズの最新のバージョンのモデルで、性能的にもコスパ的にもおすすめになります。

モデル ID バージョン 概要
gpt-4 1106-preview OpenAI の GPT-4 Tourbo 。最大トークン数は入力が128K、出力は4K。
gpt-4 vision-preview OpenAI の GPT-4 Turbo with Vision Preview 。最大トークン数は入力が128K、出力は4K。

利用できるバージョンが限られているので、以下の公式ドキュメントを参考にリージョンを選びましょう。

また、価格は以下のドキュメントになります。

GPT-3.5 シリーズ

こちらも0613 以前の古いバージョンは、最大トークン数で モデル ID がわかれていました。

モデル ID バージョン 概要
gpt-35-turbo 0613 最大トークン数4K。
gpt-35-turbo-16k 0613 最大トークン数16K。API の価格は↑ 4k のやつの2倍。

<br<

ここから2023年11月の更新により新しい 1106 では、最大トークン数16kのみになり、価格もgpt-35-turbo (0613) の最大トークン数4k のやつよりちょっと安くなって提供されました。新しい 1106 のバージョンのモデルが使える場合はこれを使うのが性能的にもコスパ的にもおすすめになります。

モデル ID バージョン 概要
gpt-35-turbo 1106 最大トークン数は入力が16K、出力は4K。

その他 (DALL-E, Wisper, Embeddings)

最近更新が静かな Embeddings や、DALL-E や Wisper といったプレビューのモデルも先ほど紹介した通り、公式ドキュメントで状況を確認しながら利用しましょう。

まとめ

openai の v1 系での Azure OpenAI へのアクセス (Python)

11月6日の OpenAI Dev Day の時期に openai のライブラリ は v.0.x 系 (最終的には v0.28.1) から v1系にアップデートされました。

Azure OpenAI へのアクセス方法も breaking changes が発生しています。過渡期になり、openai のライブラリはバージョン指定をしておかないと突然動かなくなる可能性あるので要注意です。

ということでこの辺りの変更について先週やってたことを個人的にメモしておきます。

準備

今回私は VS Code 上で jupyter notebook を動かしながらやってます。もしさっと試したい方向けに、ざっくりですが私の準備作業からメモしておきます。

とりあえず .env ファイル作って Azure OpenAI の endpoint と api が定義しておきます。

AZURE_OPENAI_ENDPOINT=https://xxxxxxx.openai.azure.com/
AZURE_OPENAI_API_KEY=xxxxxqaaaaaabbbb

まずは requirements.txt にはこれだけ入れておく。

python-dotenv

あとは pip install -r requirements.txt をしてからだけ実行した状態にしておきます。

from dotenv import load_dotenv

load_dotenv()

notebook はこんな感じ。

Chat completions

Chat completions: v0.28.1 までの実装方法

requirements.txt で openai の version を 0.28.1 に固定して pip install しておきます。

python-dotenv
openai==0.28.1

今まではこんな感じでしたね。

import openai
import os

openai.api_type = "azure"
openai.api_key = os.getenv("AZURE_OPENAI_API_KEY")
openai.api_base = os.getenv("AZURE_OPENAI_ENDPOINT")
openai.api_version = "2023-05-15"

GPT_DEPLOYMENT_NAME = "gpt-4"

completion = openai.ChatCompletion.create(
        engine=GPT_DEPLOYMENT_NAME,
        messages=[
            {"role": "system", "content": "あなたは関西弁のチャットボットです"},
            {"role": "user", "content": "こんにちは"}
        ]
    )

answer = completion['choices'][0]['message']['content']
print(answer)

Chat completions: v1系での実装方法

requirements.txt で openai の version を 11/13時点で最新の 1.2.3 に固定して pip install しておきます。1.* とか 1.2.* でもいいかなぁと思いつつ、1.1.2 リリースの同日に 1.2.0 が出たりとバタバタしており、いきなり動かくなるリスクは最小限にしたいのでこのブログでは固定にしておきます (でも bug fix での update が多いので常に最新にしておきたいところ)。

python-dotenv
openai==1.2.3

で、v1 系からは client をインスタンス化して API にアクセスする感じに変わりました。私は古いやつよりこちらの方が好みです。

import os
from openai import AzureOpenAI

GPT_DEPLOYMENT_NAME = "gpt-4"

client = AzureOpenAI(
  azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT"), 
  api_key=os.getenv("AZURE_OPENAI_KEY"),  
  api_version="2023-12-01-preview"
)

completion = client.chat.completions.create(
    model=GPT_DEPLOYMENT_NAME,
        messages=[
            {"role": "system", "content": "あなたは博多弁のチャットボットです"},
            {"role": "user", "content": "こんにちは"}
        ]
)

print(completion.choices[0].message.content)

余談その1ですが、内部の実装をみると client をインスタンス化するときに deployment name を指定する方法もあったけど、先週はそこのコメントで書かれてる通りには動作しなかったので今回はふれないでおきます。

ちなみに Chat Completions の API で利用できる api_version は こちら に記載がありますが、2023年12月に 2023-12-01-preview が出ており、これを使うと json modeseed の指定も可能となっています。

余談その2ですが API のレスポンスには model_dump_json() ってメソッドがついてるのでレスポンスの確認はしやすくなりました。

Embeddings

Embeddings: v0.28.1 までの実装方法

v0.28.1 では numpy が必要でしたので requirements.txt はこうしておく必要がありました。

python-dotenv
openai==0.28.1
numpy

で、実装方法はこんな感じ。

import openai
import os

openai.api_type = "azure"
openai.api_key = os.getenv("AZURE_OPENAI_API_KEY")
openai.api_base = os.getenv("AZURE_OPENAI_ENDPOINT")
openai.api_version = "2023-05-15"

ADA_DEPLOYMENT_NAME = "text-embedding-ada-002"

text="こんにちは"

vector = openai.Embedding.create(input=text, deployment_id=ADA_DEPLOYMENT_NAME)["data"][0]["embedding"]

print(vector)

Embeddings: v1系での実装方法

v1系で明示的に numpy を入れる必要はなくなり、実装もこんな感じに。

import os
from openai import AzureOpenAI

ADA_DEPLOYMENT_NAME = "text-embedding-ada-002"

client = AzureOpenAI(
  azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT"), 
  api_key=os.getenv("AZURE_OPENAI_KEY"),  
  api_version="2023-12-01-preview"
)

text = "こんにちは"

vector = client.embeddings.create(input=text, model=ADA_DEPLOYMENT_NAME).data[0].embedding
print(vector)

ちなみに Embeddings の API で利用できる api_version は こちら に記載がありますが、こちらも今のところ 2023-05-15 のままでいっかって感じですかね。

あとは先ほども書きましたが、API のレスポンスには model_dump_json() ってメソッドがついてるのでレスポンスの確認はしやすくなりました (embeddings の結果はあんま確認しないか...)。

response = client.embeddings.create(input=text, model=ADA_DEPLOYMENT_NAME)
print(response.model_dump_json(indent=2))

Azure OpenAI のアクセスにネットワーク制限をする (サービスエンドポイント編)

今回は、Function App/App Service から Azure OpenAI へアクセスを仮想ネットワークのみにしたいというケースの話です。

Azure OpenAI へのアクセスを仮想ネットワークのみに限定することは可能ですが方法はいくつかあります。

そして Azure OpenAI のみに限らず世間では、 Azure での閉域網 = Private endpoint な傾向を感じています (←私の個人的な主観ですので統計データなどはありませぬ)。
サービスエンドポイントの知名度の低さなのだろうか。

サービスエンドポイントと private endopoint の違いを理解得ずとりあえず private endpoint を使うって話しになると、無駄に運用コストはかかるし設定はサービスエンドポイントに比べめんどくさくて良いことは何もないです。

ということで、今回のブログではサービスエンドポイントでの設定を書いていきます。

サービスエンドポイントについて

Azure OpenAI にサービスエンドポイントを構成するということを超ざっくり説明すると、Azure OpenAI へのアクセスを特定の仮想ネットワークのサブネットからしかアクセスできなくするということです。

我ながらさすがにざっくりすぎなので、ちゃんとした説明は公式ドキュメントを見ていただければと思っていますが、それよりも日本マイクロソフトのサポートチームのブログが一番わかりやすいと個人的に思っているのでリンクをはっておきます。

これをみて違いを理解し、それでも Private endpoint を使う理由がある場合のみに利用すればよいものと思っています。

jpaztech.github.io

Function App/App Service と Azure OpenAI 間でサービスエンドポイントを構成する

要点

今回の具体的なユースケース例は以下とします。

  • Function App は HttpTriger (つまり Web API) で、認証したユーザーのみがアクセス可能
  • Azure OpenAI は Function App からのアクセスのみに制限したい

これをサービスエンドポイントを構成する観点で書くとこうなります。

  • Function App の outbound の通信 (つまり Azure OpenAI へのアクセス)を、仮想ネットワーク統合(VNet 統合 / VNet integration) 機能によって特定の VNet / subnet 経由に限定する。
    • outbound の設定であり、Function App への inbound ではない点には注意。inbound は別の設定になる。
    • Function App/App Servcie で VNet 統合を利用するには特定のプランである必要があります。こちらの公式ドキュメント のドキュメントをご確認ください。
  • Azure OpenAI は特定の VNet の subnet からのアクセスのみに制限する (サービスエンドポイントとして構成する) 。

Function App で VNet 統合を構成する

ということで、Function App の Outbund の設定からしていきましょう。Azure ポータルで Function App のリソースを開き (Web App でも一緒) > "Networking" をクリックします。ブラウザのウインドウサイズをある程度ひろげておくと、以下の配置で見えます。

注意点は先述していますが、大事なでもう一度書いておきます。

  • 特定以上のプランじゃないと VNet 統合は使えません。既存で Consumption plan を使っていた場合使えないので、VNet 統合を使いたい場合はどこかの App Service plan や Premium plan に相乗りなどを検討しましょう。
  • 図でわかるように Outbound の制限だということです。Inbound の制限は別になることを理解して混乱しないようにしましょう。

で、肝心の設定ですが、Outbound traffic の中にある VNet integration をクリックして VNet/sub net を選択 (もしくは新規に作成) すればおしまいです。超簡単です。

Azure OpenAI の設定

先ほど指定した VNet / Sub net を指定するだけですが手順を書いていきます。

Azure portal で Azure OpenAI のリソースを開き "Networking" をクリック > "Selected Networks and Private Endpoints" をクリック > "+Add existing virtual network" をクリックします。

Function App の Outbound で指定した VNet と Subnet の指定をして "Add" ボタンをクリックします。

初めてだと、同じブレードでもう一度ボタンをクリックが必要になるはずなので、クリックします。

(私の環境のリソースが初めて作るのじゃないから表示されなかった...)

最後に "Save" ボタンをクリックします。これで設定完了。予想よりもクリックするボタンが多いことがあるので注意ってだけです。

これで、この Azure OpenAI のリソースは今回指定した Subnet からのアクセスからしか受け付けなくなりました。

まとめ

Service endpoint ですむケースには Service endpoint を使いましょう。

参考

Azure AI Studio (Azure OpenAI Studio) へアクセスできるユーザーを追加する

Azure OpenAI の登場で新たに Azure に来たユーザーも増え、まだ操作が慣れていないとアクセス許可どうすんねんと思う人も増えただろうと思ってのネタになります。

Azure ポータルで設定・確認する

今回は Azure ポータルでの操作を書いていきます。

Azure ポータルで IAM を変更

まず Azure Portal を開きます。

しょっぱなから余談ですが、Azure Portal を開くときは「azure portal」とかでググるよりもアドレスバーに直接「p」を打つと portal.azure.com が表示されるので (過去に Azure Portal を開いたかにも依存します) 、それで Enter キーをッターンした方が早いです。url が表示されない場合、何度かポータルを開いてると出てくるようになります。

話しは戻りますが、Azure Portal で OpenAI のリソースを開き "アクセス制御 (IAM)" > "追加" > "ロールの割り当ての追加" をクリックします。

※ ロールを付与する操作は強めの権限が必要ですので、ここがクリックできず disabled になっている場合は、管理者の方に操作できるロールをつけてもらうなどする必要があります。

また余談ですが、"アクセス制御 (IAM)" は基本的にどのリソースにもあり、ユーザーやグループなどのロールを制御します。リソースグループの "アクセス制御 (IAM)" でロールをなんらかの付与したら、そのリソースグループにあるリソースにも継承して同じロールが割り当てられるといった感じでロールが継承されて付与されます。

肝心などのロールを割り当てるかについては、モデルをデプロイしたりするなら "Cognitive Services OpenAI Contibutor" を選びます。

"Cognitive Services OpenAI User" はチャットのプレイグラウンドは使えますがデプロイとかできないので、検証したい開発者に割り当てるのは物足りない感じです。

「メンバーを選択する」をクリックして追加したいメンバーやグループを追加します。

ロールを割り当てたいメンバーが複数人いたり人の出入りが多いなら、事前にグループを作っておいて必要なメンバーをそのグループに含めて、権限はグループに対して付与するのが管理的には楽です。

追加したら、「レビューと割り当て」をクリックして登録します。

割り当てられたユーザーの確認

OpenAI のリソースを開き "アクセス制御 (IAM)" にある "ロールの割り当て" を開くと確認ができます。

Azure Pipelines で matrix の値を動的に設定したい (Azure DevOps)

Azure Pipelines で、Job は依存関係を設定しない場合は並列で動作します。
同じ処理だけどパラメーターだけ異なるような Job を複数構成したい場合、matrix を使うことでいい感じに YAML を書くことができます。

今回は、その matrix を構成を動的にセットする方法のメモです。

基本的な書き方

基本的な書き方はこんな感じ。これで 6行目からの job_a 完了後、13行目からの job_b で matrix を使っています。18行目から27行目で構成されている変数のセットを使って3つの Job が並列で動作します。

動作させるとこんな感じで job_b は3つが動作します。

先述のコードの18~27行目の matrix の定義は以下のように1行で書くことも書けます。

matrix: { proj1: { PramA: proj1-val-A, PramB: proj1-val-B }, proj2: { PramA: proj2-val-A, PramB: proj2-val-B }, proj3: { PramA: proj3-val-A, PramB: proj3-val-B } }

動的に値をセットする

これを動的にセットする場合は、先述で紹介した一行で書く感じで変数を渡せばいいんですが、ダブルクォーテーション付きの値を渡す必要があります。

以下の例は11行目で matrix にセットしたい値を普通に書いちゃってますが、この部分はやりたいようにスクリプトとかで動的に構成すればいいって話です。動的に出力された結果がここにあるように JSON で出力されるようにすれば動作するサンプルになります。

あとは12行目で変数としてセットして、その値を20行目で取得しています。matrix にセットする際に変数は Runtime expressions ($[xxx] って書き方)で構成する必要があるのもポイントです。 template expression とかだとエラーになります。

参考

自分用メモ:

  • pipeline-sandbox > matrix-sandbox repo

プロンプトエンジニアリングの基礎: 2/3 (C# +Azure.OpenAI SDK)

前回から引き続きで、DeepLearning.AIというサイトの無償コンテンツのひとつで OpenAI + Python の「ChatGPT Prompt Engineering for Developers」を受講して学んだことのまとめメモの2回目です。

  • プロンプトエンジニアリングの基礎: 1/3 (C# +Azure.OpenAI SDK)
    • プロンプトエンジニアリングにおける2大原則
  • プロンプトエンジニアリングの基礎: 2/3 (C# +Azure.OpenAI SDK) 👈 今ここ
    • プロンプトの育て方、文章要約、感情分析+α の Tips
  • プロンプトエンジニアリングの基礎: 3/3 (C# +Azure.OpenAI SDK)
    • 概要は後日更新予定

今回はこんな内容をまとめています。

準備

前回同様で、以下のようなベースのコードがあって try-and-error って region の中をいじっていきます。

using Azure.AI.OpenAI;
using Azure;

namespace Learning.PromptEngineering;

internal class Program
{
    private static async Task Main()
    {
        var options = OpenAIOptions.ReadFromUserSecrets();
        var client = new OpenAIClient(new Uri(options.Endpoint), new AzureKeyCredential(options.ApiKey));

        #region try-and-error


        var prompt = """

            """;

        #endregion

        var result = await GetChatCompletionAsync(client, options, prompt);
        Console.WriteLine(result);
    }

    private static async Task<string> GetChatCompletionAsync(OpenAIClient client, OpenAIOptions options, string prompt)
    {
        var chatCompletionsOptions = new ChatCompletionsOptions
        {
            MaxTokens = 1000,
            Messages =
            {
                new ChatMessage(ChatRole.User, prompt)
            }
        };

        var response = await client.GetChatCompletionsAsync(options.DeploymentName, chatCompletionsOptions);
        return response.Value.Choices[0].Message.Content;
    }
}

この構成の詳しくは以前の記事に書いています。

blog.beachside.dev

Iterative Prompt Development

いいプロンプトを作成するには、試して繰り返して開発するんだよって話しです。
製品の詳細が書かれた文章から製品概要を作成する例をもとに手法を学んでいきます。

ここでは、DeepLearning.AI で学んだ、プロンプトをトライアンドエラーでイテレーティブに作り上げていく基本的なプロセスの一例を示すのが目的なので、出力結果がほんまに適切に変わったかはあまりフォーカスしてない点はご了承くださいね。それやるともっと細かい話になってしまうので。

最初のプロンプト

まずは私が以下買おうと思ってる AsRock のグラボを題材にこんな factSheet (長文)と prompt を用意しました。

        // こちらから引用させて頂きました♪
        // https://pg.asrock.com/Graphics-Card/AMD/Radeon%20RX%207900%20XTX%20Phantom%20Gaming%2024GB%20OC/index.jp.asp
        var factSheet = """
            ## PRODUCT NAME:

            AMD Radeon RX 7900 XTX Phantom Gaming 24GB OC

            ## PRODUCT BRIEF

            - クロック:GPU /メモリ
              - ブーストクロック: 最大 2615MHz / 20Gbps
              - ゲームクロック: 2455MHz / 20Gbps
            - 主な仕様
              - AMD Radeon™ RX 7900 XTX GPU
              - 24GB GDDR6 on 384-Bit Memory Bus
              - 96 AMD RDNA 3 Compute Units (With Rt+Ai Accelerators)
              - 96MB AMD Infinity Cache™ Technology
              - PCI® Express 4.0 Support
              - 3 x 8 ピン 電源コネクタ
              - 3 x DisplayPort™ 2.1 / 1 x HDMI™ 2.1
            - 主な特徴
              - Polychrome SYNC
              - Phantom Gaming 3X Cooling System
              - Striped Ring Fan
              - Reinforced Metal Frame
              - スタイリッシュなメタルバックプレート
              - 0dB サイレントクーリング
              - Super Alloy Graphics Card

            ## PRODUCT FEATURES

            - Reverse Spin
              - The center fan spins reversely to lower turbulence and enhance air dispersion through the heatsink.
            - Phantom Gaming 3X Cooling System For Cool And Silent.
              - Crafted for the best balance between the thermal efficiency and silence by all the details.
            - Striped Ring Fan Designed For Enhanced Airflow
              - ASRock’s all new Striped Ring Fan get more lateral intake and to provide better airflow through the cooling array.
            - Air Deflecting Fin Guide Airflow To Go Through Regularly & Quickly.
              - Guide the airflow to go more regularly and quickly to enhance the cooling efficiency by the V-shaped cutting fins and the V-shaped air vents.
            - Ultra-Fit Heatpipe Consolidated To Maximize The Contact.
              - The heatpipes are consolidated to maximize the contact among each others and also the GPU baseplate for the optimized heat dissipation.
            - Nickel-Plated Copper Base Maximize GPU Contact Area.
              - With premium copper base heatsink design, the direct contact area to the GPU would be maximized to improve thermal transfer effectively.
            - High-Density Metal Welding Improve Heat Dissipation.
              - Effectively isolate all coverage of the gap between pipe and stacked fins, hence improve heat dissipation effectively.
            - Nano Thermal Paste Perfect Thermal Teamwork.
              - Eliminate the gaps in the contact area to maximize heat transfer and thermal efficiency.
            - Premium Thermal Pad Better Heat Transfer.
              - The premium thermal pad helps to transfer the heat of the components to the heatsink, improving heat dissipation.
            - Precise Screw Torque Optimized Mounting Pressure.
              - ASRock adopts precise screw torque when assembling its graphics cards to optimize the cooler mounting pressure to improve thermal efficiency while avoiding damage to GPU die.
            - 0dB サイレントクーリング
              - 作業負荷が軽いときには、0dB サイレントクーリング技術がノイズなしにファンを完全に停止します。
            - Polychrome SYNC
              - 統合された ARGB LED を使用して、独自のカラフルな照明効果を作成してください。また、Polychrome SYNC に対応する ASRock マザーボードと同期させることもできます。
            - LED On/Off Switch On Or Off? Switch As You Want.
              - You can switch not only the built-in ARGB LEDs but also the ARGB LEDs equipping with the connected strips/devices at once.
            - ARGB Pin-Header More ARGB, More Fancy.
              - With the ARGB pin-header, it can connect ARGB strips/devices to make the lighting effects more rich and vivid.
            - 強化された金属製フレーム
              - 強化された構造で PCB が曲がることを防止します。
            - スタイリッシュなメタルバックプレート
              - Phantom Gaming ルックです。Phantom Gaming グラフィックスカードのスタイリッシュなメタルプレートは、おしゃれな外観で頑丈な構造です。さらに、裏側のサーマルパッドも熱効率を向上させます。
            - Japanese SP-Cap
              - With a high conductive polymer as the electrolyte, it has a lower equivalent series resistance (ESR) to provide outstanding electrical characteristics. In addition to that, it also has excellence in product operational life, reliability and heat resistance.
            - SPS (Smart Power Stage)
              - Dr.MOS design features the latest SPS (Smart Power Stage) technology. It’s optimized for monitoring current and temperature of each phase, thus delivering smoother and neater power to the GPU with enhanced performance and OC capability.
            - プレミアム 100A パワーチョーク
              - 従来のチョークと比較して、ASRock の新世代プレミアムパワーチョークは飽和電流を最大 3 倍まで効果的に増加させるため、マザーボードの Vcore 電圧が強化・向上します。
            - 2 オンスの銅 PCB
              - PCB レイヤー向けに厳選された銅材料を使用しています。2 オンスの銅 PCB は、オーバークロックの際に温度を低く抑えて、優れたエネルギー効率を提供します。
            - マットブラック PCB
              - 新しい神秘的なマットブラックと銅のカラースキームは ASRock のハイエンドマザーボードの最高のコンポーネントにぴったりです。
            - 高密度ガラス繊維 PCB
              - 高密度ガラス繊維 PCB 設計は、PCB レイヤー間の隙間を減らして、湿度による電気短絡からマザーボードを保護します。
            """;

        var prompt = $"""
            あなたのタスクは、製品の Fact sheet に基づいて、製品の販売 Web サイトでの説明文を作成することです。
            説明文は、日本語で作成する必要があります。
            以下の3つのバッククォートで区切られた Fact sheet の情報に基づいて、製品の概要を記述してください。

            Fact sheet: ```{factSheet}```
            """;

これを実行するとこんな感じで、440文字弱の説明文ができました。

文字数を制限する

文章を短くするなら、文字数や単語数や文章数の制約を付ける方法があります。今回はシンプルに「文字数は約100文字にしてください。」と指定してみました。

        var prompt = $"""
            あなたのタスクは、製品の Fact sheet に基づいて、製品の販売 Web サイトでの説明文を作成することです。
            説明文は、日本語で作成する必要があります。
            文字数は約100文字にしてください。

            以下の3つのバッククォートで区切られた Fact sheet の情報に基づいて、製品の概要を記述してください。

            Fact sheet: ```{factSheet}```
            """;

結果は... さっきより短くなってるけど約280文字。英語だとうまく制御できるやつもあれば、英語でもうまく指定通りにできることもあるので、うまくいかないときはもっとプロンプトを工夫したり MaxTokens を制御するとか必要そうですね。

誰を対象としてどんな内容を生成してほしいか

読み手に応じて文章はことなるものです。ということで、今回は、実際に購入するエンドユーザー向けではなく、PC パーツの小売業者向けと仮定して、それにあった文章を生成するようにしてみます。文字列制限はとりあえずはずしました。

        var prompt = $"""
            あなたのタスクは、製品の Fact sheet に基づいて、製品の販売 Web サイトでの説明文を作成することです。
            説明文は、日本語で作成する必要があります。
            この説明文は、PCパーツの小売業者を対象としています。そのため、製品の技術的な強みにフォーカスしてください。
            ただし、文章は500文字以内にまとめてください。
            
            Fact sheet: ```{factSheet}```
            """;

結果はこんな感じになりました。元々技術要素強めの文章ではありますが、気持ちは伝わった感じしますね。

出力形式の指定

最後にこんなプロンプトにして、出力形式を指定してみます。

        var prompt = $"""
            あなたのタスクは、製品の Fact sheet に基づいて、製品の販売 Web サイトでの説明文を作成することです。
            説明文は、日本語で作成する必要があります。
            この説明文は、PCパーツの小売業者を対象としています。そのため、製品の技術的な強みにフォーカスしてください。
            文章の構成として、"製品概要"1文章で完結に概要を説明し、
            そのあとに "PRODUCT BRIEF" を Markdown の Table で出力してください。
            
            Fact sheet: ```{factSheet}```
            """;

結果はこんな感じで出してくれました。まぁ...まぁってところでしょうか。

もとの学習コンテンツで伝えたいことは、思った回答じゃないときはその部分をより具体的に指示することを繰り返して改善していこうって話だと思いますが、前回学んだ原則をベースに改善していくことがプロンプトエンジニアリングの第一歩って感じの話でしたね。

文章要約のコツ

DeepLearning.AI のコンテンツの中では、いくつかのプロンプトの例から出力内容の改善をする流れをやっていました。
内容的にサンプルのコードを書くほどでもない気がしてるのでポイントだけ書くと、文章要約する際は要約したいポイントは明確に指示しようって話しでした。

例えば、商品レビューで商品の発送と配達にフォーカスしたい場合だと、以下のように指示しようって感じ。

  • あなたのタスクは Eコマース サイトから製品レビューの短い概要を生成し、配送部門にフィードバックを提供することです。以下にレビューおを最大200文字で要約し、製品の発送と配達について言及した側面に焦点を当ててください。

Inferring

ChatGPT でやれることとして、文章から感情を推測したりその文章に含まれているトピックやキーワードを抽出することも可能です。

例えば商品のレビューの文章に対して何かする場合、怒りの感情があるフィードバックなのか、なんの商品についてのフィードバックなのかを抽出することも可能で、そのプロンプトの例を書いていきます。

Sentiment の分析のプロンプト例:

三重のバッククォートで区切られた次の製品レビューの感情は何ですか?
「positive」または「negative」のいずれか1つの単語で答えてください。

怒りの感情があるかの例:

次のレビューの文章で、レビューアーは怒りの感情を持っていますか?   
レビューは3つのバッククォートで区切られています。  
「Yes」または「No」で答えてください。

商品名と製造会社(ブランド) を抽出例

レビューの文章から次の項目を特定します。

- レビューアーが購入した商品
- 商品を製造した会社

「Item」と「Brand」をキーとして応答を JSON オブジェクトとしてフォーマットします。  
情報が存在しない場合は、値として「unknown」を使用します。応答はできるだけ短くしてください。

実際のプロンプトで、先述のタスクを一度に実行してみます。コードは冒頭の「準備」のセクションで書いたやつに以下のを実行させてみます。

        var reviewText = """
            寝室におしゃれなランプが欲しかったのですが、これは追加の収納スペースもついているのに価格もそれほど高くありませんでした。
            発送中にランプのケーブルが切れてしまったようですが、会社はすぐに新しいものを送ってくれました。
            こちらも数日以内に届きました。組み立ても簡単でした。
            足りない部品があったのでサポートに連絡したところ、こちらもすぐに発送してくれました。
            ルミナは顧客と製品を大切にする素晴らしい会社と感じました。
            """;

        var prompt = $"""
            Review Text は 3 つのバッククォートで区切られています。
            あなたタスクは、Review Text から次のことを特定します。

            - 感情 ("Positive" または "Negative" のどちらかで回答)
            - レビューアーは、怒りの感情を持っているか ( "true" または "False" で回答)
            - レビューアーが購入した商品。情報が存在しない場合は "Item unknown" と回答。
            - 商品のブランド。情報が存在しない場合は "Brand unknown" と回答。

            回答はできるだけ短くしてください。

            Review Text: ``` {reviewText} ```
            """;

わかりやすいレビューだったので、いい感じに回答を得れました。

他にも色々試していい感じでした。例えば「開封済みの物が届いた。誰が使ったかもわからないので気分が悪いです。XXX から二度と商品を買いません。」(← XXX には実際はブランド名書いてます) って文章だと結果はこうなりました。

ということ感情の推論はかなりいい感じにできます。そうすると、JSON 形式でプロパティ名も指定して結果を出力させ、にして結果を自分たちの API に送り、怒りのレビューだったら API からアラートを出すみたいな機能は簡単に実現できそうですね。
こういうタスクのチェーンは Semantic Kernel とか LangChain とか使うと容易にできますが、そんな話はまた別の今後の記事で書ければと思っています。

終わりに

前回の内容と似たような感じですがここら辺は Zero-shot, Few-shot, CoT とかのその他諸々の基本的な手法に通じて、そういうのも意識しつつ次回もまとめていこうと思うところです。