GitHubにある機械学習プロジェクトを、RenderのWeb Serviceを使って実際にWeb上へ公開するまでの手順をまとめます。
はじめに
初めて機械学習を使ったプロジェクトをGitHubにアップロードした際、無料でWeb上に公開してみたいと思い調べました。
ローカルで動いているFastAPI + PyTorchアプリを、できるだけ構成を変えずに公開することを目的としていたため、今回はRenderを選びました。
GitHubリポジトリ:
公開したWebアプリ:
YouTubeで公開した動画:
この記事では、単なる静的サイトではなく、バックエンドやAPIを持つWebアプリを公開したい人を対象に、なぜRenderを選んだのか、Renderの制限、GitHubとの接続、そして実際のデプロイまでを順番に説明します。
1. 無料でデプロイする候補
Webアプリを公開する方法を調べると、GitHub Pages、Vercel、Renderなど、さまざまなサービスが候補になります。
今回のAVESでは、ユーザーが画像をアップロードすると、
画像
↓
FastAPI
↓
PyTorch
↓
MobileNetV2
↓
鳥の種類を予測
↓
結果をブラウザに返す
という順番で処理を行います。
つまり、HTML・CSS・JavaScriptだけではなく、Pythonを実行してAPIとして画像を処理するバックエンドが必要です。
① Render・Vercel・GitHub Pagesの違い
| 項目 | Render | Vercel | GitHub Pages |
|---|---|---|---|
| 静的サイト | ○ | ○ | ○ |
| JavaScript | ○ | ○ | ○ |
| Pythonバックエンド | ○ | ○¹ | × |
| FastAPI | ○ | ○¹ | × |
| サーバー上でPyTorchを実行 | ○ | 制約あり¹ | × |
| 今回のAVESとの相性 | ◎ | △ | × |
| 主な用途 | Web Service / API / Webアプリ | フロントエンド / サーバーレス | 静的サイト |
¹ VercelでもPythonやFastAPIを利用できます。ただし、VercelではPythonアプリをServerless Functionsとして実行する構成が基本です。
GitHub Pagesは静的サイト向けなので、今回のようにFastAPIやPyTorchをサーバー側で実行するアプリには向いていません。
今回は、ローカルで動いているFastAPI + PyTorchアプリを、できるだけ構成を変えずに公開することだったため、今回はRenderを選びました。
2. Renderの特徴
Renderは、WebアプリケーションやAPIなどをクラウド上にデプロイできるプラットフォームです。
GitHubなどのGitリポジトリと接続すると、リポジトリのコードを取得し、Build Commandで依存関係をインストールした後、Start Commandでアプリを起動できます。
今回使用するのは Web Service です。
RenderではStatic Siteも利用できますが、今回のAVESではFastAPIを実行する必要があるため、Static SiteではなくWeb Serviceを選びました。
① Static SiteではなくWeb Serviceを使う理由
Static Siteは、HTML・CSS・JavaScriptなどの静的サイトを配信するためのものです。
一方、AVESではFastAPIが画像を受け取り、PyTorchを使って画像を処理する必要があります。
そのため、
Static Site
↓
HTML / CSS / JavaScript
ではなく、
Web Service
↓
FastAPI
↓
PyTorch
↓
MobileNetV2
という構成になります。
② Render Freeプランの制限
❶ 15分間アクセスがないと停止する
RenderのFree Web Serviceは、15分間インバウンドトラフィックがないとスピンダウンします。
その後、再びアクセスするとサービスが再起動します。
AVESみたいな個人開発のデモとしては十分ですが、常に低遅延で応答することが必要な本番サービスでは注意が必要です。
❷ ファイルシステムは永続的ではない
Free Web Serviceのファイルシステムは永続的ではありません。
今回のAVESでは、学習済みモデルの、bird_classifier.pthをリポジトリに含め、デプロイ時にアプリと一緒に配置しています。
そのため、ユーザーがアップロードした画像などを永続保存する設計にはしていません。
❸ 無料の稼働時間には上限がある
RenderのFree Web Serviceには、ワークスペースあたり月750時間のFree instance hoursがあります。
Free Web Serviceの稼働時間がこの枠にカウントされます。無料枠を使い切ると、その月の残り期間はFree Web Serviceが停止されます。
3. 今回のアプリの構成
今回作ったAVESは、鳥の画像を分類するWebアプリです。
モデルには MobileNetV2 を使用しています。
学習したモデルは、bird_classifier.pthとして保存しています。
処理手順は、
ユーザー
↓
画像をアップロード
↓
HTML / JavaScript
↓
POST /predict/
↓
FastAPI
↓
画像を処理
↓
MobileNetV2
↓
Softmax
↓
予測結果 + Confidence + 豆知識を表示
という流れです。
4. デプロイ前の準備
ここから実際にRenderへデプロイします。
今回のプロジェクトは、GitHubでの最低限の構成は
AVES/
├── web.py
├── bird_classifier.pth
├── requirements.txt
└── README.md
① web.py
FastAPIのアプリケーション本体です。
ファイル内で、
app = FastAPI()
としてFastAPIのアプリケーションを作成しています。
また、学習済みモデルを読み込みます。
② bird_classifier.pth
モデルの学習にはbird_classifier.pyを使用しましたが、Webアプリとして必要なのは、学習によって生成されたbird_classifier.pthです。
③ requirements.txtを作る
Renderで必要なPythonパッケージをインストールできるように、プロジェクトのルートにrequirements.txtを作ります。
今回使用した内容は以下です。
fastapi
uvicorn[standard]
torch
torchvision
Pillow
python-multipart
| パッケージ | 用途 |
|---|---|
| FastAPI | API・Webサーバー |
| Uvicorn | FastAPIを起動するASGIサーバー |
| PyTorch | 機械学習モデルの推論 |
| Torchvision | MobileNetV2などの画像モデル |
| Pillow | 画像の読み込み・変換 |
| python-multipart | ファイルアップロードの処理 |
後ほどRenderのBuild Commandで、
pip install -r requirements.txt
を指定することで、Render側に必要なパッケージをインストールできます。
5. Renderでデプロイの流れ
① 事前準備を済ませたら、Renderにログインします。
DashboardからNew → Web Serviceを選択します。
その後、GitHubアカウントを接続し、デプロイしたいリポジトリを選択します。
接続後、デプロイしたいリポジトリを選択します。
② Name
好きな名前を設定します。
この名前はRender上のサービス名やonrender.comのサブドメインに使用されます。
今回はAVESと設定しました。
③ Language
LanguageではPythonを選択。
④ Branch
通常は、main を選択します。GitHubで別のブランチを使用している場合は、そのブランチを選択してください。
⑤ Build Command
Build Commandには、
pip install -r requirements.txt
と入力します。
Build Commandは、Renderがアプリを起動する前に実行するコマンドです。
⑥ Start Command
次にStart Commandを設定します。
今回使用したコマンドは、
uvicorn web:app --host 0.0.0.0 --port $PORT
ここは特に重要なので、それぞれの機能を解説します。
❶ web:appとは?
今回のファイル名は、web.pyです。
その中に、
app = FastAPI()
があります。
したがって、web:appは、
web.py
↓
app
を意味します。
もしファイル名がmain.pyで、FastAPIの変数がappなら、
main:app
になります。
❷ --host 0.0.0.0 は?
--host 0.0.0.0
外部からのHTTPリクエストを受けられるよう、アプリをすべてのネットワークインターフェースで待ち受けるために指定しています。
RenderのWeb Serviceでは、公開HTTPサーバーを0.0.0.0にバインドする必要があります。
❸ --port $PORT
portも重要です。
Renderでは実行時にポート番号をPORT環境変数として渡します。
そのため、--port 8000 のようにポートを固定するのではなく、
--port $PORT
として、Renderから渡されたポートを使用します。
⑦ Freeプランを選択
AVESは学習・ポートフォリオ目的のアプリなので、まずは無料プランで十分だと判断しました。
Freeプランの制限については、先ほど説明した通り、
- 15分間アクセスがないとスピンダウンする
- ローカルファイルが永続保存されない
- 月750時間のFree instance hoursがある
- 帯域幅やビルドにも利用量の制限がある
といった点に注意が必要です。
⑧ 環境変数
APIキーなどの秘密情報を使用するアプリの場合は、RenderのEnvironment Variablesを利用します。
APIキー、パスワード、アクセストークンなどをGitHubに直接書かないようにしてください。
ここまでの設定が終わったら、Create Web Serviceをクリックします。
6. デプロイ後
デプロイが成功すると、Renderから、
https://設定した名前.onrender.com
のようなURLが発行されます。デプロイ中はRenderのLogsから、ビルドやアプリの起動状況を確認できます。
7. デプロイに失敗した場合
Renderでのデプロイは、設定を間違えるとエラーになることがあります。
今回特に確認したいのは、以下の3点です。
① web.pyが見つからない
例えば、
Error loading ASGI app.
Could not import module "web".
と表示された場合、Renderがweb.pyを見つけられていない可能性があります。
まずGitHub上で、
AVES/
├── web.py
├── requirements.txt
└── ...
となっているか確認します。
さらにStart Commandが、
uvicorn web:app --host 0.0.0.0 --port $PORT
になっているか確認します。
② ModuleNotFoundErrorが出る
例えば、
ModuleNotFoundError: No module named 'fastapi'
などが出た場合は、requirements.txtを確認します。
必要なライブラリが入っているか確認し、変更をGitHubにpushした後、再度デプロイします。
③ bird_classifier.pthが見つからない
例えば、
FileNotFoundError:
bird_classifier.pth
と表示された場合は、モデルファイルがGitHubリポジトリに存在するか確認します。
私自身、実際のデプロイ時に
.pth忘れてしまい、このエラーが発生しました
8. デプロイ後の動作
デプロイが成功した後、ブラウザからAVESを開いて画像をアップロードします。
フロントエンドでは画像をFormDataへ送信します。
最終的に、
{
"class": "blue_jay",
"confidence": 0.962
}
のようなJSONを返し、ブラウザ上に予測結果を表示します。
9. まとめ
今回のデプロイで行ったことをまとめると、
1. FastAPIアプリを作る
↓
2. 学習済みモデル(.pth)を用意する
↓
3. requirements.txtを作る
↓
4. GitHubにコードをアップロード
↓
5. RenderでWeb Serviceを作成
↓
6. GitHubリポジトリを接続
↓
7. Build Commandを設定
↓
8. Start Commandを設定
↓
9. Environment Variablesを設定(必要な場合)
↓
10. Freeプランを選択
↓
11. Create Web Service
↓
12. 公開URLからアクセス
機械学習モデルを作るだけでなく、APIとして提供し、Webアプリとしてユーザーが利用できる状態まで持っていくことで、モデルを実際のサービスへ組み込む流れについても学ぶことができました。
これからバックエンド付きのWebアプリを作ってみたい人は、まずローカル環境で動かし、その後GitHubにpushして、RenderのWeb Serviceに接続するという流れで試してみると分かりやすいと思います。


