GPU - TECH PLAY - TECH PLAY

TECH PLAY

GPU

むベント

マガゞン

技術ブログ

Amazon EC2 で AMI 䞊で利甚できるむンスタンスタむプを指定できるようになりたした 「このAMI、うっかり関係ないむンスタンスタむプで起動されお起動倱敗した」みたいな事故、地味に起きがちです。 今回、AMI偎に利甚できるむンスタンスタむプを定矩できるアップデヌトが入ったので、実際に觊っお挙動を確認しおみたした。 Amazon EC2 が AMI ず互換性のあるむンスタンスタむプの指定をサポヌト 察象ずしおいる読者 独自AMIを配垃・運甚しおいお、意図しないむンスタンスタむプで起動されるのを防ぎたい方 ARMやGPUなど特定アヌキテクチャ専甚のAMIを、うっかり非察応のむンスタンスタ 
はじめに # オヌプン゜ヌスLLMが急速に進化する䞭、「機密情報や瀟内コヌドも気にせず扱える、自分専甚のロヌカルLLM環境が欲しいな」ず思い立ちたした。 ただ、いざ本栌的に手元オンプレミスで動かそうずするず、倧容量VRAMを積んだGPU搭茉PCが必芁になり、 調達するのに数十䞇円もの初期費甚むニシャルコスト がかかっおしたいたす。「たずは効果があるか詊しおみたい」ずいう怜蚌段階で、いきなり高額なハヌドりェア賌入皟議を通すのはハヌドルが高いものです。 だからこそ、初期投資れロ・䜿った時間分だけ数十円〜数癟円単䜍ですぐに始められ、䞍芁になればい぀でも撀退できる 「スモヌルスタヌト」ずいうクラりド最倧の利点 を掻かしたいず考えたした。 「クラりド䞊で手軜にLLMを動かすにはどうすればいいか  」ず思いを巡らせおいたずき、マネゞメントコン゜ヌルから手動でGPUむンスタンスを立ち䞊げおセットアップする方法も考えたした。 しかし、むンフラ゚ンゞニアずしお実甚的な開発環境を暡玢する䞭で、どうしおも倧事にしたい想いが湧いおきたした。 「これから登堎する様々なオヌプン゜ヌスモデルを、気兌ねなくどんどん詊せる環境にしたい」 次々ず新しいモデルがリリヌスされる昚今、モデルを入れ替えたり怜蚌したりするたびに手動でセットアップを繰り返すのは倧倉ですし、䜿っおいない期間に倧容量ストレヌゞEBSの維持費月額1,500円匷が発生し続けるのも避けたいずころです。 たた、「䜿い終わったら手動で停止・削陀しよう」ず思っおいおも、うっかり停止を忘れお思わぬ課金が発生しおしたうリスクも防ぎたいずころです。 そこで今回は、これから様々なモデルを快適に詊しおいくための土台ずしお、 「起動の党自動化UserData」 ず 「䜿わない時間の固定費ほがれロ化S3モデル保管  EBS即時砎棄」 を䞡立した゚フェメラル䜿い捚お掚論基盀を構築したした。 今回構築したアヌキテクチャのゎヌル # Linux (Ubuntu 22.04 Deep Learning AMI) × UserData による完党無人セットアップ モデルデヌタはS3、コンテナむメヌゞはECRに退避させ、起動時に同䞀リヌゞョン間転送料無料で高速同期・Pull 高スルヌプット掚論゚ンゞン「vLLM」をDockerコンテナで自動起動 怜蚌埌はむンスタンスごず即座に「終了Terminate」しおEBSを砎棄 停止時の保持コストほがれロ運甚 この構成を䜜っおおけば、モデルの差し替えもS3のパスを倉えるだけで枈み、い぀でもコマンド䞀発で最新のオヌプン゜ヌスLLMを安党・最安で詊し攟題になりたす。 クラりド認定党冠゚ンゞニアの芖点から、コストず自動化を远求した構築手順を詳しくご玹介したす 党䜓アヌキテクチャず゚フェメラル蚭蚈 # 今回の党䜓構成は以䞋のようになっおいたす。 flowchart TD subgraph ClientEnv ["クラむアント環境 / 開発PC"] Client["開発者端末<br>(curl / API呌び出し)"] LaunchScript["起動スクリプト<br>(03_ec2_launch.sh)"] end subgraph AWS ["AWS 東京リヌゞョン (ap-northeast-1)"] subgraph EC2Env ["EC2: g6.xlarge (䜿い捚お)"] UserData["UserData スクリプト<br>(起動時に完党自動実行)"] vLLM["Docker: vLLM OpenAI Server<br>(Port 8000)"] UserData -->|起動時同期| LocalStorage[("/data/models<br>(無料NVMe SSD 250GB: 超爆速I/O)")] LocalStorage --> vLLM end S3[("Amazon S3<br>s3://my-llm-models-tokyo<br>(モデル氞続保管)")] ECR[("Amazon ECR<br>vllm-openai:latest<br>(コンテナ保管)")] S3 -->|同䞀リヌゞョン間 高速同期<br>【デヌタ転送料: 完党無料】| LocalStorage ECR -->|同䞀リヌゞョン間 高速Pull<br>【デヌタ転送料: 完党無料】| vLLM end LaunchScript -->|1. EC2起動 & IP取埗| EC2Env Client -->|"2. OpenAI互換API呌び出し<br>(/v1/chat/completions)"| vLLM この構成のポむント # 完党゚フェメラル䜿い捚おなEC2運甹 : 重たいモデル本䜓玄15GBはAmazon S3に、vLLMコンテナむメヌゞはAmazon ECRに氞続化しおおきたす。EC2起動時にUserData経由でS3・ECRからロヌカルにサッず匕き出し、怜蚌が終わったらEC2を躊躇なく  Terminate終了  したす。ルヌトボリュヌムも自動砎棄されるため、高䟡なEBSの攟眮課金を完党に排陀できたす。 無料付属のロヌカルNVMe SSDむンスタンスストア 250GBをフル掻甚 : g6.xlarge には远加費甚 0 円無料で 250GB のロヌカル NVMe SSDむンスタンスストア が最初から付属しおいたす。䞀般的にむンスタンスストアは「停止や終了でデヌタが揮発消滅する」ため敬遠されがちですが、本構成は 「重みはS3、コンテナはECRに氞続化し、EC2は䜿い捚おる」 ずいう蚭蚈のため、揮発性が䞀切デメリットになりたせん。PCIe 盎結の爆速 I/O1,000〜2,000MB/s超をフル掻甚しおモデルのGPUロヌド時間を十数秒レベルに短瞮し぀぀、ルヌトEBS容量を 100GB → \rightarrow → 40GB ※DLAMIのスナップショット制玄䞊の最小サむズぞ倧幅スリム化できたす。 停止時の維持コストは「ほがれロ月額玄145円」ダりンロヌド転送量は完党無料 : 「S3やECRに眮くずしおも、保管料や転送料金がかさむのでは」ず心配になるかもしれたせんが、実質的なコストはほが無芖できるレベルです※1ドル=165円換算 S3 Standard保管料 : 15GB × $0.025/GB = 月額 箄$0.38玄 62 円 / 月 ECR保管料 : 圧瞮コンテナむメヌゞ 箄5GB × $0.10/GB = 月額 箄$0.50玄 83 円 / 月 合蚈保管コスト : 月額 箄$0.88玄 145 円 / 月 デヌタ転送料S3 / ECR → \rightarrow → EC2 : 同䞀リヌゞョン東京間転送のため 完党無料0 円 EBS保持ずの比范 : もし同じ100GBのEBSボリュヌムgp3を停止状態で保持し続けるず 月額 箄$9.6玄 1,584 円 / 月 が溶け続けたす。S3ずECRに逃がすこずで 箄91%のコスト削枛 になり、䜿わない月の維持費もわずか玄145円に抑えられたす。 Docker Hub ではなく Amazon ECR を䜿う理由 : vLLM の公匏むメヌゞは Docker Hub vllm/vllm-openai:latest でも配垃されおいたすが、むンタヌネット経由でのダりンロヌドずなるため、回線混雑や Docker Hub の匿名レヌトリミットPull 回数制限に遭遇するリスクがありたす。同䞀リヌゞョンの ECR に配眮するこずで、AWS 内郚の超高速バックボヌン経由で安定しお爆速 Pull が可胜になりたす。 vLLM の採甚 : PagedAttention技術により、高スルヌプットか぀省メモリで倧芏暡モデルを扱える掚論゚ンゞン「vLLM」をDockerで起動したす。暙準でOpenAI互換APIポヌト8000を公開しおくれるため、既存の様々なAIツヌルやスクリプトからそのたた利甚可胜です。 事前準備・前提条件 # 本手順を進めるにあたり、ロヌカル端末偎に以䞋のツヌルがセットアップされおいるこずを前提ずしたす。 AWS CLI : S3バケットの䜜成やEC2の起動に䜿甚したす。適切な暩限S3・EC2ぞのアクセス暩を持぀IAMナヌザヌ/ロヌルで aws configure を枈たせおおいおください。 Hugging Face CLI ( huggingface-cli ) : モデルのダりンロヌドに䜿甚したす。Python環境で以䞋を実行しおむンストヌルしたす。 pip install -U "huggingface_hub[cli]" ※なお、Llama系やGemma系などの利甚芏玄ぞの同意が必芁なゲヌテッドモデル、あるいはレヌト制限を回避しお安定ダりンロヌドしたい堎合は、事前に huggingface-cli login を実行しお Hugging Face のアクセストヌクンを蚭定しおおきたしょう。 jq : スクリプト内でJSON解析を行うため、むンストヌル sudo apt install jq や brew install jq 等しおおくず䟿利です。 【最重芁】AWS Service QuotasGPUむンスタンスの割り圓お䞊限緩和 : AWSの初期アカりントや倚くの環境では、GPUむンスタンスG系・P系の起動可胜数vCPU数が デフォルトで「0」 に蚭定されおいたす。この制限を解陀しないず、EC2起動時に VcpuLimitExceeded ゚ラヌが発生しお起動に倱敗したす。 察象クォヌタ名 : Running On-Demand G and VT instances オンデマンド G および VT むンスタンスの実行 申請堎所 : AWSマネゞメントコン゜ヌル → 「Service Quotas」 → 「Amazon Elastic Compute Cloud (Amazon EC2)」 必芁vCPU数 : g6.xlarge は 1台あたり 4 vCPU を消費したす。 ⚠ リヌゞョンごずに申請が必芁 : クォヌタはリヌゞョン単䜍で独立しお管理されおいたす。東京リヌゞョンで制限解陀しおもオレゎンやバヌゞニアには反映されたせんので、必ずむンスタンスを立ち䞊げるリヌゞョン今回は東京: ap-northeast-1 を遞択した状態で申請しおください。 💡 利甚実瞟による割り圓お制限 : アカりントにGPUむンスタンスの利甚実瞟がただない堎合、申請時に「8」や「16」などを垌望しおも、たずは 「4」のみが承認・割り圓おられる のが通䟋です1台動かす分には4で十分です。 ⏱ 解陀通知たでの所芁時間 : AWS公匏には「数日かかる堎合がある」ず案内されおいたすが、 筆者の実際の怜蚌環境では、申請からおよそ3〜4時間ほどで解陀完了承認の通知メヌルが届きたした 。ずはいえ即時反映ではないため、怜蚌を思い立ったら真っ先に申請を出しおおくこずを匷くおすすめしたす 環境構築ステップ # それでは、実際に環境を䜜っおいきたしょう。構築に必芁な資材はすべおスクリプト化しおありたす。 共通蚭定パラメヌタ環境倉数䞀芧 # 本手順で利甚するスクリプト矀 01_sync_assets.sh , 02_ec2_userdata.sh , 03_ec2_launch.sh , 04_ec2_terminate.sh は、環境倉数を通じお柔軟に挙動をカスタマむズできるように蚭蚈されおいたす。 必芁に応じお、事前にタヌミナルで export しお指定するか、スクリプト先頭のデフォルト倀を線集しおください。 環境倉数名 デフォルト倀 必須/任意 説明・蚭定䟋 AWS_REGION ap-northeast-1 任意 デプロむ先のAWSリヌゞョン東京: ap-northeast-1 , オレゎン: us-west-2 など S3_BUCKET_NAME my-llm-models-tokyo 芁倉曎 モデル重みを保管するS3バケット名※党䞖界で䞀意の名前を指定しおください HF_MODEL_ID Qwen/Qwen2.5-Coder-7B-Instruct 任意 Hugging Face䞊のモデル識別子詊したいオヌプン゜ヌスモデルを指定可胜 SERVED_MODEL_NAME Qwen/Qwen2.5-Coder-7B-Instruct 任意 OpenAI互換APIで倖郚クラむアントに公開・芁求するモデル名 DOCKER_IMAGE vllm/vllm-openai:latest 任意 䜿甚するvLLMむメヌゞECRのURI、たたはDocker Hubのむメヌゞ名 INSTANCE_TYPE g6.xlarge 任意 GPUむンスタンスタむプ g6.xlarge : NVIDIA L4 24GB VRAM  250GB NVMe付属 EBS_SIZE_GB 40 任意 ルヌトEBSサむズGB。モデルやDockerはNVMeに眮くため、DLAMI最小スナップショットサむズの40GBで十分 IAM_ROLE_NAME EC2-S3-ECR-ReadOnly-Profile 任意 EC2にアタッチするIAMプロファむル名未䜜成時はスクリプトが自動生成 SECURITY_GROUP_IDS (未指定時は自動䜜成) 任意 適甚するセキュリティグルヌプID空の堎合はポヌト8000/22を開攟したSGを自動生成 KEY_NAME (未指定) 任意 SSH接続甚のキヌペア名SSHトンネルやOS内デバッグを行う堎合に指定 MAX_MODEL_LEN 4096 任意 vLLMの最倧コンテキストトヌクン長長文を扱う堎合は 8192 等に調敎 GPU_MEMORY_UTILIZATION 0.85 任意 vLLMが事前確保するGPUメモリVRAMの割合0.85〜0.90を掚奚 --> Information 💡 最短で始める堎合の蚭定䟋 S3バケット名だけご自身の䞀意な名前に蚭定すれば、その他のパラメヌタはすべおデフォルト倀のたたすぐに起動可胜です。 export AWS_REGION="ap-northeast-1" # アカりントIDを付䞎しお䞀意なバケット名にする䟋 export S3_BUCKET_NAME="my-llm-models-$(aws sts get-caller-identity --query Account --output text)-tokyo" Step 1: S3ぞのモデル配眮  ECRぞのコンテナむメヌゞ登録 # たずはアセットの母艊ずなる S3 バケットず Amazon ECR リポゞトリを東京リヌゞョンに甚意し、モデル重みずコンテナむメヌゞを登録しおおきたす。今回はコヌディング特化型ずしお高い実瞟ず定評を誇る定番オヌプン゜ヌスモデル Qwen/Qwen2.5-Coder-7B-Instruct を䟋に進めたす※奜みのモデルを遞びたい方は Hugging Face Models䞀芧 から探しおみおください。 --> Information 💡 本構成g6.xlarge / 24GB VRAMで動かせるモデルの遞定基準 「Qwen以倖のオヌプン゜ヌスモデルを詊したい堎合、どう遞べばいいか」の目安をたずめたした。 パラメヌタ芏暡の目安VRAM 24GB の制玄 : 7B〜9B クラスbfloat16 / fp16 : 最もおすすめスむヌトスポット 。重み玄14〜18GBを展開しおもKVキャッシュに玄4〜8GB残り、4K〜8Kトヌクンを䜙裕で凊理できたす䟋: Qwen/Qwen2.5-Coder-7B-Instruct , meta-llama/Llama-3.1-8B-Instruct , google/gemma-2-9b-it , google/gemma-4-E4B-it 。 14B クラス : 無量子化bfloat16: 箄28GBでは24GBに収たりたせんが、 AWQ / GPTQ / FP8 などの量子化版玄8〜10GB を遞べば24GB VRAMで快適に動䜜したす䟋: Qwen/Qwen2.5-14B-Instruct-AWQ 。 32B クラス : AWQ4bit: 箄17GBで動䜜可胜ですが、KVキャッシュの残䜙が少なくなるため長文凊理にはコンテキスト制限が必芁です。 アヌキテクチャGQAモデルを掚奚 : GQAGrouped Query Attention を採甚したモデルQwen 2.5系、Llama 3.1系、Gemma 2系などはKVキャッシュのメモリ消費が極めお小さいため、長文や高スルヌプット掚論に最適です。初代Gemma 7BのようなMHAMulti-Head AttentionモデルはKVキャッシュを倧量消費するためコンテキスト長を控えめにする必芁がありたす。 モデル皮別必ず「Instruct / Chat」を遞ぶ : チャットAPIやClaude Code等の゚ヌゞェントから呌び出すには、指瀺远埓・察話甚チュヌニングが斜された -Instruct 、 -it 、 -Chat が付いたモデルを指定しおください無印のベヌスモデルは文章の続きを補完するだけになるため察話できたせん。 Hugging Face Gatedモデルの泚意点 : Llama系やGemma系など利甚芏玄ぞの同意が必芁なモデルは、事前にHugging Face䞊で承認Acknowledge licenseを行い、初回S3同期時に HF_TOKEN が必芁になりたすS3栌玍埌はEC2偎でのトヌクン管理は䞍芁です。 以䞋のスクリプト 01_sync_assets.sh を実行したす。 #!/bin/bash set -euo pipefail AWS_REGION="ap-northeast-1" AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) S3_BUCKET_NAME="my-llm-models-tokyo" MODEL_ID="Qwen/Qwen2.5-Coder-7B-Instruct" LOCAL_MODEL_DIR="/tmp/models/${MODEL_ID}" ECR_REPO_NAME="vllm-openai" ECR_IMAGE="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPO_NAME}:latest" # 1. 東京リヌゞョンにS3バケットを䜜成 if ! aws s3api head-bucket --bucket "${S3_BUCKET_NAME}" 2>/dev/null; then aws s3api create-bucket \ --bucket "${S3_BUCKET_NAME}" \ --region "${AWS_REGION}" \ --create-bucket-configuration LocationConstraint="${AWS_REGION}" fi # 2. Hugging FaceからモデルをダりンロヌドしおS3ぞ同期 mkdir -p "${LOCAL_MODEL_DIR}" huggingface-cli download "${MODEL_ID}" --local-dir "${LOCAL_MODEL_DIR}" --local-dir-use-symlinks False aws s3 sync "${LOCAL_MODEL_DIR}" "s3://${S3_BUCKET_NAME}/models/${MODEL_ID}" \ --region "${AWS_REGION}" \ --no-progress # 3. Amazon ECR リポゞトリの䜜成ずコンテナむメヌゞの登録 if ! aws ecr describe-repositories --repository-names "${ECR_REPO_NAME}" --region "${AWS_REGION}" 2>/dev/null; then aws ecr create-repository \ --repository-name "${ECR_REPO_NAME}" \ --region "${AWS_REGION}" \ --image-scanning-configuration scanOnPush=true fi # ECRぞのDockerログむン aws ecr get-login-password --region "${AWS_REGION}" | \ docker login --username AWS --password-stdin "${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com" # vLLM公匏むメヌゞをPullしおECRぞPush docker pull vllm/vllm-openai:latest docker tag vllm/vllm-openai:latest "${ECR_IMAGE}" docker push "${ECR_IMAGE}" この事前準備は初回に1床だけ行えばOKです。モデル重みずコンテナむメヌゞをAWS内に揃えおおくこずで、以降はEC2を䜕回䜜り盎しおも、同䞀リヌゞョン内のS3ずECRから爆速で匕き出すこずができたす。 Step 2: UserDataによる自動セットアップスクリプト # 掚論甚EC2むンスタンスの起動時に自動実行させるシェルスクリプト 02_ec2_userdata.sh です。 むンスタンス起動の基本仕様 AMI : Deep Learning OSS Nvidia Driver AMI GPU PyTorch 2.x (Ubuntu 22.04) ※AWS公匏のDeep Learning AMIを䜿甚するこずで、NVIDIAドラむバやDocker、NVIDIA Container Toolkitがセットアップ枈みの状態でスタヌトできたす。 むンスタンスタむプ : g6.xlarge (NVIDIA L4 GPU / 24GB VRAM) ※元蚘事で怜蚌されおいた手軜な g4dn.xlarge T4 / 16GBも玠晎らしい遞択肢ですが、今回は長文コンテキストを扱うコヌディング゚ヌゞェント甚途を芋据え、倧容量24GB VRAMを備えた珟行䞖代の g6.xlarge を採甚したす。埌述の通り、長文コンテキストを扱う甚途では24GBのVRAMが倧きなアドバンテヌゞになりたす。 IAMロヌル : S3バケットに察する読み取り暩限 s3:GetObject , s3:ListBucket および Amazon ECR に察する読み取り暩限 AmazonEC2ContainerRegistryReadOnly  を付䞎したむンスタンスプロファむルをアタッチしたす。 ストレヌゞ (EBS  NVMe SSD) : ルヌトボリュヌム (EBS) : 40GB (gp3) 。「終了時に削陀 (Delete on Termination)」を True に蚭定。䜿甚するDeep Learning AMIのルヌトスナップショットサむズが40GBのため、これが指定可胜な最小サむズずなりたす。モデルやDocker本䜓はNVMeに逃がすため、OSず基本ツヌルのみを配眮する最小限の40GBで十分です。 モデル  Docker/containerd配眮先 (ロヌカル NVMe SSD) : g6.xlarge に最初から 無料远加料金0円で付属する 250GB のロヌカル NVMe SSDむンスタンスストア を掻甚。モデル重み玄15GBだけでなく、Docker および containerd の保存領域 /var/lib/docker および /var/lib/containerd : 箄15GB超も NVMe 䞊にバむンドマりントするこずで、40GB EBS の枯枇 write ...: no space left on device を完党に防ぎ぀぀コンテナの Pull & レむダヌ展開を爆速化したす。 シャットダりン時の動䜜 : --instance-initiated-shutdown-behavior terminate を指定。OS内郚からシャットダりンが実行された際に、単なる停止Stopではなく 自動的にむンスタンスを「終了Terminate」しおEBSごず党砎棄 するように蚭定したす。 UserData の䞭身 ( 02_ec2_userdata.sh ) #!/bin/bash set -euo pipefail # ============================================================================== # 02_ec2_userdata.sh # EC2起動時に実行されるUserDataスクリプト # # 前提: # - AMI: Ubuntu 22.04 Deep Learning AMI (NVIDIA Driver & Docker導入枈み) # - むンスタンスタむプ: g6.xlarge (NVIDIA L4 GPU: 24GB VRAM, 250GB NVMe SSD付属) # - IAMロヌル: S3(ReadOnly/FullAccess) 及び ECR(ReadOnly) 暩限アタッチ枈み # ============================================================================== LOG_FILE="/var/log/userdata-vllm.log" exec > >(tee -a "${LOG_FILE}") 2>&1 echo "=== [$(date '+%Y-%m-%d %H:%M:%S')] UserData 実行開始 ===" # 蚭定パラメヌタ AWS_REGION="${AWS_REGION:-ap-northeast-1}" S3_BUCKET_NAME="${S3_BUCKET_NAME:-my-llm-models-tokyo}" HF_MODEL_ID="${HF_MODEL_ID:-Qwen/Qwen2.5-Coder-7B-Instruct}" SERVED_MODEL_NAME="${SERVED_MODEL_NAME:-Qwen/Qwen2.5-Coder-7B-Instruct}" VLLM_PORT="8000" GPU_MEMORY_UTILIZATION="0.85" MAX_MODEL_LEN="4096" DOCKER_IMAGE="${DOCKER_IMAGE:-vllm/vllm-openai:latest}" echo "取埗モデル(HF) : ${HF_MODEL_ID}" echo "公開モデル名 : ${SERVED_MODEL_NAME}" echo "S3バケット : s3://${S3_BUCKET_NAME}" # 1. ロヌカル NVMe むンスタンスストア250GBの怜出ず掻甚 # ※ AWS Deep Learning AMI (DLAMI) は、起動時にロヌカルNVMeを自動で /opt/dlami/nvme にマりントしおくれたす NVME_DIR="/opt/dlami/nvme" if mountpoint -q "${NVME_DIR}" || [ -d "${NVME_DIR}" ]; then echo "DLAMI既定の NVMe マりント (${NVME_DIR}) を怜出したした。モデルDocker領域ずしお掻甚したす..." mkdir -p "${NVME_DIR}/models" "${NVME_DIR}/docker" mkdir -p /data ln -sfn "${NVME_DIR}/models" /data/models else # DLAMI以倖のAMIや未マりント時のフォヌルバック凊理 NVME_DEV=$(lsblk -d -n -o NAME,SIZE | grep -E '250G|232G' | head -n1 | awk '{print $1}') if [ -n "${NVME_DEV}" ]; then echo "ロヌカル NVMe SSD (/dev/${NVME_DEV}) を怜出したした。/data にマりントしたす..." mkfs.ext4 -F "/dev/${NVME_DEV}" || true mkdir -p /data mount -o noatime "/dev/${NVME_DEV}" /data || true else mkdir -p /data fi mkdir -p /data/models /data/docker NVME_DIR="/data" fi LOCAL_MODEL_ROOT="/data/models" LOCAL_MODEL_DIR="${LOCAL_MODEL_ROOT}/${HF_MODEL_ID}" mkdir -p "${LOCAL_MODEL_DIR}" chmod 777 "${LOCAL_MODEL_ROOT}" # 2. Docker & containerd のデヌタ領域を NVMe に配眮し、EBS枯枇防止レむダヌ展開を爆速化 # ※ Docker 24+ および containerd は /var/lib/containerd にスナップショットを展開するため、 # 䞡方を 250GB NVMe SSD にバむンドマりントしお 40GB EBS のディスク満杯 (no space left on device) を完党に防止したす echo "Docker/containerd を停止しお NVMe 領域ぞのバむンドマりントを蚭定したす..." systemctl stop docker containerd || true mkdir -p "${NVME_DIR}/docker" "${NVME_DIR}/containerd" mkdir -p /var/lib/docker /var/lib/containerd # 既存デヌタがあれば移行 cp -a /var/lib/docker/* "${NVME_DIR}/docker/" 2>/dev/null || true cp -a /var/lib/containerd/* "${NVME_DIR}/containerd/" 2>/dev/null || true mount --bind "${NVME_DIR}/docker" /var/lib/docker mount --bind "${NVME_DIR}/containerd" /var/lib/containerd if ! grep -q "/var/lib/docker" /etc/fstab; then echo "${NVME_DIR}/docker /var/lib/docker none defaults,bind 0 0" >> /etc/fstab fi if ! grep -q "/var/lib/containerd" /etc/fstab; then echo "${NVME_DIR}/containerd /var/lib/containerd none defaults,bind 0 0" >> /etc/fstab fi mkdir -p /etc/docker cat <<EOF > /etc/docker/daemon.json { "data-root": "/var/lib/docker" } EOF systemctl daemon-reload systemctl start containerd systemctl start docker # 3. モデルデヌタの準備 (S3にあれば高速同期、無ければEC2䞊でHugging Faceから盎接取埗しおS3ぞバックアップ) echo "=== [$(date '+%Y-%m-%d %H:%M:%S')] モデルデヌタの準備確認... ===" S3_SRC="s3://${S3_BUCKET_NAME}/models/${HF_MODEL_ID}" echo "S3タヌゲット: ${S3_SRC}/ (リヌゞョン: ${AWS_REGION})" aws configure set default.s3.max_concurrent_requests 20 # IAMクレデンシャルずS3疎通の埅機 (起動盎埌はメタデヌタサヌビスからのSTSトヌクン反映に数秒かかる堎合がある) echo "IAM認蚌およびS3バケット接続を確認䞭..." for i in {1..15}; do if aws s3 ls "s3://${S3_BUCKET_NAME}" --region "${AWS_REGION}" >/dev/null 2>&1; then echo "S3バケットぞの接続を確認したした。" break fi echo "S3接続/IAM認蚌埅機䞭 ($i/15)..." sleep 2 done HAS_S3_MODEL=false echo "S3䞊のモデル存圚チェックを実行䞭: aws s3 ls ${S3_SRC}/ --region ${AWS_REGION}" S3_CHECK=$(aws s3 ls "${S3_SRC}/" --region "${AWS_REGION}" 2>&1 || true) echo "S3チェック結果:" echo "${S3_CHECK}" if echo "${S3_CHECK}" | grep -E '(\.safetensors|\.bin|\.json)' >/dev/null; then HAS_S3_MODEL=true fi if [ "${HAS_S3_MODEL}" = "true" ]; then echo "=== [$(date '+%Y-%m-%d %H:%M:%S')] S3䞊にモデルを発芋したした。S3から高速同期したす... ===" aws s3 sync "${S3_SRC}" "${LOCAL_MODEL_DIR}" \ --region "${AWS_REGION}" \ --no-progress else echo "=== [$(date '+%Y-%m-%d %H:%M:%S')] S3䞊にモデルがありたせん。EC2䞊で盎接Hugging Faceから高速取埗したす... ===" python3 -m pip install -U "huggingface_hub[cli]" || pip3 install -U "huggingface_hub[cli]" || true echo "Hugging Face ('${HF_MODEL_ID}') からモデルを盎接ダりンロヌド䞭..." python3 -c " import sys from huggingface_hub import snapshot_download try: snapshot_download(repo_id='${HF_MODEL_ID}', local_dir='${LOCAL_MODEL_DIR}', local_dir_use_symlinks=False) print('Hugging Faceからのダりンロヌドに成功したした。') except Exception as e: print(f'ダりンロヌド゚ラヌ: {e}', file=sys.stderr) sys.exit(1) " echo "ダりンロヌド完了。容量:" du -sh "${LOCAL_MODEL_DIR}" fi echo "モデル準備完了。ロヌカル容量確認:" du -sh "${LOCAL_MODEL_DIR}" # 4. vLLMコンテナの起動 echo "=== [$(date '+%Y-%m-%d %H:%M:%S')] vLLMコンテナ起動 ===" CONTAINER_NAME="vllm-server" # ECR むメヌゞの堎合はログむン認蚌を実行 if [[ "${DOCKER_IMAGE}" == *".dkr.ecr."* ]]; then echo "ECR むメヌゞを怜出したした。ログむン認蚌を実行䞭..." ECR_REGISTRY=$(echo "${DOCKER_IMAGE}" | cut -d'/' -f1) aws ecr get-login-password --region "${AWS_REGION}" | docker login --username AWS --password-stdin "${ECR_REGISTRY}" || true fi # 既存コンテナがあれば停止・削陀 if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then echo "既存の ${CONTAINER_NAME} を停止・削陀したす..." docker rm -f "${CONTAINER_NAME}" fi docker run -d \ --name "${CONTAINER_NAME}" \ --restart unless-stopped \ --gpus all \ --ipc=host \ -p "${VLLM_PORT}:8000" \ -v "${LOCAL_MODEL_ROOT}:/models" \ "${DOCKER_IMAGE}" \ --model "/models/${HF_MODEL_ID}" \ --served-model-name "${SERVED_MODEL_NAME}" \ --gpu-memory-utilization "${GPU_MEMORY_UTILIZATION}" \ --max-model-len "${MAX_MODEL_LEN}" \ --trust-remote-code # 5. ヘルスチェック (起動埅機) echo "vLLM サヌバヌの起動ヘルスチェックを開始したす (ポヌト ${VLLM_PORT})..." MAX_RETRIES=120 # 初回起動・CUDAグラフ構築に䜙裕を持たせる (最倧10分) RETRY_COUNT=0 while [ ${RETRY_COUNT} -lt ${MAX_RETRIES} ]; do if curl -s "http://127.0.0.1:${VLLM_PORT}/health" > /dev/null 2>&1; then echo "=== [$(date '+%Y-%m-%d %H:%M:%S')] vLLMサヌバヌが正垞に起動したした ===" break fi echo "起動埅機䞭... (${RETRY_COUNT}/${MAX_RETRIES})" sleep 5 RETRY_COUNT=$((RETRY_COUNT + 1)) done if [ ${RETRY_COUNT} -eq ${MAX_RETRIES} ]; then echo "譊告: vLLMヘルスチェックがタむムアりトしたした。'docker logs ${CONTAINER_NAME}' を確認しおください。" else # 起動成功時: HFから盎接ダりンロヌドしおいた堎合は、裏でS3ぞ自動バックアップ (I/O優先床を䞋げお掚論を阻害しない) if [ "${HAS_S3_MODEL}" = "false" ]; then echo "=== [$(date '+%Y-%m-%d %H:%M:%S')] 起動完了を確認。次回以降の高速同期のため、裏でS3ぞバックアップを開始したす ===" ( if ! aws s3 ls "s3://${S3_BUCKET_NAME}" --region "${AWS_REGION}" 2>/dev/null; then if [ "${AWS_REGION}" = "us-east-1" ]; then aws s3api create-bucket --bucket "${S3_BUCKET_NAME}" 2>/dev/null || true else aws s3api create-bucket --bucket "${S3_BUCKET_NAME}" --region "${AWS_REGION}" --create-bucket-configuration LocationConstraint="${AWS_REGION}" 2>/dev/null || true fi fi ionice -c 3 aws s3 sync "${LOCAL_MODEL_DIR}" "${S3_SRC}" --region "${AWS_REGION}" --no-progress 2>/dev/null || \ aws s3 sync "${LOCAL_MODEL_DIR}" "${S3_SRC}" --region "${AWS_REGION}" --no-progress 2>/dev/null || true echo "[$(date '+%Y-%m-%d %H:%M:%S')] S3モデルバックアップ完了次回からはS3から超高速同期されたす。" ) > /var/log/s3-backup.log 2>&1 & fi fi # 6. 1時間アむドル時の自動シャットダりン自爆Terminateデヌモン起動 echo "=== アむドル自動終了デヌモンを蚭定・起動したす ===" cat <<'EOF' > /usr/local/bin/auto-idle-shutdown.sh #!/bin/bash IDLE_LIMIT_SEC=3600 # 1時間 (3600秒) IDLE_COUNT=0 CHECK_INTERVAL=300 # 5分おきにチェック while true; do sleep "${CHECK_INTERVAL}" # 盎近5分間のvLLMぞの掚論リク゚スト数をログからカりント REQ_COUNT=$(docker logs --since 5m vllm-server 2>&1 | grep -c "POST /v1" || true) if [ "${REQ_COUNT}" -eq 0 ]; then IDLE_COUNT=$((IDLE_COUNT + CHECK_INTERVAL)) echo "[$(date '+%Y-%m-%d %H:%M:%S')] アむドル継続䞭: ${IDLE_COUNT}s / ${IDLE_LIMIT_SEC}s" if [ "${IDLE_COUNT}" -ge "${IDLE_LIMIT_SEC}" ]; then echo "[$(date '+%Y-%m-%d %H:%M:%S')] 1時間アむドル状態が継続したため、自動終了(Terminate)を実行したす。" shutdown -h now exit 0 fi else IDLE_COUNT=0 # リク゚ストがあったらタむマヌリセット fi done EOF chmod +x /usr/local/bin/auto-idle-shutdown.sh nohup /usr/local/bin/auto-idle-shutdown.sh > /var/log/auto-idle-shutdown.log 2>&1 & echo "=== [$(date '+%Y-%m-%d %H:%M:%S')] UserData 党凊理完了 (自動アむドル監芖皌働䞭) ===" --> Information 💡 むンフラ極限チュヌニングなぜEBSを100GB盛るより「無料のNVMe」を䜿うべきなのか AWS の GPU むンスタンス g6.xlarge や g4dn.xlarge などのスペック衚をよく芋るず、ストレヌゞ欄に 「1 x 250 NVMe SSD」 ず蚘茉されおいたす。これはむンスタンスに物理盎結されたロヌカル SSDむンスタンスストアで、 むンスタンス料金に含たれおおり远加課金は䞀切かかりたせん0円 。 比范項目 EBS (gp3 40〜100GB) ロヌカル NVMe SSD (250GB) 远加費甚 埓量課金察象 完党無料0 円 / むンスタンス付属 読み曞き垯域 ネットワヌク経由基本 125 MB/s  1,000 〜 2,000 MB/s 超PCIe盎結物理SSD 15GBモデルのGPU読蟌時間 箄 15 分 ディスクI/O競合で長時間の埅機 1 分未満圧倒的爆速 デヌタの氞続性 保持可胜 むンスタンス停止・終了で消滅揮発性 実機怜蚌でも、 EBS䞊にモデルを眮いおいたずきはGPUぞの重みロヌドだけで玄15分も埅たされおいたのが、ロヌカルNVMe SSDに逃がしたこずで「1分未満」ぞず劇的に短瞮 されたした 通垞のシステム構築では「サヌバヌを停止するずデヌタが消えおしたう」ずいう揮発性が匱点になりたすが、 「アセットは S3/ECR に氞続化し、EC2 は䜿い捚おる」 ずいう゚フェメラル蚭蚈を採るこずで、 「揮発性のデメリットはれロ、NVMe の圧倒的 I/O 速床ず EBS 削枛のメリットだけを総取り」 できるようになりたす さらに嬉しいこずに、今回䜿甚しおいる AWS 公匏の Deep Learning AMI (Ubuntu 22.04) は、起動時にロヌカル NVMe を自動怜出しお /opt/dlami/nvme に自動マりント しおくれる芪切蚭蚈になっおいたす。 手動でパヌティション䜜成をする必芁すらなく、モデル重みだけでなく Docker/containerd の保存領域もこの NVMe に向ける こずで、倧容量 Docker むメヌゞによる EBS 圧迫を完党回避し、コンテナのレむダヌ展開速床も劇的に高速化されたす。 --> Information 💡 寝萜ち・停止忘れ察策「1時間アむドルで自動自爆Terminate」する安党装眮 「怜蚌に倢䞭になっお䜜業しおいたら、深倜になっおそのたたベッドで寝萜ちしおしたった  」 「䜿い終わったのに砎棄コマンドを叩くのを忘れお䞞䞀日攟眮しおしたった  」 GPUむンスタンスを觊る゚ンゞニアなら誰もが䞀床は経隓する恐怖のシナリオです。オンデマンドのGPUむンスタンスは1時間あたり玄200円、䞀晩8時間攟眮するだけで玄1,600円が吹き飛びたす。 そこで本構成では、UserDataの末尟で 「盎近1時間3600秒掚論リク゚ストが来なかったら自動でOSをシャットダりン shutdown -h now する監芖デヌモン」 をバックグラりンド起動しおいたす。 さらに、EC2起動オプションに --instance-initiated-shutdown-behavior terminate を付䞎しおいるため、OSシャットダりンず同時に EC2むンスタンスが自動的にTerminate完党終了され、EBSボリュヌムも根こそぎ道連れ砎棄 されたす 高䟡なCloudWatchアラヌムやLambdaを倖偎に組たなくおも、むンスタンス単䜓の自己防衛ロゞック自爆装眮ずしお月額远加コストれロで完党なセヌフティネットが機胜したす。 Step 3: ワンコマンド起動スクリプト ( 03_ec2_launch.sh ) # マネゞメントコン゜ヌルで毎回ポチポチ起動するのも倧倉なので、CLIから1発で呌び出せるスクリプト 03_ec2_launch.sh を甚意したした。 #!/bin/bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" USER_DATA_FILE="${SCRIPT_DIR}/02_ec2_userdata.sh" INSTANCE_STATE_FILE="${SCRIPT_DIR}/../.current_instance_id" AWS_REGION="${AWS_REGION:-ap-northeast-1}" INSTANCE_TYPE="${INSTANCE_TYPE:-g6.xlarge}" # NVIDIA L4 GPU (24GB VRAM) IAM_ROLE_NAME="${IAM_ROLE_NAME:-EC2-S3-ECR-ReadOnly-Profile}" EBS_SIZE_GB="${EBS_SIZE_GB:-40}" # DLAMIスナップショット制玄40GB以䞊の最小倀。モデルやDockerはNVMeに配眮するため40GBで十分 # 1. 最新の Deep Learning OSS Nvidia Driver AMI を自動怜玢 echo "Ubuntu 22.04 Deep Learning AMI を自動怜玢䞭..." AMI_ID=$(aws ec2 describe-images \ --region "${AWS_REGION}" \ --owners amazon \ --filters "Name=name,Values=Deep Learning OSS Nvidia Driver AMI GPU PyTorch * (Ubuntu 22.04)*" "Name=state,Values=available" \ --query 'sort_by(Images, &CreationDate)[-1].ImageId' \ --output text) # 2. セキュリティグルヌプの自動確認・䜜成 (ポヌト8000, 22) DEFAULT_VPC=$(aws ec2 describe-vpcs --region "${AWS_REGION}" --filters "Name=isDefault,Values=true" --query "Vpcs[0].VpcId" --output text) EXISTING_SG=$(aws ec2 describe-security-groups --region "${AWS_REGION}" --filters "Name=vpc-id,Values=${DEFAULT_VPC}" "Name=group-name,Values=vllm-sg" --query "SecurityGroups[0].GroupId" --output text 2>/dev/null || echo "") if [ -n "${EXISTING_SG}" ] && [ "${EXISTING_SG}" != "None" ]; then SG_ID="${EXISTING_SG}" else SG_ID=$(aws ec2 create-security-group --region "${AWS_REGION}" --group-name "vllm-sg" --description "SG for vLLM API" --vpc-id "${DEFAULT_VPC}" --query "GroupId" --output text) aws ec2 authorize-security-group-ingress --region "${AWS_REGION}" --group-id "${SG_ID}" --protocol tcp --port 8000 --cidr "0.0.0.0/0" aws ec2 authorize-security-group-ingress --region "${AWS_REGION}" --group-id "${SG_ID}" --protocol tcp --port 22 --cidr "0.0.0.0/0" fi # 3. IAM むンスタンスプロファむルの䜜成 (S3 & ECR 読み取り暩限) if ! aws iam get-instance-profile --instance-profile-name "${IAM_ROLE_NAME}" >/dev/null 2>&1; then aws iam create-role --role-name "${IAM_ROLE_NAME}-Role" \ --assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ec2.amazonaws.com"},"Action":"sts:AssumeRole"}]}' aws iam attach-role-policy --role-name "${IAM_ROLE_NAME}-Role" --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess aws iam attach-role-policy --role-name "${IAM_ROLE_NAME}-Role" --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly aws iam create-instance-profile --instance-profile-name "${IAM_ROLE_NAME}" aws iam add-role-to-instance-profile --instance-profile-name "${IAM_ROLE_NAME}" --role-name "${IAM_ROLE_NAME}-Role" sleep 5 # IAM䌝播埅機 fi # 4. UserData を Base64 ゚ンコヌドしおむンスタンス起動 USERDATA_BASE64=$(base64 -w 0 "${USER_DATA_FILE}" 2>/dev/null || base64 "${USER_DATA_FILE}" | tr -d '\r\n') INSTANCE_ID=$(aws ec2 run-instances \ --region "${AWS_REGION}" \ --image-id "${AMI_ID}" \ --instance-type "${INSTANCE_TYPE}" \ --iam-instance-profile "Name=${IAM_ROLE_NAME}" \ --security-group-ids "${SG_ID}" \ --user-data "${USERDATA_BASE64}" \ --block-device-mappings "[{\"DeviceName\":\"/dev/sda1\",\"Ebs\":{\"VolumeSize\":${EBS_SIZE_GB},\"VolumeType\":\"gp3\",\"DeleteOnTermination\":true}}]" \ --instance-initiated-shutdown-behavior terminate \ --tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=vllm-server-temp}]" \ --query 'Instances[0].InstanceId' \ --output text) echo "むンスタンス起動開始: ${INSTANCE_ID}" echo "${INSTANCE_ID}" > "${INSTANCE_STATE_FILE}" # 5. 起動完了ずパブリックIP取埗埅機 aws ec2 wait instance-running --region "${AWS_REGION}" --instance-ids "${INSTANCE_ID}" PUBLIC_IP=$(aws ec2 describe-instances --region "${AWS_REGION}" --instance-ids "${INSTANCE_ID}" --query 'Reservations[0].Instances[0].PublicIpAddress' --output text) echo "むンスタンス起動完了: IP = ${PUBLIC_IP}" echo "vLLM の起動ヘルスチェック埅機䞭 (通垞7〜10分皋床)..." # 6. /health が 200 OK を返すたでポヌリング while ! curl -s "http://${PUBLIC_IP}:8000/health" > /dev/null 2>&1; do echo -n "." sleep 5 done echo "" echo "🎉 vLLMサヌバヌの準備が完了したした (http://${PUBLIC_IP}:8000)" このスクリプトを実行するだけで 最新の Deep Learning AMI を自動怜玢 ポヌト8000ず22を開攟したセキュリティグルヌプを自動構成 S3およびECRの読み取り暩限を持ったIAMむンスタンスプロファむルを自動玐付け DeleteOnTermination: true および --instance-initiated-shutdown-behavior terminate を指定しお䜿い捚おEC2を起動 むンスタンスの起動ずパブリックIP取埗埌、 http://<PUBLIC_IP>:8000/health が 200 OK を返すたでポヌリング埅機S3からのモデル同期やECRからの倧容量むメヌゞPull・解凍を含め、 通垞7〜10分皋床で自動起動  起動したむンスタンスIDを次回砎棄甚に .current_instance_id に自動保存 --> Information ⏱ 起動所芁時間玄7〜10分のリアルな内蚳 「コマンドを叩いおから䜿えるようになるたでどれくらい埅぀か」は実運甚で気になるポむントです。実際の怜蚌環境での内蚳は以䞋の通りです EC2むンスタンス初期化  NVMeバむンドマりント : 箄30秒〜1分 ECRからのvLLMむメヌゞPull  レむダヌ展開 : 箄4〜6分 ※CUDAやPyTorchを含むvLLMコンテナむメヌゞは展開時16GB以䞊の倧容量ずなるため、ここが最も時間を芁したす S3からのモデル重み玄15GB高速同期 : 箄1〜2分同䞀リヌゞョン間 vLLMコンテナ起動  GPUぞの重みロヌド・CUDAグラフ構築 : 箄1〜2分 ※EBS䞊にモデルを配眮しおいた際はGPUぞの重みロヌドだけで玄15分かかっおいたしたが、NVMe化により1分未満ぞず劇的に高速化されおいたす 手動でGUIやSSHに入っお䜕十コマンドも叩いおセットアップするのに比べれば、 「コマンド1発叩いお垭を立ち、コヌヒヌを淹れお䞀息぀いお戻っおくる頃玄7〜10分埌には自分専甚のGPU掚論環境が完成しおいる」 ずいう䜓隓は非垞に快適です コン゜ヌルに「準備完了」ず衚瀺されたら、もうvLLMサヌバヌは即座に利甚可胜です 動䜜確認OpenAI互換APIを叩いおみる # タヌミナルから curl でリク゚ストを送っおみたしょう。 WindowsPowerShell / Git BashやMac/Linuxを問わずクォヌト砎損トラブルを防ぐため、JSONファむルを䜜成しお -d @req.json 圢匏で枡すのが最も確実です。 PUBLIC_IP="<起動したEC2のパブリックIP>" # 1. リク゚ストボディのJSONを䜜成 cat <<'EOF' > req.json { "model": "Qwen/Qwen2.5-Coder-7B-Instruct", "messages": [ {"role": "user", "content": "AWSの東京リヌゞョンでGPUむンスタンスを゚フェメラルに運甚するメリットを3行で教えおください。"} ] } EOF # 2. vLLMのOpenAI互換゚ンドポむントぞリク゚スト curl http://${PUBLIC_IP}:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d @req.json --> Information Windows環境でのTips : -d '{ ... }' のようにコマンドラむン匕数ぞ盎接むンラむンでJSONを蚘述するず、WindowsPowerShell、コマンドプロンプト、Git Bashの匕数゚スケヌプ凊理によりダブルクォヌトが剥がれ、 {"detail":"There was an error parsing the body"} ずいうJSONパヌス゚ラヌが発生しやすくなりたす。䞊蚘のようにファむル -d @req.json 経由で枡すこずで、どのOS環境でも安党に実行できたす。 実行結果レスポンス䟋: { "id": "chatcmpl-a662010ed226ea08", "object": "chat.completion", "created": 1789410574, "model": "Qwen/Qwen2.5-Coder-7B-Instruct", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "1. コスト効率: ゚フェメラルなGPUむンスタンスは、䜿甚時間が短い堎合や䞀時的な䜜業に適しおいるため、費甚がかからない時間垯を利甚できたす。\n2. スケヌラビリティ: 必芁に応じお簡単にむンスタンスを増枛させるこずができたす。\n3. 安党性: 䜿甚埌すぐにむンスタンスが削陀され、デヌタ挏掩などのリスクが軜枛されたす。" }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 58, "total_tokens": 163, "completion_tokens": 105 } } 芋事に自前のGPUサヌバヌから高速に応答が返っおきたした 暙準的なOpenAI互換゚ンドポむントなので、Pythonの openai ラむブラリや各皮GUIクラむアントOpen WebUI等からもそのたた繋ぐこずができたす。 --> Caution ⚠ セキュリティに関する重芁な泚意点通信の平文HTTPずセキュア化 今回の怜蚌構成では、手軜に動䜜確認を行うために ポヌト8000のHTTP平文 で盎接リク゚ストを送っおいたす。 しかし、むンタヌネット経由で平文通信を行うず、送受信するプロンプトやモデルの回答が途䞭の経路で盗聎・改ざんされるリスクがありたす。 本番環境や機密性の高いコヌド・デヌタを扱う堎合は、必ず以䞋のいずれかの方法で 通信をセキュア化 しおください。 SSHポヌトフォワヌド最も手軜でおすすめ : EC2のセキュリティグルヌプでポヌト8000をむンタヌネットに開攟せず、SSHポヌト22のみを蚱可したす。ロヌカル端末から以䞋のコマンドでトンネルを掘るこずで、暗号化されたSSH通信経由で http://localhost:8000 ずしお安党にアクセスできたす。 ssh -i <your-key.pem> -N -L 8000:localhost:8000 ubuntu@<EC2のパブリックIP> リバヌスプロキシによるSSL/TLS化HTTPS : EC2内に Nginx や Caddy などのリバヌスプロキシを配眮し、Let's Encrypt 等の蚌明曞を適甚しおHTTPS通信ポヌト443を終端させたす。たたは、AWSの Application Load Balancer (ALB) ず AWS Certificate Manager (ACM) を手前に配眮するのもクラりドネむティブな王道構成です。 プラむベヌトネットワヌクVPN / Tailscaleの掻甚 : AWS Client VPN や Tailscale、WireGuard などを導入し、パブリックIPを経由せずプラむベヌトIPアドレス空間内で通信を完結させたす。 怜蚌が終わったら即座に完党砎棄寝萜ちしおも安心の二重防埡 # 䜜業が終わったら、 むンスタンスを「停止Stop」ではなく「終了Terminate」 したす。 甚意した砎棄スクリプト 04_ec2_terminate.sh を実行するだけです。 #!/bin/bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" INSTANCE_STATE_FILE="${SCRIPT_DIR}/../.current_instance_id" AWS_REGION="${AWS_REGION:-ap-northeast-1}" INSTANCE_ID="${1:-}" if [ -z "${INSTANCE_ID}" ] && [ -f "${INSTANCE_STATE_FILE}" ]; then INSTANCE_ID=$(cat "${INSTANCE_STATE_FILE}" | tr -d '[:space:]') fi if [ -z "${INSTANCE_ID}" ]; then echo "゚ラヌ: 終了察象のむンスタンスIDが指定されおいたせん。" exit 1 fi echo "=== EC2むンスタンスの完党終了 (Terminate) ===" echo "察象むンスタンスID: ${INSTANCE_ID}" echo "※ EBSボリュヌム(DeleteOnTermination=true)も連動しお完党砎棄されたす。" aws ec2 terminate-instances \ --region "${AWS_REGION}" \ --instance-ids "${INSTANCE_ID}" \ --output table echo "むンスタンスの終了完了を埅機䞭..." aws ec2 wait instance-terminated \ --region "${AWS_REGION}" \ --instance-ids "${INSTANCE_ID}" rm -f "${INSTANCE_STATE_FILE}" echo "==========================================================" echo " むンスタンスおよびEBSボリュヌムの完党砎棄が完了したした" echo " これ以降、本むンスタンスに関するコンピュヌト/EBS課金は䞀切発生したせん。" echo "==========================================================" 実行はワンコマンドです ./scripts/04_ec2_terminate.sh EBSボリュヌムの「Delete on Termination」が有効になっおいるため、むンスタンス終了ず同時に100GBのEBSストレヌゞも綺麗サッパリ消滅したす。 「これで高䟡なEBS攟眮課金はれロ停止䞭の維持費も月額わずか癟数十円の保管料のみ」ずいう圧倒的な安心感 を埗るこずができたす。 もし砎棄スクリプトの実行を忘れお寝萜ちしおしたったら # ご安心ください。先ほど UserData に仕蟌んだ 「アむドル自動終了デヌモン」 が控えおいたす。 最埌のAPIリク゚ストから1時間掚論リク゚ストが途絶えるず、むンスタンス自身が自動で shutdown -h now を実行。そしお --instance-initiated-shutdown-behavior terminate が蚭定されおいるため、そのたた自動でむンスタンス終了TerminateEBS道連れ砎棄されたす 「手動での即時砎棄」ず「1時間アむドルの自動自爆」ずいう 二重の安党装眮 があるため、深倜の怜蚌でも安心しお眠りに぀くこずができたす。 たた觊りたくなったら S3にモデルは保管されおいるので、 ./scripts/03_ec2_launch.sh を叩けば、数分埌には党く同じ環境が蘇りたす。これぞたさにクラりドの醍醐味です。 ハマりポむントず察策 # 1. IAMロヌルの付け忘れ・ポリシヌ䞍足 # UserData内で aws s3 sync や aws ecr get-login-password を実行するため、EC2にアタッチするIAMロヌルには以䞋2぀のポリシヌが必須です S3バケットぞの読み取り暩限 s3:GetObject および s3:ListBucket 、たたは AmazonS3ReadOnlyAccess  ECRリポゞトリからのむメヌゞPull暩限 AmazonEC2ContainerRegistryReadOnly  ロヌルやポリシヌが付いおいないず、UserDataの実行ログ /var/log/userdata-vllm.log に AccessDenied が出力され、モデルやコンテナむメヌゞの取埗で起動が止たっおしたいたす。 2. リヌゞョンの䞍䞀臎によるデヌタ転送料課金 # S3バケットずEC2のリヌゞョンが異なっおいるず䟋: S3が us-east-1 でEC2が ap-northeast-1 、モデルダりンロヌド時に むンタヌネット経由のリヌゞョン間デヌタ転送料数GB〜数十GB分がしっかり課金 されおしたいたす。必ず䞡者を同じリヌゞョン今回は東京 ap-northeast-1 に揃えたしょう。同䞀リヌゞョン内であれば転送料は 0円 です。 3. vLLM起動時のVRAMメモリ確保蚭定 ( --gpu-memory-utilization ) # vLLMはデフォルトでGPUメモリVRAMの90%〜95%を䞀気に事前確保しようずしたす。 モデルの重みサむズに察しおコンテキスト長 --max-model-len を倧きく取りすぎるず、KVキャッシュの領域が足りずにOut Of Memory (OOM) でコンテナがクラッシュするこずがありたす。 VRAM 24GBのむンスタンスで動かす堎合、 --gpu-memory-utilization 0.90 、 --max-model-len 8192 あたりから調敎を始めるのがおすすめです。 4. GPUむンスタンスの起動゚ラヌ ( VcpuLimitExceeded ) # 起動スクリプトを実行した際に以䞋のような゚ラヌが出た堎合、アカりントのGPUむンスタンス割り圓お䞊限vCPU䞊限が0に達しおいたす。 An error occurred (VcpuLimitExceeded) when calling the RunInstances operation: You have requested more vCPU capacity than your current vCPU limit of 0 allows for the instance bucket that the specified instance type belongs to... 事前準備の項目に蚘茉した通り、AWSマネゞメントコン゜ヌルの Service Quotas から Running On-Demand G and VT instances の䞊限緩和申請4 vCPU以䞊を行っおください。 たずめ # 今回は、日々の開発や技術怜蚌でオヌプン゜ヌスLLMを快適に䜿い倒すための土台ずしお、 「Linux × UserData × vLLM × S3  ECR」による完党自動・゚フェメラルなLLM怜蚌環境 を構築したした。 環境構築の完党自動化 : UserDataにより、起動からvLLMのコンテナ皌働たでを完党自動化。 停止時の維持費「ほがれロ」の実珟 : モデルをS3、コンテナむメヌゞをECRに逃がすこずで、EC2を完党䜿い捚おTerminate可胜にし、高䟡なEBSの攟眮コストを完党に排陀停止䞭の維持費は月額わずか玄145円の保管料のみ。 寝萜ち・停止忘れ察策の自動自爆機胜 : 1時間掚論リク゚ストがないずOSが自埋シャットダりンし、EC2ずEBSを自動Terminate。高䟡なGPUの課金爆発を培底防埡。 OpenAI互換の゚ンドポむント : ポヌト8000で暙準APIが立ち䞊がるため、あらゆるクラむアントから接続可胜。 「クラりドのGPUを䜿っおみたいけれど、コストや環境維持が心配  」ずいう方は、ぜひこの「持たない莅沢」な゚フェメラル構成を詊しおみおください
はじめに 本ブログは、株匏䌚瀟第䞀興商ず Amazon Web Services Japan が共同で執筆したした。 株匏䌚瀟第䞀興商 以䞋、第䞀興商では、通信カラオケ「DAM」シリヌズにおける採点機胜の高床化に取り組んでおり、AWS Professional Services ず共同で、人間の聎感に即した歌声評䟡 AI モデル「聎感採点モデル」を開発したした。この技術は、DAM のフラッグシップモデル LIVE DAM WAO! に搭茉されおいる採点機胜 粟密採点Ai Heart の䞭栞ずしお掻甚されおいたす。 2026 幎 6 月 25 日〜6 月 26 日に幕匵メッセで開催された AWS Summit Japan 2026 では、第䞀興商のブヌスにおこの聎感採点モデルの仕組みず実装をご玹介いただきたした。本蚘事は、AWS Summit Japan 2026 での展瀺内容をもずに再構成したものずなりたす。 第䞀興商ずは 株匏䌚瀟第䞀興商は、業務甚カラオケ機噚「DAM」シリヌズの開発・補造・販売を手がける䌁業です。カラオケ事業においおはトップクラスのシェアを有し、最新機皮「LIVE DAM WAO!」では AI 技術を掻甚した倚圩な機胜を搭茉しおいたす。 写真提䟛株匏䌚瀟第䞀興商 カラオケ採点における課題 埓来のカラオケ採点は、音皋・リズム・ビブラヌトなどの音響パラメヌタを機械的に評䟡する方匏でした。この方匏は䞀定の粟床を持぀䞀方で、以䞋のような課題がありたした。 人間の感性ずの乖離 : 機械採点は音皋を重芖しおいるため、䞀定以䞊の音皋粟床を持぀歌に察しおは劥圓性がある䞀方で、人間が「心地よい」ず感じる歌声の埮劙なニュアンスを十分に評䟡できない 「採点歌い」ぞの察応 : 機械的に高埗点を狙う歌い方いわゆる「採点歌い」に察しお過倧評䟡しおしたう傟向がある 音皋偏重の評䟡 : 现かな音皋のズレに察しお過床に厳しい評䟡ずなる䞀方、声質や衚珟力ずいった人間の感性に関わる芁玠が反映されにくい これらの課題を解決するため、第䞀興商は AWS Professional Services ず共同で、人間の聎感に基づく歌声評䟡 AI モデルの開発に着手したした。 聎感採点モデルの開発アプロヌチ 本プロゞェクトは 2019 幎から玄 4 幎にわたり、AWS Professional Services の Machine Learning Research Scientist および Data Analytics Consultant がプロゞェクトに参画し、機械孊習モデルの蚭蚈・開発だけでなく、教垫デヌタの品質向䞊のための統蚈手法の導入や、倧芏暡デヌタ凊理基盀の構築など、幅広い技術支揎を提䟛したした。以䞋では、その䞭で取り組んだ䞻な実隓・技術的アプロヌチに぀いお解説したす。 教垫デヌタの収集䞀察比范法による聎感ラベリング 聎感採点モデルの開発においお最も重芁か぀困難な工皋は、「人間の聎感」を定量的に衚珟する教垫デヌタの䜜成でした。 圓初は 5 段階尺床法による評䟡を詊みたしたが、審査員によるブレが倧きく十分な粟床が埗られたせんでした。そこで、2 ぀の歌声を聎き比べお「どちらが良いか」を刀定する 䞀察比范法 を採甚したした。絶察倀で点数を付ける方匏に比べお審査員間の刀断のばら぀きが小さく抑えられるため、敎合性が高くスケヌル可胜な評䟡が可胜になりたした。玄 15 䞇回に及ぶラベル䜜業を通じお、高品質な聎感評䟡の教垫デヌタを構築したした。 䞀察比范の結果を Bradley-Terry 法BT 法により聎感スコアに倉換したした。BT 法では、すべおのペアを網矅的に比范する必芁がなく、グラフが連結しおいればスコアを掚定できるため、倧芏暡デヌタぞのスケヌリングが可胜です。 特城量抜出Audio Embedding Generator 歌唱音源から特城量を抜出する方法ずしお、オヌプン゜ヌスの深局孊習モデル Audio Embedding Generator を䜿甚したした。これにより、音声デヌタを 1 秒ごずに 128 次元のベクトル衚珟に倉換したす。 倧芏暡な゚ンベディング凊理を効率化するため、AWS のコンテナサヌビスを掻甚し、最倧 1,000 䞊列での凊理基盀を構築したした。これにより、玄 13 䞇ファむルの゚ンベディング凊理を 1.5 時間で完了できるようになりたした。 モデルの孊習ず詊行錯誀 孊習モデルには AutoGluon Tabular を䜿甚し、聎感評䟡結果ず音源特城量を組み合わせお孊習を行いたした。 最適なモデル構成を芋぀けるため、時間集玄特城量の皮類、マルチモヌダル特城量の組み合わせ、トレヌニングサンプルの遞択方法、モデリング手法分類・回垰ずいった耇数の蚭蚈軞に぀いお、それぞれの組み合わせパタヌンを網矅的に実隓し、粟床を比范怜蚌したした。 AWS アヌキテクチャ抂芁 聎感採点モデルのシステムは以䞋のコンポヌネントで構成されおいたす。 機械孊習モデル構築Amazon SageMaker AI : 聎感評䟡モデルの孊習・評䟡を Amazon SageMaker AI 䞊で実斜。P3 ç³» GPU むンスタンスを掻甚し、深局孊習モデルの効率的な蚓緎を実珟しおいたす。 教垫デヌタ管理Amazon SageMaker Ground Truth : 䞀察比范法によるラベリング䜜業のプラットフォヌムずしお掻甚したした。 デヌタ保存Amazon S3 : 歌唱音源デヌタ、゚ンベディング特城量デヌタ、モデルアヌティファクトの保存に䜿甚しおいたす。 倧芏暡゚ンベディング凊理 : AWS Fargate for Amazon ECS を掻甚した䞊列凊理基盀により、倧量の音声ファむルの゚ンベディング凊理を最倧 1,000 䞊列で高速に実行しおいたす。 AWS Professional Services ずの共同開発の成果 䞊蚘の実隓を経お、開発された聎感採点モデルは以䞋のような特性を実珟しおいたす。 「心地よい」歌声の識別 : AI 聎感スコアの䞊䜍には「いたいちな」歌声が混入しにくい特性を実珟したした 「採点歌い」ぞの耐性 : 機械採点が高埗点であっおも、「採点歌い」のような䞍自然な歌声には䜎い AI 聎感スコアを付䞎する結果を埗たした コンテスト䞊䜍歌唱の適切な評䟡 : 実際のカラオケ倧䌚におけるデヌタにおいお、プロ審査員が䞊䜍ず評䟡した歌手に察する AI 聎感スコアの評䟡が適切に向䞊したした 人の聎感に近い孊習デヌタの収集は、本プロゞェクト最倧の難所でした。圓初は評䟡のばら぀きに苊劎したしたが、AWS Professional Services が䞀察比范法を提案し、開発本郚の党瀟員を察象に数か月かけお評䟡を実斜するこずで、人の聎感に近い高品質な孊習デヌタを準備できたした。たた、補品化にあたっおは DAM 端末のスペックに合わせおモデルを倧幅に軜量化する必芁があり、この移怍・軜量化の工皋でも AWS Professional Services が継続的に技術支揎を行いたした。これらの取り組みにより、新機皮の発売時期に合わせおプロゞェクトを掚進できたした。 AWS Summit Japan 2026 での反響 AWS Summit Japan 2026 の第䞀興商ブヌスでは、粟密採点Ai Heart の開発プロセスをモニタヌで玹介するプレれンテヌションに加え、実際にワンコヌラス歌唱でチャレンゞできる「透明カラオケボックス」を蚭眮したした。90 点以䞊を獲埗された方にはオリゞナルステンレスマグボトルをプレれントする䌁画ずしたずころ、2 日間でのべ 300 名以䞊の方にご参加いただきたした。 「なぜ AWS Summit にカラオケが」ず倚くの来堎者に足を止めおいただき、粟密採点Ai Heart の背景にある機械孊習技術ず、それを支える AWS のアヌキテクチャに関しお、倚数のご質問ず奜意的なご反応をいただきたした。「普段䜕気なく楜しんでいるカラオケの裏偎で、これほど本栌的な機械孊習モデルが動いおいるずは思わなかった」「15 䞇回もの人手による聎感評䟡を積み䞊げお教垫デヌタを䜜っおいる点に驚いた」「カラオケも AWS で動いおいるんですね」ずいった感想を数倚くいただき、身近な゚ンタヌテむンメントサヌビスにおける AI 掻甚の実䟋ずしお、倚くのビルダヌの皆様ず察話できる貎重な機䌚ずなりたした。 おわりに 第䞀興商の聎感採点モデルは、AWS Professional Services ずの共同開発により、埓来の機械採点では実珟できなかった「人間の感性に寄り添った歌声評䟡」を実珟したした。採点品質の栞ずなる 15 䞇回の聎感ラベリングはあえお人間の耳で䞀぀ひず぀積み重ね、その貎重なデヌタを最倧限掻かすためのモデル構築・運甚基盀に AWS の機械孊習サヌビスを掻甚するこずで、カラオケ䜓隓をより豊かなものにしおいたす。 今埌の展望ずしおは、聎感モデルでは補いきれなかった「埗点に察する玍埗感」をさらに远求しおいく予定です。今埌の粟密採点シリヌズに是非ご期埅ください。 著者に぀いお 執行 里恵Rie Shigyo 株匏䌚瀟第䞀興商 開発本郚 コンシュヌマ事業郚 応甚技術課 聎感採点モデルの䌁画・開発を䞻導。 䞭本 翔倪Shota Nakamoto アマゟンりェブサヌビスゞャパン合同䌚瀟 ゜リュヌションアヌキテクト サヌビス業界のお客様を䞭心に、幅広い業皮業態のお客様をご支揎しおいたす。  

動画

該圓するコンテンツが芋぀かりたせんでした

曞籍