d2l-ai/d2l-zh · error · AssertionError
X.shape[0] == y.shape[0]
Error message
X.shape[0] == y.shape[0]
What it means
An AssertionError in d2l.paddle.split_batch verifying that the feature tensor X and label tensor y have identical first dimensions (batch size). split_batch scatters X and y across multiple GPU/CPU devices for multi-device training (sec_multi_gpu); mismatched batch sizes would misalign samples with labels on the devices, so it refuses to proceed.
Source
Thrown at d2l/paddle.py:1483
class Benchmark:
"""用于测量运行时间"""
def __init__(self, description='Done'):
"""Defined in :numref:`sec_hybridize`"""
self.description = description
def __enter__(self):
self.timer = d2l.Timer()
return self
def __exit__(self, *args):
print(f'{self.description}: {self.timer.stop():.4f} sec')
def split_batch(X, y, devices):
"""将X和y拆分到多个设备上
Defined in :numref:`sec_multi_gpu`"""
assert X.shape[0] == y.shape[0]
return (paddlescatter(X, devices),
paddlescatter(y, devices))
def resnet18(num_classes, in_channels=1):
"""稍加修改的ResNet-18模型
Defined in :numref:`sec_multi_gpu_concise`"""
def resnet_block(in_channels, out_channels, num_residuals,
first_block=False):
blk = []
for i in range(num_residuals):
if i == 0 and not first_block:
blk.append(d2l.Residual(in_channels, out_channels,
use_1x1conv=True, strides=2))
else:
blk.append(d2l.Residual(out_channels, out_channels))
return nn.Sequential(*blk)
View on GitHub (pinned to e6b18ccea7)
Solutions
- Draw X and y from the same batch tuple: for X, y in train_iter: X, y = split_batch(X, y, devices) — never assemble them separately.
- If building batches manually, assert X.shape[0] == y.shape[0] yourself before split_batch with a message including both shapes.
- Fix custom collate/transpose functions that change one tensor's leading dimension (e.g. reshape without -1).
- Verify no drop_last=True/False asymmetry between multiple iterators feeding the same step.
Example fix
# before (X, y from different batches)
X = next(it_x); y = next(it_y)
split_batch(X, y, devices) # AssertionError if sizes differ
# after (aligned batch)
for X, y in train_iter:
X_shards, y_shards = split_batch(X, y, devices) Defensive patterns
Strategy: validation
Validate before calling
if X.shape[0] != y.shape[0]:
raise ValueError(f'batch size mismatch: X={X.shape[0]} vs y={y.shape[0]}; '
f'load X and y from the same batch tuple')
X_shards, y_shards = split_batch(X, y, devices) Type guard
def is_aligned_batch(X, y) -> bool:
return X.shape[0] == y.shape[0] Try / catch
try:
split_batch(X, y, devices)
except AssertionError:
raise ValueError(f'X batch {X.shape[0]} != y batch {y.shape[0]}; '
f'check data pipeline alignment') from None Prevention
- Always unpack X, y from the same yielded batch; never interleave two iterators.
- Check custom collate/reshape functions preserve the leading dimension (use reshape(-1, ...) where needed).
- Assert alignment yourself with an informative message before calling split_batch.
When it happens
Trigger: Passing X and y produced by different data pipelines (e.g. y from a previous batch); a custom collate that pads X but not y; off-by-one slicing when manually batching (X = batch[:256], y = batch[1:257]); mixing a shuffled iterator for X with an unshuffled one for y.
Common situations: Hand-rolled training loops around train_batch_ch13/split_batch in the multi-GPU chapter; datasets where __getitem__ returns misaligned pairs; copying single-GPU code that never checked the invariant and only failing when moving to multiple devices.
Related errors
- X.shape[0] == y.shape[0]
- X.shape[0] == y.shape[0]
- train_loss < 0.5
- train_acc <= 1 and train_acc > 0.7
- test_acc <= 1 and test_acc > 0.7
AI-assisted analysis of d2l-ai/d2l-zh@e6b18ccea7 (2026-08-14).
Data as JSON: /api/errors/ed7f9945bbe86800.
Report an issue: GitHub.