Communitygithub.com

pytorch-patterns

PyTorch深層学習のパターンとベストプラクティス。ロバストで効率的かつ再現可能な学習パイプライン、モデルアーキテクチャ、データローディングを構築するためのガイド。PyTorchの学習ループ、モデルアーキテクチャ、データローディングの作成やレビュー、再現性が確保できない実行時に活用します。

pytorch-patterns とは?

このスキルは、PyTorchを用いた深層学習開発において、堅牢で効率的かつ再現可能なコードを書くためのパターン集です。デバイスに依存しないコーディング(CPU/GPU両対応)、乱数シードの設定による再現性の確保、テンソル形状の明示的な管理といった基本原則から、`nn.Module`の整理された構造、重み初期化、学習ループの定型パターン、カスタムデータセットと効率的なDataLoaderの設定、チェックポイントの保存/読み込み、混合精度学習(AMP)や勾配チェックポイント、`torch.compile`による高速化まで幅広くカバーします。また、`model.eval()`の忘れやインプレース演算による自動微分の破壊、データローディングの非効率など、よくあるアンチパターンを避けるための実践的なアドバイスも提供します。このスキルはClaude CodeやCursor、Codexなどのエージェントと共に利用でき、コード生成やレビューの際に一貫した高品質なPyTorchコードを出力するための指針となります。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/everything-claude-code/tree/main/skills/pytorch-patterns

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

PyTorch開発パターン

PyTorchの慣用的なパターンとベストプラクティス。堅牢で効率的かつ再現可能な深層学習アプリケーションを構築するためのガイドです。

アクティベートすべきタイミング

  • 新しいPyTorchモデルや学習スクリプトを書くとき
  • 深層学習コードをレビューするとき
  • 学習ループやデータパイプラインをデバッグするとき
  • GPUメモリ使用量や学習速度を最適化するとき
  • 再現可能な実験環境をセットアップするとき

基本原則

1. デバイスに依存しないコード

デバイスをハードコードせず、CPUとGPUの両方で動作するコードを常に記述します。

# 良い例:デバイス非依存
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = MyModel().to(device)
data = data.to(device)

# 悪い例:デバイスのハードコード
model = MyModel().cuda()  # GPUがないとクラッシュ
data = data.cuda()

2. 再現性を最優先に

再現可能な結果を得るために、すべての乱数シードを設定します。

# 良い例:完全な再現性設定
def set_seed(seed: int = 42) -> None:
    torch.manual_seed(seed)
    torch.cuda.manual_seed_all(seed)
    np.random.seed(seed)
    random.seed(seed)
    torch.backends.cudnn.deterministic = True
    torch.backends.cudnn.benchmark = False

# 悪い例:シード制御なし
model = MyModel()  # 実行ごとに異なる重み

3. テンソル形状の明示的な管理

テンソルの形状を常にドキュメント化し、検証します。

# 良い例:形状注釈付きフォワード
class MyModel(nn.Module):
    def forward(self, x: torch.Tensor) -> torch.Tensor:
        # x: (batch_size, channels, height, width)
        x = self.conv1(x)    # -> (batch_size, 32, H, W)
        x = self.pool(x)     # -> (batch_size, 32, H//2, W//2)
        x = x.view(x.size(0), -1)  # -> (batch_size, 32*H//2*W//2)
        return self.fc(x)    # -> (batch_size, num_classes)

# 悪い例:形状追跡なし
def forward(self, x):
    x = self.conv1(x)
    x = self.pool(x)
    x = x.view(x.size(0), -1)  # これのサイズは?
    return self.fc(x)           # これで動くの?

モデルアーキテクチャのパターン

クリーンなnn.Module構造

# 良い例:整理されたモジュール
class ImageClassifier(nn.Module):
    def __init__(self, num_classes: int, dropout: float = 0.5) -> None:
        super().__init__()
        self.features = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=3, padding=1),
            nn.BatchNorm2d(64),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(2),
        )
        self.classifier = nn.Sequential(
            nn.Dropout(dropout),
            nn.Linear(64 * 16 * 16, num_classes),
        )

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        x = self.features(x)
        x = x.view(x.size(0), -1)
        return self.classifier(x)

# 悪い例:全部forwardに詰め込む
class ImageClassifier(nn.Module):
    def __init__(self):
        super().__init__()

    def forward(self, x):
        x = F.conv2d(x, weight=self.make_weight())  # 呼び出すたびに重みを作成!
        return x

適切な重み初期化

# 良い例:明示的な初期化
def _init_weights(self, module: nn.Module) -> None:
    if isinstance(module, nn.Linear):
        nn.init.kaiming_normal_(module.weight, mode="fan_out", nonlinearity="relu")
        if module.bias is not None:
            nn.init.zeros_(module.bias)
    elif isinstance(module, nn.Conv2d):
        nn.init.kaiming_normal_(module.weight, mode="fan_out", nonlinearity="relu")
    elif isinstance(module, nn.BatchNorm2d):
        nn.init.ones_(module.weight)
        nn.init.zeros_(module.bias)

model = MyModel()
model.apply(model._init_weights)

学習ループのパターン

標準的な学習ループ

# 良い例:ベストプラクティスに従った完全な学習ループ
def train_one_epoch(
    model: nn.Module,
    dataloader: DataLoader,
    optimizer: torch.optim.Optimizer,
    criterion: nn.Module,
    device: torch.device,
    scaler: torch.amp.GradScaler | None = None,
) -> float:
    model.train()  # 常に学習モードに設定
    total_loss = 0.0

    for batch_idx, (data, target) in enumerate(dataloader):
        data, target = data.to(device), target.to(device)

        optimizer.zero_grad(set_to_none=True)  # zero_grad()より効率的

        # 混合精度学習
        with torch.amp.autocast("cuda", enabled=scaler is not None):
            output = model(data)
            loss = criterion(output, target)

        if scaler is not None:
            scaler.scale(loss).backward()
            scaler.unscale_(optimizer)
            torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
            scaler.step(optimizer)
            scaler.update()
        else:
            loss.backward()
            torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
            optimizer.step()

        total_loss += loss.item()

    return total_loss / len(dataloader)

検証ループ

# 良い例:適切な評価
@torch.no_grad()  # torch.no_grad()ブロックでラップするより効率的
def evaluate(
    model: nn.Module,
    dataloader: DataLoader,
    criterion: nn.Module,
    device: torch.device,
) -> tuple[float, float]:
    model.eval()  # 常に評価モードに設定 — Dropout無効化、BNは実行時統計を使用
    total_loss = 0.0
    correct = 0
    total = 0

    for data, target in dataloader:
        data, target = data.to(device), target.to(device)
        output = model(data)
        total_loss += criterion(output, target).item()
        correct += (output.argmax(1) == target).sum().item()
        total += target.size(0)

    return total_loss / len(dataloader), correct / total

データパイプラインパターン

カスタムデータセット

# 良い例:型ヒント付きのクリーンなDataset
class ImageDataset(Dataset):
    def __init__(
        self,
        image_dir: str,
        labels: dict[str, int],
        transform: transforms.Compose | None = None,
    ) -> None:
        self.image_paths = list(Path(image_dir).glob("*.jpg"))
        self.labels = labels
        self.transform = transform

    def __len__(self) -> int:
        return len(self.image_paths)

    def __getitem__(self, idx: int) -> tuple[torch.Tensor, int]:
        img = Image.open(self.image_paths[idx]).convert("RGB")
        label = self.labels[self.image_paths[idx].stem]

        if self.transform:
            img = self.transform(img)

        return img, label

効率的なDataLoader設定

# 良い例:最適化されたDataLoader
dataloader = DataLoader(
    dataset,
    batch_size=32,
    shuffle=True,            # 学習時はシャッフル
    num_workers=4,           # 並列データローディング
    pin_memory=True,         # CPU→GPU転送の高速化
    persistent_workers=True, # エポック間でワーカーを維持
    drop_last=True,          # BatchNormのための一貫したバッチサイズ
)

# 悪い例:低速なデフォルト設定
dataloader = DataLoader(dataset, batch_size=32)  # num_workers=0, pin_memoryなし

可変長データ用のカスタムcollate

# 良い例:collate_fnで系列をパディング
def collate_fn(batch: list[tuple[torch.Tensor, int]]) -> tuple[torch.Tensor, torch.Tensor]:
    sequences, labels = zip(*batch)
    # バッチ内の最大長にパディング
    padded = nn.utils.rnn.pad_sequence(sequences, batch_first=True, padding_value=0)
    return padded, torch.tensor(labels)

dataloader = DataLoader(dataset, batch_size=32, collate_fn=collate_fn)

チェックポイントのパターン

チェックポイントの保存と読み込み

# 良い例:全学習状態を含む完全なチェックポイント
def save_checkpoint(
    model: nn.Module,
    optimizer: torch.optim.Optimizer,
    epoch: int,
    loss: float,
    path: str,
) -> None:
    torch.save({
        "epoch": epoch,
        "model_state_dict": model.state_dict(),
        "optimizer_state_dict": optimizer.state_dict(),
        "loss": loss,
    }, path)

def load_checkpoint(
    path: str,
    model: nn.Module,
    optimizer: torch.optim.Optimizer | None = None,
) -> dict:
    checkpoint = torch.load(path, map_location="cpu", weights_only=True)
    model.load_state_dict(checkpoint["model_state_dict"])
    if optimizer:
        optimizer.load_state_dict(checkpoint["optimizer_state_dict"])
    return checkpoint

# 悪い例:重みだけ保存(学習再開不可)
torch.save(model.state_dict(), "model.pt")

パフォーマンス最適化

混合精度学習

# 良い例:GradScalerによるAMP
scaler = torch.amp.GradScaler("cuda")
for data, target in dataloader:
    with torch.amp.autocast("cuda"):
        output = model(data)
        loss = criterion(output, target)
    scaler.scale(loss).backward()
    scaler.step(optimizer)
    scaler.update()
    optimizer.zero_grad(set_to_none=True)

大規模モデル向け勾配チェックポイント

# 良い例:計算量とメモリのトレードオフ
from torch.utils.checkpoint import checkpoint

class LargeModel(nn.Module):
    def forward(self, x: torch.Tensor) -> torch.Tensor:
        # 逆伝播時に活性化を再計算してメモリ節約
        x = checkpoint(self.block1, x, use_reentrant=False)
        x = checkpoint(self.block2, x, use_reentrant=False)
        return self.head(x)

高速化のためのtorch.compile

# 良い例:モデルをコンパイルして高速実行(PyTorch 2.0+)
model = MyModel().to(device)
model = torch.compile(model, mode="reduce-overhead")

# モード: "default"(安全)、"reduce-overhead"(より高速)、"max-autotune"(最速)

クイックリファレンス:PyTorchの慣用表現

慣用表現説明
model.train() / model.eval()学習/評価の前に必ずモード設定
torch.no_grad()推論時の勾配計算を無効化
optimizer.zero_grad(set_to_none=True)より効率的な勾配クリア
.to(device)デバイス非依存のテンソル/モデル配置
torch.amp.autocast最大2倍高速化の混合精度学習
pin_memory=TrueCPU→GPUデータ転送の高速化
torch.compileJITコンパイルによる高速化(2.0+)
weights_only=Trueセキュアなモデル読み込み
torch.manual_seed再現可能な実験
gradient_checkpointing計算量とメモリのトレードオフ

避けるべきアンチパターン

# 悪い例:検証中にmodel.eval()を忘れる
model.train()
with torch.no_grad():
    output = model(val_data)  # Dropoutが有効!BatchNormはバッチ統計を使用!

# 良い例:常に評価モードを設定
model.eval()
with torch.no_grad():
    output = model(val_data)

# 悪い例:インプレース演算が自動微分を壊す
x = F.relu(x, inplace=True)  # 勾配計算を壊す可能性
x += residual                  # インプレース加算がautogradグラフを壊す

# 良い例:アウトオブプレース演算
x = F.relu(x)
x = x + residual

# 悪い例:学習ループ内でデータを何度もGPUに移動
for data, target in dataloader:
    model = model.cuda()  # イテレーションごとにモデルを移動!

# 良い例:ループの前に一度だけモデルを移動
model = model.to(device)
for data, target in dataloader:
    data, target = data.to(device), target.to(device)

# 悪い例:backwardの前に.item()を使う
loss = criterion(output, target).item()  # グラフから切り離し!
loss.backward()  # エラー:.item()は逆伝播できない

# 良い例:ログ記録のためだけに.item()を使う
loss = criterion(output, target)
loss.backward()
print(f"損失: {loss.item():.4f}")  # backward後の.item()は問題ない

# 悪い例:torch.saveの不適切な使用
torch.save(model, "model.pt")  # モデル全体を保存(脆弱、移植性なし)

# 良い例:state_dictを保存
torch.save(model.state_dict(), "model.pt")

覚えておくこと:PyTorchコードはデバイス非依存、再現可能、メモリ意識高くあるべきです。迷ったらtorch.profilerでプロファイリングし、torch.cuda.memory_summary()でGPUメモリを確認しましょう。

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/claude-api

Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.

affaan-m/everything-claude-code

End-to-end marketing campaign planning and execution. Covers audience research, positioning, campaign angle definition, landing page copy, email sequences, social posts, ad copy, short-form video scripts, and content calendars. Use as the orchestration layer for multi-channel product launches. Use when planning or executing a multi-channel product launch, or producing landing page, email, social, or ad copy.

affaan-m/everything-claude-code

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/everything-claude-code-conventions

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/frontend-design

Create distinctive, production-grade frontend interfaces with high design quality. Use when the user asks to build web components, pages, or applications and the visual direction matters as much as the code quality.

affaan-m/gget

gget CLI and Python workflow for quick genomic database queries, sequence lookup, BLAST-style searches, enrichment checks, and reproducible bioinformatics evidence logs.

affaan-m/literature-review

Systematic literature-review workflow for academic, biomedical, technical, and scientific topics, including search planning, source screening, synthesis, citation checks, and evidence logging.

affaan-m/motion-ui

Production-ready UI motion system for React/Next.js. Use when implementing animations, transitions, or motion patterns.

affaan-m/project-guidelines-example

Example project-specific skill template based on a real production application.

affaan-m/pubmed-database

Direct PubMed and NCBI E-utilities search workflows for biomedical literature, MeSH queries, PMID lookup, citation retrieval, and API-backed literature monitoring.

affaan-m/scholar-evaluation

Structured scholarly-work evaluation for papers, proposals, literature reviews, methods sections, evidence quality, citation support, and research-writing feedback.

affaan-m/uspto-database

USPTO patent and trademark data workflow for official record lookup, PatentSearch queries, TSDR checks, assignment data, and reproducible IP research logs.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

関連スキル