huggingface-transformers

Práticas recomendadas do Hugging Face Transformers, incluindo carregamento de modelos, tokenização, fluxos de fine-tuning e otimização de inferência. Use ao trabalhar com modelos transformer, fine-tuning de LLMs, implementação de tarefas de PLN ou otimização de inferência com transformers.

O que é huggingface-transformers?

Este skill oferece um guia abrangente para usar a biblioteca Hugging Face Transformers, cobrindo desde o carregamento de modelos pré-treinados (como BERT, GPT, LLaMA, T5) até a otimização para produção. É especialmente útil para desenvolvedores e pesquisadores que precisam implementar tarefas de PLN, fine-tuning de modelos ou deploy eficiente. A documentação detalhada inclui padrões de carregamento com quantização (8-bit e 4-bit), práticas críticas de tokenização (padding, truncamento, lotes), fluxos completos de fine-tuning com o Trainer e com LoRA, pipelines de alto nível (classificação, QA, geração, zero-shot), e técnicas de otimização de inferência como processamento em lote, precisão mista, exportação ONNX e quantização dinâmica. O skill também aborda soluções para problemas comuns como falta de memória CUDA e tokenização lenta, sendo compatível com ambientes Python padrão e bibliotecas como PyTorch, Hugging Face Datasets, PEFT e Optimum.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/applied-artificial-intelligence/claude-code-toolkit/tree/main/skills/huggingface-transformers

Installed? Explore more Programação e Desenvolvimento skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Perguntar na sua IA favorita

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

Documentação

Práticas Recomendadas do Hugging Face Transformers

Guia abrangente para usar a biblioteca Hugging Face Transformers, incluindo carregamento de modelos, tokenização, fluxos de fine-tuning, uso de pipelines, conjuntos de dados personalizados e otimização de deployment.


Referência Rápida

Quando usar este skill:

  • Carregar e usar transformers pré-treinados (BERT, GPT, T5, LLaMA, etc.)
  • Fine-tuning de modelos em dados personalizados
  • Implementar tarefas de PLN (classificação, QA, geração, etc.)
  • Otimizar inferência (quantização, ONNX, etc.)
  • Depurar problemas de tokenização
  • Usar pipelines do Hugging Face
  • Implantar transformers em produção

Modelos abordados:

  • Encoders: BERT, RoBERTa, DeBERTa, ALBERT
  • Decoders: GPT-2, GPT-Neo, LLaMA, Mistral
  • Encoder-Decoders: T5, BART, Flan-T5
  • Visão: ViT, CLIP, Stable Diffusion

Parte 1: Padrões de Carregamento de Modelos

Padrão 1: Carregamento Básico de Modelo

from transformers import AutoModel, AutoTokenizer

# Carregar modelo e tokenizer
model_name = "bert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModel.from_pretrained(model_name)

# Para tarefas específicas
from transformers import AutoModelForSequenceClassification
model = AutoModelForSequenceClassification.from_pretrained(
    model_name,
    num_labels=3  # Para classificação de 3 classes
)

Padrão 2: Carregamento com Configuração Específica

from transformers import AutoConfig, AutoModel

# Modificar a configuração
config = AutoConfig.from_pretrained("bert-base-uncased")
config.hidden_dropout_prob = 0.2  # Dropout personalizado
config.attention_probs_dropout_prob = 0.2

# Carregar modelo com configuração personalizada
model = AutoModel.from_pretrained("bert-base-uncased", config=config)

# Ou criar modelo do zero com a configuração
model = AutoModel.from_config(config)

Padrão 3: Carregamento de Modelos Quantizados (Eficiência de Memória)

from transformers import AutoModel, BitsAndBytesConfig
import torch

# Quantização de 8 bits (redução de 50% da memória)
quantization_config = BitsAndBytesConfig(load_in_8bit=True)

model = AutoModel.from_pretrained(
    "meta-llama/Llama-2-7b-hf",
    quantization_config=quantization_config,
    device_map="auto"  # Posicionamento automático em dispositivos
)

# Quantização de 4 bits (redução de 75% da memória)
quantization_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_compute_dtype=torch.float16,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_use_double_quant=True
)

model = AutoModel.from_pretrained(
    "meta-llama/Llama-2-13b-hf",
    quantization_config=quantization_config,
    device_map="auto"
)

Padrão 4: Carregamento a partir de Caminho Local

# Salvar modelo localmente
model.save_pretrained("./meu-modelo")
tokenizer.save_pretrained("./meu-modelo")

# Carregar do caminho local
model = AutoModel.from_pretrained("./meu-modelo")
tokenizer = AutoTokenizer.from_pretrained("./meu-modelo")

Parte 2: Práticas Recomendadas de Tokenização

Padrões Críticos de Tokenização

from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")

# ✅ CORRETO: Todos os argumentos necessários
tokens = tokenizer(
    texto,
    padding=True,  # Preencher até o maior da sequência
    truncation=True,  # Truncar para max_length
    max_length=512,  # Comprimento máximo da sequência
    return_tensors="pt"  # Retornar tensores PyTorch
)

# Acessar componentes
input_ids = tokens['input_ids']  # IDs dos tokens
attention_mask = tokens['attention_mask']  # Máscara de preenchimento
token_type_ids = tokens.get('token_type_ids')  # IDs de segmento (BERT)

# ❌ ERRADO: Faltando argumentos críticos
tokens = tokenizer(texto)  # Sem padding, truncamento ou formato de tensor!

Tokenização em Lote

# Tokenizar múltiplos textos eficientemente
textos = ["Primeiro texto", "Segundo texto", "Terceiro texto"]

tokens = tokenizer(
    textos,
    padding=True,  # Preencher todos até o maior do lote
    truncation=True,
    max_length=128,
    return_tensors="pt"
)

# Forma resultante: [tamanho_do_lote, comprimento_máximo]
print(tokens['input_ids'].shape)  # torch.Size([3, max_len_no_lote])

Manipulação de Tokens Especiais

# Adicionar tokens especiais
tokenizer.add_special_tokens({
    'additional_special_tokens': ['[PERSONALIZADO]', '[MARCADOR]']
})

# Redimensionar embeddings do modelo para corresponder
model.resize_token_embeddings(len(tokenizer))

# Codificar com tokens especiais preservados
texto = "Olá [PERSONALIZADO] mundo"
tokens = tokenizer(texto, add_special_tokens=True)

# Decodificar
decodificado = tokenizer.decode(tokens['input_ids'][0], skip_special_tokens=False)

Tokenização para Diferentes Tarefas

# Classificação de texto (sequência única)
tokens = tokenizer(
    "Este filme foi ótimo!",
    padding="max_length",
    truncation=True,
    max_length=128,
    return_tensors="pt"
)

# Resposta a perguntas (par de sequências)
pergunta = "Qual é a capital da França?"
contexto = "A França é um país na Europa. Paris é sua capital."

tokens = tokenizer(
    pergunta,
    contexto,
    padding="max_length",
    truncation="only_second",  # Truncar apenas o contexto
    max_length=384,
    return_tensors="pt"
)

# Geração de texto (modelos decoder-only)
prompt = "Era uma vez"
tokens = tokenizer(prompt, return_tensors="pt")
# Nenhum padding necessário para entrada de geração

Parte 3: Fluxos de Fine-Tuning

Padrão 1: Fine-Tuning Simples com Trainer

from transformers import (
    AutoModelForSequenceClassification,
    AutoTokenizer,
    Trainer,
    TrainingArguments
)
from datasets import load_dataset

# 1. Carregar conjunto de dados
dataset = load_dataset("glue", "mrpc")

# 2. Carregar modelo
model = AutoModelForSequenceClassification.from_pretrained(
    "bert-base-uncased",
    num_labels=2
)
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")

# 3. Tokenizar conjunto de dados
def tokenize_function(exemplos):
    return tokenizer(
        exemplos["sentence1"],
        exemplos["sentence2"],
        padding="max_length",
        truncation=True,
        max_length=128
    )

tokenized_datasets = dataset.map(tokenize_function, batched=True)

# 4. Definir argumentos de treinamento
training_args = TrainingArguments(
    output_dir="./resultados",
    evaluation_strategy="epoch",
    learning_rate=2e-5,
    per_device_train_batch_size=16,
    per_device_eval_batch_size=16,
    num_train_epochs=3,
    weight_decay=0.01,
    logging_dir="./logs",
    logging_steps=100,
    save_strategy="epoch",
    load_best_model_at_end=True,
    metric_for_best_model="accuracy",
)

# 5. Definir métricas
from datasets import load_metric
import numpy as np

metric = load_metric("accuracy")

def compute_metrics(eval_pred):
    logits, labels = eval_pred
    predictions = np.argmax(logits, axis=-1)
    return metric.compute(predictions=predictions, references=labels)

# 6. Criar Trainer
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["validation"],
    compute_metrics=compute_metrics,
)

# 7. Treinar
trainer.train()

# 8. Salvar
trainer.save_model("./modelo-finetuned")

Padrão 2: Fine-Tuning com LoRA (Eficiente em Parâmetros)

from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import LoraConfig, get_peft_model, TaskType

# Carregar modelo base
model = AutoModelForCausalLM.from_pretrained(
    "meta-llama/Llama-2-7b-hf",
    load_in_8bit=True,  # 8 bits para eficiência de memória
    device_map="auto"
)

# Configurar LoRA
lora_config = LoraConfig(
    task_type=TaskType.CAUSAL_LM,
    r=8,  # Rank LoRA
    lora_alpha=32,  # Alpha LoRA
    lora_dropout=0.1,
    target_modules=["q_proj", "v_proj"],  # Quais camadas adaptar
)

# Aplicar LoRA
model = get_peft_model(model, lora_config)

# Verificar parâmetros treináveis
model.print_trainable_parameters()
# Saída: trainable params: 4.2M || all params: 6.7B || trainable%: 0.062%

# Treinar com Trainer (mesmo de antes)
# Apenas parâmetros LoRA são atualizados!

Padrão 3: Loop de Treinamento Personalizado

import torch
from torch.utils.data import DataLoader
from transformers import AdamW, get_scheduler

# Preparar dataloaders
train_dataloader = DataLoader(tokenized_datasets["train"], batch_size=16, shuffle=True)
eval_dataloader = DataLoader(tokenized_datasets["validation"], batch_size=16)

# Otimizador
optimizer = AdamW(model.parameters(), lr=2e-5)

# Agendador de taxa de aprendizado
num_epochs = 3
num_training_steps = num_epochs * len(train_dataloader)
lr_scheduler = get_scheduler(
    "linear",
    optimizer=optimizer,
    num_warmup_steps=500,
    num_training_steps=num_training_steps
)

# Loop de treinamento
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)

for epoch in range(num_epochs):
    model.train()
    for batch in train_dataloader:
        batch = {k: v.to(device) for k, v in batch.items()}

        outputs = model(**batch)
        loss = outputs.loss
        loss.backward()

        optimizer.step()
        lr_scheduler.step()
        optimizer.zero_grad()

    # Avaliação
    model.eval()
    for batch in eval_dataloader:
        batch = {k: v.to(device) for k, v in batch.items()}
        with torch.no_grad():
            outputs = model(**batch)
        # Calcular métricas

Parte 4: Uso de Pipelines (API de Alto Nível)

Pipeline de Classificação de Texto

from transformers import pipeline

# Carregar pipeline
classifier = pipeline(
    "text-classification",
    model="distilbert-base-uncased-finetuned-sst-2-english"
)

# Predição única
resultado = classifier("Eu amo este produto!")
# [{'label': 'POSITIVE', 'score': 0.9998}]

# Predição em lote
resultados = classifier([
    "Ótimo serviço!",
    "Experiência terrível",
    "Qualidade mediana"
])

Pipeline de Resposta a Perguntas

qa_pipeline = pipeline("question-answering", model="distilbert-base-uncased-distilled-squad")

resultado = qa_pipeline(
    question="Qual é a capital da França?",
    context="A França é um país na Europa. Sua capital é Paris, uma bela cidade."
)
# {'score': 0.98, 'start': 49, 'end': 54, 'answer': 'Paris'}

Pipeline de Geração de Texto

generator = pipeline("text-generation", model="gpt2")

outputs = generator(
    "Era uma vez",
    max_length=50,
    num_return_sequences=3,
    temperature=0.7,
    top_k=50,
    top_p=0.95,
    do_sample=True
)

for output in outputs:
    print(output['generated_text'])

Pipeline de Classificação Zero-Shot

classifier = pipeline("zero-shot-classification", model="facebook/bart-large-mnli")

resultado = classifier(
    "Este é um curso sobre programação Python.",
    candidate_labels=["educação", "tecnologia", "negócios", "esportes"]
)
# {'sequence': '...', 'labels': ['educação', 'tecnologia', ...], 'scores': [0.85, 0.12, ...]}

Parte 5: Otimização de Inferência

Otimização 1: Processamento em Lote

# ❌ LENTO: Processar um de cada vez
for texto in textos:
    output = model(**tokenizer(texto, return_tensors="pt"))

# ✅ RÁPIDO: Processar em lotes
tamanho_lote = 32
for i in range(0, len(textos), tamanho_lote):
    lote = textos[i:i+tamanho_lote]
    inputs = tokenizer(lote, padding=True, truncation=True, return_tensors="pt")
    outputs = model(**inputs)

Otimização 2: Precisão Mista (AMP)

from torch.cuda.amp import autocast, GradScaler

scaler = GradScaler()

for batch in dataloader:
    optimizer.zero_grad()

    # Passagem direta em precisão mista
    with autocast():
        outputs = model(**batch)
        loss = outputs.loss

    # Passagem reversa com gradientes escalados
    scaler.scale(loss).backward()
    scaler.step(optimizer)
    scaler.update()

Otimização 3: Exportação ONNX

from transformers import AutoModelForSequenceClassification, AutoTokenizer
from optimum.onnxruntime import ORTModelForSequenceClassification

# Exportar para ONNX
model = AutoModelForSequenceClassification.from_pretrained("bert-base-uncased")
model.save_pretrained("./onnx-model", export=True)

# Carregar modelo ONNX (inferência mais rápida)
ort_model = ORTModelForSequenceClassification.from_pretrained("./onnx-model")

# Inferência (2-3x mais rápida)
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
inputs = tokenizer("Olá mundo", return_tensors="pt")
outputs = ort_model(**inputs)

Otimização 4: Quantização Dinâmica

import torch

# Quantizar modelo para int8
modelo_quantizado = torch.quantization.quantize_dynamic(
    model,
    {torch.nn.Linear},  # Quantizar camadas Lineares
    dtype=torch.qint8
)

# Modelo 4x menor, inferência 2-3x mais rápida em CPU

Parte 6: Problemas Comuns e Soluções

Problema 1: CUDA sem Memória

Problema: RuntimeError: CUDA out of memory

Soluções:

# Solução 1: Reduzir tamanho do lote
training_args = TrainingArguments(
    per_device_train_batch_size=8,  # Era 32
    gradient_accumulation_steps=4,  # Lote efetivo = 8*4 = 32
)

# Solução 2: Usar checkpointing de gradientes
model.gradient_checkpointing_enable()

# Solução 3: Usar modelo de 8 bits
from transformers import BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(load_in_8bit=True)
model = AutoModel.from_pretrained("model-name", quantization_config=quantization_config)

# Solução 4: Limpar cache
import torch
torch.cuda.empty_cache()

Problema 2: Tokenização Lenta

Problema: Tokenização é o gargalo

Soluções:

# Solução 1: Usar tokenizers rápidos
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased", use_fast=True)

# Solução 2: Tokenizar conjunto de dados uma vez, armazenar em cache
tokenized_dataset = dataset.map(
    tokenize_function,
    batched=True,
    num_proc=4,  # Processamento paralelo
    remove_columns=dataset.column_names,
    load_from_cache_file=True  # Armazenar resultados em cache
)

# Solução 3: Usar lotes maiores para tokenização
tokenizer(
    textos,
    padding=True,
    truncation=True,
    max_length=512,
    return_tensors="pt",
    batched=True,  # Processar múltiplos textos de uma vez
    batch_size=1000
)

Problema 3: Resultados Inconsistentes

Problema: Modelo produz resultados diferentes para a mesma entrada

Solução:

# Definir sementes para reprodutibilidade
import random
import numpy as np
import torch

random.seed(42)
np.random.seed(42)
torch.manual_seed(42)
torch.cuda.manual_seed_all(42)

# Para modelos de geração, defina também
outputs = model.generate(
    **inputs,
    do_sample=False  # Desabilitar amostragem para resultados determinísticos
)

Individual skills in this repo

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

Habilidades Relacionadas