{"record":{"id":"f11baf3242a1f1f3","repo":"hiyouga/LlamaFactory","slug":"batching-strategy-self-batching-strategy-value-r","errorCode":null,"errorMessage":"batching_strategy={self.batching_strategy.value!r} does not support multimodal data; use the NORMAL strategy for image/video training.","messagePattern":"batching_strategy=(.+?) does not support multimodal data; use the NORMAL strategy for image/video training\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"src/llamafactory/v1/core/utils/batching.py","lineNumber":328,"sourceCode":"                    samples: list[ModelInput] = next(self._data_iter)\n                except StopIteration:\n                    break\n\n                self._buffer.put(self._drop_unsupervised(samples))\n        else:\n            from ...plugins.trainer_plugins.batching import BatchingPlugin\n\n            BatchingPlugin(self.batching_strategy).fill_buffer(self._buffer, self._batch_info, self._next_samples)\n\n    def _generate_batch(self) -> list[BatchInput] | None:\n        if self.batching_strategy == BatchingStrategy.NORMAL:\n            return default_collate_fn(self._buffer, self._batch_info, self.renderer)\n        else:\n            # Non-NORMAL strategies (dynamic / padding_free) collate ragged pixel tensors with a\n            # bare default_collate and have no vision-tower alignment, so multimodal data would\n            # crash or hang. Fail loud instead of silently mishandling it.\n            if any(k in s for s in self._buffer.samples for k in _MULTIMODAL_PASSTHROUGH_KEYS):\n                raise NotImplementedError(\n                    f\"batching_strategy={self.batching_strategy.value!r} does not support multimodal data; \"\n                    \"use the NORMAL strategy for image/video training.\"\n                )\n\n            from ...plugins.trainer_plugins.batching import BatchingPlugin\n\n            return BatchingPlugin(self.batching_strategy).generate_batch(self._buffer, self._batch_info)\n\n    def _next_samples(self, restart: bool) -> list[ModelInput] | None:\n        try:\n            return next(self._data_iter)\n        except StopIteration:\n            if not restart:\n                return None\n\n            # Dynamic batching may restart the provider to fill one token-budgeted batch.\n            self._data_iter = iter(self._data_provider)\n            try:","sourceCodeStart":310,"sourceCodeEnd":346,"githubUrl":"https://github.com/hiyouga/LlamaFactory/blob/f28afaf6355af515454dfb16c97d728307c93897/src/llamafactory/v1/core/utils/batching.py#L310-L346","documentation":"Non-NORMAL batching strategies (dynamic/packing/padding_free) collate ragged multimodal tensors with a bare default_collate and have no vision-tower alignment, so image/video/audio batches would crash or corrupt training. The scheduler detects any _MULTIMODAL_PASSTHROUGH_KEYS (pixel_values, input_features, etc.) in buffered samples under a non-NORMAL strategy and raises NotImplementedError instead of mishandling the data.","triggerScenarios":"Training a multimodal model with batching_strategy set to a packing/dynamic/padding_free strategy while samples carry pixel_values/video/input_features keys (i.e. media was successfully rendered).","commonSituations":"Copying a text-model efficiency config (packing or padding_free for throughput) onto a vision/audio fine-tune; enabling efficient batching globally in a shared YAML that is also used for VLM runs.","solutions":["Set batching_strategy to BatchingStrategy.NORMAL for the multimodal run","Keep separate config profiles: packing/padding_free for text models, NORMAL for image/video/audio models","Remove literal media placeholder text if media was unintentional (sample should not carry mm passthrough keys for pure-text training)"],"exampleFix":"# before\nscheduler = Batching(..., batching_strategy=BatchingStrategy.PACKING)  # with image samples -> NotImplementedError\n\n# after\nfrom llamafactory.v1.core.utils.batching import BatchingStrategy\nscheduler = Batching(..., batching_strategy=BatchingStrategy.NORMAL)","handlingStrategy":"validation","validationCode":"def strategy_allows_multimodal(strategy, samples) -> bool:\n    if strategy == BatchingStrategy.NORMAL:\n        return True\n    return not any(k in s for s in samples for k in (\"pixel_values\", \"input_features\", \"video_grid_thw\"))","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep two config profiles: NORMAL for multimodal, packing/padding_free for text-only","CI-test multimodal training with the exact batching_strategy you ship"],"tags":["batching","multimodal","packing","not-implemented","training"],"backgroundTag":null,"analyzedSha":"f28afaf6355af515454dfb16c97d728307c93897","analyzedAt":"2026-08-14T21:57:28.298Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}