Pular para o conteúdo principal

Capítulo 3: Esquecimento Catastrófico

Preservando Conhecimento Durante o Fine-Tuning​

O esquecimento catastrófico é um dos maiores desafios no fine-tuning. Compreender esse fenômeno ajuda você a criar estratégias de treinamento melhores.


O que é Esquecimento Catastrófico?​

O esquecimento catastrófico ocorre quando uma rede neural perde conhecimentos previamente aprendidos após ser treinada com novos dados.

Exemplo de Cenário​

Um LLM pré-treinado sabe:

  • Como traduzir idiomas
  • Conhecimento geral de mundo
  • Raciocínio matemático
  • Geração de código

Após o fine-tuning com dados de suporte ao cliente:

  • ✅ Excelente em suporte ao cliente
  • ❌ Pode ter dificuldades com tradução
  • ❌ Pode perder parte do conhecimento geral
  • ❌ A qualidade da geração de código pode cair

Por Que Isso Acontece?​

Interferência nos Pesos​

Redes neurais armazenam conhecimento em seus pesos. Quando você treina com novos dados:

Original weights (W) → encode general knowledge
New training → updates W to (W')
W' optimizes for new task → may break old task representations

Mudança de Distribuição​

O modelo se adapta à distribuição específica dos seus dados, podendo perder a capacidade de generalização.


Medindo o Esquecimento Catastrófico​

Avaliação Antes/Depois​

from lm_eval import evaluator
from lm_eval.models.huggingface import HFLM

def evaluate_model(model_path, tasks=["hellaswag", "arc_easy", "mmlu"]):
"""Evaluate model on standard benchmarks."""
model = HFLM(pretrained=model_path)
results = evaluator.simple_evaluate(
model=model,
tasks=tasks,
num_fewshot=0,
)
return results

# Before fine-tuning
baseline_results = evaluate_model("meta-llama/Llama-3.1-8B")
print("Baseline:", baseline_results)

# After fine-tuning
finetuned_results = evaluate_model("./my-finetuned-model")
print("Fine-tuned:", finetuned_results)

# Compare
for task in ["hellaswag", "arc_easy", "mmlu"]:
baseline = baseline_results["results"][task]["acc"]
finetuned = finetuned_results["results"][task]["acc"]
diff = finetuned - baseline
print(f"{task}: {diff:+.2%} ({'↑' if diff > 0 else '↓'})")

Testes Específicos de Capacidade​

# Create a test suite for capabilities you want to preserve
test_cases = [
{"prompt": "Translate to French: Hello, how are you?",
"expected_contains": "Bonjour"},
{"prompt": "What is 15 * 17?",
"expected_contains": "255"},
{"prompt": "Write a Python function to reverse a string",
"expected_contains": "def"},
]

def test_capabilities(model, tokenizer, test_cases):
"""Test if model retains specific capabilities."""
for test in test_cases:
output = model.generate(
tokenizer.encode(test["prompt"], return_tensors="pt"),
max_new_tokens=100
)
response = tokenizer.decode(output[0], skip_special_tokens=True)
passed = test["expected_contains"] in response
print(f"{'✅' if passed else '❌'} {test['prompt'][:50]}...")

Estratégias de Mitigação​

1. Use Taxas de Aprendizado Menores​

# Full fine-tuning: lower LR preserves more knowledge
training_args = TrainingArguments(
learning_rate=1e-5, # Lower than default
# vs 2e-5 or higher for PEFT
)

2. Menos Épocas de Treinamento​

# Less training = less forgetting
training_args = TrainingArguments(
num_train_epochs=1, # Start with 1
# Monitor validation performance
# Only increase if underfitting
)

3. Técnicas de Regularização​

Decaimento de Peso (Weight Decay)​

training_args = TrainingArguments(
weight_decay=0.01, # Penalize large weight changes
)

Consolidação Elástica de Pesos (EWC)​

# EWC adds a penalty for changing important weights
# (Research technique, not directly in HF Trainer)
loss = cross_entropy_loss + lambda * sum(
importance[i] * (theta[i] - theta_star[i])^2
for i in parameters
)

4. Mistura/Repetição de Dados​

# Mix original pre-training style data with fine-tuning data
from datasets import concatenate_datasets

# Your specific data
finetuning_data = load_dataset("your/dataset")

# General instruction data to maintain capabilities
general_data = load_dataset("databricks/dolly-15k", split="train[:1000]")

# Mix them (e.g., 80% specific, 20% general)
mixed_dataset = concatenate_datasets([
finetuning_data,
general_data.shuffle().select(range(len(finetuning_data) // 4))
])

5. Use PEFT em Vez Disso​

A mitigação mais eficaz: não atualize todos os pesos

from peft import LoraConfig, get_peft_model

# Only update small adapters, preserving base model
lora_config = LoraConfig(
r=16,
lora_alpha=32,
target_modules=["q_proj", "v_proj"],
)

model = get_peft_model(base_model, lora_config)
# Base model weights frozen → no catastrophic forgetting!

Vantagem do PEFT​

Por Que PEFT Previne o Esquecimento​

Evidência Empírica​

MétodoDesempenho na TarefaRetenção em Benchmarks
Full FT95%70-85%
LoRA93%95-99%
QLoRA92%95-99%

Métodos PEFT normalmente retêm 95%+ do desempenho de base em tarefas não relacionadas.


Estratégia de Avaliação​

Protocolo de Avaliação Abrangente​

def comprehensive_evaluation(model_path, baseline_path):
"""Evaluate both task performance and capability retention."""

# 1. Task-specific evaluation (your fine-tuning goal)
task_score = evaluate_on_task(model_path, your_test_set)

# 2. General capability benchmarks
benchmarks = ["hellaswag", "arc_easy", "mmlu", "gsm8k"]
baseline_scores = {}
finetuned_scores = {}

for bench in benchmarks:
baseline_scores[bench] = evaluate_benchmark(baseline_path, bench)
finetuned_scores[bench] = evaluate_benchmark(model_path, bench)

# 3. Calculate retention
retention = {}
for bench in benchmarks:
retention[bench] = finetuned_scores[bench] / baseline_scores[bench]

avg_retention = sum(retention.values()) / len(retention)

print(f"Task Performance: {task_score:.2%}")
print(f"Average Capability Retention: {avg_retention:.2%}")

# 4. Trade-off analysis
if task_score > 0.90 and avg_retention > 0.95:
print("✅ Good balance achieved")
elif task_score > 0.90 and avg_retention < 0.90:
print("⚠️ High task performance but significant forgetting")
else:
print("❌ Consider adjusting training")

return {
"task_score": task_score,
"retention": retention,
"avg_retention": avg_retention
}

Resumo das Melhores Práticas​

Para Minimizar o Esquecimento Catastrófico:​

EstratégiaDificuldadeEficácia
Use PEFT (LoRA/QLoRA)Fácil⭐⭐⭐⭐⭐
Taxa de aprendizado menorFácil⭐⭐⭐
Menos épocasFácil⭐⭐⭐
Mistura de dadosMédia⭐⭐⭐⭐
Decaimento de pesoFácil⭐⭐
Early stoppingFácil⭐⭐⭐

Abordagem Recomendada​

  1. Comece com PEFT (LoRA ou QLoRA)
  2. Se PEFT não for suficiente, tente o fine-tuning completo com:
    • Taxa de aprendizado baixa (1e-5)
    • Poucas épocas (1-2)
    • Mistura de dados
    • Avaliação abrangente

Principais Pontos​

✅ Esquecimento catastrófico é quando modelos perdem conhecimento após o fine-tuning

✅ Isso ocorre porque os pesos são modificados para se ajustar à nova distribuição de dados

✅ Métodos PEFT evitam em grande parte o esquecimento mantendo os pesos base congelados

✅ Para fine-tuning completo: use LR baixo, poucas épocas, mistura de dados

✅ Sempre avalie tanto o desempenho na tarefa quanto a retenção de capacidades

✅ O trade-off é: especialização na tarefa vs. capacidade geral


Próximos Passos​

Teste seu conhecimento com o Quiz do Módulo 2, depois continue para Módulo 3: Fine-Tuning Eficiente em Parâmetros.


Verificação Rápida​

Antes de avançar, certifique-se de que você consegue responder:

  1. O que é esquecimento catastrófico e por que ele ocorre?
  2. Como métodos PEFT ajudam a prevenir o esquecimento catastrófico?
  3. Quais são três estratégias para minimizar o esquecimento no fine-tuning completo?