本文へ移動
cccskills
無料GitHub で公開

model-pruning

Reduza o tamanho de LLMs e acelere a inferência usando técnicas de pruning como Wanda e SparseGPT. Use para comprimir modelos sem retreinamento, alcançando 50% de esparsidade com perda mínima de acurácia, ou ativando inferência mais rápida em aceleradores de hardware. Cobre pruning não estruturado, pruning estruturado, esparsidade N:M, pruning por magnitude e métodos one-shot.

インストール方法を見る

含まれるファイル(2)

  • SKILL.md14.0 KB
  • references/wanda.md9.3 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Model Pruning: Comprimindo LLMs

Quando Usar Esta Skill

Use Model Pruning quando você precisar:

  • Reduzir tamanho do modelo de 40-60% com <1% de perda de acurácia
  • Acelerar a inferência usando esparsidade amigável ao hardware (speedup 2-4×)
  • Fazer deploy em hardware limitado (dispositivos móveis, edge)
  • Comprimir sem retreinamento usando métodos one-shot
  • Habilitar serving eficiente com pegada de memória reduzida

Técnicas-chave: Wanda (weights × activations), SparseGPT (segunda ordem), pruning estruturado, esparsidade N:M

Papers: Wanda ICLR 2024 (arXiv 2306.11695), SparseGPT (arXiv 2301.00774)

Instalação

# Implementação Wanda
git clone https://github.com/locuslab/wanda
cd wanda
pip install -r requirements.txt

# Opcional: SparseGPT
git clone https://github.com/IST-DASLab/sparsegpt
cd sparsegpt
pip install -e .

# Dependências
pip install torch transformers accelerate

Quick Start

Wanda Pruning (One-Shot, Sem Retreinamento)

Fonte: ICLR 2024 (arXiv 2306.11695)

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

# Carrega modelo
model = AutoModelForCausalLM.from_pretrained(
    "meta-llama/Llama-2-7b-hf",
    torch_dtype=torch.float16,
    device_map="cuda"
)
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-2-7b-hf")

# Dados de calibração (pequeno dataset para estatísticas de ativação)
calib_data = [
    "The quick brown fox jumps over the lazy dog.",
    "Machine learning is transforming the world.",
    "Artificial intelligence powers modern applications.",
]

# Função de pruning Wanda
def wanda_prune(model, calib_data, sparsity=0.5):
    """
    Wanda: Prune por magnitude de peso × ativação de entrada.

    Args:
        sparsity: Fração de pesos a fazer prune (0.5 = 50%)
    """
    # 1. Coleta estatísticas de ativação
    activations = {}

    def hook_fn(name):
        def hook(module, input, output):
            # Armazena nomas de ativação de entrada
            activations[name] = input[0].detach().abs().mean(dim=0)
        return hook

    # Registra hooks para todas as camadas lineares
    hooks = []
    for name, module in model.named_modules():
        if isinstance(module, torch.nn.Linear):
            hooks.append(module.register_forward_hook(hook_fn(name)))

    # Executa dados de calibração
    model.eval()
    with torch.no_grad():
        for text in calib_data:
            inputs = tokenizer(text, return_tensors="pt").to(model.device)
            model(**inputs)

    # Remove hooks
    for hook in hooks:
        hook.remove()

    # 2. Prune pesos baseado em |weight| × ativação
    for name, module in model.named_modules():
        if isinstance(module, torch.nn.Linear) and name in activations:
            W = module.weight.data
            act = activations[name]

            # Computa importância: |weight| × ativação
            importance = W.abs() * act.unsqueeze(0)

            # Achata e encontra threshold
            threshold = torch.quantile(importance.flatten(), sparsity)

            # Cria máscara
            mask = importance >= threshold

            # Aplica máscara (prune)
            W *= mask.float()

    return model

# Aplica pruning Wanda (50% sparsidade, one-shot, sem retreinamento)
pruned_model = wanda_prune(model, calib_data, sparsity=0.5)

# Salva
pruned_model.save_pretrained("./llama-2-7b-wanda-50")

SparseGPT (Pruning de Segunda Ordem)

Fonte: arXiv 2301.00774

from sparsegpt import SparseGPT

# Carrega modelo
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-7b-hf")

# Inicializa SparseGPT
pruner = SparseGPT(model)

# Dados de calibração
calib_data = load_calibration_data()  # ~128 amostras

# Prune (one-shot, reconstrução layer-wise)
pruned_model = pruner.prune(
    calib_data=calib_data,
    sparsity=0.5,           # 50% sparsidade
    prunen=0,               # Não estruturado (0) ou N:M estruturado
    prunem=0,
    percdamp=0.01,          # Damping para inversa de Hessian
)

# Resultados: Pruning quasi-sem perda em 50% sparsidade

N:M Structured Pruning (Acelerador de Hardware)

def nm_prune(weight, n=2, m=4):
    """
    Pruning N:M: Mantém N pesos a cada M pesos consecutivos.
    Exemplo: 2:4 = manter 2 a cada 4 pesos.

    Compatível com sparse tensor cores NVIDIA (2:4, 4:8).
    """
    # Reshape peso em grupos de M
    shape = weight.shape
    weight_flat = weight.flatten()

    # Padding para múltiplo de M
    pad_size = (m - weight_flat.numel() % m) % m
    weight_padded = F.pad(weight_flat, (0, pad_size))

    # Reshape em (num_groups, m)
    weight_grouped = weight_padded.reshape(-1, m)

    # Encontra top-N em cada grupo
    _, indices = torch.topk(weight_grouped.abs(), n, dim=-1)

    # Cria máscara
    mask = torch.zeros_like(weight_grouped)
    mask.scatter_(1, indices, 1.0)

    # Aplica máscara
    weight_pruned = weight_grouped * mask

    # Reshape de volta
    weight_pruned = weight_pruned.flatten()[:weight_flat.numel()]
    return weight_pruned.reshape(shape)

# Aplica sparsidade 2:4 (hardware NVIDIA)
for name, module in model.named_modules():
    if isinstance(module, torch.nn.Linear):
        module.weight.data = nm_prune(module.weight.data, n=2, m=4)

# 50% sparsidade, 2× speedup em A100 com sparse tensor cores

Conceitos Principais

1. Critérios de Pruning

Pruning por Magnitude (baseline):

# Prune pesos com os menores valores absolutos
importance = weight.abs()
threshold = torch.quantile(importance, sparsity)
mask = importance >= threshold

Wanda (weights × activations):

# Importância = |weight| × input_activation
importance = weight.abs() * activation
# Melhor que magnitude pura (considera uso)

SparseGPT (segunda ordem):

# Usa Hessian (segunda derivada) para importância
# Mais acurado mas computacionalmente caro
importance = weight^2 / diag(Hessian)

2. Estruturado vs Não Estruturado

Não estruturado (granular fino):

  • Prune pesos individuais
  • Qualidade superior (melhor acurácia)
  • Sem speedup de hardware (esparsidade irregular)

Estruturado (granular grosso):

  • Prune neurônios, heads ou camadas inteiras
  • Qualidade inferior (mais perda de acurácia)
  • Speedup de hardware (esparsidade regular)

Semi-estruturado (N:M):

  • O melhor dos dois mundos
  • 50% sparsidade (2:4) → 2× speedup em GPUs NVIDIA
  • Perda mínima de acurácia

3. Padrões de Esparsidade

# Não estruturado (aleatório)
# [1, 0, 1, 0, 1, 1, 0, 0]
# Pros: Flexível, alta qualidade
# Cons: Sem speedup

# Estruturado (bloco)
# [1, 1, 0, 0, 1, 1, 0, 0]
# Pros: Amigável ao hardware
# Cons: Mais perda de acurácia

# N:M (semi-estruturado)
# [1, 0, 1, 0] [1, 1, 0, 0]  (padrão 2:4)
# Pros: Speedup de hardware + boa qualidade
# Cons: Requer hardware específico (NVIDIA)

Estratégias de Pruning

Estratégia 1: Pruning Gradual por Magnitude

def gradual_prune(model, initial_sparsity=0.0, final_sparsity=0.5, num_steps=100):
    """Aumenta gradualmente sparsidade durante o treinamento."""
    for step in range(num_steps):
        # Sparsidade atual
        current_sparsity = initial_sparsity + (final_sparsity - initial_sparsity) * (step / num_steps)

        # Prune na sparsidade atual
        for module in model.modules():
            if isinstance(module, torch.nn.Linear):
                weight = module.weight.data
                threshold = torch.quantile(weight.abs().flatten(), current_sparsity)
                mask = weight.abs() >= threshold
                weight *= mask.float()

        # Treina um passo
        train_step(model)

    return model

Estratégia 2: Pruning Layer-wise

def layer_wise_prune(model, sparsity_per_layer):
    """Sparsidade diferente para camadas diferentes."""
    # Camadas iniciais: Menos pruning (mais importantes)
    # Camadas finais: Mais pruning (menos críticas)

    sparsity_schedule = {
        "layer.0": 0.3,   # 30% sparsidade
        "layer.1": 0.4,
        "layer.2": 0.5,
        "layer.3": 0.6,   # 60% sparsidade
    }

    for name, module in model.named_modules():
        if isinstance(module, torch.nn.Linear):
            # Encontra índice da camada
            for layer_name, sparsity in sparsity_schedule.items():
                if layer_name in name:
                    # Prune em sparsidade específica da camada
                    prune_layer(module, sparsity)
                    break

    return model

Estratégia 3: Pruning Iterativo + Fine-tuning

def iterative_prune_finetune(model, target_sparsity=0.5, iterations=5):
    """Prune gradualmente com fine-tuning entre iterações."""
    current_sparsity = 0.0
    sparsity_increment = target_sparsity / iterations

    for i in range(iterations):
        # Aumenta sparsidade
        current_sparsity += sparsity_increment

        # Prune
        prune_model(model, sparsity=current_sparsity)

        # Fine-tune (recupera acurácia)
        fine_tune(model, epochs=2, lr=1e-5)

    return model

# Resultados: Melhor acurácia que one-shot em alta sparsidade

Deployment em Produção

Pipeline Completo de Pruning

from transformers import Trainer, TrainingArguments

def production_pruning_pipeline(
    model_name="meta-llama/Llama-2-7b-hf",
    target_sparsity=0.5,
    method="wanda",  # ou "sparsegpt"
):
    # 1. Carrega modelo
    model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype=torch.float16)
    tokenizer = AutoTokenizer.from_pretrained(model_name)

    # 2. Carrega dados de calibração
    calib_dataset = load_dataset("wikitext", "wikitext-2-raw-v1", split="train[:1000]")

    # 3. Aplica pruning
    if method == "wanda":
        pruned_model = wanda_prune(model, calib_dataset, sparsity=target_sparsity)
    elif method == "sparsegpt":
        pruner = SparseGPT(model)
        pruned_model = pruner.prune(calib_dataset, sparsity=target_sparsity)

    # 4. (Opcional) Fine-tune para recuperar acurácia
    training_args = TrainingArguments(
        output_dir="./pruned-model",
        num_train_epochs=1,
        per_device_train_batch_size=4,
        learning_rate=1e-5,
        bf16=True,
    )

    trainer = Trainer(
        model=pruned_model,
        args=training_args,
        train_dataset=finetune_dataset,
    )

    trainer.train()

    # 5. Salva
    pruned_model.save_pretrained("./pruned-llama-7b-50")
    tokenizer.save_pretrained("./pruned-llama-7b-50")

    return pruned_model

# Uso
pruned_model = production_pruning_pipeline(
    model_name="meta-llama/Llama-2-7b-hf",
    target_sparsity=0.5,
    method="wanda"
)

Avaliação

from lm_eval import evaluator

# Avalia modelo pruned vs original
original_results = evaluator.simple_evaluate(
    model="hf",
    model_args="pretrained=meta-llama/Llama-2-7b-hf",
    tasks=["arc_easy", "hellaswag", "winogrande"],
)

pruned_results = evaluator.simple_evaluate(
    model="hf",
    model_args="pretrained=./pruned-llama-7b-50",
    tasks=["arc_easy", "hellaswag", "winogrande"],
)

# Compara
print(f"Original: {original_results['results']['arc_easy']['acc']:.3f}")
print(f"Pruned:   {pruned_results['results']['arc_easy']['acc']:.3f}")
print(f"Degradation: {(original_results - pruned_results):.3f}")

# Resultados típicos em 50% sparsidade:
# - Wanda: <1% perda de acurácia
# - SparseGPT: <0.5% perda de acurácia
# - Magnitude: 2-3% perda de acurácia

Melhores Práticas

1. Seleção de Sparsidade

# Conservador (seguro)
sparsity = 0.3  # 30%, <0.5% perda

# Balanceado (recomendado)
sparsity = 0.5  # 50%, ~1% perda

# Agressivo (arriscado)
sparsity = 0.7  # 70%, 2-5% perda

# Extremo (depende do modelo)
sparsity = 0.9  # 90%, degradação significativa

2. Seleção de Método

# One-shot, sem retreinamento → Wanda ou SparseGPT
if no_retraining_budget:
    use_method = "wanda"  # Mais rápido

# Melhor qualidade → SparseGPT
if need_best_quality:
    use_method = "sparsegpt"  # Mais acurado

# Speedup de hardware → N:M estruturado
if need_speedup:
    use_method = "nm_prune"  # 2:4 ou 4:8

3. Evite Armadilhas Comuns

# ❌ Ruim: Prune sem dados de calibração
prune_random(model)  # Sem estatísticas de ativação

# ✅ Bom: Use dados de calibração
prune_wanda(model, calib_data)

# ❌ Ruim: Sparsidade muito alta de uma vez
prune(model, sparsity=0.9)  # Perda maciça de acurácia

# ✅ Bom: Gradual ou iterativo
iterative_prune(model, target=0.9, steps=10)

Comparação de Performance

Métodos de pruning em 50% sparsidade (LLaMA-7B):

MétodoPerda de AcuráciaVelocidadeMemóriaRetreinamento Necessário
Magnitude-2.5%1.0×-50%Não
Wanda-0.8%1.0×-50%Não
SparseGPT-0.4%1.0×-50%Não
N:M (2:4)-1.0%2.0×-50%Não
Structured-3.0%2.0×-50%Não

Fonte: Paper Wanda (ICLR 2024), Paper SparseGPT

Recursos

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Especialista em construir experiências 3D para a web - Three.js, React Three Fiber, Spline, WebGL e cenas 3D interativas. Cobre configuradores de produtos, portfólios 3D, websites imersivos e adição de profundidade às experiências web. Use quando: website 3D, three.js, WebGL, react three fiber, experiência 3D.

日本語の概要は準備中です。原文の説明を表示しています。

artubss/SKILLS-CLAUDE-CODE112026年5月17日 更新

Quando o usuário quer planejar, projetar ou implementar um teste A/B ou experimento. Também use quando o usuário menciona "teste A/B", "split test", "experimento", "testar essa mudança", "copy variante", "teste multivariado" ou "hipótese". Para implementação de rastreamento, veja analytics-tracking.

日本語の概要は準備中です。原文の説明を表示しています。

artubss/SKILLS-CLAUDE-CODE112026年5月17日 更新

Auditar e melhorar a acessibilidade web seguindo as diretrizes WCAG 2.1. Use quando solicitado para "melhorar acessibilidade", "auditoria a11y", "conformidade WCAG", "suporte a leitor de tela", "navegação por teclado" ou "tornar acessível".

日本語の概要は準備中です。原文の説明を表示しています。

artubss/SKILLS-CLAUDE-CODE112026年5月17日 更新

Testes e benchmarking de agentes LLM incluindo testes comportamentais, avaliação de capacidades, métricas de confiabilidade e monitoramento em produção—onde até os melhores agentes alcançam menos de 50% em benchmarks do mundo real. Use quando: testes de agentes, avaliação de agentes, benchmark de agentes, confiabilidade de agentes, teste de agentes.

日本語の概要は準備中です。原文の説明を表示しています。

artubss/SKILLS-CLAUDE-CODE112026年5月17日 更新

Criar, gerenciar e orquestrar agentes de IA usando o CLI AI Maestro. Use quando o usuário pedir para "criar agente", "listar agentes", "deletar agente", "hibernar agente", "despertar agente", "instalar plugin", "mostrar agente", "reiniciar agente" ou qualquer tarefa de gerenciamento do ciclo de vida do agente.

日本語の概要は準備中です。原文の説明を表示しています。

artubss/SKILLS-CLAUDE-CODE112026年5月17日 更新

Gerencie múltiplos agentes CLI locais via sessões tmux (iniciar/parar/monitorar/atribuir) com agendamento compatível com cron.

日本語の概要は準備中です。原文の説明を表示しています。

artubss/SKILLS-CLAUDE-CODE112026年5月17日 更新

artubss のスキルをすべて見る

このスキルの問題を報告する