この記事は何
最近GPUリソースを利用する処理を行うAPIを実装する必要があり、FastAPIをGCE上に立てました。
あまり方法がまとまっている記事がなかったので記事としてまとめます。
前提
GCEはDockerでもホストすることができますが、Container-Optimized OSを用いるとGPUリソースの利用がとてもめんどくさく、また動かせたとしてもパフォーマンスはネイティブで実行した場合の方が高いことがわかったので今回はDockerを用いずにホストを行います。
また、今回は処理が非常にシンプルでオートスケーリングなども考える必要がないので、一つのサーバーでFastAPIを立ち上げることを想定しています。
GCEのセットアップ
まずはGCEのセットアップを行います。
セットアップを行う上でのポイントは以下の通りです。
- OSはDebian系を利用
- ファイアウォールでhttpリクエストを許可する
ファイアウォールの設定については以下の記事をご覧ください。
スクリプト
とりあえず以下のスクリプトとアプリケーションコードをSSHなどでサーバーに入り実行すればFastAPIのサーバーにHTTPアクセスできます。
コードはGitHubなどで管理し、cloneをしてくると簡単にセットアップができると思います。
Pythonのバージョンは利用するイメージによって変更してください。
#!/bin/bash
# エラーが発生した場合スクリプトを停止
set -e
# --- 仮想環境のセットアップ ---
echo "Creating Python 3.10 virtual environment..."
python3.10 -m venv .venv
echo "Activating virtual environment..."
source .venv/bin/activate
# --- Pythonライブラリのインストール ---
echo "Upgrading pip..."
pip install --upgrade pip
echo "Installing PyTorch for CUDA 12.x..."
# PyTorchのバージョンとCUDAバージョンの互換性を確認してください。
# 公式サイト (https://pytorch.org/) で適切なコマンドを確認することをお勧めします。
# ここではCUDA 12.1向けの一般的なコマンドを使用します。
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
echo "Installing dependencies from requirements.txt..."
pip install -r requirements.txt
echo "Setup complete."
# --- iptables のインストール ---
echo "Checking and installing iptables if necessary (Debian/Ubuntu)..."
if ! command -v iptables &> /dev/null; then
echo "iptables not found, attempting to install..."
sudo apt-get update && sudo apt-get install -y iptables
else
echo "iptables is already installed."
fi
# --- ここまで iptables インストール ---
# --- 既存のサーバープロセスを停止 ---
echo "Stopping existing Uvicorn server processes if any..."
# 'uvicorn app.main:app' を含むプロセスを検索して停止 (-f オプションでコマンドライン全体を検索)
# プロセスが存在しなくてもエラーにならないように || true を追加
pkill -f "uvicorn app.main:app" || true
# --- ポートフォワーディング設定 (iptables) ---
echo "Setting up port forwarding using iptables..."
# このコマンドは sudo 権限が必要です
echo "Forwarding HTTP (80) to 8000..." # HTTPルールを削除
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8000 # HTTPルールを削除
echo "Port forwarding rule added."
# --- サーバーの起動 ---
echo "Starting Uvicorn server in the background..."
# nohupでバックグラウンド実行し、出力を nohup.out にリダイレクト
nohup uvicorn app.main:app --host 0.0.0.0 --port 8000 > nohup.out 2>&1 &
# 仮想環境を無効化
deactivate
echo "Setup script finished. Uvicorn is running in the background."
必須になるrequirements.txtは以下の通りです。
fastapi
uvicorn[standard]
ポイントの説明
この処理の中でのポイントを簡単に紹介します。
iptablesの利用
基本的にGCEのOSは80番ポートを直接開けることはできません。
その代わりに、iptablesを用いて80番ポートのリクエストを8000番に流しています。
こうすることで権限などを特にいじらずにHTTPリクエストをFastAPIで受け取ることが可能です。
nohupの利用
今回はプロセスをバックグラウンド化するのにnohupを用いており、スクリプトを実行するごとに既存のプロセスを殺し再起動するようにしています。
よりちゃんとしたい場合はsystemdなどを用いてデーモン化するのも良いと思います。