Communitygithub.com

padrões-pytorch

Padrões de deep learning PyTorch e melhores práticas para construir pipelines de treinamento, arquiteturas de modelo e carregamento de dados robustos, eficientes e reproduzíveis.

O que é padrões-pytorch?

Esta skill fornece um guia abrangente de padrões idiomáticos PyTorch e melhores práticas para desenvolvimento de deep learning. Ela cobre princípios fundamentais como código independente de dispositivo, reprodutibilidade e gerenciamento explícito de formas de tensores. A skill inclui padrões para arquiteturas de modelo (estrutura limpa de nn.Module, inicialização adequada de pesos), loops de treinamento (treinamento padrão com precisão mista, validação), pipelines de dados (Dataset personalizado, configuração eficiente de DataLoader, collate_fn) e checkpointing. Ela também aborda otimização de desempenho com precisão mista, checkpointing de gradiente e torch.compile. Cada padrão é ilustrado com exemplos de código comparando abordagens boas e ruins, com foco em código independente de dispositivo e reprodutibilidade. A skill inclui uma tabela de referência rápida de expressões idiomáticas PyTorch e uma seção de antipadrões para evitar, como operações in-place que quebram a computação do gradiente.

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

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Padrões de Desenvolvimento PyTorch

Padrões idiomáticos PyTorch e melhores práticas para construir aplicações de deep learning robustas, eficientes e reproduzíveis.

Quando Ativar

  • Escrevendo novos modelos ou scripts de treinamento PyTorch
  • Revisando código de deep learning
  • Depurando loops de treinamento ou pipelines de dados
  • Otimizando uso de memória GPU ou velocidade de treinamento
  • Configurando experimentos reproduzíveis

Princípios Fundamentais

1. Código Independente de Dispositivo

Sempre escreva código que funcione tanto em CPU quanto GPU sem hardcodar dispositivos.

# Bom: Independente de dispositivo
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = MyModel().to(device)
data = data.to(device)

# Ruim: Dispositivo hardcodado
model = MyModel().cuda()  # Quebra se não houver GPU
data = data.cuda()

2. Reprodutibilidade Primeiro

Defina todas as sementes aleatórias para resultados reproduzíveis.

# Bom: Configuração completa de reprodutibilidade
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

# Ruim: Nenhum controle de semente
model = MyModel()  # Pesos diferentes a cada execução

3. Gerenciamento Explícito de Formas

Sempre documente e verifique as formas dos tensores.

# Bom: Passagem forward anotada com formas
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)

# Ruim: Nenhum rastreamento de forma
def forward(self, x):
    x = self.conv1(x)
    x = self.pool(x)
    x = x.view(x.size(0), -1)  # De que tamanho é isso?
    return self.fc(x)           # Isso vai funcionar?

Padrões de Arquitetura de Modelo

Estrutura Limpa de nn.Module

# Bom: Módulo bem organizado
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)

# Ruim: Tudo no forward
class ImageClassifier(nn.Module):
    def __init__(self):
        super().__init__()

    def forward(self, x):
        x = F.conv2d(x, weight=self.make_weight())  # Cria peso a cada chamada!
        return x

Inicialização Adequada de Pesos

# Bom: Inicialização explícita
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)

Padrões de Loop de Treinamento

Loop de Treinamento Padrão

# Bom: Loop de treinamento completo com melhores práticas
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()  # Sempre defina modo de treino
    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)  # Mais eficiente que zero_grad()

        # Treinamento com precisão mista
        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)

Loop de Validação

# Bom: Avaliação adequada
@torch.no_grad()  # Mais eficiente que envolver em bloco torch.no_grad()
def evaluate(
    model: nn.Module,
    dataloader: DataLoader,
    criterion: nn.Module,
    device: torch.device,
) -> tuple[float, float]:
    model.eval()  # Sempre defina modo de avaliação — desabilita dropout, usa estatísticas BN em execução
    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

Padrões de Pipeline de Dados

Dataset Personalizado

# Bom: Dataset limpo com dicas de tipo
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

Configuração Eficiente de DataLoader

# Bom: DataLoader otimizado
dataloader = DataLoader(
    dataset,
    batch_size=32,
    shuffle=True,            # Embaralhar para treinamento
    num_workers=4,           # Carregamento paralelo de dados
    pin_memory=True,         # Transferência CPU->GPU mais rápida
    persistent_workers=True, # Manter workers vivos entre épocas
    drop_last=True,          # Tamanhos de lote consistentes para BatchNorm
)

# Ruim: Padrões lentos
dataloader = DataLoader(dataset, batch_size=32)  # num_workers=0, sem pin_memory

Collate Personalizado para Dados de Comprimento Variável

# Bom: Preencher sequências em collate_fn
def collate_fn(batch: list[tuple[torch.Tensor, int]]) -> tuple[torch.Tensor, torch.Tensor]:
    sequences, labels = zip(*batch)
    # Preencher até comprimento máximo no lote
    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)

Padrões de Checkpointing

Salvar e Carregar Checkpoints

# Bom: Checkpoint completo com todo o estado de treinamento
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

# Ruim: Salvando apenas pesos do modelo (não pode retomar treinamento)
torch.save(model.state_dict(), "model.pt")

Otimização de Desempenho

Treinamento com Precisão Mista

# Bom: AMP com GradScaler
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)

Checkpointing de Gradiente para Modelos Grandes

# Bom: Trocar computação por memória
from torch.utils.checkpoint import checkpoint

class LargeModel(nn.Module):
    def forward(self, x: torch.Tensor) -> torch.Tensor:
        # Recalcular ativações durante backward para economizar memória
        x = checkpoint(self.block1, x, use_reentrant=False)
        x = checkpoint(self.block2, x, use_reentrant=False)
        return self.head(x)

torch.compile para Velocidade

# Bom: Compilar o modelo para execução mais rápida (PyTorch 2.0+)
model = MyModel().to(device)
model = torch.compile(model, mode="reduce-overhead")

# Modos: "default" (seguro), "reduce-overhead" (mais rápido), "max-autotune" (mais rápido)

Referência Rápida: Expressões Idiomáticas PyTorch

ExpressãoDescrição
model.train() / model.eval()Sempre defina modo antes de treinar/avaliar
torch.no_grad()Desabilitar gradientes para inferência
optimizer.zero_grad(set_to_none=True)Limpeza de gradientes mais eficiente
.to(device)Posicionamento de tensor/modelo independente de dispositivo
torch.amp.autocastPrecisão mista para velocidade 2x
pin_memory=TrueTransferência de dados CPU→GPU mais rápida
torch.compileCompilação JIT para velocidade (2.0+)
weights_only=TrueCarregamento seguro de modelo
torch.manual_seedExperimentos reproduzíveis
gradient_checkpointingTrocar computação por memória

Antipadrões a Evitar

# Ruim: Esquecer model.eval() durante validação
model.train()
with torch.no_grad():
    output = model(val_data)  # Dropout ainda ativo! BatchNorm usa estatísticas do lote!

# Bom: Sempre defina modo de avaliação
model.eval()
with torch.no_grad():
    output = model(val_data)

# Ruim: Operações in-place quebrando autograd
x = F.relu(x, inplace=True)  # Pode quebrar computação de gradiente
x += residual                  # Adição in-place quebra o grafo autograd

# Bom: Operações out-of-place
x = F.relu(x)
x = x + residual

# Ruim: Mover dados para GPU repetidamente dentro do loop de treinamento
for data, target in dataloader:
    model = model.cuda()  # Move modelo a CADA iteração!

# Bom: Mover modelo uma vez antes do loop
model = model.to(device)
for data, target in dataloader:
    data, target = data.to(device), target.to(device)

# Ruim: Usar .item() antes de backward
loss = criterion(output, target).item()  # Desanexa do grafo!
loss.backward()  # Erro: não pode retropropagar através de .item()

# Bom: Chamar .item() apenas para logging
loss = criterion(output, target)
loss.backward()
print(f"Loss: {loss.item():.4f}")  # .item() após backward é seguro

# Ruim: Não usar torch.save adequadamente
torch.save(model, "model.pt")  # Salva modelo inteiro (frágil, não portátil)

# Bom: Salvar state_dict
torch.save(model.state_dict(), "model.pt")

Lembre-se: O código PyTorch deve ser independente de dispositivo, reproduzível e consciente de memória. Em caso de dúvida, faça perfil com torch.profiler e verifique a memória GPU com torch.cuda.memory_summary().

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.

Habilidades Relacionadas