ゼファーネットのロゴ

AWS Nitro Enclaves を使用した機密データに対する大規模な言語モデルの推論 |アマゾン ウェブ サービス

日付:

この投稿は、Leidos の Justin Miles、Liv d'Aliberti、Joe Kovba との共同執筆です。 

Leidos は、フォーチュン 500 の科学技術ソリューションのリーダーであり、防衛、諜報、国土安全保障、民間、医療市場における世界で最も困難な課題のいくつかに対処するために取り組んでいます。この投稿では、Leidos が AWS と協力して、プライバシーを保護する大規模言語モデル (LLM) 推論のアプローチを開発した方法について説明します。 AWS Nitro エンクレーブ.

LLM は、人間に似た言語を理解して生成するように設計されており、政府、医療、金融、知的財産などの多くの業界で使用されています。 LLM は、チャットボット、コンテンツ生成、言語翻訳、感情分析、質問応答システム、検索エンジン、コード生成など、幅広い用途に使用できます。 LLM ベースの推論をシステムに導入すると、モデルの漏洩、データ プライバシーの侵害、意図しない LLM ベースのサービス操作などのプライバシーの脅威が発生する可能性があります。 LLM が推論中に機密情報を公開しないようにするには、技術的なアーキテクチャを実装する必要があります。

この投稿では、Nitro Enclaves が LLM モデルの展開、特に個人を特定できる情報 (PII) または保護された医療情報 (PHI) を使用する展開の保護にどのように役立つかについて説明します。この投稿は教育目的のみを目的としており、追加の制御なしで実稼働環境で使用しないでください。

LLM と Nitro Enclave の概要

潜在的な使用例は、PII と PHI を含む質問応答サービスを実行するように設計された LLM ベースの機密性の高いクエリ チャットボットです。現在の LLM チャットボット ソリューションのほとんどは、セキュリティ上の懸念から、質問を入力するときに PII または PHI を含めるべきではないことをユーザーに明示的に通知しています。これらの懸念を軽減し、顧客データを保護するために、サービス所有者は主に次のようなユーザー保護に依存しています。

  • 墨消し – 文書、テキスト、またはその他の形式のコンテンツ内の PII などの機密情報を特定し、隠蔽するプロセス。これは、応答を自動的に編集するようにトレーニングされたモデルまたは LLM に送信される前に、入力データを使用して実現できます。
  • マルチファクタ認証 – LLM にアクセスするためにユーザーが自分の身元を確認するために複数の認証方法を提供することを要求するセキュリティ プロセス。
  • トランスポート層セキュリティ(TLS) – ユーザーと LLM サービスの間で転送されるデータのプライバシーを強化する安全な通信を提供する暗号化プロトコル。

これらの実践によりサービスのセキュリティ体制は強化されますが、すべての機密性の高いユーザー情報や、ユーザーが知らないうちに存続する可能性のあるその他の機密情報を保護するには十分ではありません。

この使用例では、LLM サービスは、従業員の医療給付に関する質問に答えたり、個人の退職金制度を提供したりするように設計されています。次のサンプル アーキテクチャを分析して、データ プライバシーのリスク領域を特定してみましょう。

llm-リスクエリア図

図 1 – データ プライバシーのリスク領域の図

潜在的なリスク領域は次のとおりです。

  1. 特権ユーザーは、サーバーを収容するインスタンスにアクセスできます。サービスに対する意図的でない、または許可されていない変更により、機密データが意図しない方法で漏洩する可能性があります。
  2. ユーザーは、サービスがアプリケーション ログに機密情報を公開したり保持したりしないことを信頼する必要があります。
  3. アプリケーション パッケージを変更すると、サービスが変更され、機密データが漏洩する可能性があります。
  4. インスタンスにアクセスできる特権ユーザーは、サービスで使用される LLM に無制限にアクセスできます。変更により、誤った情報または不正確な情報がユーザーに返される可能性があります。

Nitro Enclaves は、さらなる隔離を提供します。 アマゾン エラスティック コンピューティング クラウド (Amazon EC2) インスタンスにより、使用中のデータを管理者レベルのユーザーを含む不正アクセスから保護します。上記のアーキテクチャでは、意図しない変更により機密データがプレーンテキストで保存され、そのデータにアクセスする必要のないユーザーに誤って公開される可能性があります。 Nitro Enclaves を使用すると、EC2 インスタンスから隔離された環境を作成し、CPU とメモリのリソースをエンクレーブに割り当てることができます。このエンクレーブは、非常に制限の厳しい仮想マシンです。エンクレーブ内で機密データを処理するコードを実行すると、親プロセスはエンクレーブ データを表示できなくなります。

Nitro Enclaves には次の利点があります。

  • メモリとCPUの分離 – Nitro Hypervisor を利用して、エンクレーブの CPU とメモリを親インスタンスのユーザー、アプリケーション、ライブラリから分離します。この機能は、エンクレーブとソフトウェアを分離するのに役立ち、意図しないイベントが発生する表面積を大幅に削減します。
  • 個別の仮想マシン – エンクレーブは、機密性の高いデータをさらに保護し、安全に処理するために EC2 インスタンスに接続された分離された仮想マシンです。
  • インタラクティブなアクセスはありません – エンクレーブは、親インスタンスとの安全なローカル ソケット接続のみを提供します。永続的なストレージ、対話型アクセス、外部ネットワークはありません。
  • 暗号証明書 – Nitro Enclaves のオファー 暗号証明書、エンクレーブの ID を証明し、許可されたコードのみがエンクレーブで実行されていることを確認するために使用されるプロセス。
  • AWSの統合 – Nitro Enclaves は次のものと統合されています AWSキー管理サービス (AWS KMS) を使用すると、エンクレーブ内で AWS KMS を使用して暗号化されたファイルを復号化できます。 AWS証明書マネージャー Nitro Enclaves の (ACM) を使用すると、Nitro Enclaves を備えた EC2 インスタンスで実行されている Web アプリケーションやサーバーでパブリックおよびプライベート SSL/TLS 証明書を使用できます。

Nitro Enclaves が提供するこれらの機能を使用すると、PII および PHI データに関連するリスクを軽減できます。機密性の高いユーザー データを処理する場合は、LLM サービスに Nitro Enclaves を含めることをお勧めします。

ソリューションの概要

Nitro Enclaves を含むサンプル サービスのアーキテクチャを調べてみましょう。次の図に示すように、Nitro Enclaves を組み込むことにより、LLM は PHI または PII データを処理するためのより安全なチャットボットになります。

llm-using-aws-nitro-enclaves-diagram

図 2 – ソリューション概要図

アプリケーションがエンクレーブ内でホストされている場合、PII、PHI、質問などのユーザー データは、要求と応答のプロセス全体を通じて暗号化されたままになります。推論中に実行される手順は次のとおりです。

  1. チャットボット アプリは一時的な AWS 認証情報を生成し、ユーザーに質問の入力を求めます。 PII または PHI が含まれる可能性がある質問は、AWS KMS 経由で暗号化されます。暗号化されたユーザー入力は一時的な認証情報と結合されて、暗号化されたリクエストが作成されます。
  2. 暗号化されたデータは、Flask がホストする HTTP サーバーに POST リクエストとして送信されます。機密データを受け入れる前に、このエンドポイントを HTTPs 用に構成する必要があります。
  3. クライアント アプリは POST リクエストを受信し、安全なローカル チャネル (vsock など) 経由で Nitro Enclaves 内で実行されているサーバー アプリに転送します。
  4. Nitro Enclaves サーバー アプリは、一時的な認証情報を使用してリクエストを復号化し、LLM にクエリを実行し、応答を生成します。モデル固有の設定はエンクレーブ内に保存され、暗号化証明書で保護されます。
  5. サーバー アプリは、同じ一時認証情報を使用して応答を暗号化します。
  6. 暗号化された応答は、POST リクエストからの応答として、クライアント アプリを通じてチャットボット アプリに返されます。
  7. チャットボット アプリは、KMS キーを使用して応答を復号化し、平文をユーザーに表示します。

前提条件

開始する前に、ソリューションをデプロイするには次の前提条件が必要です。

EC2インスタンスを設定する

EC2 インスタンスを構成するには、次の手順を実行します。

  1. を起動します r5.8xlarge を使用する EC2 インスタンス amzn2-ami-kernel-5.10-hvm-2.0.20230628.0-x86_64-gp2 AMI Nitro Enclaves が有効になっている状態。
  2. Nitro Enclaves CLI をインストールして、Nitro Enclaves アプリケーションを構築して実行します。
    • sudo amazon-linux-extras install aws-nitro-enclaves-cli -y
    • sudo yum install aws-nitro-enclaves-cli-devel -y
  3. Nitro Enclaves CLI のインストールを確認します。
    • nitro-cli –version
    • この投稿で使用されているバージョンは 1.2.2 です
  4. Git と Docker をインストールして Docker イメージを構築し、GitHub からアプリケーションをダウンロードします。インスタンス ユーザーを Docker グループに追加します ( は IAM インスタンス ユーザーです):
    • sudo yum install git -y
    • sudo usermod -aG ne <USER>
    • sudo usermod -aG docker <USER>
    • sudo systemctl start docker && sudo systemctl enable docker
  5. Nitro Enclaves アロケーターと vsock プロキシ サービスを開始して有効にします。
    • sudo systemctl start nitro-enclaves-allocator.service && sudo systemctl enable nitro-enclaves-allocator.service
    • sudo systemctl start nitro-enclaves-vsock-proxy.service && sudo systemctl enable nitro-enclaves-vsock-proxy.service

Nitro Enclaves は、vsock と呼ばれるローカル ソケット接続を使用して、親インスタンスとエンクレーブの間に安全なチャネルを作成します。

すべてのサービスが開始されて有効になったら、インスタンスを再起動して、すべてのユーザー グループとサービスが正しく実行されていることを確認します。

sudo shutdown -r now

Nitro Enclaves アロケーター サービスを構成する

Nitro Enclaves は、エンクレーブを実行するためにインスタンスの CPU とメモリの一部を指定する分離環境です。 Nitro Enclaves アロケーター サービスを使用すると、エンクレーブを実行するために親インスタンスから取得される CPU の数とメモリの量を指定できます。

テキスト エディタを使用してエンクレーブの予約リソースを変更します (このソリューションでは、十分なリソースを提供するために 8 つの CPU と 70,000 MiB メモリを割り当てます)。

vi /etc/nitro_enclaves/allocatory.yaml

AWS-Nitro-Enclaves-Allocator-Service-Config

図 3 – AWS Nitro Enclaves Allocator サービス構成

プロジェクトを複製する

EC2 インスタンスを構成した後、コードをダウンロードして、Nitro Enclaves 内の LLM を使用して機密性の高いチャットボットを実行できます。

更新する必要があります server.py LLM 応答を暗号化するために最初に作成した適切な KMS キー ID を含むファイルを作成します。

  1. GitHub プロジェクトのクローンを作成します。
    • cd ~/ && git clone https://<THE_REPO.git>
  2. プロジェクト フォルダーに移動して、 enclave_base を含む Docker イメージ Nitro Enclaves ソフトウェア開発キット (SDK) Nitro Hypervisor からの暗号化証明書ドキュメント用 (このステップには最大 15 分かかる場合があります):
    • cd /nitro_llm/enclave_base
    • docker build ./ -t “enclave_base”

LLM を EC2 インスタンスに保存する

応答を生成するための自然言語処理には、オープンソースの Bloom 560m LLM を使用しています。このモデルは PII および PHI に合わせて微調整されていませんが、LLM がエンクレーブ内でどのように生存できるかを示しています。 Dockerfile 経由でエンクレーブにコピーできるように、モデルを親インスタンスに保存する必要もあります。

  1. プロジェクトに移動します。
    • cd /nitro_llm
  2. モデルをローカルに保存するために必要な要件をインストールします。
    • pip3 install requirements.txt
  3. 実行する save_model.py モデルを保存するアプリ /nitro_llm/enclave/bloom ディレクトリ:
    • python3 save_model.py

Nitro Enclaves イメージをビルドして実行する

Nitro Enclaves を実行するには、アプリケーションの Docker イメージからエンクレーブ イメージ ファイル (EIF) を作成する必要があります。エンクレーブ ディレクトリにある Dockerfile には、エンクレーブ内で実行されるファイル、コード、および LLM が含まれています。

エンクレーブの構築と実行が完了するまでに数分かかります。

  1. プロジェクトのルートに移動します。
    • cd /nitro_llm
  2. エンクレーブ イメージ ファイルを次のようにビルドします。 enclave.eif:
    • nitro-cli build-enclave --docker-uri enclave:latest --output-file enclave.eif
AWS-Nitro-Enclave-Build-Result

図 4 – AWS Nitro Enclaves のビルド結果

エンクレーブが構築されると、一連の一意のハッシュとプラットフォーム構成レジスタ (PCR) が作成されます。 PCR は、ハードウェアとアプリケーションのアイデンティティを証明するための連続的な測定です。これらの PCR は暗号化証明に必要であり、KMS キー ポリシーの更新ステップで使用されます。

  1. からのリソースを使用してエンクレーブを実行します。 allocator.service (追加 --attach-console 最後の引数はエンクレーブをデバッグ モードで実行します):
    • nitro-cli run-enclave --cpu-count 8 --memory 70000 --enclave-cid 16 --eif-path enclave.eif

EIF ファイル サイズの少なくとも 4 倍を割り当てる必要があります。これは、 allocator.service 前の手順から。

  1. 次のコマンドを使用して、エンクレーブが実行されていることを確認します。
    • nitro-cli describe-enclaves
AWS-Nitro-Enclave-Describe-Command-Response

図 5 – AWS Nitro Enclave Describe コマンド

KMS キーポリシーを更新する

KMS キー ポリシーを更新するには、次の手順を実行します。

  1. AWS KMS コンソールで、 顧客管理キー ナビゲーションペインに表示されます。
  2. 前提条件として生成したキーを検索します。
  3. 選択する 編集 主要な政策について。
  4. 次の情報を使用してキー ポリシーを更新します。
    • あなたのアカウントID
    • IAM ユーザー名
    • 更新された Cloud9 環境インスタンスのロール
    • kms:Encrypt & kms:Decrypt
    • 条件ステートメントを使用して、PCR (PCR0、PCR1、PCR2 など) をキー ポリシーにエンクレーブします。

次の主要なポリシー コードを参照してください。

{
   "Version":"2012-10-17",
   "Id":"key-default-1",
   "Statement":[
      {
         "Sid":"Enable User permissions",
         "Effect":"Allow",
         "Principal":{
            "AWS":"arn:aws:iam:::user/"
         },
         "Action":[
            "kms:CreateAlias",
            "kms:CreateKey",
            "kms:DeleteAlias",
            "kms:Describe*",
            "kms:GenerateRandom",
            "kms:Get*",
            "kms:List*",
            "kms:TagResource",
            "kms:UntagResource",
            "iam:ListGroups",
            "iam:ListRoles",
            "iam:ListUsers"
         ],
         "Resource":"*"
      },
      {
         "Sid":"Enable Enclave permissions",
         "Effect":"Allow",
         "Principal":{
            "AWS":"arn:aws:iam:::role/"
         },
         "Action":[
            "kms:Encrypt",
            "kms:Decrypt"
         ],
         "Resource":"*",
         "Condition":{
            "StringEqualsIgnoreCase":{
               "kms:RecipientAttestation:PCR0":"",
               "kms:RecipientAttestation:PCR1":"",
               "kms:RecipientAttestation:PCR2":""
            }
         }
      }
   ]
}

チャットボット アプリを保存する

AWS アカウントの外部に存在する機密性の高いクエリのチャットボット アプリケーションを模倣するには、 chatbot.py アプリを作成し、Cloud9 環境内で実行します。 Cloud9 環境は、エンクレーブを実行している EC2 からのアクセス許可の関連付けを解除するために、一時的な認証情報としてそのインスタンス ロールを使用します。次の手順を実行します。

  1. Cloud9 コンソールで、作成した環境を開きます。
  2. 次のコードを次のような新しいファイルにコピーします。 chatbot.py メインディレクトリに移動します。
  3. 必要なモジュールをインストールします。
    • pip install boto3
    • Pip install requests
  4. Amazon EC2 コンソールで、Nitro Enclaves インスタンスに関連付けられた IP をメモします。
  5. URL変数を更新します http://<ec2instanceIP>:5001.
"""
Modules for a basic chatbot like application and AWS communications
"""
import base64
import requests
import boto3
 
def get_identity_document():
    """
    Get identity document for current EC2 Host
    """
    identity_doc = requests.get(
        "http://169.254.169.254/latest/dynamic/instance-identity/document", timeout=30)
    return identity_doc
 
def get_region(identity):
    """
    Get account of current instance identity
    """
    region = identity.json()["region"]
    return region
 
def get_account(identity):
    """
    Get account of current instance identity
    """
    account = identity.json()["accountId"]
    return account
 
def set_identity():
    """
    Set region and account for KMS
    """
    identity = get_identity_document()
    region = get_region(identity)
    account = get_account(identity)
    return region, account
 
def prepare_server_request(ciphertext):
    """
    Get the AWS credential from EC2 instance metadata
    """
    instance_prof = requests.get(
        "http://169.254.169.254/latest/meta-data/iam/security-credentials/", timeout=30)
    instance_profile_name = instance_prof.text
 
    instance_prof_json = requests.get(
        f"http://169.254.169.254/latest/meta-data/iam/security-credentials/{instance_profile_name}",
        timeout=30)
    response = instance_prof_json.json()
 
    credential = {
        'access_key_id': response['AccessKeyId'],
        'secret_access_key': response['SecretAccessKey'],
        'token': response['Token'],
        'region': REGION,
        'ciphertext': ciphertext
    }
    return credential
 
def get_user_input():
    """
    Start chatbot to collect user input
    """
    print("Chatbot: Hello! How can I assist you?")
    user_input = input('Your Question: ')
    return user_input.lower()
 
def encrypt_string(user_input, alias, kms):
    """
    Encrypt user input using AWS KMS
    """
    file_contents = user_input
    encrypted_file = kms.encrypt(KeyId=f'alias/{alias}', Plaintext=file_contents)
    encrypted_file_contents = encrypted_file[u'CiphertextBlob']
    encrypted_file_contents_base64 = base64.b64encode(encrypted_file_contents)
    return encrypted_file_contents_base64.decode()
 
def decrypt_data(encrypted_data, kms):
    """
    Decrypt the LLM response using AWS KMS
    """
    try:
        ciphertext_blob = base64.b64decode(encrypted_data)
        response = kms.decrypt(CiphertextBlob=ciphertext_blob)
        decrypted_data = response['Plaintext'].decode()
        return decrypted_data
    except ImportError as e_decrypt:
        print("Decryption failed:", e_decrypt)
        return None
 
REGION, ACCOUNT = set_identity()
  
def main():
    """
    Main function to encrypt/decrypt data and send/receive with parent instance
    """
    kms = boto3.client('kms', region_name=REGION)
    alias = "ncsnitro"
    user_input = get_user_input()
    encrypted_input = encrypt_string(user_input, alias, kms)
    server_request = prepare_server_request(encrypted_input)
    url = 'http://<EC2 Instance Private IP>:5001'
    x = requests.post(url, json = server_request)
    response_body = x.json()
    llm_response = decrypt_data(response_body["EncryptedData"], kms)
    print(llm_response)
 
if __name__ == '__main__':
    main()

  1. チャットボット アプリケーションを実行します。
    • python3 chat.py

実行中、端末はユーザー入力を求め、先ほどのアーキテクチャ図に従って安全な応答を生成します。

プライベートな質問と回答のチャットボットを実行する

Nitro Enclaves が EC2 インスタンス上で稼働しているため、チャットボットの PHI および PII の質問をより安全に行うことができます。例を見てみましょう。

Cloud9 環境内で、チャットボットに質問し、ユーザー名を提供します。

質問-メールにアクセスできません

図 6 – チャットボットに質問する

AWS KMS は質問を暗号化します。質問は次のスクリーンショットのようになります。

暗号化された質問

図 7 – 暗号化された質問

次に、それはエンクレーブに送信され、保護された LLM に要求されます。 LLM の質問と応答は、次のスクリーンショットのようになります (結果と暗号化された応答は、デバッグ モードでのみエンクレーブ内で表示されます)。

llmからの質問と回答

図 8 – LLM からの応答

次に、結果は AWS KMS を使用して暗号化され、復号化するために Cloud9 環境に返されます。

最終的な復号化された応答

図 9 – 最終的な復号化された応答

クリーンアップ

リソースをクリーンアップするには、次の手順を実行します。

  1. エンクレーブを収容するために作成された EC2 インスタンスを停止します。
  2. Cloud9 環境を削除します。
  3. KMS キーを削除します。
  4. EC2 インスタンスのロールと IAM ユーザー権限を削除します。

まとめ

この投稿では、Nitro Enclaves を使用して、PII および PHI 情報をより安全に送受信する LLM 質問応答サービスを展開する方法を紹介しました。これは Amazon EC2 にデプロイされ、エンクレーブは AWS KMS と統合されており、KMS キーへのアクセスが制限されているため、Nitro Enclaves とエンドユーザーのみがキーを使用して質問を復号化できます。

より大きなワークロードをサポートするためにこのアーキテクチャを拡張することを計画している場合は、モデル選択プロセスが EC2 リソースのモデル要件と一致していることを確認してください。さらに、最大リクエスト サイズと、それが HTTP サーバーとモデルに対する推論時間に与える影響を考慮する必要があります。これらのパラメーターの多くは、モデルと HTTP サーバーの設定を通じてカスタマイズできます。

ワークロードの特定の設定と要件を判断する最良の方法は、微調整された LLM を使用してテストすることです。この投稿には機密データの自然言語処理のみが含まれていましたが、このアーキテクチャを変更して、オーディオ、コンピューター ビジョン、またはマルチモダリティをサポートする代替 LLM をサポートすることができます。ここで強調されているのと同じセキュリティ原則は、あらゆる形式のデータに適用できます。この投稿の作成に使用したリソースは、次の場所から入手できます。 GitHubレポ.

このソリューションを自分の環境にどのように適応させるかをコメントセクションで共有してください。


著者について

ジャスティン・マイルズ 彼は、技術局傘下の Leidos デジタル モダナイゼーション セクターのクラウド エンジニアです。余暇には、ゴルフや旅行を楽しんでいます。

リヴ・ダリベルティ Office of Technology 傘下の Leidos AI/ML Accelerator の研究者です。 彼らの研究は、プライバシーを保護する機械学習に焦点を当てています。

クリス・レンゾ AWS 防衛および航空宇宙組織内のシニア ソリューション アーキテクトです。仕事以外では、暖かい気候と旅行のバランスを楽しんでいます。

ジョー・コブバ Leidos デジタル モダナイゼーション セクターの副社長です。自由時間には、フットボールの試合の審判やソフトボールを楽しんでいます。

スポット画像

最新のインテリジェンス

スポット画像