{"record":{"id":"ed7f9945bbe86800","repo":"d2l-ai/d2l-zh","slug":"x-shape-0-y-shape-0-ed7f99","errorCode":null,"errorMessage":"X.shape[0] == y.shape[0]","messagePattern":"X\\.shape\\[0\\] == y\\.shape\\[0\\]","errorType":"validation","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"d2l/paddle.py","lineNumber":1483,"sourceCode":"\nclass Benchmark:\n    \"\"\"用于测量运行时间\"\"\"\n    def __init__(self, description='Done'):\n        \"\"\"Defined in :numref:`sec_hybridize`\"\"\"\n        self.description = description\n\n    def __enter__(self):\n        self.timer = d2l.Timer()\n        return self\n\n    def __exit__(self, *args):\n        print(f'{self.description}: {self.timer.stop():.4f} sec')\n\ndef split_batch(X, y, devices):\n    \"\"\"将X和y拆分到多个设备上\n\n    Defined in :numref:`sec_multi_gpu`\"\"\"\n    assert X.shape[0] == y.shape[0]\n    return (paddlescatter(X, devices),\n            paddlescatter(y, devices))\n\ndef resnet18(num_classes, in_channels=1):\n    \"\"\"稍加修改的ResNet-18模型\n\n    Defined in :numref:`sec_multi_gpu_concise`\"\"\"\n    def resnet_block(in_channels, out_channels, num_residuals,\n                     first_block=False):\n        blk = []\n        for i in range(num_residuals):\n            if i == 0 and not first_block:\n                blk.append(d2l.Residual(in_channels, out_channels,\n                                        use_1x1conv=True, strides=2))\n            else:\n                blk.append(d2l.Residual(out_channels, out_channels))\n        return nn.Sequential(*blk)\n","sourceCodeStart":1465,"sourceCodeEnd":1501,"githubUrl":"https://github.com/d2l-ai/d2l-zh/blob/e6b18ccea71451a55fcd861d7b96fddf2587b09a/d2l/paddle.py#L1465-L1501","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before (X, y from different batches)\nX = next(it_x); y = next(it_y)\nsplit_batch(X, y, devices)  # AssertionError if sizes differ\n# after (aligned batch)\nfor X, y in train_iter:\n    X_shards, y_shards = split_batch(X, y, devices)","handlingStrategy":"validation","validationCode":"if X.shape[0] != y.shape[0]:\n    raise ValueError(f'batch size mismatch: X={X.shape[0]} vs y={y.shape[0]}; '\n                     f'load X and y from the same batch tuple')\nX_shards, y_shards = split_batch(X, y, devices)","typeGuard":"def is_aligned_batch(X, y) -> bool:\n    return X.shape[0] == y.shape[0]","tryCatchPattern":"try:\n    split_batch(X, y, devices)\nexcept AssertionError:\n    raise ValueError(f'X batch {X.shape[0]} != y batch {y.shape[0]}; '\n                     f'check data pipeline alignment') from None","preventionTips":["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."],"tags":["d2l","paddle","multi-gpu","data-loading","assertion","batching"],"backgroundTag":null,"analyzedSha":"e6b18ccea71451a55fcd861d7b96fddf2587b09a","analyzedAt":"2026-08-14T20:05:26.414Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}