Programa
Quantas vezes você já se deparou com um valor de loss NaN ao treinar uma rede neural profunda?
Depois de horas de treino, a curva de loss parece saudável e, do nada, dispara para o infinito. O motivo geralmente são gradientes explosivos — valores de gradiente que crescem tanto durante o backpropagation que as atualizações de parâmetros ficam instáveis e o modelo quebra. Esse problema afeta ainda mais as redes recorrentes, mas também aparece em transformers e redes feedforward profundas.
O gradient clipping resolve isso restringindo o tamanho dos gradientes antes que eles cheguem ao otimizador. É uma adição de uma linha ao seu loop de treino que mantém as atualizações limitadas sem alterar nada no modelo.
Neste artigo, vou explicar a intuição por trás do gradient clipping, os dois principais métodos, como escolher o limiar e como implementar em PyTorch e TensorFlow.
Mas afinal, o que é loss em ciência de dados? Leia nosso post Loss function in machine learning para descobrir.
O que é gradient clipping?
Gradient clipping é uma técnica que limita a magnitude dos gradientes durante o treino para evitar atualizações de parâmetros instáveis.
Quando um gradiente fica grande demais, o otimizador dá um passo enorme no espaço de parâmetros e empurra os pesos para uma região onde o loss explode. O clipping ajuda limitando o tamanho desse passo antes que ele cause estragos.
É importante notar que o gradient clipping não afeta a arquitetura do modelo. Você não adiciona camadas nem muda funções de ativação. Ele só altera o processo de treino, interceptando os gradientes entre o backpropagation e o passo do otimizador.
Isso o torna barato de testar e fácil de remover. Como você verá adiante, basta uma linha de código.
Como o gradient clipping funciona
A mecânica é simples. A operação de clipping fica entre o backward pass e o passo do otimizador e segue os mesmos quatro passos a cada iteração.
- Calcular os gradientes: rode o forward pass, calcule o loss e execute o backpropagation. Nada muda aqui: os gradientes fluem pela rede como sempre.
- Checar a magnitude do gradiente: meça quão grandes estão os gradientes. Dependendo do método, isso significa olhar valores individuais ou calcular a norma geral em todos os parâmetros.
- Reduzir os gradientes se passarem do limiar: se a magnitude ultrapassar o limite definido, reduza os gradientes proporcionalmente. Se não, deixe como estão.
- Atualizar os parâmetros do modelo: passe os gradientes recortados para o otimizador e aplique a atualização de pesos.
Na maioria das vezes, seus gradientes ficam abaixo do limite e o treino segue como se não houvesse clipping. Quando surge um pico, o clipping o intercepta antes que o otimizador reaja.
É isso.
Métodos comuns de gradient clipping
Existem duas formas de aplicar clipping, e a diferença está no que você mede e no que você escala.
Clip by value
Clip by value limita individualmente cada elemento do gradiente.
Você escolhe um intervalo, digamos [-1.0, 1.0], e qualquer valor de gradiente fora desse intervalo é ajustado para o limite mais próximo. Um gradiente de 2.5 vira 1.0. Um gradiente de -2.5 vira -1.0. Valores já dentro do intervalo permanecem como estão.

Exemplo de clip by value
O apelo está na simplicidade. Não há matemática além de uma operação de mínimo/máximo, e é rápido de executar.
Mas há um ponto negativo. Recortar valores individuais muda a direção do vetor gradiente. Se um componente for recortado e os outros não, o vetor atualizado deixa de apontar exatamente para onde o backpropagation indicou. O otimizador acaba dando um passo numa direção um pouco errada.
Por isso o clip by value é menos usado na prática.
Clip by norm
Clip by norm escala todo o vetor gradiente quando sua magnitude total excede um limiar.
Em vez de olhar valores individuais, ele calcula a norma de todos os gradientes juntos (geralmente a norma L2) e compara com um valor máximo. Se a norma estiver abaixo do limiar, nada acontece. Se estiver acima, cada gradiente é multiplicado pelo mesmo fator de escala para trazer a norma de volta ao limite.

Exemplo de clip by norm
A vantagem é preservar a direção. Como todo componente encolhe pelo mesmo fator, o vetor gradiente continua apontando na direção original. Você só encurta o passo, sem redirecioná-lo.
É por isso que o clip by norm virou padrão. O clip_grad_norm_ do PyTorch e o clipnorm do TensorFlow implementam esse método, e a maioria dos pipelines modernos já o usa por padrão.
Gradientes explosivos vs. gradientes que desaparecem
Gradientes explosivos e gradientes que desaparecem são problemas comuns em deep learning, mas apenas um deles é resolvido com gradient clipping.
Gradientes explosivos
Acontecem quando os valores de gradiente crescem demais durante o backpropagation.
Isso geralmente aparece em redes profundas ou arquiteturas recorrentes, onde os gradientes são multiplicados por muitas camadas ou passos de tempo. Se essas multiplicações se acumulam no sentido errado, a magnitude explode. O otimizador então faz uma atualização enorme, os pesos saltam para valores extremos e o loss costuma virar NaN ou Inf.
Você verá isso como picos repentinos no loss ou um modelo que diverge do nada.
Gradientes que desaparecem
É o problema oposto. Os valores de gradiente encolhem em direção a zero à medida que retropropagam pela rede.
Quando os gradientes ficam pequenos demais, as atualizações de peso se tornam minúsculas. Camadas iniciais param de aprender, camadas profundas aprendem devagar e o treino praticamente estagna. A curva de loss achata e não melhora, mesmo após muitas épocas.
Esse foi o principal motivo de RNNs terem dificuldades com sequências longas antes de LSTMs e GRUs.
Onde o gradient clipping entra
Gradient clipping combate gradientes explosivos, não gradientes que desaparecem.
O clipping reduz gradientes que estão grandes demais, mas não faz nada quando eles são muito pequenos. Para gradientes que desaparecem, você precisa de melhor inicialização de pesos, conexões residuais, normalização em lote (batch) ou arquiteturas pensadas para preservar o fluxo do gradiente.
Clip by norm em detalhes
Clip by norm é o método que a maioria das pessoas procura quando fala de gradient clipping.
O processo tem três etapas. Primeiro, calcule a norma de todos os gradientes combinados. Segundo, compare essa norma com o limiar escolhido. Terceiro, reescale os gradientes se a norma estiver grande demais.
A norma geralmente é a L2, o que significa elevar ao quadrado cada valor do gradiente, somar tudo e tirar a raiz quadrada. Se você tem gradientes g_1, g_2, ..., g_n em todos os parâmetros do modelo, a norma L2 é:

Fórmula de clipping por norma
Com a norma em mãos, compare-a com seu limiar c. Se ||g|| <= c, os gradientes passam sem alteração. Se ||g|| > c, cada gradiente é multiplicado pelo fator de escala c / ||g||. Isso faz a nova norma ficar exatamente em c.
Isso importa porque todo componente encolhe pelo mesmo fator. As proporções relativas entre os valores de gradiente permanecem, o que mantém a direção original do vetor. Você encurta o passo do otimizador, não muda o rumo.
Essa propriedade de preservar a direção faz do clipping por norma a escolha padrão. Clip by value pode torcer a direção do vetor; clip by norm só altera o comprimento.
O clip_grad_norm_ do PyTorch e o clipnorm do TensorFlow fazem exatamente isso. Quando alguém diz "estou usando gradient clipping", quase sempre quer dizer clipping por norma.
Como escolher o limiar de gradient clipping
O limiar é um hiperparâmetro, ou seja, não existe um valor universal que funcione para todo modelo.
Se você definir alto demais, o clipping quase nunca será acionado. Os gradientes quase sempre ficam abaixo do limite, então a rede de segurança não pega nada. O treino segue como se o clipping não existisse e os picos de loss continuam quando os gradientes explodem.
Se definir baixo demais, você recorta de forma agressiva. Cada batch tem seus gradientes reduzidos, deixando as atualizações menores do que deveriam. O aprendizado desacelera e o modelo leva mais tempo para convergir — às vezes, muito mais.
Um ponto de partida comum é 1.0, que funciona bem para muitas arquiteturas. Valores entre 0.5 e 5.0 cobrem a maioria dos casos práticos.
A melhor abordagem é monitorar as normas dos gradientes durante o treino. Registre a norma sem clipping a cada passo e observe a distribuição. Se a maior parte das normas ficar em torno de 0.3 com picos ocasionais de 50, defina o limiar acima da faixa típica, mas bem abaixo dos picos — 2.0 ou 3.0 seriam razoáveis aqui.
Trate como qualquer hiperparâmetro: comece com 1.0, observe o comportamento e ajuste com base no treino.
Gradient clipping em redes neurais recorrentes
Foi nas RNNs que o gradient clipping virou técnica padrão primeiro.
O motivo é a forma como RNNs propagam gradientes no tempo. O backpropagation through time multiplica as mesmas matrizes de peso por muitos passos de tempo, e essas multiplicações repetidas podem se acumular em valores enormes. Sequências longas pioram o problema.
LSTMs e GRUs reduziram o problema com mecanismos de portas, mas não eliminaram. Ambas as arquiteturas ainda se beneficiam do clipping, especialmente ao treinar em sequências longas ou com taxas de aprendizado altas.
Para treinar RNNs, clip by norm com limiar entre 1.0 e 5.0 é o padrão típico. Se você estiver usando nn.LSTM ou nn.GRU do PyTorch e seu loss explodir no treino, adicionar clip_grad_norm_ é geralmente a primeira coisa a tentar.
Gradient clipping no deep learning moderno
O gradient clipping não sumiu quando transformers substituíram as RNNs.
Modelos de linguagem grandes como GPT e BERT usam clipping no pré-treino e no fine-tuning. O mesmo vale para vision transformers, modelos de difusão e a maioria das arquiteturas profundas com centenas de camadas. Os otimizadores Adam e AdamW, dominantes hoje, costumam ser combinados com clipping por norma em limiares próximos de 1.0.
A razão é a mesma das RNNs. Redes profundas multiplicam gradientes ao longo de muitas camadas, e lotes grandes combinados com taxas de aprendizado altas podem gerar picos ocasionais. O clipping lida com esses picos sem afetar os passos normais de treino.
A maioria das implementações de referência inclui clipping por padrão. O Trainer da Hugging Face, o PyTorch Lightning e o DeepSpeed expõem clipping como opção padrão de configuração. Se você estiver treinando algo maior que um modelo de brinquedo, o clipping quase certamente faz parte do pipeline.
É uma linha que custa quase nada e evita que execuções despenquem após horas de computação. Por isso permanece.
Gradient clipping no PyTorch
O PyTorch trata o clipping com uma única função utilitária: torch.nn.utils.clip_grad_norm_.
A chamada de clipping vai entre loss.backward() e optimizer.step(). O backpropagation precisa preencher os gradientes primeiro; depois o clipping os reduz se necessário; então o otimizador aplica a atualização. Colocar a chamada em outro lugar não funciona.
Aqui vai um script completo e executável que treina um MLP pequeno em dados sintéticos de regressão com gradient clipping ativado:
import torch
import torch.nn as nn
from torch.utils.data import DataLoader, TensorDataset
torch.manual_seed(42)
# Synthetic regression data
n_samples = 1000
n_features = 20
inputs = torch.randn(n_samples, n_features)
targets = (inputs.sum(dim=1, keepdim=True) * 2.0 + torch.randn(n_samples, 1) * 0.1)
dataset = TensorDataset(inputs, targets)
dataloader = DataLoader(dataset, batch_size=32, shuffle=True)
# Small feedforward network
model = nn.Sequential(
nn.Linear(n_features, 64),
nn.ReLU(),
nn.Linear(64, 64),
nn.ReLU(),
nn.Linear(64, 1),
)
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
loss_fn = nn.MSELoss()
# Training loop with gradient clipping
n_epochs = 5
max_grad_norm = 1.0
for epoch in range(n_epochs):
epoch_loss = 0.0
for batch_inputs, batch_targets in dataloader:
optimizer.zero_grad()
predictions = model(batch_inputs)
loss = loss_fn(predictions, batch_targets)
loss.backward()
# Gradient clipping
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=max_grad_norm)
optimizer.step()
epoch_loss += loss.item()
print(f("Epoch {epoch + 1}: loss = {epoch_loss / len(dataloader):.4f}"))

Saída do PyTorch
A função clip_grad_norm_ recebe dois argumentos principais:
-
parameters: os parâmetros do modelo cujos gradientes você quer recortar. Passemodel.parameters()para cobrir o modelo inteiro. -
max_norm: o limiar para a norma do gradiente.1.0é um ponto de partida comum.
Há um argumento opcional norm_type que, por padrão, é 2.0 (norma L2). Raramente você vai precisar mudar isso.
O sublinhado no final de clip_grad_norm_ indica operação in place. A função modifica diretamente os gradientes dentro do atributo .grad de cada parâmetro, então você não precisa usar o valor de retorno. Ela retorna a norma total antes do clipping, útil para logar.
Para clip-by-value em vez de clip-by-norm, o PyTorch tem torch.nn.utils.clip_grad_value_:
torch.nn.utils.clip_grad_value_(model.parameters(), clip_value=0.5)
Mas, como discutido, você raramente (ou nunca) vai usar essa implementação.
Esse é todo o setup. Duas linhas adicionadas ao seu loop de treino.
Gradient clipping no TensorFlow
O TensorFlow trata o clipping no nível do otimizador, e não como uma função separada.
Ao criar um otimizador, você passa clipnorm ou clipvalue como argumento. O otimizador aplica o clipping internamente a cada passo, então você não precisa modificar seu loop de treino.
Aqui vai um exemplo funcional usando a API Keras com dados sintéticos de regressão:
import numpy as np
import tensorflow as tf
tf.random.set_seed(42)
np.random.seed(42)
# Synthetic regression data
n_samples = 1000
n_features = 20
x_train = np.random.randn(n_samples, n_features).astype(np.float32)
y_train = (x_train.sum(axis=1, keepdims=True) * 2.0
+ np.random.randn(n_samples, 1).astype(np.float32) * 0.1)
# Small feedforward network
model = tf.keras.Sequential([
tf.keras.layers.Dense(64, activation="relu", input_shape=(n_features,)),
tf.keras.layers.Dense(64, activation="relu"),
tf.keras.layers.Dense(1),
])
# Optimizer with gradient clipping by norm
optimizer = tf.keras.optimizers.Adam(learning_rate=1e-3, clipnorm=1.0)
model.compile(optimizer=optimizer, loss="mse")
model.fit(x_train, y_train, epochs=5, batch_size=32)

Saída do TensorFlow
Os dois argumentos fazem coisas diferentes:
-
clipnormrecorta pela norma L2 de cada tensor de gradiente. Se a norma exceder o limiar, o tensor é escalado proporcionalmente para baixo. -
clipvaluerecorta individualmente cada elemento do gradiente. Qualquer valor acima do limiar é limitado a ele, e qualquer valor abaixo do limiar negativo é limitado ao negativo.
Para trocar de clipping por norma para clipping por valor, basta alternar o argumento:
optimizer = tf.keras.optimizers.Adam(learning_rate=1e-3, clipvalue=0.5)
Ambos funcionam com qualquer otimizador do Keras: Adam, SGD, RMSprop, AdamW e outros. Há também o argumento global_clipnorm, que recorta com base na norma calculada em todos os gradientes combinados, e não por tensor. Isso se aproxima mais do comportamento padrão do PyTorch.
Se você estiver escrevendo um loop de treino customizado com tf.GradientTape, o otimizador ainda faz o clipping quando você chama apply_gradients:
for epoch in range(5):
for batch_x, batch_y in zip(np.array_split(x_train, 32), np.array_split(y_train, 32)):
with tf.GradientTape() as tape:
predictions = model(batch_x, training=True)
loss = tf.reduce_mean(tf.square(predictions - batch_y))
gradients = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
Essa é a diferença entre os frameworks. O PyTorch coloca o clipping nas suas mãos, dentro do loop. O TensorFlow embute no próprio otimizador. A lógica por trás é a mesma.
Gradient clipping vs. outras técnicas de estabilização
Gradient clipping não é a única forma de estabilizar o treino — e nem sempre é a ferramenta certa.
Outras técnicas lidam com problemas parecidos, mas diferentes. Algumas evitam que os gradientes cresçam demais desde o início, outras impedem que desapareçam e algumas tornam a superfície de loss mais fácil de otimizar. Veja algumas delas.
Batch normalization
Batch normalization normaliza as ativações dentro de cada mini-batch durante o treino.
Ela mantém as saídas das camadas em uma faixa estável, deixando as magnitudes dos gradientes mais previsíveis. Redes com batch norm toleram taxas de aprendizado maiores, convergem mais rápido e são menos sensíveis à inicialização de pesos.
Mas batch norm não impede diretamente explosões de gradiente. Ela reduz a frequência, não resolve quando acontecem. Por isso muitos modelos combinam batch norm com gradient clipping.
Conexões residuais
Conexões residuais adicionam atalhos que pulam uma ou mais camadas, permitindo que os gradientes fluam diretamente das camadas mais tardias para as iniciais.
Isso resolve o problema de gradientes que desaparecem em redes profundas. Sem conexões residuais, treinar redes com mais de 20–30 camadas fica difícil porque os gradientes encolhem ao retropropagar. Com elas, redes com centenas de camadas treinam sem problemas.
Conexões residuais atacam o extremo oposto do problema em relação ao clipping. Clipping lida com gradientes grandes demais. Residuais lidam com gradientes pequenos demais.
Inicialização cuidadosa de pesos
Os valores iniciais dos pesos definem a magnitude inicial das ativações e dos gradientes. Uma má inicialização pode causar explosões ou desaparecimentos desde o primeiro passo.
Métodos como Xavier e He escalam os pesos iniciais com base no tamanho da camada. Isso mantém as variâncias das ativações estáveis no início do treino, prevenindo muitos problemas de gradiente antes que apareçam.
Uma boa inicialização reduz a chance de precisar de clipping, mas não elimina. Picos ainda podem surgir depois, especialmente com taxas de aprendizado altas ou batches atípicos.
Como tudo se encaixa
Essas técnicas não são alternativas, e sim complementares, resolvendo partes diferentes do mesmo problema.
Um setup moderno típico usa inicialização cuidadosa no início, conexões residuais na arquitetura, normalização por lote (ou por camada) dentro da rede e gradient clipping como rede de segurança durante a otimização. Cada uma cobre um modo de falha específico e, juntas, tornam o treino de redes profundas viável.
Conclusão
Gradient clipping é uma das correções mais simples em deep learning e resolve um problema que pode arruinar horas de treino em um único passo.
A boa notícia é que você não precisa mudar a arquitetura nem reescrever o código de treino. Uma linha no PyTorch ou um argumento no TensorFlow já implementa o clipping.
Ele funciona melhor como parte de um conjunto maior. Combine com inicialização cuidadosa de pesos, conexões residuais e normalização por batch ou por camada, e você terá um pipeline que lida com instabilidade por vários ângulos.
Se o seu loss está explodindo, comece pelo clipping. Se está desaparecendo, busque outra solução. E se você estiver treinando algo maior que um modelo pequeno, adicione clipping ao pipeline por padrão e siga em frente.
Gradient clipping é só um dos muitos termos que todo engenheiro de machine learning precisa dominar. Se você quer aprender os demais e ficar pronto para o mercado em 2026, inscreva-se hoje mesmo na nossa trilha Machine Learning Engineer.
Torne-se um cientista de ML
Perguntas frequentes sobre gradient clipping
O que é gradient clipping em deep learning?
Gradient clipping é uma técnica que limita o tamanho dos gradientes durante o treino de redes neurais para evitar atualizações de parâmetros instáveis. Quando os gradientes crescem demais no backpropagation, o otimizador dá passos enormes que empurram os pesos para regiões ruins e fazem o loss explodir. O clipping limita a magnitude antes do passo do otimizador, mantendo as atualizações controladas mesmo quando os gradientes brutos disparam.
Quando devo usar gradient clipping?
Use gradient clipping sempre que o treino estiver instável, especialmente se você notar picos repentinos no loss, valores NaN ou divergência após horas de treino. É prática padrão para redes recorrentes como LSTMs e GRUs, e para arquiteturas profundas treinadas com taxas de aprendizado altas. Se a curva de loss está saudável, você pode pular, mas adicioná-lo como rede de segurança não atrapalha.
Qual a diferença entre clip by value e clip by norm?
Clip by value limita individualmente cada elemento do gradiente, o que pode mudar a direção do vetor gradiente. Clip by norm escala o vetor inteiro quando sua magnitude total excede um limiar, preservando a direção original enquanto encurta o passo. Clip by norm é a escolha padrão no deep learning moderno porque não distorce a direção da atualização.
Como escolher um bom limiar para gradient clipping?
Comece com 1.0 e ajuste conforme o que observar no treino. Registre as normas dos gradientes sem clipping ao longo dos batches e veja a distribuição. Defina o limiar acima da faixa típica, mas bem abaixo dos picos que você quer capturar. Se alto demais, o clipping nunca ativa; se baixo demais, você desacelera o aprendizado à toa.
Gradient clipping também resolve gradientes que desaparecem?
Não. Gradient clipping trata apenas gradientes explosivos, quando os valores crescem demais. Gradientes que desaparecem são o problema oposto, quando os valores encolhem para zero e o aprendizado praticamente para. Para gradientes que desaparecem, use melhor inicialização de pesos, conexões residuais, normalização (batch/layer) ou arquiteturas como LSTMs e GRUs.




