{"record":{"id":"a7ff4e04dd9fef20","repo":"sgl-project/sglang","slug":"patch-size-must-be-greater-than-1-otherwise-this","errorCode":null,"errorMessage":"patch_size must be greater than 1, otherwise this doesn't make sense","messagePattern":"patch_size must be greater than 1, otherwise this doesn't make sense","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/models/inkling_common/hmlp.py","lineNumber":42,"sourceCode":"\n    p = 3\n    while p * p <= n:\n        while n % p == 0:\n            factors.append(p)\n            n //= p\n        p += 2\n\n    if n > 1:\n        factors.append(n)\n    return factors\n\n\ndef plan_out_scales(\n    temporal_patch_size: int, patch_size: int, n_layers: int, n_channels: int = 3\n) -> list[tuple[int, int, int, int]]:\n    \"\"\"Plan the ``(time, height, width, channels)`` scale at each HMLP layer.\"\"\"\n    if patch_size <= 1:\n        raise ValueError(\n            \"patch_size must be greater than 1, otherwise this doesn't make sense\"\n        )\n\n    def _round_up(x: int) -> int:\n        return int(np.ceil(x / 64)) * 64\n\n    last_h_scale = 1\n    scales: list[tuple[int, int, int, int]] = [(1, 1, 1, n_channels)]\n    for pscale in _prime_factors(patch_size)[::-1]:\n        last_h_scale *= pscale\n        scales.append(\n            (\n                1,\n                last_h_scale,\n                last_h_scale,\n                _round_up((last_h_scale**2) * n_channels),\n            )\n        )","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/models/inkling_common/hmlp.py#L24-L60","documentation":"plan_out_scales refuses patch_size <= 1 because the whole point of patch planning is to compute downscaled (time,height,width,channel) shapes per HMLP layer; with patch 1 there is no downsampling and the scale plan is meaningless. It is a configuration sanity check at model init time.","triggerScenarios":"Constructing the Inkling HMLP (init -> plan_out_scales) with a vision config whose patch_size is 1 or 0 (or a temporal_patch_size mistakenly passed in the patch_size slot).","commonSituations":"Custom/converted vision encoder configs with patch_size: 1; argument order mistakes when calling plan_out_scales directly; text-only configs reused for a vision tower; typos in exported checkpoints.","solutions":["Set a real patch size (> 1, e.g. 14 or 16) in the vision config","Check argument order if calling plan_out_scales manually — patch_size is the 2nd positional arg","If the model truly has no patching, bypass the HMLP scale planner rather than passing 1"],"exampleFix":"# before\nplan_out_scales(temporal_patch_size=2, patch_size=1, n_layers=8)\n# after\nplan_out_scales(temporal_patch_size=2, patch_size=16, n_layers=8)","handlingStrategy":"validation","validationCode":"assert patch_size > 1, f\"patch_size={patch_size} must be > 1\"\nplan_out_scales(temporal_patch_size, patch_size, n_layers)","typeGuard":"def valid_patch_size(p) -> bool: return isinstance(p, int) and p > 1","tryCatchPattern":null,"preventionTips":["Validate vision patch_size at config load","Use keyword args when calling plan_out_scales to avoid positional mix-ups","Reject converted checkpoints with patch_size <= 1 during export validation"],"tags":["sglang","value-error","vision-encoder","config-validation","inkling"],"backgroundTag":"invalid-argument-validation","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}