Disabling Autograd

By default, every operation involving an array with requires_grad=True records itself into the computation graph. During evaluation and inference you usually don’t need gradients — disabling autograd avoids the overhead and memory of building the graph.

npg.no_grad

Use npg.no_grad as a context manager to suspend gradient tracking for a block of code:

import numpygrad as npg

x = npg.random.randn((4, 8), requires_grad=True)
model = ...

with npg.no_grad():
    pred = model(x)   # no graph is built
    # pred.grad_fn is None

Operations inside the block still run and return correct numeric results — gradients just aren’t tracked.

Use as a decorator

npg.no_grad also works as a function decorator:

@npg.no_grad()
def evaluate(model, x, y):
    pred = model(x)
    return nn.mse(pred, y)

val_loss = evaluate(model, x_val, y_val)

Typical usage

The most common pattern is to use no_grad around your validation loop:

# training step — gradients needed
optimizer.zero_grad()
loss = nn.cross_entropy_loss(model(x_train), y_train)
loss.backward()
optimizer.step()

# validation — no gradients needed
with npg.no_grad():
    val_loss = nn.cross_entropy_loss(model(x_val), y_val)
    print(f"val loss: {val_loss.item():.4f}")