{"record":{"id":"e4bcdb869c0a4f63","repo":"sgl-project/sglang","slug":"perturbation-configs-length-must-match-batch-size","errorCode":null,"errorMessage":"perturbation_configs length must match batch size, got {len(perturbation_configs)=} {batch_size=}.","messagePattern":"perturbation_configs length must match batch size, got (.+?) (.+?)\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/models/dits/ltx_2.py","lineNumber":2000,"sourceCode":"        video_memory_prefix_len: int = 0,\n        late_layer_ratio: float = 1.0,\n        late_audio_self_attention_mask: Optional[torch.Tensor] = None,\n        **kwargs,\n    ) -> tuple[torch.Tensor | None, torch.Tensor | None]:\n        batch_size = hidden_states.size(0)\n        audio_timestep = audio_timestep if audio_timestep is not None else timestep\n\n        if num_frames is None or height is None or width is None:\n            raise ValueError(\n                \"num_frames/height/width must be provided for RoPE coordinate generation.\"\n            )\n        if audio_num_frames is None:\n            raise ValueError(\n                \"audio_num_frames must be provided for RoPE coordinate generation.\"\n            )\n        perturbation_configs = kwargs.get(\"perturbation_configs\")\n        if perturbation_configs is not None and len(perturbation_configs) != batch_size:\n            raise ValueError(\n                \"perturbation_configs length must match batch size, got \"\n                f\"{len(perturbation_configs)=} {batch_size=}.\"\n            )\n\n        if video_coords is None:\n            # Wan-style SP-RoPE: when SP is enabled, each rank runs on its local\n            # time shard but RoPE positions must be offset to global time.\n            #\n            # We assume equal time sharding across SP ranks.\n            if model_parallel_is_initialized():\n                sp_world_size = get_sp_world_size()\n                sp_rank = get_sp_parallel_rank()\n            else:\n                sp_world_size = 1\n                sp_rank = 0\n\n            video_shift = int(sp_rank) * int(num_frames) if sp_world_size > 1 else 0\n            video_coords = self.rope.prepare_video_coords(","sourceCodeStart":1982,"sourceCodeEnd":2018,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/models/dits/ltx_2.py#L1982-L2018","documentation":"When the optional perturbation_configs kwarg is supplied (flow-matching perturbation schedules per sample), its length must equal the batch size of hidden_states. A mismatch would misalign per-sample perturbation handling, so forward validates it.","triggerScenarios":"Calling forward with hidden_states of batch B but a perturbation_configs list of a different length — e.g. batching multiple requests while reusing a single-sample perturbation config, or vice versa.","commonSituations":"Continuous batching/scheduler changes that resize hidden_states without regenerating perturbation configs; static single-sample configs reused after batch aggregation; off-by-one when slicing configs per chunk.","solutions":["Regenerate perturbation_configs per batch with len == hidden_states.size(0), or pass None to disable perturbation","Slice/expand the config list to the current batch size before forward (e.g. [cfg[0]] * batch_size if the config is batch-homogeneous)","Add an assert in the batching layer that config count tracks batch size"],"exampleFix":"# before\nout = model(hidden_states, ..., perturbation_configs=cfgs)  # len(cfgs)=1, batch=4\n\n# after\ncfgs = cfgs * hidden_states.size(0)\nout = model(hidden_states, ..., perturbation_configs=cfgs)","handlingStrategy":"validation","validationCode":"if perturbation_configs is not None:\n    assert len(perturbation_configs) == hidden_states.size(0), 'config/batch mismatch'\n    # or: perturbation_configs = perturbation_configs * hidden_states.size(0)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Regenerate per-sample configs after every rebatch","Assert config length equals batch size in the scheduler"],"tags":["batch-mismatch","perturbation","flow-matching","ltx-2","forward"],"backgroundTag":"batch-size-mismatch","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}