LSTM Batch Pollution: One Bad Sample Corrupts the Entire Batch

2026-07-04 BUG-005 Pipeline: PARTIAL Detection: 100%
+24
Gap (healthy → bug)
100%
Detection rate
0%
False positives
BUG-005 Anomaly Chart

Anomalies detected: 0 (healthy) → 24 (bug) → 0 (fixed). Perfect resolution.

1. The Bug

nn.LSTM on CUDA produces NaN in batch mode but correct output in single-sample mode. This is a sample independence violation — one corrupted sample poisons the entire batch.

Upstream: pytorch#173334 — OPEN since June 2025.

2. Reproduction

lstm = nn.LSTM(4, 8, batch_first=True).cuda()
x_batch = torch.randn(4, 5, 4).cuda()
x_batch[0] = float('nan')  # corrupt one sample
out, _ = lstm(x_batch)
# ALL 4 outputs are NaN — even samples 1,2,3 with clean inputs!

3. NeuralDBG Diagnosis

With the DeepMLP architecture, NeuralDBG captures 24 anomalies vs 0 healthy:

4. The Fix

# Filter NaN samples before LSTM
valid_mask = ~torch.isnan(x_batch).any(dim=(1,2))
x_clean = x_batch[valid_mask]

After fix: 0 anomalies — perfect resolution. The 1→4→0 pattern proves the detection is causal.

5. Detection Metrics — DeepMLP

Gap: +24 anomalies from healthy to bug, 0 false positives, 100% detection.

Causal Chain

graph LR A["nan_detected
LSTM_lstm
[nan_detected]"] -->|"Temporal(0)
conf=0.90"| B["gradient_health
Linear_lin
[exploding]"] B -->|"Temporal(1)
conf=0.70"| C["optimizer_instability
optimizer
[diverging]"] style A fill:#f85149,stroke:#f85149,color:#fff style B fill:#d29922,stroke:#d29922,color:#fff style C fill:#d29922,stroke:#d29922,color:#fff

Detection Metrics

PhaseAnomaliesEventsStatus
Healthy baseline046Clean
Bug injected2470Detected
After fix046Resolved
Key insight: One NaN sample silently corrupts the entire batch. NeuralDBG localizes the root cause to the LSTM layer in step 1 — hours before the loss shows NaN.