1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

VRAMってなんだ?〜DRAMとの違いをGPU初心者向けに完全解説〜

1
Posted at

この記事の対象読者

  • 「CUDA out of memory」エラーに遭遇したことがある方
  • VRAMとDRAM(普通のメモリ)の違いがよくわからない方
  • 機械学習やゲーミングでGPUを使い始めた方
  • グラフィックボードを購入する際にスペックの見方を知りたい方

この記事で得られること

  • VRAMの正体: 普通のメモリ(DRAM)との根本的な違いを理解できる
  • VRAM容量の選び方: 用途別に必要なVRAM容量がわかる
  • VRAM監視の実践スキル: PythonでVRAM使用量を確認・管理できるようになる
  • トラブル対処力: 「メモリ不足」エラーに適切に対処できるようになる

この記事で扱わないこと

  • GPUアーキテクチャの詳細(CUDAコアの仕組みなど)
  • メモリの電気回路レベルの動作原理
  • データセンター向けHBMメモリの詳細

1. VRAMとの出会い

「またCUDA out of memoryか...」

私が初めてローカルでLLMを動かそうとしたとき、このエラーに何度泣かされたかわからない。32GBもRAMを積んでるのに、なぜ8GBしかないGPUメモリが足りないと言われるのか。当時の私には全く理解できなかった。

結論から言うと、VRAMとDRAM(普通のメモリ)は全くの別物だ。家のリビングにある巨大な本棚(DRAM)と、作業机の上の小さな書類トレイ(VRAM)みたいなもの。いくら本棚が大きくても、机の上で同時に広げられる書類の数は書類トレイのサイズで決まる。

この記事では、VRAMとDRAMの違いを徹底的に解きほぐし、「なぜGPUには専用のメモリが必要なのか」を完全に理解できるようにする。

ここまでで、VRAMがなんとなく「GPU専用の特別なメモリ」らしいとイメージできただろうか。次は、この記事で登場する用語を整理しておこう。


2. 前提知識の確認

本題に入る前に、この記事で登場する用語を確認する。

2.1 RAM(Random Access Memory)とは

コンピュータが「今使っているデータ」を一時的に置いておく場所。電源を切ると消える。料理で言えば「まな板」のようなもので、調理中の食材を置いておく作業スペースだ。

2.2 DRAM(Dynamic RAM)とは

RAMの実装方式の一つ。「Dynamic」は「動的」という意味で、データを保持するために定期的にリフレッシュ(再充電)が必要。PCの「メインメモリ」と呼ばれるものは基本的にこれ。DDR4、DDR5などがDRAMの規格だ。

2.3 GPU(Graphics Processing Unit)とは

グラフィック処理に特化したプロセッサ。CPUが「なんでもできる優秀な1人」だとすると、GPUは「単純作業を超高速でこなす1万人のチーム」。大量のデータを並列処理するのが得意で、近年はAI・機械学習の計算に不可欠となっている。

2.4 帯域幅(Bandwidth)とは

データ転送の「道路の広さ」。1秒間にどれだけのデータを運べるかを表す。単位は GB/s(ギガバイト毎秒)。帯域幅が広いほど、大量のデータを高速にやり取りできる。

これらの用語が押さえられたら、VRAMが生まれた背景を見ていこう。


3. VRAMが生まれた背景

3.1 なぜGPUには専用メモリが必要なのか

1990年代初頭、3Dグラフィックスの需要が急増した。テクスチャデータ、頂点情報、フレームバッファなど、グラフィック処理には大量のデータを超高速で読み書きする必要がある。

問題は、CPUとメインメモリ(DRAM)の間の帯域幅だった。当時のメインメモリは数GB/s程度の帯域幅しかなく、グラフィック処理の要求に全く追いつけなかった。

そこで生まれたのが**VRAM(Video RAM)**だ。GPUの隣に専用の高速メモリを配置し、グラフィック処理に必要なデータを超高速でやり取りできるようにした。

3.2 VRAMの進化の歴史

世代 規格 帯域幅(理論値) 登場時期
第1世代 GDDR 〜10 GB/s 2003年頃
第2世代 GDDR3 〜20 GB/s 2004年頃
第3世代 GDDR5 〜200 GB/s 2008年頃
第4世代 GDDR6 〜500 GB/s 2018年頃
第5世代 GDDR6X 〜1,000 GB/s 2020年頃
最新世代 GDDR7 〜1,500 GB/s 2024年〜

ちなみに、AI用途のデータセンターGPU(NVIDIA H100など)では、さらに高速な**HBM(High Bandwidth Memory)**が使われており、帯域幅は3,000 GB/s以上に達する。

背景がわかったところで、VRAMとDRAMの具体的な違いを見ていこう。


4. 基本概念と仕組み

4.1 VRAM vs DRAM:決定的な違い

初心者が混乱する最大のポイントは「どっちも同じメモリじゃないの?」という疑問だ。確かにどちらもデータを一時保存するものだが、設計思想が根本的に異なる。

比較項目 DRAM(メインメモリ) VRAM(GPUメモリ)
接続先 CPU GPU
帯域幅 〜100 GB/s 〜1,500 GB/s
レイテンシ 低い(高速応答) 高い(応答は遅め)
得意なこと ランダムアクセス 大量データの連続転送
容量(一般的) 16〜64 GB 8〜24 GB
価格/GB 安い 高い

4.2 なぜVRAMは帯域幅を重視するのか

GPUの仕事を考えてみよう。例えば画像認識AIは、1枚の画像(数MB)に対して数十億回の計算を行う。この計算に必要なデータ(重みパラメータ、中間結果など)を、GPUは何度も読み書きする。

【DRAMの場合】
CPU <--100 GB/s--> DRAM
「1車線の道路を高速で走る」イメージ

【VRAMの場合】
GPU <--1,000 GB/s--> VRAM
「10車線の高速道路を走る」イメージ

GPUは「多少の遅延があっても、大量のデータを一気に運べること」を重視する。だからVRAMは帯域幅特化型の設計になっている。

4.3 GDDR vs HBM:VRAMにも種類がある

VRAMと一口に言っても、実は2つの主要な系統がある。

VRAM
├── GDDR系(ゲーミング・コンシューマー向け)
│   ├── GDDR5
│   ├── GDDR6 / GDDR6X
│   └── GDDR7(2024年〜)
│
└── HBM系(AI・データセンター向け)
    ├── HBM2
    ├── HBM3 / HBM3E
    └── HBM4(2026年〜予定)

GDDR系は従来のメモリチップをGPU周辺に配置する方式。コスト効率が良く、ゲーミングGPUはほぼ全てこれ。

HBM系はメモリチップを垂直に積層し、GPUと同じパッケージ内に配置する方式。帯域幅はGDDRの2〜3倍だが、製造コストが高い。NVIDIA H100やAMD MI300Xなどのプロ向けGPUで採用されている。

基本概念が理解できたところで、実際にPythonでVRAMを確認・監視する方法を見ていこう。


5. 実践:実際に使ってみよう

5.1 環境構築

# 必要なパッケージのインストール
pip install torch pynvml

5.2 環境別の設定ファイル

VRAMを効率的に使うための設定を3種類用意した。用途に応じて選択してほしい。

開発環境用(config.yaml)

# config.yaml - 開発環境用(このままコピーして使える)
environment: development
gpu:
  device_id: 0
  memory_fraction: 0.8  # VRAMの80%まで使用
  allow_growth: true    # 必要に応じてメモリを確保
logging:
  level: DEBUG
  show_memory_stats: true
pytorch:
  # 開発時はメモリ効率より可読性を優先
  cudnn_benchmark: false
  deterministic: true

本番環境用(config.production.yaml)

# config.production.yaml - 本番環境用
environment: production
gpu:
  device_id: 0
  memory_fraction: 0.95  # VRAMを最大限活用
  allow_growth: false    # メモリを事前に確保
logging:
  level: INFO
  show_memory_stats: false
pytorch:
  # 本番は速度を優先
  cudnn_benchmark: true
  deterministic: false

テスト環境用(config.test.yaml)

# config.test.yaml - CI/CD用
environment: test
gpu:
  device_id: 0
  memory_fraction: 0.5  # 複数テストが並列実行されることを想定
  allow_growth: true
logging:
  level: WARNING
  show_memory_stats: false
pytorch:
  cudnn_benchmark: false
  deterministic: true  # テストの再現性を担保

5.3 基本的なVRAM確認スクリプト

#!/usr/bin/env python3
"""
VRAM使用状況を確認するスクリプト
実行方法: python check_vram.py
"""
import torch


def get_vram_info(device_id: int = 0) -> dict:
    """
    指定したGPUのVRAM情報を取得する
    
    Args:
        device_id: GPUのデバイスID(デフォルト: 0)
    
    Returns:
        VRAM情報を含む辞書
    """
    if not torch.cuda.is_available():
        return {"error": "CUDAが利用できません"}
    
    # デバイスプロパティを取得
    props = torch.cuda.get_device_properties(device_id)
    
    # メモリ情報を取得
    total_memory = props.total_memory
    allocated_memory = torch.cuda.memory_allocated(device_id)
    reserved_memory = torch.cuda.memory_reserved(device_id)
    free_memory = total_memory - reserved_memory
    
    return {
        "device_name": props.name,
        "total_vram_gb": total_memory / (1024**3),
        "allocated_gb": allocated_memory / (1024**3),
        "reserved_gb": reserved_memory / (1024**3),
        "free_gb": free_memory / (1024**3),
        "utilization_percent": (reserved_memory / total_memory) * 100
    }


def print_vram_status():
    """VRAM状況を見やすく表示"""
    info = get_vram_info()
    
    if "error" in info:
        print(f"エラー: {info['error']}")
        return
    
    print("=" * 50)
    print(f"GPU: {info['device_name']}")
    print("=" * 50)
    print(f"総VRAM:     {info['total_vram_gb']:.2f} GB")
    print(f"使用中:     {info['allocated_gb']:.2f} GB")
    print(f"予約済み:   {info['reserved_gb']:.2f} GB")
    print(f"空き:       {info['free_gb']:.2f} GB")
    print(f"使用率:     {info['utilization_percent']:.1f} %")
    print("=" * 50)


if __name__ == "__main__":
    print_vram_status()

5.4 実行結果

上記のコードを実行すると、以下のような出力が得られる:

$ python check_vram.py
==================================================
GPU: NVIDIA GeForce RTX 4090
==================================================
総VRAM:     24.00 GB
使用中:     0.00 GB
予約済み:   0.00 GB
空き:       24.00 GB
使用率:     0.0 %
==================================================

5.5 よくあるエラーと対処法

エラー 原因 対処法
CUDA out of memory VRAMが不足している バッチサイズを小さくする / torch.cuda.empty_cache() を呼ぶ
RuntimeError: CUDA error: out of memory 他のプロセスがVRAMを占有 nvidia-smi で確認し、不要なプロセスを終了
AssertionError: Torch not compiled with CUDA enabled CPU版PyTorchがインストールされている pip install torch --index-url https://download.pytorch.org/whl/cu121 で再インストール
VRAMが解放されない Pythonの参照が残っている del tensor + gc.collect() + torch.cuda.empty_cache()
nvidia-smi と PyTorch の表示が異なる PyTorchのキャッシュ機構 これは正常動作。PyTorchは一度確保したVRAMをキャッシュする

5.6 環境診断スクリプト

問題が発生した場合は、以下のスクリプトで環境を診断できる:

#!/usr/bin/env python3
"""
GPU/VRAM環境診断スクリプト
実行方法: python diagnose_gpu.py
"""
import sys
import subprocess


def check_environment():
    """環境をチェックして問題を報告"""
    issues = []
    info = []
    
    # 1. Pythonバージョン確認
    py_version = f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"
    info.append(f"Python: {py_version}")
    if sys.version_info < (3, 9):
        issues.append(f"Python 3.9以上を推奨(現在: {py_version}")
    
    # 2. PyTorch確認
    try:
        import torch
        info.append(f"PyTorch: {torch.__version__}")
        
        # CUDA確認
        if torch.cuda.is_available():
            info.append(f"CUDA: {torch.version.cuda}")
            info.append(f"cuDNN: {torch.backends.cudnn.version()}")
            
            # GPU情報
            gpu_count = torch.cuda.device_count()
            info.append(f"検出されたGPU数: {gpu_count}")
            
            for i in range(gpu_count):
                props = torch.cuda.get_device_properties(i)
                vram_gb = props.total_memory / (1024**3)
                info.append(f"  GPU {i}: {props.name} ({vram_gb:.1f} GB)")
        else:
            issues.append("CUDAが利用できません(CPU版PyTorch?)")
    except ImportError:
        issues.append("PyTorchがインストールされていません")
    
    # 3. nvidia-smi確認
    try:
        result = subprocess.run(
            ["nvidia-smi", "--query-gpu=driver_version", "--format=csv,noheader"],
            capture_output=True, text=True, timeout=10
        )
        if result.returncode == 0:
            driver = result.stdout.strip()
            info.append(f"NVIDIAドライバ: {driver}")
        else:
            issues.append("nvidia-smiの実行に失敗")
    except FileNotFoundError:
        issues.append("nvidia-smiが見つかりません(ドライバ未インストール?)")
    except subprocess.TimeoutExpired:
        issues.append("nvidia-smiがタイムアウト")
    
    # 結果表示
    print("\n" + "=" * 50)
    print("環境情報")
    print("=" * 50)
    for line in info:
        print(f"  {line}")
    
    print("\n" + "=" * 50)
    if issues:
        print("検出された問題")
        print("=" * 50)
        for issue in issues:
            print(f"  - {issue}")
    else:
        print("問題は検出されませんでした")
        print("=" * 50)
    
    return len(issues) == 0


if __name__ == "__main__":
    success = check_environment()
    sys.exit(0 if success else 1)

5.7 VRAMリアルタイム監視スクリプト(オプション)

学習中のVRAM使用状況をリアルタイムで監視したい場合:

#!/usr/bin/env python3
"""
VRAMリアルタイム監視スクリプト
実行方法: python monitor_vram.py
終了: Ctrl+C
"""
import time
import torch


def monitor_vram(interval: float = 1.0, device_id: int = 0):
    """
    VRAMをリアルタイム監視
    
    Args:
        interval: 更新間隔(秒)
        device_id: 監視するGPUのID
    """
    if not torch.cuda.is_available():
        print("エラー: CUDAが利用できません")
        return
    
    props = torch.cuda.get_device_properties(device_id)
    total_gb = props.total_memory / (1024**3)
    
    print(f"監視開始: {props.name} ({total_gb:.1f} GB)")
    print("終了するには Ctrl+C を押してください\n")
    print(f"{'時刻':<10} {'使用中':>10} {'予約済':>10} {'空き':>10} {'使用率':>8}")
    print("-" * 50)
    
    try:
        while True:
            allocated = torch.cuda.memory_allocated(device_id) / (1024**3)
            reserved = torch.cuda.memory_reserved(device_id) / (1024**3)
            free = total_gb - reserved
            util = (reserved / total_gb) * 100
            
            timestamp = time.strftime("%H:%M:%S")
            print(f"{timestamp:<10} {allocated:>9.2f}G {reserved:>9.2f}G {free:>9.2f}G {util:>7.1f}%")
            
            time.sleep(interval)
    except KeyboardInterrupt:
        print("\n監視を終了しました")


if __name__ == "__main__":
    monitor_vram()

実装方法がわかったので、次は具体的なユースケースを見ていこう。


6. ユースケース別ガイド

6.1 ユースケース1: 機械学習モデルの学習

想定読者: ローカルでLLMやStable Diffusionを動かしたい方

推奨VRAM容量:

  • 8GB: 小規模モデル、Stable Diffusion 1.5
  • 12GB: 中規模モデル、SDXL
  • 24GB: 大規模モデル、LLM(7B〜13Bパラメータ)

サンプルコード:

"""
機械学習用のVRAM最適化設定
"""
import torch
import gc


def setup_ml_environment(memory_fraction: float = 0.9):
    """
    機械学習向けにVRAM設定を最適化
    
    Args:
        memory_fraction: 使用するVRAMの割合(0.0〜1.0)
    """
    if not torch.cuda.is_available():
        print("警告: CUDAが利用できません。CPUモードで実行します。")
        return torch.device("cpu")
    
    # VRAMの使用量を制限(他のプロセスとの共存用)
    torch.cuda.set_per_process_memory_fraction(memory_fraction)
    
    # cuDNNの自動チューニングを有効化(学習が速くなる)
    torch.backends.cudnn.benchmark = True
    
    # 未使用メモリを解放
    gc.collect()
    torch.cuda.empty_cache()
    
    device = torch.device("cuda:0")
    props = torch.cuda.get_device_properties(device)
    print(f"GPU設定完了: {props.name}")
    print(f"利用可能VRAM: {props.total_memory / (1024**3) * memory_fraction:.1f} GB")
    
    return device


def release_vram():
    """VRAMを明示的に解放"""
    gc.collect()
    torch.cuda.empty_cache()
    torch.cuda.synchronize()
    print("VRAMキャッシュをクリアしました")


# 使用例
if __name__ == "__main__":
    device = setup_ml_environment(memory_fraction=0.8)
    
    # ここでモデルの学習を実行...
    
    release_vram()

6.2 ユースケース2: ゲーミング環境の最適化

想定読者: PCゲーマーでVRAM使用量が気になる方

推奨VRAM容量:

  • 8GB: フルHD(1080p)、中〜高設定
  • 12GB: WQHD(1440p)、高設定
  • 16GB以上: 4K、最高設定 + レイトレーシング

サンプルコード:

"""
ゲーミング環境向けのVRAM監視ツール
Pythonで動かすゲームやエミュレータの監視に便利
"""
import torch
import time
from dataclasses import dataclass


@dataclass
class VRAMSnapshot:
    """VRAM使用状況のスナップショット"""
    timestamp: float
    used_gb: float
    total_gb: float
    
    @property
    def usage_percent(self) -> float:
        return (self.used_gb / self.total_gb) * 100


class GamingVRAMMonitor:
    """ゲーミング用途のVRAM監視クラス"""
    
    def __init__(self, warning_threshold: float = 0.85):
        """
        Args:
            warning_threshold: 警告を出すVRAM使用率(0.0〜1.0)
        """
        self.warning_threshold = warning_threshold
        self.history: list[VRAMSnapshot] = []
        
        if torch.cuda.is_available():
            props = torch.cuda.get_device_properties(0)
            self.total_gb = props.total_memory / (1024**3)
            self.gpu_name = props.name
        else:
            raise RuntimeError("CUDAが利用できません")
    
    def snapshot(self) -> VRAMSnapshot:
        """現在のVRAM状況をスナップショット"""
        used = torch.cuda.memory_reserved(0) / (1024**3)
        snap = VRAMSnapshot(
            timestamp=time.time(),
            used_gb=used,
            total_gb=self.total_gb
        )
        self.history.append(snap)
        
        # 警告チェック
        if snap.usage_percent > self.warning_threshold * 100:
            print(f"警告: VRAM使用率が{snap.usage_percent:.1f}%に達しています!")
        
        return snap
    
    def get_peak_usage(self) -> float:
        """最大使用量を取得(GB)"""
        if not self.history:
            return 0.0
        return max(s.used_gb for s in self.history)


# 使用例
if __name__ == "__main__":
    monitor = GamingVRAMMonitor(warning_threshold=0.9)
    print(f"GPU: {monitor.gpu_name} ({monitor.total_gb:.1f} GB)")
    
    # 5秒ごとに10回監視
    for i in range(10):
        snap = monitor.snapshot()
        print(f"[{i+1}] 使用中: {snap.used_gb:.2f} GB ({snap.usage_percent:.1f}%)")
        time.sleep(5)
    
    print(f"\nピーク使用量: {monitor.get_peak_usage():.2f} GB")

6.3 ユースケース3: 複数GPUの管理

想定読者: 研究開発や本番環境で複数GPUを使う方

推奨構成: GPU数 × VRAMで総容量を確保

サンプルコード:

"""
複数GPU環境の管理スクリプト
"""
import torch
from dataclasses import dataclass


@dataclass
class GPUInfo:
    """GPU情報を保持するデータクラス"""
    device_id: int
    name: str
    total_vram_gb: float
    free_vram_gb: float
    
    @property
    def used_vram_gb(self) -> float:
        return self.total_vram_gb - self.free_vram_gb


def get_all_gpus() -> list[GPUInfo]:
    """全GPUの情報を取得"""
    if not torch.cuda.is_available():
        return []
    
    gpus = []
    for i in range(torch.cuda.device_count()):
        props = torch.cuda.get_device_properties(i)
        total = props.total_memory / (1024**3)
        reserved = torch.cuda.memory_reserved(i) / (1024**3)
        free = total - reserved
        
        gpus.append(GPUInfo(
            device_id=i,
            name=props.name,
            total_vram_gb=total,
            free_vram_gb=free
        ))
    
    return gpus


def select_best_gpu() -> int:
    """最も空きVRAMが多いGPUを選択"""
    gpus = get_all_gpus()
    if not gpus:
        raise RuntimeError("利用可能なGPUがありません")
    
    best = max(gpus, key=lambda g: g.free_vram_gb)
    print(f"選択されたGPU: {best.name} (空き: {best.free_vram_gb:.1f} GB)")
    return best.device_id


def print_gpu_summary():
    """全GPUのサマリーを表示"""
    gpus = get_all_gpus()
    
    if not gpus:
        print("利用可能なGPUがありません")
        return
    
    print("\n" + "=" * 60)
    print(f"{'ID':<4} {'GPU名':<30} {'総容量':>8} {'空き':>8}")
    print("=" * 60)
    
    total_vram = 0
    total_free = 0
    
    for gpu in gpus:
        print(f"{gpu.device_id:<4} {gpu.name:<30} {gpu.total_vram_gb:>7.1f}G {gpu.free_vram_gb:>7.1f}G")
        total_vram += gpu.total_vram_gb
        total_free += gpu.free_vram_gb
    
    print("-" * 60)
    print(f"{'合計':<35} {total_vram:>7.1f}G {total_free:>7.1f}G")
    print("=" * 60)


# 使用例
if __name__ == "__main__":
    print_gpu_summary()
    
    # 最適なGPUを自動選択してモデルを配置
    best_gpu_id = select_best_gpu()
    device = torch.device(f"cuda:{best_gpu_id}")

ユースケースを把握できたところで、この先の学習パスを確認しよう。


7. 学習ロードマップ

この記事を読んだ後、次のステップとして以下をおすすめする。

初級者向け(まずはここから)

  1. nvidia-smiコマンドを使いこなす

    • nvidia-smi -l 1 でリアルタイム監視
    • nvidia-smi --query-gpu=... で必要な情報だけ取得
  2. PyTorchのメモリ管理を学ぶ

中級者向け(実践に進む)

  1. メモリ効率の良いモデル実装

    • 勾配チェックポインティング
    • Mixed Precision Training(FP16/BF16)
  2. プロファイリングツールの活用

上級者向け(さらに深く)

  1. カスタムCUDAカーネルの実装

  2. 分散学習でのメモリ最適化

    • DeepSpeed ZeRO
    • FSDP(Fully Sharded Data Parallel)

8. まとめ

この記事では、VRAMについて以下を解説した:

  1. VRAMとDRAMの違い: VRAMはGPU専用の高帯域幅メモリ。普通のメモリ(DRAM)とは設計思想が根本的に異なる
  2. VRAMの種類: GDDR系(ゲーミング向け)とHBM系(AI・データセンター向け)がある
  3. 実践的な使い方: PythonでVRAMを監視・管理する方法

私の所感

VRAMは今後ますます重要になると考えている。特にローカルLLMの需要が増える中、「24GBでは足りない」という声が珍しくなくなってきた。GDDR7やHBM4の登場で帯域幅は改善されるが、容量の壁はなかなか超えられない。

個人的には、VRAMを「高い買い物」と思わず「将来への投資」と捉えることをおすすめする。今8GBで妥協すると、半年後に後悔する可能性が高い。

この記事が、VRAMで悩む誰かの助けになれば幸いだ。


参考文献

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?