AzureのOpenAI周りの構築で躓いたこと

この記事は[NTTコムウェア AdventCalendar 2023](https://qiita.com/advent-calendar/2023/nttcomware) 18日目の記事です。

# はじめに
OpenAI ServiceがAzureで独占的に利用できるようになったことでGPTを使うためにAzureを初めて使ったという人も多くなってきたのではないかと思います。
今回はそんなOpenAI周りでAzureを使うにあたって躓いたポイントを紹介していきたいと思います。

# 1. 閉域網が使いにくい
社内でGPTを利用するにあたって様々なセキュリティ要件が決まっていると思いますが閉域網化しようとするといろいろと苦労します。

## まず各種サービスが高くなる
OpenAI Service/API Management/AI Search/FrontDoor/Functionsといったサービスをエンタープライズレベルとして閉域網化されたアーキテクチャを構築する場合いくらかかるでしょうか？

各種サービスでプライベートエンドポイントやVNET統合を利用するためには料金プランを上位のものにする必要があります。
この例ですと、API Managementは仮想ネットワークサポートしているPremiumプランが必要となりこれだけで40万円/月以上(2023/12現在)かかります。

ActiveDirectoryに関してもIP制限等の条件付きアクセスポリシーを利用しようと思うとPremiumプラン以上が必要になってきます。なおかつ、ActiveDirectoryのプランに関してはAzureポータル上から契約を上げられないためMicrosoftとの契約変更が必要になり手続き上の手間もかかかります。

AI SearchやFrontDoor等を使う場合もそれぞれ料金プランを上げないと閉域網化できないため、構成によっては最終的に月額70～80万円を覚悟することになります。

従量課金で使った分だけの料金で済むのがクラウドの大きなメリットだと思いますが、閉域網化する際の料金形態は固定でかかってくるものが多いためそう気軽に導入できるものではないでしょう。

## サービスによってVNETとの接続方法が異なる
これは特にPaaSを閉域網と接続する際に悩む部分なのですが、サービスによって閉域網化する際の名称や考え方が異なります。
 - OpenAI Service: プライベートエンドポイントで通信
 - App ServiceやFunctions: VNET統合で通信、外部へはプライベートエンドポイントへ送信
 - AI Search: プライベートエンドポイントで通信、外部へは共有プライベートアクセスで送信

PaaSはインターネットからのアクセスを前提として作られているせいかVNETと通信しようとすると無理に後付けしたような仕様と戦うことになり、かなりやりづらいです。

## 同一リージョン内の通信はprivate ipが利用される
- 例えば東日本リージョンにあるストレージと同じリージョン内にあるAI Searchで通信する際はprivate ipが利用される
- ストレージが西日本でAI Searchが東日本にある場合はpublic ipが利用される
- 問題となるのはストレージのIP制限はpublic ipにしか対応していないため、同一リージョン内の通信をIP制限することは仕様上不可能になっている。
- これが通信元も通信先も自身が管理しているリソースあればプライベートリンク等を活用することでセキュアな設定を可能とすることができるが、通信先が別組織等で他管理の場合は手の打ちようがない。
- 実際にとあるプロジェクトでは開発環境をAzure東日本リージョンに構築していたため、すべての東日本リージョンにあるリソースとの通信がprivate ipになってしまい大苦戦した。

## 閉域化するとCI/CDパイプラインが大変
DevOpsのPipelineを利用することでAzureへ簡単にデプロイすることができるわけですが、閉域化するとめんどくさいことになります。
- まず、DevOpsはエージェントを立ち上げてそのエージェントからデプロイ作業を実施しますがこの時エージェントは固定IPを持っていないため個別にネットワークを穴あけすることができません。
- 次に考えることとしては、リソースのネットワーク設定に信頼されたマイクロソフトサービスは通信を許可する、という設定があるためこれだ！と思って設定したわけですが、なぜかAzure DevOpsは信頼されたＭＳサービス一覧に入っておらず無理でした（入れといてくれよ！）
- 最後の手段として閉域網内に自前でカスタムエージェントを立ち上げてこれで毎回Pipelineを動かす方法で無事動かすことができましたが、比較的に大がかりなのでできればやりたくなかったというのが正直なところです。(ちなみに通常のVMではなくVMSSを使うのがおすすめです)

## 閉域化のまとめ
Azureの特にPaaSはRBACを前提として作られているものが多いと感じます。VNETを構成して閉域網化するよりも要件が許すのであればRBACでシステムを構成するのが変なことになり辛くおすすめです。

# 2. Functionsが使いにくい(サーバーレスとは言えない)
サーバーレスと言えば開発者はコードを書くことに集中できてその下回りのサーバーは意識しなくていいよ、というイメージかと思いますがFunctionsはこのイメージでいると痛い目に合います。(特にAWS Lambdaと比べると)

## コールドスタートが遅い
初回起動時やインスタンスがスケールする際には新しいインスタンスがスピンアップしてくるわけですが、この時間が遅いです。
3秒以上かかる場合が多々あり、場合によっては数十秒かかる場合もありWebAPIのバックエンドとして利用するには現実的ではないのかなと思います。（これでも昔よりは早くなってきているので今後Lambda並みに早くなってほしいところです）

回避するためにはホットスタンバイのような仕組みが用意されていますが、これはPremiumプランが必要となりますしPremiumプランでは通常のサーバーのように固定で料金もかかってきますのでサーバーレスのメリットである使った分だけ課金のメリットも失われてしまい微妙です。それなら通常のAppServiceを使えばいいじゃんと思ってしまいます。

## VNETとの通信はPremiumプラン以上
従量課金ではVNETと通信ができないため、閉域網化したい場合はPremiumが必須です。
ただPremiumですと前述の通りサーバーレスのメリットが消えてしまいます。

## OSの選択がある
サーバーを意識しなくていいのがサーバーレスなのにOSを選択とは何を言っているんだという感じもしますが、LinuxかWindowsの選択でいろいろ制約が変わります。
- Pythonを利用するにはLinuxを選択しなければならない(Windowsでは動かない)
- LinuxとWindowsで設定すべき環境変数が異なる
- 対応しているデプロイ方式もOSで差がある
  例えばRunFromPackageのデプロイ方式がVSCodeではWindowsでは対応しているが、LinuxではZipDdeployになっていたりと差がある
  
これ以外にもいろいろあると思いますが、基本的にwindowsのほうが対応は手厚いイメージです。一部PythonはLinuxしか対応していないようにLinuxでしかできないものもあるので注意は必要です。

# 3. AI Search(旧Cognitive Search)について
文章検索するために必要なデータソースとの接続から事前加工処理、文章検索まで一気通貫でやってくれる便利なサービスでGPTと合わせて使われることが多いかと思います。
ただ独自のパイプラインを構築する必要があり慣れるのに時間がかかるサービスでもあります。

## デバッグがつらい
- 入出力をチェーンしていってパイプランが構成されていますが、それぞれの入出力がどうなっているか公式ドキュメントと睨めっこしながらエラーと戦うことになります
- ポータル上にデバッガーが用意されているためデバッグ時は基本的にこれを利用するのがおすすめです
- ただしネットワーク制限してしまうとポータル上からデバッガーは動かなくなるので注意が必要です

## 3分50秒の制限
パイプライン上で自前の処理をしたい場合は、カスタムスキルというものを構成して処理を記載します。
- ただしこのカスタムスキルは3分50秒以内に必ず終わらせる必要があります。
- 3分50秒に収まるようにうまく並列度や処理量を調整する職人技みたいな作業を要します
- 全処理のうち1つでもタイムアウトするとパイプラインすべてが失敗するため余裕を持った設計が重要です
- 時間帯によってGPTの機嫌が悪かったりすると今まで動いていたものがタイムアウトしたりして苦戦しました

# おわりに
いろいろと愚痴に近いことも書きましたが、使いやすいサービスがAzureにはたくさんありますので今日紹介したようなポイントに気を付けながら皆様快適なクラウドライフを送りましょう！

---
- 記載の内容は2023/12時点のものとなります。
- 記載されている会社名、製品名、サービス名は、各社の商標または登録商標です。