AWS EC2 Ubuntu GPU 深層学習環境:安全で再現可能な 2026 セットアップ

Amazon EC2 で安全かつ再現可能な Ubuntu GPU ワークフロー

2017 年版のチェックリストは、全員が書き込める Git デプロイフック、古い Bazel リポジトリ設定、バージョン未指定の TensorFlow ソースビルド、固定されていない Python パッケージ、公開 Notebook の手順を混在させていました。いずれも現在の標準手順には適しません。

2026 年版では最初にバージョン行列とコスト境界を決め、Jupyter をループバックだけにバインドして認証付きトンネルから利用し、マシンを安全に再現または廃止できる証拠を残します。これはワークフローであり、任意のフレームワーク版が任意の GPU、CPU アーキテクチャ、ドライバ、CUDA スタックと動くという保証ではありません。起動前とインストール前に、選択したリリースの公式行列を確認してください。

1. プラットフォーム経路を意図的に一つ選ぶ

経路適する用途再現性の境界
AWS Deep Learning AMI(DLAMI)対話作業を最短でサポート対象として開始リージョンと AMI ID を固定し、そのイメージのリリースノートを読み、文書どおりに環境を有効化し、プリインストール済み CUDA やフレームワークを安易に置換しない
AWS Deep Learning Containerチームのワークフロー、CI、反復可能なジョブ不変ダイジェストでイメージを固定し、ホストドライバと GPU ランタイムを記録し、データと秘密をイメージ外に置く
標準 Ubuntu AMI完全な制御が必要、または AWS イメージが要件を満たさない場合Ubuntu AMI を固定し、現在の NVIDIA 手順だけでドライバ/ツールキットを導入する。この経路は互換性確認とパッチ管理が最も多い

AWS DLAMI には一般的なフレームワークと NVIDIA コンポーネントが構成済みです。AWS Deep Learning Container 文書から保守中のコンテナカタログへ進めます。標準 Ubuntu は自動的に再現性が高いわけではありません。AMI、リポジトリのキーリング、パッケージ版、フレームワークのロック、検証出力を記録して初めて再現可能になります。

インストール途中で経路を混ぜないでください。特に、選択したフレームワーク文書が明示的に対応すると示さない限り、無関係な CUDA runfile、ディストリビューションパッケージ、pip 提供の CUDA ライブラリを一つの環境に重ねないでください。

2. 起動前に互換性インベントリを作る

最も新しそうな GPU からではなく、必要なフレームワークリリースから外側へ選択します。次の各セルを記録してください。

記録する正確な値根拠/確認方法
AWS 配置リージョン、アベイラビリティーゾーン、インスタンスタイプ、購入モデル現在の EC2 コンソール/API とアクセラレーテッドインスタンス仕様
マシンイメージAMI ID、イメージ名、所有者、作成日EC2 イメージ詳細。ID はリージョン固有
CPUx86_64 または arm64インスタンス仕様と uname -m
GPUモデル、数、メモリ、NVIDIA アーキテクチャ、Compute CapabilityEC2 仕様、nvidia-smiNVIDIA CUDA GPU 表
ドライバ正確なドライバ版nvidia-smiNVIDIA ドライバユーティリティ資料
CUDAドライバが対応する CUDA 上限と、別にインストール済みツールキット版nvidia-sminvcc の導入証明ではない。該当時は nvcc --version
フレームワーク名前、正確な版/ビルド、対応 Python/CUDA/cuDNN/Compute Capability選択したリリースの公式インストール/ビルド行列
Python 環境Python、pip、直接・推移依存すべて、wheel ハッシュこの OS、CPU アーキテクチャ、Python 版向けに作ったロックファイル

不明なセルがある、AMI の所有者が想定と違う、CPU アーキテクチャ向け wheel がない、GPU メモリまたは Compute Capability が不足する、フレームワーク行列がドライバ/CUDA の組み合わせと矛盾する場合は、起動前に止めます。

3. セキュリティとコスト制御を先に置く

  • GPU インスタンス開始前に AWS Budget と通知を作ります。通知だけでは自動停止しません。自動制御が目的なら予算アクションを別途設定してテストします。選択リージョンの現在料金、Spot 中断、クォータ、EBS、スナップショット、パブリック IPv4、転送、アイドル資源を確認します。
  • インバウンドルール不要の Systems Manager Session Manager を優先します。SSH が必要なら TCP 22 を固定管理者 CIDR だけに許可します。8888 を 0.0.0.0/0::/0 に公開してはいけません。
  • 必要なアーティファクト、データ、ログ、Systems Manager 資源だけに限定した最小権限のインスタンスロールを付けます。長期 AWS アクセスキーをインスタンスへコピーしません。
  • IMDSv2 を必須にします。ホストのみの構成では hop limit を 1 に保ち、コンテナネットワークで必要な値は明示的に審査します。必要でない限り、メタデータからインスタンスタグを公開しません。
  • EBS を暗号化し、可能なら永続データと使い捨て作業領域を分離し、各ボリュームの DeleteOnTermination を確認します。インスタンスストアのデータは一時的と見なします。
  • 専用 Unix ユーザーと制限的な権限を使います。chmod -R 777、無認証のデプロイフック、共有書き込み可能な checkout は使いません。

権限を持つ管理端末から、既存インスタンスに IMDSv2 を必須化します。

INSTANCE_ID='replace-with-instance-id'

aws ec2 modify-instance-metadata-options 
  --instance-id "$INSTANCE_ID" 
  --http-tokens required 
  --http-endpoint enabled 
  --http-put-response-hop-limit 1 
  --instance-metadata-tags disabled

第一者資料は IMDS 設定EC2 IAM ロールセキュリティグループルールEBS 暗号化AWS Budgetsです。

4. 変更前に稼働中ホストを記録する

通常のインスタンスユーザーで実行します。IMDSv2 トークンは短命で、マニフェストに書き込まず、秘密ではない二つのメタデータ項目を取得後に破棄します。トークンヘッダーは curl の引数リストではなく標準入力経由で渡しますが、shell とホストは信頼済みとして扱います。運用インベントリにも機密性のある基盤情報が含まれ得るため、run-manifest/ は非公開にします。

set -euo pipefail
umask 077
mkdir -p run-manifest

cat /etc/os-release | tee run-manifest/os-release.txt
uname -m | tee run-manifest/cpu-architecture.txt
python3 --version 2>&1 | tee run-manifest/python-system.txt

metadata_base='http://169.254.169.254/latest'
metadata_token="$(curl --fail --silent --show-error 
  --request PUT 
  --header 'X-aws-ec2-metadata-token-ttl-seconds: 60' 
  "$metadata_base/api/token")"
for key in ami-id instance-type; do
  builtin printf 
    'header = "X-aws-ec2-metadata-token: %s"n' 
    "$metadata_token" 
    | curl --fail --silent --show-error 
      --config - 
      "$metadata_base/meta-data/$key" 
    | tee "run-manifest/$key.txt"
  printf 'n'
done
unset metadata_token

command -v nvidia-smi >/dev/null || {
  printf '%sn' 'nvidia-smi is missing; stop and repair the driver path.' >&2
  exit 1
}
nvidia-smi | tee run-manifest/nvidia-smi.txt
nvidia-smi 
  --query-gpu=name,pci.bus_id,driver_version,memory.total 
  --format=csv,noheader 
  | tee run-manifest/gpu-inventory.csv

if command -v nvcc >/dev/null; then
  nvcc --version | tee run-manifest/nvcc.txt
else
  printf '%sn' 'nvcc not installed; no local CUDA toolkit recorded.' 
    | tee run-manifest/nvcc.txt
fi

標準 Ubuntu 経路では、現在の NVIDIA CUDA Installation Guide for Linuxに従います。そこでサポートされるリポジトリ/キーリング手順と事前確認を使い、古い apt-key、未署名リポジトリ、HTTP パッケージソースを復活させません。ドライバ変更後、公式手順が要求すれば再起動して再度記録し、ドライバ/ライブラリ不一致なら停止します。

5. 隔離されロックされた Python 環境を作る

選択したフレームワークビルドが対応する Python 版を使います。仮想環境は Python パッケージを隔離しますが、ドライバやシステムライブラリの互換性は解決しません。

本番と同じ OS、CPU アーキテクチャ、Python マイナー版、パッケージインデックスポリシーで requirements.lock を作ります。直接・推移依存をすべて固定し、検証済みハッシュを含めます。使用前にロックをレビューし、長期環境へ版指定なしの pip install tensorflow numpy pandas jupyter を実行しません。

set -euo pipefail
umask 077

python3 -m venv .venv
.venv/bin/python -m pip install 
  --require-hashes 
  --only-binary=:all: 
  --requirement requirements.lock
.venv/bin/python -m pip check
.venv/bin/python -m pip freeze --all 
  | tee run-manifest/python-freeze.txt
sha256sum requirements.lock 
  | tee run-manifest/requirements-lock.sha256

対応対象の標準 Linux GPU 構成では、TensorFlow の現在の公式 pip 経路は tensorflow[and-cuda] extra を使いますが、正確なリリースと解決された全依存をロックする必要があります。DLAMI では文書指定の構成済み環境を有効化する場合があります。TensorFlow pip インストール、Python の venv 文書、pip の再現可能インストール指針を確認してください。

6. フレームワークが GPU 上で実行されることを証明する

nvidia-smi だけでなく、フレームワークレベルの演算を実行します。次の TensorFlow スモークテストはパッケージビルド、可視デバイス、デバイス詳細を表示し、行列積が GPU 0 に配置されることを要求します。

import json
import platform

import tensorflow as tf

tf.random.set_seed(20260901)
gpus = tf.config.list_physical_devices("GPU")
report = {
    "python": platform.python_version(),
    "tensorflow": tf.__version__,
    "build": tf.sysconfig.get_build_info(),
    "gpus": [
        tf.config.experimental.get_device_details(device)
        for device in gpus
    ],
}
print(json.dumps(report, indent=2, default=str))

if not gpus:
    raise SystemExit("no GPU visible to TensorFlow")

with tf.device("/GPU:0"):
    left = tf.random.uniform((512, 512))
    right = tf.random.uniform((512, 512))
    product = tf.linalg.matmul(left, right)

print({"device": product.device, "shape": product.shape.as_list()})
if "GPU:0" not in product.device.upper():
    raise SystemExit(f"operation was not placed on GPU 0: {product.device}")

ロック済み環境のインタプリタで実行し、出力をジョブ記録に残します。GPU が見えるだけでは、数値の正しさ、モデル収束、複数 GPU 通信、混合精度動作、メモリ容量を証明できません。実際のワークロードに近い小さなテストも加えます。

7. Jupyter をローカルかつ認証付きに保つ

Jupyter Server はコードを実行できるため、そのアクセスを shell アクセスと同様に扱います。トークン認証は既定で有効です。認証を有効のままにし、生成トークンをチケットやログに記録せず、ループバックだけにバインドします。

set -euo pipefail
umask 077
mkdir -p notebooks
cd notebooks

../.venv/bin/jupyter lab 
  --no-browser 
  --ServerApp.ip=127.0.0.1 
  --ServerApp.port=8888 
  --ServerApp.port_retries=0 
  --ServerApp.open_browser=False

8888 のインバウンドセキュリティグループルールを追加しません。管理端末から次のいずれかのトンネルを使います。SSH の場合:

ssh -N 
  -L 127.0.0.1:8888:127.0.0.1:8888 
  ubuntu@replace-with-hostname

または Session Manager の前提設定を完了し、ローカルプラグインを導入した後:

INSTANCE_ID='replace-with-managed-instance-id'

aws ssm start-session 
  --target "$INSTANCE_ID" 
  --document-name AWS-StartPortForwardingSession 
  --parameters '{"portNumber":["8888"],"localPortNumber":["8888"]}'

ローカルで http://127.0.0.1:8888/ を開き、インスタンス端末だけに表示されたトークンを入力します。永続パスワードが必要なら Jupyter の対話式パスワードコマンドを使い、ハッシュだけを保存します。パスワードとトークンを同時に無効化してはいけません。Jupyter Server セキュリティループバック既定値と公開サーバーの警告AWS Session Manager ポート転送を参照してください。

8. コード、秘密、データ、ログを分離する

  • コード:通常ユーザー所有の checkout を使います。Git で正確な commit と submodule を記録し、未審査の post-receive フックでデプロイしません。
  • 秘密:範囲を限定したインスタンスロールと承認済みシークレットストアを使います。キーを commit、Notebook、AMI/コンテナ、インベントリログへ入れません。
  • 入力データ:可能なら読み取り専用でマウントまたは取得します。データセット版とチェックサムを記録し、非公開オブジェクト URL や顧客識別子は記録しません。
  • 出力:明示した周期で、永続暗号化 EBS または承認済みオブジェクトストレージに checkpoint を書きます。インスタンスストア利用機を停止する前に遠隔コピーを検証します。
  • ログ:パッケージ、ドライバ、フレームワーク、コマンド、終了状態、時刻、ワークロード指標を記録し、集中保存前にトークン、署名 URL、プロンプト、個人・規制対象データを除去します。

デプロイ権限を変えずにソース状態を記録します。

set -euo pipefail

git status --porcelain=v1
git rev-parse HEAD | tee run-manifest/source-commit.txt
git submodule status --recursive 
  | tee run-manifest/source-submodules.txt

commit 照会は Git `rev-parse`に記載されています。dirty な状態は再現性の停止条件です。高価なジョブの前に commit、破棄、または差分を明示的にアーカイブします。

9. ソースビルドを例外として扱う

ソースパッチ、未対応 Compute Capability、コンパイラ要件が不可避でない限り、リリース済み wheel、DLAMI 環境、または不変コンテナを使います。TensorFlow をビルドする前に、テスト済みビルド構成と該当する Bazel インストール文書から次の行列を埋めます。

必須の固定項目記録値
TensorFlow タグと完全な Git commit
Python 版
Bazel 版
コンパイラと標準ライブラリ版
NVIDIA ドライバ、CUDA ツールキット、cuDNN
GPU モデル、アーキテクチャ、Compute Capability
ベース AMI またはコンテナダイジェスト
ビルドフラグ、パッチ、wheel ハッシュ、期待テスト

現在の Bazel が古い TensorFlow を構築できると仮定してはいけません。互換性セルが文書根拠ではなく推測のままなら続行しません。

set -euo pipefail
SOURCE_REF='replace-with-reviewed-tag-or-commit'

git clone --filter=blob:none 
  https://github.com/tensorflow/tensorflow.git
git -C tensorflow fetch --tags --prune
git -C tensorflow checkout --detach "$SOURCE_REF"
git -C tensorflow status --porcelain=v1
git -C tensorflow rev-parse HEAD

使い捨てボリュームまたはコンテナ内でビルドし、完全なログを保存し、ソースツリー外の新しい環境で wheel を検証してチェックサムを残します。ビルド完了だけでは GPU 経路や対象ワークロードの動作証明になりません。

10. 非公開の再現性マニフェストを維持する

機械可読マニフェストをロック、テスト出力、チェックサムと共に保管します。アカウント ID、インスタンス ID、内部ホスト名、バケット名、オブジェクトパス、トークン、データセット識別子を公開しません。

schema_version: 1
captured_at_utc: replace-with-iso-8601-time
aws:
  region: replace
  availability_zone: replace
  instance_type: replace
  purchase_model: replace
  ami_id: replace
  ami_name: replace
  cpu_architecture: replace
gpu:
  model: replace
  count: replace
  architecture: replace
  compute_capability: replace
  driver_version: replace
  driver_cuda_ceiling: replace
  toolkit_version: replace-or-not-installed
environment:
  python_version: replace
  framework_name: tensorflow
  framework_version: replace
  framework_build: replace
  requirements_lock_sha256: replace
source:
  commit: replace
  dirty: false
  container_digest: replace-or-not-used
verification:
  gpu_smoke_test: pass-or-fail
  workload_smoke_test: pass-or-fail
storage:
  root_delete_on_termination: replace
  durable_output_location: private-reference-only

マニフェストはシステム事実であり、資格情報ではありません。機密性の高い資源対応表は、さらに狭いアクセス制御の下で別に保存します。

11. 検証、停止、ロールバック、クリーンアップ

有料作業の前に:

  • 予算、通知先、インスタンス料金モデル、アイドル容量を停止する担当者または自動化を確認します。
  • セキュリティグループに Notebook ポートがなく、IMDSv2 必須、インスタンスロール最小、ボリューム暗号化済みで、必要に応じ SSH/SSM アクセスが記録されることを確認します。
  • EC2 モデル/アーキテクチャを uname -m、GPU インベントリ、Compute Capability、ドライバ、CUDA ツールキット、ロック済み Python パッケージ、フレームワークビルド情報と照合します。
  • pip check、GPU スモークテスト、小さなワークロードテスト、checkpoint 復元、トンネル限定 Jupyter を確認します。
  • ログとマニフェストに秘密や非公開データがなく、インスタンスなしで永続出力を復元できることを確認します。

作業終了時は checkpoint を flush・検証し、Jupyter を止め、マニフェストと必要ログをコピーしてから、権限を持つ管理端末でインスタンスを停止します。

INSTANCE_ID='replace-with-instance-id'

aws ec2 stop-instances --instance-ids "$INSTANCE_ID"
aws ec2 wait instance-stopped --instance-ids "$INSTANCE_ID"

停止するとインスタンス計算料金は終わりますが、EBS、スナップショット、パブリック IPv4/Elastic IP、他サービスの料金は継続し得ます。停止/起動でインスタンスストアのデータは消えます。終了時は既定でルート EBS が削除され、他の EBS は DeleteOnTermination に依存します。操作前に EC2 インスタンス状態変化を確認してください。

終了は、バックアップ、復元、ボリュームフラグ、共有依存、保存義務を明示的な人手ゲートで検証した後だけ行います。ロールバック用に不変 AMI/コンテナ参照、環境ロック、ソース commit、マニフェスト、データ版、既知良好なテスト出力を保持し、文書のないマシンをその場で修理せず再構築します。

12. 公式資料

13. 2017 年原文アーカイブ

出典保存のため、source_export の可視本文を完全に収録します。行末空白だけを正規化し、内容の追加、削除、修正、有効化はしていません。古い HTTP リポジトリ、apt-key、全員書き込み可能なフック、固定されていないインストール一覧、公開 Jupyter リンクは歴史資料であり、実行してはいけません。


1. Git server building.`

$ ssh-­keygen -­t rsa ­-C "user.email"`
 Modifying hooks:`

$ vim sample.git/hooks/post-receive`
 Sample code for hooks:`

#!/bin/sh

GIT_WORK_TREE=/home/ubuntu/Deployment/sample git checkout -f

chmod -R 777 /home/ubuntu/Deployment/sample`
2. Install bazel.
 1). Add Bazel distribution URI as a package source (one time setup)

echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list
curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -


If you want to install the testing version of Bazel, replace stable with testing.2). Install and update Bazel

sudo apt-get update && sudo apt-get install bazel
 Once installed, you can upgrade to a newer version of Bazel with:

sudo apt-get upgrade bazel


3. Tensorflow compiling.
4. Python module installing.

  - tensorflow
  - numpy
  - pandas

5. Juypter.
 https://punchagan.muse-amuse.in/posts/create-a-public-jupyter-server-quickly.html

Leave a Reply